From f906ec40d4428733fb0ef5aa8a895719e07ad69e Mon Sep 17 00:00:00 2001 From: Evan Shrubsole Date: Mon, 21 Jun 2021 13:47:44 +0200 Subject: [PATCH] Handle null return from ToI420 in encoders In cases where ToI420 fails it should be able to return null. Bug: webrtc:12877 Change-Id: Ia13859c104d978a29712ae10f8e15acada8406ac Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/222613 Reviewed-by: Ilya Nikolaevskiy Commit-Queue: Evan Shrubsole Cr-Commit-Position: refs/heads/master@{#34342} --- .../codecs/av1/libaom_av1_encoder.cc | 14 ++++++++++++++ .../codecs/vp8/libvpx_vp8_encoder.cc | 7 +++++++ .../codecs/vp9/libvpx_vp9_encoder.cc | 17 +++++++++++++++-- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/modules/video_coding/codecs/av1/libaom_av1_encoder.cc b/modules/video_coding/codecs/av1/libaom_av1_encoder.cc index 84f3453630..3b5fdd78e2 100644 --- a/modules/video_coding/codecs/av1/libaom_av1_encoder.cc +++ b/modules/video_coding/codecs/av1/libaom_av1_encoder.cc @@ -588,12 +588,26 @@ int32_t LibaomAv1Encoder::Encode( // kNative. As a workaround to this, we perform ToI420() a second time. // TODO(https://crbug.com/webrtc/12602): When Android buffers have a correct // ToI420() implementaion, remove his workaround. + if (!converted_buffer) { + RTC_LOG(LS_ERROR) << "Failed to convert " + << VideoFrameBufferTypeToString( + converted_buffer->type()) + << " image to I420. Can't encode frame."; + return WEBRTC_VIDEO_CODEC_ENCODER_FAILURE; + } if (converted_buffer->type() != VideoFrameBuffer::Type::kI420 && converted_buffer->type() != VideoFrameBuffer::Type::kI420A) { converted_buffer = converted_buffer->ToI420(); RTC_CHECK(converted_buffer->type() == VideoFrameBuffer::Type::kI420 || converted_buffer->type() == VideoFrameBuffer::Type::kI420A); } + if (!converted_buffer) { + RTC_LOG(LS_ERROR) << "Failed to convert " + << VideoFrameBufferTypeToString( + converted_buffer->type()) + << " image to I420. Can't encode frame."; + return WEBRTC_VIDEO_CODEC_ENCODER_FAILURE; + } prepped_input_frame = VideoFrame(converted_buffer, frame.timestamp(), frame.render_time_ms(), frame.rotation()); } diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc index dd72872ed8..e2849dbe6f 100644 --- a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc +++ b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc @@ -1336,6 +1336,13 @@ LibvpxVp8Encoder::PrepareBuffers(rtc::scoped_refptr buffer) { if (converted_buffer->type() != VideoFrameBuffer::Type::kI420 && converted_buffer->type() != VideoFrameBuffer::Type::kI420A) { converted_buffer = converted_buffer->ToI420(); + if (!converted_buffer) { + RTC_LOG(LS_ERROR) << "Failed to convert " + << VideoFrameBufferTypeToString( + converted_buffer->type()) + << " image to I420. Can't encode frame."; + return {}; + } RTC_CHECK(converted_buffer->type() == VideoFrameBuffer::Type::kI420 || converted_buffer->type() == VideoFrameBuffer::Type::kI420A); } diff --git a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc index 2a7b125d36..511e6df585 100644 --- a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc +++ b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc @@ -1068,8 +1068,15 @@ int LibvpxVp9Encoder::Encode(const VideoFrame& input_image, break; } default: { - i010_copy = - I010Buffer::Copy(*input_image.video_frame_buffer()->ToI420()); + auto i420_buffer = input_image.video_frame_buffer()->ToI420(); + if (!i420_buffer) { + RTC_LOG(LS_ERROR) << "Failed to convert " + << VideoFrameBufferTypeToString( + input_image.video_frame_buffer()->type()) + << " image to I420. Can't encode frame."; + return WEBRTC_VIDEO_CODEC_ERROR; + } + i010_copy = I010Buffer::Copy(*i420_buffer); i010_buffer = i010_copy.get(); } } @@ -1908,6 +1915,12 @@ rtc::scoped_refptr LibvpxVp9Encoder::PrepareBufferForProfile0( if (converted_buffer->type() != VideoFrameBuffer::Type::kI420 && converted_buffer->type() != VideoFrameBuffer::Type::kI420A) { converted_buffer = converted_buffer->ToI420(); + if (!converted_buffer) { + RTC_LOG(LS_ERROR) << "Failed to convert " + << VideoFrameBufferTypeToString(buffer->type()) + << " image to I420. Can't encode frame."; + return {}; + } RTC_CHECK(converted_buffer->type() == VideoFrameBuffer::Type::kI420 || converted_buffer->type() == VideoFrameBuffer::Type::kI420A); }