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