diff options
author | emircan <emircan@chromium.org> | 2016-01-15 00:59:27 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-01-15 09:00:38 +0000 |
commit | 8428d41278c107c107736454dc4fdddbd14969bd (patch) | |
tree | ed8c911e772aecc90b7f610f65abf8f33e357d12 | |
parent | 4977dd61169929d41ac1ff5d50c3b194bce71e60 (diff) | |
download | chromium_src-8428d41278c107c107736454dc4fdddbd14969bd.zip chromium_src-8428d41278c107c107736454dc4fdddbd14969bd.tar.gz chromium_src-8428d41278c107c107736454dc4fdddbd14969bd.tar.bz2 |
Verify returned frames from media::VideoFrame::Wrap*() methods
BUG=552112
CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel
Review URL: https://codereview.chromium.org/1476523005
Cr-Commit-Position: refs/heads/master@{#369705}
26 files changed, 181 insertions, 89 deletions
diff --git a/cc/layers/video_layer_impl_unittest.cc b/cc/layers/video_layer_impl_unittest.cc index b5f1c0f..3558376 100644 --- a/cc/layers/video_layer_impl_unittest.cc +++ b/cc/layers/video_layer_impl_unittest.cc @@ -343,6 +343,7 @@ TEST(VideoLayerImplTest, NativeYUVFrameGeneratesYUVQuad) { mailbox_holder, mailbox_holder, mailbox_holder, base::Bind(EmptyCallback), gfx::Size(10, 10), gfx::Rect(10, 10), gfx::Size(10, 10), base::TimeDelta()); + ASSERT_TRUE(video_frame); video_frame->metadata()->SetBoolean(media::VideoFrameMetadata::ALLOW_OVERLAY, true); FakeVideoFrameProvider provider; diff --git a/cc/resources/video_resource_updater_unittest.cc b/cc/resources/video_resource_updater_unittest.cc index 064829e..5186aab 100644 --- a/cc/resources/video_resource_updater_unittest.cc +++ b/cc/resources/video_resource_updater_unittest.cc @@ -87,18 +87,21 @@ class VideoResourceUpdaterTest : public testing::Test { static uint8_t u_data[kDimension * kDimension / 2] = {0}; static uint8_t v_data[kDimension * kDimension / 2] = {0}; - return media::VideoFrame::WrapExternalYuvData( - media::PIXEL_FORMAT_YV16, // format - size, // coded_size - gfx::Rect(size), // visible_rect - size, // natural_size - size.width(), // y_stride - size.width() / 2, // u_stride - size.width() / 2, // v_stride - y_data, // y_data - u_data, // u_data - v_data, // v_data - base::TimeDelta()); // timestamp + scoped_refptr<media::VideoFrame> video_frame = + media::VideoFrame::WrapExternalYuvData( + media::PIXEL_FORMAT_YV16, // format + size, // coded_size + gfx::Rect(size), // visible_rect + size, // natural_size + size.width(), // y_stride + size.width() / 2, // u_stride + size.width() / 2, // v_stride + y_data, // y_data + u_data, // u_data + v_data, // v_data + base::TimeDelta()); // timestamp + EXPECT_TRUE(video_frame); + return video_frame; } static void ReleaseMailboxCB(const gpu::SyncToken& sync_token) {} @@ -112,14 +115,17 @@ class VideoResourceUpdaterTest : public testing::Test { const gpu::SyncToken sync_token(7); const unsigned target = GL_TEXTURE_2D; - return media::VideoFrame::WrapNativeTexture( - media::PIXEL_FORMAT_ARGB, - gpu::MailboxHolder(mailbox, sync_token, target), - base::Bind(&ReleaseMailboxCB), - size, // coded_size - gfx::Rect(size), // visible_rect - size, // natural_size - base::TimeDelta()); // timestamp + scoped_refptr<media::VideoFrame> video_frame = + media::VideoFrame::WrapNativeTexture( + media::PIXEL_FORMAT_ARGB, + gpu::MailboxHolder(mailbox, sync_token, target), + base::Bind(&ReleaseMailboxCB), + size, // coded_size + gfx::Rect(size), // visible_rect + size, // natural_size + base::TimeDelta()); // timestamp + EXPECT_TRUE(video_frame); + return video_frame; } scoped_refptr<media::VideoFrame> CreateTestYUVHardareVideoFrame() { @@ -133,18 +139,21 @@ class VideoResourceUpdaterTest : public testing::Test { } const gpu::SyncToken sync_token(7); const unsigned target = GL_TEXTURE_RECTANGLE_ARB; - return media::VideoFrame::WrapYUV420NativeTextures( - gpu::MailboxHolder(mailbox[media::VideoFrame::kYPlane], sync_token, - target), - gpu::MailboxHolder(mailbox[media::VideoFrame::kUPlane], sync_token, - target), - gpu::MailboxHolder(mailbox[media::VideoFrame::kVPlane], sync_token, - target), - base::Bind(&ReleaseMailboxCB), - size, // coded_size - gfx::Rect(size), // visible_rect - size, // natural_size - base::TimeDelta()); // timestamp + scoped_refptr<media::VideoFrame> video_frame = + media::VideoFrame::WrapYUV420NativeTextures( + gpu::MailboxHolder(mailbox[media::VideoFrame::kYPlane], sync_token, + target), + gpu::MailboxHolder(mailbox[media::VideoFrame::kUPlane], sync_token, + target), + gpu::MailboxHolder(mailbox[media::VideoFrame::kVPlane], sync_token, + target), + base::Bind(&ReleaseMailboxCB), + size, // coded_size + gfx::Rect(size), // visible_rect + size, // natural_size + base::TimeDelta()); // timestamp + EXPECT_TRUE(video_frame); + return video_frame; } WebGraphicsContext3DUploadCounter* context3d_; diff --git a/cc/trees/layer_tree_host_unittest_context.cc b/cc/trees/layer_tree_host_unittest_context.cc index 314e484..c84cc80 100644 --- a/cc/trees/layer_tree_host_unittest_context.cc +++ b/cc/trees/layer_tree_host_unittest_context.cc @@ -1022,16 +1022,19 @@ class LayerTreeHostContextTestDontUseLostResources color_video_frame_ = VideoFrame::CreateColorFrame( gfx::Size(4, 4), 0x80, 0x80, 0x80, base::TimeDelta()); + ASSERT_TRUE(color_video_frame_); hw_video_frame_ = VideoFrame::WrapNativeTexture( media::PIXEL_FORMAT_ARGB, gpu::MailboxHolder(mailbox, sync_token, GL_TEXTURE_2D), media::VideoFrame::ReleaseMailboxCB(), gfx::Size(4, 4), gfx::Rect(0, 0, 4, 4), gfx::Size(4, 4), base::TimeDelta()); + ASSERT_TRUE(hw_video_frame_); scaled_hw_video_frame_ = VideoFrame::WrapNativeTexture( media::PIXEL_FORMAT_ARGB, gpu::MailboxHolder(mailbox, sync_token, GL_TEXTURE_2D), media::VideoFrame::ReleaseMailboxCB(), gfx::Size(4, 4), gfx::Rect(0, 0, 3, 2), gfx::Size(4, 4), base::TimeDelta()); + ASSERT_TRUE(scaled_hw_video_frame_); color_frame_provider_.set_frame(color_video_frame_); hw_frame_provider_.set_frame(hw_video_frame_); diff --git a/chromecast/renderer/media/hole_frame_factory.cc b/chromecast/renderer/media/hole_frame_factory.cc index c4f26e6..e62378e 100644 --- a/chromecast/renderer/media/hole_frame_factory.cc +++ b/chromecast/renderer/media/hole_frame_factory.cc @@ -64,6 +64,7 @@ scoped_refptr<::media::VideoFrame> HoleFrameFactory::CreateHoleFrame( gfx::Rect(size), // visible rect size, // natural size base::TimeDelta()); // timestamp + CHECK(frame); frame->metadata()->SetBoolean(::media::VideoFrameMetadata::ALLOW_OVERLAY, true); return frame; diff --git a/content/browser/renderer_host/media/video_capture_controller_unittest.cc b/content/browser/renderer_host/media/video_capture_controller_unittest.cc index d1400bc..99e563f 100644 --- a/content/browser/renderer_host/media/video_capture_controller_unittest.cc +++ b/content/browser/renderer_host/media/video_capture_controller_unittest.cc @@ -122,11 +122,14 @@ class VideoCaptureControllerTest : public testing::Test { scoped_refptr<media::VideoFrame> WrapI420Buffer(gfx::Size dimensions, uint8_t* data) { - return media::VideoFrame::WrapExternalSharedMemory( - media::PIXEL_FORMAT_I420, dimensions, gfx::Rect(dimensions), dimensions, - data, - media::VideoFrame::AllocationSize(media::PIXEL_FORMAT_I420, dimensions), - base::SharedMemory::NULLHandle(), 0u, base::TimeDelta()); + scoped_refptr<media::VideoFrame> video_frame = + media::VideoFrame::WrapExternalSharedMemory( + media::PIXEL_FORMAT_I420, dimensions, gfx::Rect(dimensions), + dimensions, data, media::VideoFrame::AllocationSize( + media::PIXEL_FORMAT_I420, dimensions), + base::SharedMemory::NULLHandle(), 0u, base::TimeDelta()); + EXPECT_TRUE(video_frame); + return video_frame; } TestBrowserThreadBundle bundle_; @@ -317,6 +320,7 @@ TEST_F(VideoCaptureControllerTest, NormalCaptureMultipleClients) { } scoped_refptr<media::VideoFrame> video_frame = WrapI420Buffer(capture_resolution, static_cast<uint8_t*>(buffer->data())); + ASSERT_TRUE(video_frame); ASSERT_FALSE(video_frame->metadata()->HasKey( media::VideoFrameMetadata::RESOURCE_UTILIZATION)); client_a_->resource_utilization_ = 0.5; @@ -346,6 +350,7 @@ TEST_F(VideoCaptureControllerTest, NormalCaptureMultipleClients) { memset(buffer2->data(), buffer_no++, buffer2->mapped_size()); video_frame = WrapI420Buffer(capture_resolution, static_cast<uint8_t*>(buffer2->data())); + ASSERT_TRUE(video_frame); ASSERT_FALSE(video_frame->metadata()->HasKey( media::VideoFrameMetadata::RESOURCE_UTILIZATION)); client_a_->resource_utilization_ = 0.5; @@ -392,6 +397,7 @@ TEST_F(VideoCaptureControllerTest, NormalCaptureMultipleClients) { memset(buffer->data(), buffer_no++, buffer->mapped_size()); video_frame = WrapI420Buffer(capture_resolution, static_cast<uint8_t*>(buffer->data())); + ASSERT_TRUE(video_frame); device_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame, base::TimeTicks()); } @@ -440,6 +446,7 @@ TEST_F(VideoCaptureControllerTest, NormalCaptureMultipleClients) { memset(buffer3->data(), buffer_no++, buffer3->mapped_size()); video_frame = WrapI420Buffer(capture_resolution, static_cast<uint8_t*>(buffer3->data())); + ASSERT_TRUE(video_frame); device_->OnIncomingCapturedVideoFrame(std::move(buffer3), video_frame, base::TimeTicks()); @@ -457,6 +464,7 @@ TEST_F(VideoCaptureControllerTest, NormalCaptureMultipleClients) { memset(buffer4->data(), buffer_no++, buffer4->mapped_size()); video_frame = WrapI420Buffer(capture_resolution, static_cast<uint8_t*>(buffer4->data())); + ASSERT_TRUE(video_frame); device_->OnIncomingCapturedVideoFrame(std::move(buffer4), video_frame, base::TimeTicks()); // B2 is the only client left, and is the only one that should @@ -505,6 +513,7 @@ TEST_F(VideoCaptureControllerTest, ErrorBeforeDeviceCreation) { ASSERT_TRUE(buffer.get()); scoped_refptr<media::VideoFrame> video_frame = WrapI420Buffer(capture_resolution, static_cast<uint8_t*>(buffer->data())); + ASSERT_TRUE(video_frame); device_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame, base::TimeTicks()); @@ -542,6 +551,7 @@ TEST_F(VideoCaptureControllerTest, ErrorAfterDeviceCreation) { scoped_refptr<media::VideoFrame> video_frame = WrapI420Buffer(dims, static_cast<uint8_t*>(buffer->data())); + ASSERT_TRUE(video_frame); device_->OnError(FROM_HERE, "Test Error"); device_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame, base::TimeTicks()); diff --git a/content/browser/renderer_host/media/video_capture_device_client.cc b/content/browser/renderer_host/media/video_capture_device_client.cc index 28a5f67..b4d142e 100644 --- a/content/browser/renderer_host/media/video_capture_device_client.cc +++ b/content/browser/renderer_host/media/video_capture_device_client.cc @@ -368,7 +368,8 @@ void VideoCaptureDeviceClient::OnIncomingCapturedBuffer( base::SharedMemory::NULLHandle(), 0u, base::TimeDelta()); break; } - DCHECK(frame.get()); + if (!frame) + return; frame->metadata()->SetDouble(media::VideoFrameMetadata::FRAME_RATE, frame_format.frame_rate); OnIncomingCapturedVideoFrame(std::move(buffer), frame, timestamp); diff --git a/content/common/gpu/media/gpu_jpeg_decode_accelerator.cc b/content/common/gpu/media/gpu_jpeg_decode_accelerator.cc index 1082b5c..7408e46 100644 --- a/content/common/gpu/media/gpu_jpeg_decode_accelerator.cc +++ b/content/common/gpu/media/gpu_jpeg_decode_accelerator.cc @@ -248,9 +248,6 @@ class GpuJpegDecodeAccelerator::MessageFilter : public IPC::MessageFilter { params.output_video_frame_handle, // handle 0, // data_offset base::TimeDelta()); // timestamp - frame->AddDestructionObserver( - base::Bind(DecodeFinished, base::Passed(&output_shm))); - if (!frame.get()) { LOG(ERROR) << "Could not create VideoFrame for input buffer id " << params.input_buffer_id; @@ -260,6 +257,8 @@ class GpuJpegDecodeAccelerator::MessageFilter : public IPC::MessageFilter { base::SharedMemory::CloseHandle(params.input_buffer_handle); return; } + frame->AddDestructionObserver( + base::Bind(DecodeFinished, base::Passed(&output_shm))); DCHECK_GT(client_map_.count(*route_id), 0u); Client* client = client_map_[*route_id]; diff --git a/content/common/gpu/media/gpu_video_encode_accelerator.cc b/content/common/gpu/media/gpu_video_encode_accelerator.cc index ff80628..7dd9a08 100644 --- a/content/common/gpu/media/gpu_video_encode_accelerator.cc +++ b/content/common/gpu/media/gpu_video_encode_accelerator.cc @@ -276,7 +276,7 @@ void GpuVideoEncodeAccelerator::OnEncode( if (!shm->MapAt(map_offset.ValueOrDie(), map_size.ValueOrDie())) { DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnEncode(): " - "could not map frame_id=" << params.frame_id; + << "could not map frame_id=" << params.frame_id; NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); return; } @@ -294,7 +294,7 @@ void GpuVideoEncodeAccelerator::OnEncode( params.buffer_handle, params.buffer_offset, params.timestamp); - if (!frame.get()) { + if (!frame) { DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnEncode(): " << "could not create a frame"; NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); diff --git a/content/common/gpu/media/v4l2_image_processor.cc b/content/common/gpu/media/v4l2_image_processor.cc index 2e50014..f0cf397 100644 --- a/content/common/gpu/media/v4l2_image_processor.cc +++ b/content/common/gpu/media/v4l2_image_processor.cc @@ -561,6 +561,10 @@ void V4L2ImageProcessor::Dequeue() { output_visible_size_, output_record.fds, job_record->frame->timestamp()); + if (!output_frame) { + NOTIFY_ERROR(); + return; + } output_frame->AddDestructionObserver(media::BindToCurrentLoop( base::Bind(&V4L2ImageProcessor::ReuseOutputBuffer, device_weak_factory_.GetWeakPtr(), diff --git a/content/common/gpu/media/video_encode_accelerator_unittest.cc b/content/common/gpu/media/video_encode_accelerator_unittest.cc index fe36686..9224e89 100644 --- a/content/common/gpu/media/video_encode_accelerator_unittest.cc +++ b/content/common/gpu/media/video_encode_accelerator_unittest.cc @@ -1321,14 +1321,18 @@ scoped_refptr<media::VideoFrame> VEAClient::CreateFrame(off_t position) { uint8_t* frame_data_v = frame_data_u + test_stream_->aligned_plane_size[1]; CHECK_GT(current_framerate_, 0U); - return media::VideoFrame::WrapExternalYuvData( - kInputFormat, input_coded_size_, gfx::Rect(test_stream_->visible_size), - test_stream_->visible_size, input_coded_size_.width(), - input_coded_size_.width() / 2, input_coded_size_.width() / 2, - frame_data_y, frame_data_u, frame_data_v, - base::TimeDelta().FromMilliseconds(next_input_id_ * - base::Time::kMillisecondsPerSecond / - current_framerate_)); + scoped_refptr<media::VideoFrame> video_frame = + media::VideoFrame::WrapExternalYuvData( + kInputFormat, input_coded_size_, + gfx::Rect(test_stream_->visible_size), test_stream_->visible_size, + input_coded_size_.width(), input_coded_size_.width() / 2, + input_coded_size_.width() / 2, frame_data_y, frame_data_u, + frame_data_v, + base::TimeDelta().FromMilliseconds( + next_input_id_ * base::Time::kMillisecondsPerSecond / + current_framerate_)); + EXPECT_NE(nullptr, video_frame.get()); + return video_frame; } scoped_refptr<media::VideoFrame> VEAClient::PrepareInputFrame( @@ -1338,6 +1342,7 @@ scoped_refptr<media::VideoFrame> VEAClient::PrepareInputFrame( test_stream_->mapped_aligned_in_file.length()); scoped_refptr<media::VideoFrame> frame = CreateFrame(position); + EXPECT_TRUE(frame); frame->AddDestructionObserver( media::BindToCurrentLoop( base::Bind(&VEAClient::InputNoLongerNeededCallback, diff --git a/content/renderer/media/android/webmediaplayer_android.cc b/content/renderer/media/android/webmediaplayer_android.cc index a9725df..e399cde 100644 --- a/content/renderer/media/android/webmediaplayer_android.cc +++ b/content/renderer/media/android/webmediaplayer_android.cc @@ -1261,6 +1261,8 @@ void WebMediaPlayerAndroid::DrawRemotePlaybackText( remote_playback_texture_id)), canvas_size /* coded_size */, gfx::Rect(canvas_size) /* visible_rect */, canvas_size /* natural_size */, base::TimeDelta() /* timestamp */); + if (!new_frame) + return; SetCurrentFrameInternal(new_frame); } diff --git a/content/renderer/media/media_stream_video_track.cc b/content/renderer/media/media_stream_video_track.cc index bbb88f3..6ff4688 100644 --- a/content/renderer/media/media_stream_video_track.cc +++ b/content/renderer/media/media_stream_video_track.cc @@ -178,6 +178,8 @@ MediaStreamVideoTrack::FrameDeliverer::GetBlackFrame( media::VideoFrame::WrapVideoFrame( black_frame_, black_frame_->visible_rect(), black_frame_->natural_size()); + if (!wrapped_black_frame) + return nullptr; wrapped_black_frame->AddDestructionObserver( base::Bind(&ReleaseOriginalFrame, black_frame_)); diff --git a/content/renderer/media/rtc_video_decoder.cc b/content/renderer/media/rtc_video_decoder.cc index de91b6e..423b143 100644 --- a/content/renderer/media/rtc_video_decoder.cc +++ b/content/renderer/media/rtc_video_decoder.cc @@ -372,6 +372,10 @@ void RTCVideoDecoder::PictureReady(const media::Picture& picture) { scoped_refptr<media::VideoFrame> frame = CreateVideoFrame(picture, pb, timestamp, visible_rect); + if (!frame) { + NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); + return; + } bool inserted = picture_buffers_at_display_.insert(std::make_pair( picture.picture_buffer_id(), @@ -407,15 +411,15 @@ scoped_refptr<media::VideoFrame> RTCVideoDecoder::CreateVideoFrame( // as ARGB. This prevents the compositor from messing with it, since the // underlying platform can handle the former format natively. Make sure the // correct format is used and everyone down the line understands it. - scoped_refptr<media::VideoFrame> frame(media::VideoFrame::WrapNativeTexture( + scoped_refptr<media::VideoFrame> frame = media::VideoFrame::WrapNativeTexture( media::PIXEL_FORMAT_ARGB, gpu::MailboxHolder(pb.texture_mailbox(), gpu::SyncToken(), decoder_texture_target_), media::BindToCurrentLoop(base::Bind( &RTCVideoDecoder::ReleaseMailbox, weak_factory_.GetWeakPtr(), factories_, picture.picture_buffer_id(), pb.texture_id())), - pb.size(), visible_rect, visible_rect.size(), timestamp_ms)); - if (picture.allow_overlay()) { + pb.size(), visible_rect, visible_rect.size(), timestamp_ms); + if (frame && picture.allow_overlay()) { frame->metadata()->SetBoolean(media::VideoFrameMetadata::ALLOW_OVERLAY, true); } diff --git a/content/renderer/media/video_capture_impl.cc b/content/renderer/media/video_capture_impl.cc index aa06bd7..8e50ede 100644 --- a/content/renderer/media/video_capture_impl.cc +++ b/content/renderer/media/video_capture_impl.cc @@ -374,7 +374,11 @@ void VideoCaptureImpl::OnBufferReceived( NOTREACHED(); break; } - DCHECK(frame); + if (!frame) { + Send(new VideoCaptureHostMsg_BufferReady(device_id_, buffer_id, + gpu::SyncToken(), -1.0)); + return; + } frame->metadata()->SetTimeTicks(media::VideoFrameMetadata::REFERENCE_TIME, timestamp); diff --git a/content/renderer/media/video_track_adapter.cc b/content/renderer/media/video_track_adapter.cc index 9f4e2ab..f4ca1d2 100644 --- a/content/renderer/media/video_track_adapter.cc +++ b/content/renderer/media/video_track_adapter.cc @@ -201,6 +201,11 @@ void VideoTrackAdapter::VideoFrameResolutionAdapter::DeliverFrame( const base::TimeTicks& estimated_capture_time) { DCHECK(io_thread_checker_.CalledOnValidThread()); + if (!frame) { + DLOG(ERROR) << "Incoming frame is not valid."; + return; + } + double frame_rate; if (!frame->metadata()->GetDouble(media::VideoFrameMetadata::FRAME_RATE, &frame_rate)) { @@ -263,6 +268,8 @@ void VideoTrackAdapter::VideoFrameResolutionAdapter::DeliverFrame( video_frame = media::VideoFrame::WrapVideoFrame(frame, region_in_frame, desired_size); + if (!video_frame) + return; video_frame->AddDestructionObserver( base::Bind(&ReleaseOriginalFrame, frame)); diff --git a/content/renderer/media/webrtc/media_stream_remote_video_source.cc b/content/renderer/media/webrtc/media_stream_remote_video_source.cc index 6eab00b..88ceba3a 100644 --- a/content/renderer/media/webrtc/media_stream_remote_video_source.cc +++ b/content/renderer/media/webrtc/media_stream_remote_video_source.cc @@ -115,6 +115,8 @@ void MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate::RenderFrame( const_cast<uint8_t*>(frame->GetYPlane()), const_cast<uint8_t*>(frame->GetUPlane()), const_cast<uint8_t*>(frame->GetVPlane()), elapsed_timestamp); + if (!video_frame) + return; video_frame->AddDestructionObserver( base::Bind(&base::DeletePointer<cricket::VideoFrame>, frame->Copy())); } diff --git a/content/renderer/media/webrtc/webrtc_video_capturer_adapter.cc b/content/renderer/media/webrtc/webrtc_video_capturer_adapter.cc index c3b407b..abdb1b1 100644 --- a/content/renderer/media/webrtc/webrtc_video_capturer_adapter.cc +++ b/content/renderer/media/webrtc/webrtc_video_capturer_adapter.cc @@ -95,6 +95,8 @@ class WebRtcVideoCapturerAdapter::MediaVideoFrameFactory const gfx::Size output_size(output_width, output_height); scoped_refptr<media::VideoFrame> video_frame = media::VideoFrame::WrapVideoFrame(frame_, visible_rect, output_size); + if (!video_frame) + return nullptr; video_frame->AddDestructionObserver( base::Bind(&ReleaseOriginalFrame, frame_)); diff --git a/content/renderer/pepper/content_decryptor_delegate.cc b/content/renderer/pepper/content_decryptor_delegate.cc index fbead03..f9f35db 100644 --- a/content/renderer/pepper/content_decryptor_delegate.cc +++ b/content/renderer/pepper/content_decryptor_delegate.cc @@ -1038,6 +1038,11 @@ void ContentDecryptorDelegate::DeliverFrame( frame_data + frame_info->plane_offsets[PP_DECRYPTEDFRAMEPLANES_V], base::TimeDelta::FromMicroseconds( frame_info->tracking_info.timestamp)); + if (!decoded_frame) { + FreeBuffer(frame_info->tracking_info.buffer_id); + video_decode_cb.Run(Decryptor::kError, NULL); + return; + } decoded_frame->AddDestructionObserver( media::BindToCurrentLoop( base::Bind(&BufferNoLongerNeeded, diff --git a/content/renderer/pepper/pepper_media_stream_video_track_host.cc b/content/renderer/pepper/pepper_media_stream_video_track_host.cc index 7e237b8..d0e47c2 100644 --- a/content/renderer/pepper/pepper_media_stream_video_track_host.cc +++ b/content/renderer/pepper/pepper_media_stream_video_track_host.cc @@ -358,6 +358,8 @@ int32_t PepperMediaStreamVideoTrackHost::SendFrameToTrack(int32_t index) { u_data, v_data, base::TimeDelta::FromMilliseconds(ts_ms)); + if (!frame) + return PP_ERROR_FAILED; frame_deliverer_->DeliverVideoFrame(frame); } diff --git a/content/renderer/pepper/pepper_video_encoder_host.cc b/content/renderer/pepper/pepper_video_encoder_host.cc index d976368..b78131d 100644 --- a/content/renderer/pepper/pepper_video_encoder_host.cc +++ b/content/renderer/pepper/pepper_video_encoder_host.cc @@ -631,6 +631,10 @@ scoped_refptr<media::VideoFrame> PepperVideoEncoderHost::CreateVideoFrame( input_coded_size_, static_cast<uint8_t*>(buffer->video.data), buffer->video.data_size, buffer_manager_.shm()->handle(), shm_offset, base::TimeDelta()); + if (!frame) { + NotifyPepperError(PP_ERROR_FAILED); + return frame; + } frame->AddDestructionObserver( base::Bind(&PepperVideoEncoderHost::FrameReleased, weak_ptr_factory_.GetWeakPtr(), reply_context, frame_id)); diff --git a/media/base/video_frame.cc b/media/base/video_frame.cc index 4a9636f..aad4969 100644 --- a/media/base/video_frame.cc +++ b/media/base/video_frame.cc @@ -230,13 +230,13 @@ scoped_refptr<VideoFrame> VideoFrame::WrapNativeTexture( base::TimeDelta timestamp) { if (format != PIXEL_FORMAT_ARGB && format != PIXEL_FORMAT_XRGB && format != PIXEL_FORMAT_UYVY && format != PIXEL_FORMAT_NV12) { - DLOG(ERROR) << "Unsupported pixel format supported, got " + LOG(DFATAL) << "Unsupported pixel format supported, got " << VideoPixelFormatToString(format); return nullptr; } const StorageType storage = STORAGE_OPAQUE; if (!IsValidConfig(format, storage, coded_size, visible_rect, natural_size)) { - DLOG(ERROR) << __FUNCTION__ << " Invalid config." + LOG(DFATAL) << __FUNCTION__ << " Invalid config." << ConfigToString(format, storage, coded_size, visible_rect, natural_size); return nullptr; @@ -261,7 +261,7 @@ scoped_refptr<VideoFrame> VideoFrame::WrapYUV420NativeTextures( const StorageType storage = STORAGE_OPAQUE; VideoPixelFormat format = PIXEL_FORMAT_I420; if (!IsValidConfig(format, storage, coded_size, visible_rect, natural_size)) { - DLOG(ERROR) << __FUNCTION__ << " Invalid config." + LOG(DFATAL) << __FUNCTION__ << " Invalid config." << ConfigToString(format, storage, coded_size, visible_rect, natural_size); return nullptr; @@ -320,7 +320,7 @@ scoped_refptr<VideoFrame> VideoFrame::WrapExternalYuvData( base::TimeDelta timestamp) { const StorageType storage = STORAGE_UNOWNED_MEMORY; if (!IsValidConfig(format, storage, coded_size, visible_rect, natural_size)) { - DLOG(ERROR) << __FUNCTION__ << " Invalid config." + LOG(DFATAL) << __FUNCTION__ << " Invalid config." << ConfigToString(format, storage, coded_size, visible_rect, natural_size); return nullptr; @@ -355,7 +355,7 @@ scoped_refptr<VideoFrame> VideoFrame::WrapExternalYuvGpuMemoryBuffers( base::TimeDelta timestamp) { const StorageType storage = STORAGE_GPU_MEMORY_BUFFERS; if (!IsValidConfig(format, storage, coded_size, visible_rect, natural_size)) { - DLOG(ERROR) << __FUNCTION__ << " Invalid config." + LOG(DFATAL) << __FUNCTION__ << " Invalid config." << ConfigToString(format, storage, coded_size, visible_rect, natural_size); return nullptr; @@ -390,7 +390,7 @@ scoped_refptr<VideoFrame> VideoFrame::WrapExternalDmabufs( const StorageType storage = STORAGE_DMABUFS; if (!IsValidConfig(format, storage, coded_size, visible_rect, natural_size)) { - DLOG(ERROR) << __FUNCTION__ << " Invalid config." + LOG(DFATAL) << __FUNCTION__ << " Invalid config." << ConfigToString(format, storage, coded_size, visible_rect, natural_size); return nullptr; @@ -400,8 +400,10 @@ scoped_refptr<VideoFrame> VideoFrame::WrapExternalDmabufs( scoped_refptr<VideoFrame> frame = new VideoFrame(format, storage, coded_size, visible_rect, natural_size, mailbox_holders, ReleaseMailboxCB(), timestamp); - if (!frame || !frame->DuplicateFileDescriptors(dmabuf_fds)) + if (!frame || !frame->DuplicateFileDescriptors(dmabuf_fds)) { + LOG(DFATAL) << __FUNCTION__ << " Couldn't duplicate fds."; return nullptr; + } return frame; } #endif @@ -426,7 +428,7 @@ scoped_refptr<VideoFrame> VideoFrame::WrapCVPixelBuffer( // minimum OS X and iOS SDKs permits it. format = PIXEL_FORMAT_NV12; } else { - DLOG(ERROR) << "CVPixelBuffer format not supported: " << cv_format; + LOG(DFATAL) << "CVPixelBuffer format not supported: " << cv_format; return nullptr; } @@ -436,7 +438,7 @@ scoped_refptr<VideoFrame> VideoFrame::WrapCVPixelBuffer( const StorageType storage = STORAGE_UNOWNED_MEMORY; if (!IsValidConfig(format, storage, coded_size, visible_rect, natural_size)) { - DLOG(ERROR) << __FUNCTION__ << " Invalid config." + LOG(DFATAL) << __FUNCTION__ << " Invalid config." << ConfigToString(format, storage, coded_size, visible_rect, natural_size); return nullptr; @@ -463,7 +465,7 @@ scoped_refptr<VideoFrame> VideoFrame::WrapVideoFrame( if (!IsValidConfig(frame->format(), frame->storage_type(), frame->coded_size(), visible_rect, natural_size)) { - DLOG(ERROR) << __FUNCTION__ << " Invalid config." + LOG(DFATAL) << __FUNCTION__ << " Invalid config." << ConfigToString(frame->format(), frame->storage_type(), frame->coded_size(), visible_rect, natural_size); @@ -489,8 +491,10 @@ scoped_refptr<VideoFrame> VideoFrame::WrapVideoFrame( std::vector<int> original_fds; for (size_t i = 0; i < kMaxPlanes; ++i) original_fds.push_back(frame->dmabuf_fd(i)); - if (!wrapping_frame->DuplicateFileDescriptors(original_fds)) + if (!wrapping_frame->DuplicateFileDescriptors(original_fds)) { + LOG(DFATAL) << __FUNCTION__ << " Couldn't duplicate fds."; return nullptr; + } } #endif @@ -555,7 +559,7 @@ scoped_refptr<VideoFrame> VideoFrame::CreateHoleFrame( const StorageType storage = STORAGE_HOLE; const gfx::Rect visible_rect = gfx::Rect(size); if (!IsValidConfig(format, storage, size, visible_rect, size)) { - DLOG(ERROR) << __FUNCTION__ << " Invalid config." + LOG(DFATAL) << __FUNCTION__ << " Invalid config." << ConfigToString(format, storage, size, visible_rect, size); return nullptr; } @@ -839,14 +843,14 @@ scoped_refptr<VideoFrame> VideoFrame::WrapExternalStorage( // TODO(miu): This function should support any pixel format. // http://crbug.com/555909 if (format != PIXEL_FORMAT_I420) { - DLOG(ERROR) << "Only PIXEL_FORMAT_I420 format supported: " + LOG(DFATAL) << "Only PIXEL_FORMAT_I420 format supported: " << VideoPixelFormatToString(format); return nullptr; } if (!IsValidConfig(format, storage_type, coded_size, visible_rect, natural_size)) { - DLOG(ERROR) << __FUNCTION__ << " Invalid config." + LOG(DFATAL) << __FUNCTION__ << " Invalid config." << ConfigToString(format, storage_type, coded_size, visible_rect, natural_size); return nullptr; @@ -974,7 +978,7 @@ scoped_refptr<VideoFrame> VideoFrame::CreateFrameInternal( const StorageType storage = STORAGE_OWNED_MEMORY; if (!IsValidConfig(format, storage, new_coded_size, visible_rect, natural_size)) { - DLOG(ERROR) << __FUNCTION__ << " Invalid config." + LOG(DFATAL) << __FUNCTION__ << " Invalid config." << ConfigToString(format, storage, coded_size, visible_rect, natural_size); return nullptr; diff --git a/media/capture/content/thread_safe_capture_oracle.cc b/media/capture/content/thread_safe_capture_oracle.cc index a99a99a..f3ba5a4 100644 --- a/media/capture/content/thread_safe_capture_oracle.cc +++ b/media/capture/content/thread_safe_capture_oracle.cc @@ -122,7 +122,8 @@ bool ThreadSafeCaptureOracle::ObserveEventAndDecideCapture( static_cast<uint8_t*>(output_buffer->data()), output_buffer->mapped_size(), base::SharedMemory::NULLHandle(), 0u, base::TimeDelta()); - DCHECK(*storage); + if (!(*storage)) + return false; *callback = base::Bind(&ThreadSafeCaptureOracle::DidCaptureFrame, this, frame_number, base::Passed(&output_buffer), capture_begin_time, diff --git a/media/cast/test/fake_media_source.cc b/media/cast/test/fake_media_source.cc index 8e411bb..7d58a4c 100644 --- a/media/cast/test/fake_media_source.cc +++ b/media/cast/test/fake_media_source.cc @@ -557,10 +557,14 @@ void FakeMediaSource::DecodeVideo(ScopedAVPacket packet) { video_first_pts_ = avframe->pkt_pts - adjustment_pts; } - video_frame_queue_.push(VideoFrame::WrapExternalYuvData( - media::PIXEL_FORMAT_YV12, size, gfx::Rect(size), size, - avframe->linesize[0], avframe->linesize[1], avframe->linesize[2], - avframe->data[0], avframe->data[1], avframe->data[2], timestamp)); + scoped_refptr<media::VideoFrame> video_frame = + VideoFrame::WrapExternalYuvData( + media::PIXEL_FORMAT_YV12, size, gfx::Rect(size), size, + avframe->linesize[0], avframe->linesize[1], avframe->linesize[2], + avframe->data[0], avframe->data[1], avframe->data[2], timestamp); + if (!video_frame) + return; + video_frame_queue_.push(video_frame); video_frame_queue_.back()->AddDestructionObserver( base::Bind(&AVFreeFrame, avframe)); last_video_frame_timestamp_ = timestamp; diff --git a/media/filters/vpx_video_decoder.cc b/media/filters/vpx_video_decoder.cc index 40814bb..9d27bc9 100644 --- a/media/filters/vpx_video_decoder.cc +++ b/media/filters/vpx_video_decoder.cc @@ -592,6 +592,9 @@ bool VpxVideoDecoder::CopyVpxImageToVideoFrame( vpx_image->planes[VPX_PLANE_U], vpx_image->planes[VPX_PLANE_V], kNoTimestamp()); + if (!(*video_frame)) + return false; + video_frame->get()->AddDestructionObserver( memory_pool_->CreateFrameCallback(vpx_image->fb_priv)); @@ -610,6 +613,8 @@ bool VpxVideoDecoder::CopyVpxImageToVideoFrame( *video_frame = frame_pool_.CreateFrame( codec_format, visible_size, gfx::Rect(visible_size), config_.natural_size(), kNoTimestamp()); + if (!(*video_frame)) + return false; libyuv::I420Copy( vpx_image->planes[VPX_PLANE_Y], vpx_image->stride[VPX_PLANE_Y], diff --git a/media/video/gpu_memory_buffer_video_frame_pool.cc b/media/video/gpu_memory_buffer_video_frame_pool.cc index 14910ad..d5d6836 100644 --- a/media/video/gpu_memory_buffer_video_frame_pool.cc +++ b/media/video/gpu_memory_buffer_video_frame_pool.cc @@ -602,7 +602,8 @@ void GpuMemoryBufferVideoFramePool::PoolImpl:: mailbox_holders[VideoFrame::kVPlane], release_mailbox_callback, coded_size, gfx::Rect(visible_size), video_frame->natural_size(), video_frame->timestamp()); - if (video_frame->metadata()->IsTrue(VideoFrameMetadata::ALLOW_OVERLAY)) + if (frame && + video_frame->metadata()->IsTrue(VideoFrameMetadata::ALLOW_OVERLAY)) frame->metadata()->SetBoolean(VideoFrameMetadata::ALLOW_OVERLAY, true); break; case PIXEL_FORMAT_NV12: @@ -611,12 +612,19 @@ void GpuMemoryBufferVideoFramePool::PoolImpl:: output_format_, mailbox_holders[VideoFrame::kYPlane], release_mailbox_callback, coded_size, gfx::Rect(visible_size), video_frame->natural_size(), video_frame->timestamp()); - frame->metadata()->SetBoolean(VideoFrameMetadata::ALLOW_OVERLAY, true); + if (frame) + frame->metadata()->SetBoolean(VideoFrameMetadata::ALLOW_OVERLAY, true); break; default: NOTREACHED(); } + if (!frame) { + release_mailbox_callback.Run(gpu::SyncToken()); + frame_ready_cb.Run(video_frame); + return; + } + base::TimeTicks render_time; if (video_frame->metadata()->GetTimeTicks(VideoFrameMetadata::REFERENCE_TIME, &render_time)) { diff --git a/media/video/gpu_memory_buffer_video_frame_pool_unittest.cc b/media/video/gpu_memory_buffer_video_frame_pool_unittest.cc index 0e6f3ef..55dc969 100644 --- a/media/video/gpu_memory_buffer_video_frame_pool_unittest.cc +++ b/media/video/gpu_memory_buffer_video_frame_pool_unittest.cc @@ -101,18 +101,21 @@ class GpuMemoryBufferVideoFramePoolTest : public ::testing::Test { DCHECK_LE(dimension, kDimension); gfx::Size size(dimension, dimension); - return media::VideoFrame::WrapExternalYuvData( - media::PIXEL_FORMAT_YV12, // format - size, // coded_size - gfx::Rect(size), // visible_rect - size, // natural_size - size.width(), // y_stride - size.width() / 2, // u_stride - size.width() / 2, // v_stride - y_data, // y_data - u_data, // u_data - v_data, // v_data - base::TimeDelta()); // timestamp + scoped_refptr<VideoFrame> video_frame = + media::VideoFrame::WrapExternalYuvData( + media::PIXEL_FORMAT_YV12, // format + size, // coded_size + gfx::Rect(size), // visible_rect + size, // natural_size + size.width(), // y_stride + size.width() / 2, // u_stride + size.width() / 2, // v_stride + y_data, // y_data + u_data, // u_data + v_data, // v_data + base::TimeDelta()); // timestamp + EXPECT_TRUE(video_frame); + return video_frame; } protected: |