Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(25)

Side by Side Diff: content/renderer/media/rtc_video_decoder.h

Issue 13890012: Integrate VDA with WebRTC. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: update the license of rtc_video_decoder.h Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2013 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 CONTENT_RENDERER_MEDIA_RTC_VIDEO_DECODER_H_
6 #define CONTENT_RENDERER_MEDIA_RTC_VIDEO_DECODER_H_
7
8 #include <deque>
9 #include <set>
10 #include <utility>
11
12 #include "base/basictypes.h"
13 #include "base/gtest_prod_util.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/message_loop.h"
16 #include "base/synchronization/lock.h"
17 #include "base/synchronization/waitable_event.h"
18 #include "base/threading/thread.h"
19 #include "content/common/content_export.h"
20 #include "media/base/bitstream_buffer.h"
21 #include "media/base/video_decoder.h"
22 #include "media/filters/gpu_video_decoder.h"
23 #include "media/video/picture.h"
24 #include "media/video/video_decode_accelerator.h"
25 #include "third_party/webrtc/modules/video_coding/codecs/interface/video_codec_i nterface.h"
26
27 namespace base {
28 class MessageLoopProxy;
29 };
30
31 namespace media {
32 class DecoderBuffer;
33 }
34
35 namespace content {
36
37 // This class uses hardware accelerated video decoder to decode video for
38 // WebRTC. The message loop of RendererGpuVideoDecoderFactories is stored as
39 // |vda_message_loop_|. It is the compositor thread, or the renderer thread if
40 // threaded compositing is disabled. VDA::Client methods run on
41 // |vda_message_loop_|. webrtc::VideoDecoder methods run on WebRTC
42 // DecodingThread or Chrome_libJingle_WorkerThread, which are trampolined to
43 // |vda_message_loop_|. Decode() is non-blocking and queues the buffers. Decoded
44 // frames are delivered on |vda_message_loop_|.
45 class CONTENT_EXPORT RTCVideoDecoder
46 : NON_EXPORTED_BASE(public webrtc::VideoDecoder),
47 public media::VideoDecodeAccelerator::Client,
48 public base::MessageLoop::DestructionObserver {
49 public:
50 virtual ~RTCVideoDecoder();
51
52 // Creates a RTCVideoDecoder. Returns NULL if failed.
53 static scoped_ptr<RTCVideoDecoder> Create(
54 const scoped_refptr<media::GpuVideoDecoder::Factories>& factories);
55
56 // webrtc::VideoDecoder implementation.
57 // Called on WebRTC DecodingThread.
58 virtual int32_t InitDecode(const webrtc::VideoCodec* codecSettings,
59 int32_t numberOfCores) OVERRIDE;
60 // Called on WebRTC DecodingThread.
61 virtual int32_t Decode(
62 const webrtc::EncodedImage& inputImage,
63 bool missingFrames,
64 const webrtc::RTPFragmentationHeader* fragmentation,
65 const webrtc::CodecSpecificInfo* codecSpecificInfo = NULL,
66 int64_t renderTimeMs = -1) OVERRIDE;
67 // Called on WebRTC DecodingThread.
68 virtual int32_t RegisterDecodeCompleteCallback(
69 webrtc::DecodedImageCallback* callback) OVERRIDE;
70 // Called on Chrome_libJingle_WorkerThread. The child thread is blocked while
71 // this runs.
72 virtual int32_t Release() OVERRIDE;
73 // Called on Chrome_libJingle_WorkerThread. The child thread is blocked while
74 // this runs.
75 virtual int32_t Reset() OVERRIDE;
76
77 // VideoDecodeAccelerator::Client implementation.
78 virtual void NotifyInitializeDone() OVERRIDE;
79 virtual void ProvidePictureBuffers(uint32 count,
80 const gfx::Size& size,
81 uint32 texture_target) OVERRIDE;
82 virtual void DismissPictureBuffer(int32 id) OVERRIDE;
83 virtual void PictureReady(const media::Picture& picture) OVERRIDE;
84 virtual void NotifyEndOfBitstreamBuffer(int32 id) OVERRIDE;
85 virtual void NotifyFlushDone() OVERRIDE;
86 virtual void NotifyResetDone() OVERRIDE;
87 virtual void NotifyError(media::VideoDecodeAccelerator::Error error) OVERRIDE;
88
89 // base::DestructionObserver implementation. Called when |vda_message_loop_|
90 // is stopped.
91 virtual void WillDestroyCurrentMessageLoop() OVERRIDE;
92
93 private:
94 class SHMBuffer;
95 // Metadata of a bitstream buffer.
96 struct BufferData {
97 BufferData(int32 bitstream_buffer_id,
98 uint32_t timestamp,
99 int width,
100 int height,
101 size_t size);
102 BufferData();
103 ~BufferData();
104 int32 bitstream_buffer_id;
105 uint32_t timestamp; // in 90KHz
106 uint32_t width;
107 uint32_t height;
108 size_t size; // buffer size
109 };
110
111 FRIEND_TEST_ALL_PREFIXES(RTCVideoDecoderTest, IsBufferAfterReset);
112
113 RTCVideoDecoder(
114 const scoped_refptr<media::GpuVideoDecoder::Factories>& factories);
115
116 void Initialize(base::WaitableEvent* waiter);
117
118 // Requests a buffer to be decoded by VDA.
119 void RequestBufferDecode();
120
121 bool CanMoreDecodeWorkBeDone();
122
123 // Returns true if bitstream buffer id |id_buffer| comes after |id_reset|.
124 // This handles the wraparound.
125 bool IsBufferAfterReset(int32 id_buffer, int32 id_reset);
126
127 // Saves a WebRTC buffer in |decode_buffers_| for decode.
128 void SaveToDecodeBuffers_Locked(const webrtc::EncodedImage& input_image,
129 scoped_ptr<SHMBuffer> shm_buffer,
130 const BufferData& buffer_data);
131
132 // Saves a WebRTC buffer in |pending_buffers_| waiting for SHM available.
133 // Returns true on success.
134 bool SaveToPendingBuffers_Locked(const webrtc::EncodedImage& input_image,
135 const BufferData& buffer_data);
136
137 // Gets SHM and moves pending buffers to decode buffers.
138 void MovePendingBuffersToDecodeBuffers();
139
140 scoped_refptr<media::VideoFrame> CreateVideoFrame(
141 const media::Picture& picture,
142 const media::PictureBuffer& pb,
143 uint32_t timestamp,
144 uint32_t width,
145 uint32_t height,
146 size_t size);
147
148 // Resets VDA.
149 void ResetInternal();
150
151 // Tells VDA that a picture buffer can be recycled.
152 void ReusePictureBuffer(int64 picture_buffer_id, uint32 sync_point);
153
154 void DestroyTextures();
155 void DestroyVDA();
156
157 // Gets a shared-memory segment of at least |min_size| bytes from
158 // |available_shm_segments_|. Returns NULL if there is no buffer or the
159 // buffer is not big enough.
160 scoped_ptr<SHMBuffer> GetSHM_Locked(size_t min_size);
161
162 // Returns a shared-memory segment to the available pool.
163 void PutSHM_Locked(scoped_ptr<SHMBuffer> shm_buffer);
164
165 // Allocates |number| shared memory of at least |min_size| bytes.
166 void CreateSHM(int number, size_t min_size);
167
168 // Stores the buffer metadata to |input_buffer_data_|.
169 void RecordBufferData(const BufferData& buffer_data);
170 // Gets the buffer metadata from |input_buffer_data_|.
171 void GetBufferData(int32 bitstream_buffer_id,
172 uint32_t* timestamp,
173 uint32_t* width,
174 uint32_t* height,
175 size_t* size);
176
177 enum State {
178 UNINITIALIZED, // The decoder has not initialized.
179 INITIALIZED, // The decoder has initialized.
180 RESETTING, // The decoder is being reset.
181 DECODE_ERROR, // Decoding error happened.
182 };
183
184 static const int32 ID_LAST; // maximum bitstream buffer id
185 static const int32 ID_HALF; // half of the maximum bitstream buffer id
186 static const int32 ID_INVALID; // indicates Reset or Release never occurred
187
188 // The hardware video decoder.
189 scoped_ptr<media::VideoDecodeAccelerator> vda_;
190
191 // The size of the incoming video frames.
192 gfx::Size frame_size_;
193
194 // The weak pointer should live and die on the |vda_loop_proxy_|;
195 base::WeakPtrFactory<RTCVideoDecoder> weak_factory_;
196 base::WeakPtr<RTCVideoDecoder> weak_this_;
197
198 scoped_refptr<media::GpuVideoDecoder::Factories> factories_;
199
200 // The message loop to run callbacks on. This is should be the same as the one
201 // of |factories_|.
202 scoped_refptr<base::MessageLoopProxy> vda_loop_proxy_;
203
204 // The thread to create shared memory. Factories::CreateSharedMemory is
205 // trampolined to the child thread. When |vda_loop_proxy_| is the compositor
206 // thread, blocking on the child thread will deadlock. During WebRTC hang up,
207 // the child thread waits for Chrome_libJingle_WorkerThread. libJingle thread
208 // cannot finish when DecodingThread holds a WebRTC lock and blocks on the
209 // child thread. So we need to call CreateSharedMemory asynchronously from a
210 // different thread.
211 base::Thread create_shm_thread_;
212
213 // The texture target used for decoded pictures.
214 uint32 decoder_texture_target_;
215
216 // Metadata of the buffers that have been sent for decode.
217 std::list<BufferData> input_buffer_data_;
218
219 // A map from bitstream buffer IDs to bitstream buffers that are being
220 // processed by VDA. The map owns SHM buffers.
221 std::map<int32, SHMBuffer*> bitstream_buffers_in_decoder_;
222
223 // A map from picture buffer IDs to texture-backed picture buffers.
224 std::map<int32, media::PictureBuffer> assigned_picture_buffers_;
225
226 // Picture buffers that are dismissed but not deleted yet.
227 std::map<int32, media::PictureBuffer> dismissed_picture_buffers_;
228
229 // PictureBuffers given to us by VDA via PictureReady, which we sent forward
230 // as VideoFrames to be rendered via read_cb_, and which will be returned
231 // to us via ReusePictureBuffer.
232 std::set<int32> picture_buffers_at_display_;
233
234 // The id that will be given to the next picture buffer.
235 int32 next_picture_buffer_id_;
236
237 // Protects |state_|, |decode_complete_callback_| , |num_shm_buffers_|,
238 // |available_shm_segments_|, |pending_buffers_|, |decode_buffers_|,
239 // |next_bitstream_buffer_id_| and |reset_bitstream_buffer_id_|.
240 base::Lock lock_;
241
242 // The state of RTCVideoDecoder. Guarded by |lock_|.
243 State state_;
244
245 // Guarded by |lock_|.
246 webrtc::DecodedImageCallback* decode_complete_callback_;
247
248 // Total number of allocated SHM buffers. Guarded by |lock_|.
249 int num_shm_buffers_;
250
251 // Shared-memory buffer pool. Since allocating SHM segments requires a
252 // round-trip to the browser process, we keep allocation out of the
253 // steady-state of the decoder. The vector owns SHM buffers. Guarded by
254 // |lock_|.
255 std::vector<SHMBuffer*> available_shm_segments_;
256
257 // A queue storing WebRTC encoding images (and their metadata) that are
258 // waiting for the shared memory. Guarded by |lock_|.
259 std::deque<std::pair<webrtc::EncodedImage, BufferData> > pending_buffers_;
260
261 // A queue storing buffers (and their metadata) that will be sent to VDA for
262 // decode. The queue owns SHM buffers. Guarded by |lock_|.
263 std::deque<std::pair<SHMBuffer*, BufferData> > decode_buffers_;
264
265 // The id that will be given to the next bitstream buffer. Guarded by |lock_|.
266 int32 next_bitstream_buffer_id_;
267
268 // A buffer that has an id less than this should be dropped because Reset or
269 // Release has been called. Guarded by |lock_|.
270 int32 reset_bitstream_buffer_id_;
271
272 DISALLOW_COPY_AND_ASSIGN(RTCVideoDecoder);
273 };
274
275 } // namespace content
276
277 #endif // CONTENT_RENDERER_MEDIA_RTC_VIDEO_DECODER_H_
OLDNEW
« no previous file with comments | « content/renderer/media/renderer_gpu_video_decoder_factories.cc ('k') | content/renderer/media/rtc_video_decoder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698