[LibvpxVp8Encoder] Allow I420A to be scaled to I420.

In Chromium, the I420ABufferInterface implementation uses the default
CropAndScale() implementation which converts to I420 in the process.

This should be OK, because we do not encode the alpha channel anyway,
so having WebRTC scaling ignore the alpha channel might even be a good
thing. Unfortunatety, an if statement in the LibvpxVp8Encoder did not
consider I420A and I420 to be the same, resulting in dropping perfectly
valid frames.

This CL fixes that by considering I420A and I420 "compatible" in a
comparison helper function. The problem only happens in this encoder,
so only this encoder needs to be fixed.

Bug: chromium:1203206
Change-Id: Iec434d4ada897c79e09914cac823148fd5b05e57
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/216323
Reviewed-by: Evan Shrubsole <eshr@google.com>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33845}
This commit is contained in:
Henrik Boström
2021-04-27 11:35:07 +02:00
committed by Commit Bot
parent fad23c1ff3
commit 065ce9cb22

View File

@ -161,6 +161,18 @@ void ApplyVp8EncoderConfigToVpxConfig(const Vp8EncoderConfig& encoder_config,
} }
} }
bool IsCompatibleVideoFrameBufferType(VideoFrameBuffer::Type left,
VideoFrameBuffer::Type right) {
if (left == VideoFrameBuffer::Type::kI420 ||
left == VideoFrameBuffer::Type::kI420A) {
// LibvpxVp8Encoder does not care about the alpha channel, I420A and I420
// are considered compatible.
return right == VideoFrameBuffer::Type::kI420 ||
right == VideoFrameBuffer::Type::kI420A;
}
return left == right;
}
void SetRawImagePlanes(vpx_image_t* raw_image, VideoFrameBuffer* buffer) { void SetRawImagePlanes(vpx_image_t* raw_image, VideoFrameBuffer* buffer) {
switch (buffer->type()) { switch (buffer->type()) {
case VideoFrameBuffer::Type::kI420: case VideoFrameBuffer::Type::kI420:
@ -1378,7 +1390,8 @@ LibvpxVp8Encoder::PrepareBuffers(rtc::scoped_refptr<VideoFrameBuffer> buffer) {
} }
RTC_DCHECK_EQ(scaled_buffer->type(), mapped_buffer->type()) RTC_DCHECK_EQ(scaled_buffer->type(), mapped_buffer->type())
<< "Scaled frames must have the same type as the mapped frame."; << "Scaled frames must have the same type as the mapped frame.";
if (scaled_buffer->type() != mapped_buffer->type()) { if (!IsCompatibleVideoFrameBufferType(scaled_buffer->type(),
mapped_buffer->type())) {
RTC_LOG(LS_ERROR) << "When scaling " RTC_LOG(LS_ERROR) << "When scaling "
<< VideoFrameBufferTypeToString(buffer_to_scale->type()) << VideoFrameBufferTypeToString(buffer_to_scale->type())
<< ", the image was unexpectedly converted to " << ", the image was unexpectedly converted to "