1 // Copyright 2017 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef MEDIA_GPU_ANDROID_VIDEO_FRAME_FACTORY_IMPL_ 6 #define MEDIA_GPU_ANDROID_VIDEO_FRAME_FACTORY_IMPL_ 7 8 #include <memory> 9 10 #include "base/memory/weak_ptr.h" 11 #include "base/optional.h" 12 #include "base/single_thread_task_runner.h" 13 #include "base/threading/sequence_bound.h" 14 #include "gpu/config/gpu_preferences.h" 15 #include "media/base/video_frame.h" 16 #include "media/gpu/android/codec_buffer_wait_coordinator.h" 17 #include "media/gpu/android/codec_image.h" 18 #include "media/gpu/android/codec_wrapper.h" 19 #include "media/gpu/android/maybe_render_early_manager.h" 20 #include "media/gpu/android/shared_image_video_provider.h" 21 #include "media/gpu/android/video_frame_factory.h" 22 #include "media/gpu/android/ycbcr_helper.h" 23 #include "media/gpu/media_gpu_export.h" 24 #include "ui/gl/gl_bindings.h" 25 26 namespace media { 27 class CodecImageGroup; 28 class MaybeRenderEarlyManager; 29 30 // VideoFrameFactoryImpl creates CodecOutputBuffer backed VideoFrames and tries 31 // to eagerly render them to their surface to release the buffers back to the 32 // decoder as soon as possible. It's not thread safe; it should be created, used 33 // and destructed on a single sequence. It's implemented by proxying calls 34 // to a helper class hosted on the gpu thread. 35 class MEDIA_GPU_EXPORT VideoFrameFactoryImpl : public VideoFrameFactory { 36 public: 37 // Callback used to return a mailbox and release callback for an image. The 38 // release callback may be dropped without being run, and the image will be 39 // cleaned up properly. The release callback may be called from any thread. 40 using ImageReadyCB = 41 base::OnceCallback<void(gpu::Mailbox mailbox, 42 VideoFrame::ReleaseMailboxCB release_cb)>; 43 44 // |get_stub_cb| will be run on |gpu_task_runner|. 45 VideoFrameFactoryImpl( 46 scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner, 47 const gpu::GpuPreferences& gpu_preferences, 48 std::unique_ptr<SharedImageVideoProvider> image_provider, 49 std::unique_ptr<MaybeRenderEarlyManager> mre_manager, 50 base::SequenceBound<YCbCrHelper> ycbcr_helper); 51 ~VideoFrameFactoryImpl() override; 52 53 void Initialize(OverlayMode overlay_mode, InitCB init_cb) override; 54 void SetSurfaceBundle( 55 scoped_refptr<CodecSurfaceBundle> surface_bundle) override; 56 void CreateVideoFrame( 57 std::unique_ptr<CodecOutputBuffer> output_buffer, 58 base::TimeDelta timestamp, 59 gfx::Size natural_size, 60 PromotionHintAggregator::NotifyPromotionHintCB promotion_hint_cb, 61 OnceOutputCB output_cb) override; 62 void RunAfterPendingVideoFrames(base::OnceClosure closure) override; 63 64 // This should be only used for testing. SetCodecBufferWaitCorrdinatorForTesting(scoped_refptr<CodecBufferWaitCoordinator> codec_buffer_wait_coordinator)65 void SetCodecBufferWaitCorrdinatorForTesting( 66 scoped_refptr<CodecBufferWaitCoordinator> codec_buffer_wait_coordinator) { 67 codec_buffer_wait_coordinator_ = std::move(codec_buffer_wait_coordinator); 68 } 69 70 private: 71 // ImageReadyCB that will construct a VideoFrame, and forward it to 72 // |output_cb| if construction succeeds. This is static for two reasons. 73 // First, we want to snapshot the state of the world when the request is made, 74 // in case things like the texture owner change before it's returned. While 75 // it's unclear that MCVD would actually do this (it drains output buffers 76 // before switching anything, which guarantees that the VideoFrame has been 77 // created and sent to the renderer), it's still much simpler to think about 78 // if this uses the same state as the CreateVideoFrame call. 79 // 80 // Second, this way we don't care about the lifetime of |this|; |output_cb| 81 // can worry about it. 82 static void CreateVideoFrame_OnImageReady( 83 base::WeakPtr<VideoFrameFactoryImpl> thiz, 84 OnceOutputCB output_cb, 85 base::TimeDelta timestamp, 86 gfx::Size coded_size, 87 gfx::Size natural_size, 88 std::unique_ptr<CodecOutputBuffer> output_buffer, 89 scoped_refptr<CodecBufferWaitCoordinator> codec_buffer_wait_coordinator, 90 PromotionHintAggregator::NotifyPromotionHintCB promotion_hint_cb, 91 VideoPixelFormat pixel_format, 92 OverlayMode overlay_mode, 93 bool enable_threaded_texture_mailboxes, 94 scoped_refptr<base::SequencedTaskRunner> gpu_task_runner, 95 SharedImageVideoProvider::ImageRecord record); 96 97 // Callback to receive YCbCrInfo from |provider_| while creating a VideoFrame. 98 void CreateVideoFrame_OnYCbCrInfo(base::OnceClosure completion_cb, 99 YCbCrHelper::OptionalInfo ycbcr_info); 100 101 // Really create the VideoFrame, once we've tried to get the YCbCrInfo if it's 102 // needed for it. 103 void CreateVideoFrame_Finish( 104 OnceOutputCB output_cb, 105 base::TimeDelta timestamp, 106 gfx::Size coded_size, 107 gfx::Size natural_size, 108 scoped_refptr<CodecBufferWaitCoordinator> codec_buffer_wait_coordinator, 109 VideoPixelFormat pixel_format, 110 OverlayMode overlay_mode, 111 bool enable_threaded_texture_mailboxes, 112 SharedImageVideoProvider::ImageRecord record); 113 mre_manager()114 MaybeRenderEarlyManager* mre_manager() const { return mre_manager_.get(); } 115 116 std::unique_ptr<SharedImageVideoProvider> image_provider_; 117 scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner_; 118 119 // The CodecBufferWaitCoordintor that video frames should use, or nullptr. 120 scoped_refptr<CodecBufferWaitCoordinator> codec_buffer_wait_coordinator_; 121 122 OverlayMode overlay_mode_ = OverlayMode::kDontRequestPromotionHints; 123 124 // Is the sync mailbox manager enabled? 125 bool enable_threaded_texture_mailboxes_ = false; 126 127 // Current group that new CodecImages should belong to. Do not use this on 128 // our thread; everything must be posted to the gpu main thread, including 129 // destruction of it. 130 scoped_refptr<CodecImageGroup> image_group_; 131 132 std::unique_ptr<MaybeRenderEarlyManager> mre_manager_; 133 134 // Sampler conversion information which is used in vulkan context. 135 YCbCrHelper::OptionalInfo ycbcr_info_; 136 137 // Optional helper to get the Vulkan YCbCrInfo. 138 base::SequenceBound<YCbCrHelper> ycbcr_helper_; 139 140 // The current image spec that we'll use to request images. 141 SharedImageVideoProvider::ImageSpec image_spec_; 142 143 SEQUENCE_CHECKER(sequence_checker_); 144 145 base::WeakPtrFactory<VideoFrameFactoryImpl> weak_factory_{this}; 146 147 DISALLOW_COPY_AND_ASSIGN(VideoFrameFactoryImpl); 148 }; 149 150 } // namespace media 151 152 #endif // MEDIA_GPU_ANDROID_VIDEO_FRAME_FACTORY_IMPL_ 153