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