1 // Copyright 2018 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_TEST_VIDEO_PLAYER_VIDEO_DECODER_CLIENT_H_
6 #define MEDIA_GPU_TEST_VIDEO_PLAYER_VIDEO_DECODER_CLIENT_H_
7 
8 #include <stdint.h>
9 #include <map>
10 #include <memory>
11 #include <vector>
12 
13 #include "base/macros.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/sequence_checker.h"
16 #include "base/threading/thread.h"
17 #include "gpu/ipc/service/gpu_memory_buffer_factory.h"
18 #include "media/base/decode_status.h"
19 #include "media/base/video_decoder.h"
20 #include "media/base/video_decoder_config.h"
21 #include "media/gpu/test/video_player/video_player.h"
22 
23 namespace media {
24 
25 class Video;
26 class VideoFrame;
27 
28 namespace test {
29 
30 class EncodedDataHelper;
31 class FrameRenderer;
32 class VideoFrameProcessor;
33 
34 // TODO(dstaessens@) Remove allocation mode, temporary added here so we can
35 // support the thumbnail test for older platforms that don't support import.
36 enum class AllocationMode {
37   kImport,    // Client allocates video frame memory.
38   kAllocate,  // Video decoder allocates video frame memory.
39 };
40 
41 // The supported video decoding implementation.
42 enum class DecoderImplementation {
43   kVDA,    // VDA-based video decoder.
44   kVD,     // VD-based video decoder.
45   kVDVDA,  // VD-based video decoder with VdVDA.
46 };
47 
48 // Video decoder client configuration.
49 struct VideoDecoderClientConfig {
50   // The maximum number of bitstream buffer decodes that can be requested
51   // without waiting for the result of the previous decode requests.
52   size_t max_outstanding_decode_requests = 1;
53   // How the pictures buffers should be allocated.
54   AllocationMode allocation_mode = AllocationMode::kImport;
55   DecoderImplementation implementation = DecoderImplementation::kVDA;
56 };
57 
58 // The video decoder client is responsible for the communication between the
59 // video player and the video decoder. It also communicates with the frame
60 // renderer and other components. The video decoder client can only have one
61 // active decoder at any time. To decode a different stream the DestroyDecoder()
62 // and CreateDecoder() functions have to be called to destroy and re-create the
63 // decoder.
64 //
65 // All communication with the decoder is done on the |decoder_client_thread_|,
66 // so callbacks scheduled by the decoder can be executed asynchronously. This is
67 // necessary if we don't want to interrupt the test flow.
68 class VideoDecoderClient {
69  public:
70   ~VideoDecoderClient();
71 
72   // Return an instance of the VideoDecoderClient. The
73   // |gpu_memory_buffer_factory| will not be owned by the decoder client, the
74   // caller should guarantee it outlives the decoder client. The |event_cb| will
75   // be called whenever an event occurs (e.g. frame decoded) and should be
76   // thread-safe. Initialization is performed asynchronous, upon completion a
77   // 'kInitialized' event will be thrown.
78   static std::unique_ptr<VideoDecoderClient> Create(
79       const VideoPlayer::EventCallback& event_cb,
80       gpu::GpuMemoryBufferFactory* gpu_memory_buffer_factory,
81       std::unique_ptr<FrameRenderer> frame_renderer,
82       std::vector<std::unique_ptr<VideoFrameProcessor>> frame_processors,
83       const VideoDecoderClientConfig& config);
84 
85   // Wait until all frame processors have finished processing. Returns whether
86   // processing was successful.
87   bool WaitForFrameProcessors();
88   // Wait until the renderer has finished rendering all queued frames.
89   void WaitForRenderer();
90   // Get the frame renderer associated with the video decoder client.
91   FrameRenderer* GetFrameRenderer() const;
92 
93   // Initialize the video decoder for the specified |video|. This function can
94   // be called multiple times and needs to be called before Play().
95   // Initialization is performed asynchronous, upon completion a 'kInitialized'
96   // event is thrown.
97   void Initialize(const Video* video);
98   // Start decoding the video stream, decoder should be idle when this function
99   // is called. This function is non-blocking, for each frame decoded a
100   // 'kFrameDecoded' event will be thrown.
101   void Play();
102   // Queue decoder flush. This function is non-blocking, a kFlushing/kFlushDone
103   // event is thrown upon start/finish.
104   void Flush();
105   // Queue decoder reset. This function is non-blocking, a kResetting/kResetDone
106   // event is thrown upon start/finish.
107   void Reset();
108 
109  private:
110   enum class VideoDecoderClientState : size_t {
111     kUninitialized = 0,
112     kIdle,
113     kDecoding,
114     kFlushing,
115     kResetting,
116   };
117 
118   VideoDecoderClient(
119       const VideoPlayer::EventCallback& event_cb,
120       gpu::GpuMemoryBufferFactory* gpu_memory_buffer_factory,
121       std::unique_ptr<FrameRenderer> renderer,
122       std::vector<std::unique_ptr<VideoFrameProcessor>> frame_processors,
123       const VideoDecoderClientConfig& config);
124 
125   // Create a new decoder, returns whether creating was successful.
126   bool CreateDecoder();
127   // Destroy the currently active decoder.
128   void DestroyDecoder();
129 
130   // Create a new video |decoder_| on the |decoder_client_thread_|.
131   void CreateDecoderTask(bool* success, base::WaitableEvent* done);
132   // Destroy the active video |decoder_| on the |decoder_client_thread_|.
133   void DestroyDecoderTask(base::WaitableEvent* done);
134   // Initialize the video |decoder_| with |video| on the
135   // |decoder_client_thread_|.
136   void InitializeDecoderTask(const Video* video, base::WaitableEvent* done);
137 
138   // Start decoding video stream fragments on the |decoder_client_thread_|.
139   void PlayTask();
140   // Instruct the decoder to decode the next video stream fragment on the
141   // |decoder_client_thread_|.
142   void DecodeNextFragmentTask();
143   // Instruct the decoder to perform a flush on the |decoder_client_thread_|.
144   void FlushTask();
145   // Instruct the decoder to perform a Reset on the |decoder_client_thread_|.
146   void ResetTask();
147 
148   // The below functions are callbacks provided to the video decoder. They are
149   // all executed on the |decoder_client_thread_|.
150   // Called by the decoder when initialization has completed.
151   void DecoderInitializedTask(Status status);
152   // Called by the decoder when a fragment has been decoded.
153   void DecodeDoneTask(media::Status status);
154   // Called by the decoder when a video frame is ready.
155   void FrameReadyTask(scoped_refptr<VideoFrame> video_frame);
156   // Called by the decoder when flushing has completed.
157   void FlushDoneTask(media::Status status);
158   // Called by the decoder when resetting has completed.
159   void ResetDoneTask();
160 
161   // Fire the specified event.
162   void FireEvent(VideoPlayerEvent event);
163 
164   VideoPlayer::EventCallback event_cb_;
165   std::unique_ptr<FrameRenderer> frame_renderer_;
166   std::vector<std::unique_ptr<VideoFrameProcessor>> frame_processors_;
167 
168   std::unique_ptr<media::VideoDecoder> decoder_;
169   const VideoDecoderClientConfig decoder_client_config_;
170   base::Thread decoder_client_thread_;
171 
172   // Decoder client state, should only be accessed on the decoder client thread.
173   VideoDecoderClientState decoder_client_state_;
174 
175   // Index of the frame that's currently being decoded.
176   size_t current_frame_index_ = 0;
177   // The current number of outgoing bitstream buffers decode requests.
178   size_t num_outstanding_decode_requests_ = 0;
179 
180   // TODO(dstaessens@) Replace with StreamParser.
181   std::unique_ptr<media::test::EncodedDataHelper> encoded_data_helper_;
182   // The video being decoded.
183   const Video* video_ = nullptr;
184 
185   // Owned by VideoPlayerTestEnvironment.
186   gpu::GpuMemoryBufferFactory* const gpu_memory_buffer_factory_;
187 
188   SEQUENCE_CHECKER(video_player_sequence_checker_);
189   SEQUENCE_CHECKER(decoder_client_sequence_checker_);
190 
191   base::WeakPtr<VideoDecoderClient> weak_this_;
192   base::WeakPtrFactory<VideoDecoderClient> weak_this_factory_{this};
193 
194   DISALLOW_COPY_AND_ASSIGN(VideoDecoderClient);
195 };
196 
197 }  // namespace test
198 }  // namespace media
199 
200 #endif  // MEDIA_GPU_TEST_VIDEO_PLAYER_VIDEO_DECODER_CLIENT_H_
201