OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef CONTENT_RENDERER_MEDIA_RTC_VIDEO_DECODER_H_ | 5 #ifndef CONTENT_RENDERER_MEDIA_RTC_VIDEO_DECODER_H_ |
6 #define CONTENT_RENDERER_MEDIA_RTC_VIDEO_DECODER_H_ | 6 #define CONTENT_RENDERER_MEDIA_RTC_VIDEO_DECODER_H_ |
7 | 7 |
8 #include <deque> | 8 #include <deque> |
| 9 #include <map> |
9 #include <set> | 10 #include <set> |
10 #include <utility> | 11 #include <utility> |
11 | 12 |
12 #include "base/basictypes.h" | 13 #include "base/basictypes.h" |
13 #include "base/gtest_prod_util.h" | 14 #include "base/gtest_prod_util.h" |
14 #include "base/memory/weak_ptr.h" | 15 #include "base/memory/weak_ptr.h" |
15 #include "base/message_loop/message_loop.h" | 16 #include "base/message_loop/message_loop.h" |
16 #include "base/synchronization/lock.h" | 17 #include "base/synchronization/lock.h" |
17 #include "base/synchronization/waitable_event.h" | 18 #include "base/synchronization/waitable_event.h" |
18 #include "base/threading/thread.h" | 19 #include "base/threading/thread.h" |
19 #include "content/common/content_export.h" | 20 #include "content/common/content_export.h" |
20 #include "media/base/bitstream_buffer.h" | 21 #include "media/base/bitstream_buffer.h" |
21 #include "media/base/video_decoder.h" | 22 #include "media/base/video_decoder.h" |
22 #include "media/filters/gpu_video_decoder.h" | |
23 #include "media/video/picture.h" | 23 #include "media/video/picture.h" |
24 #include "media/video/video_decode_accelerator.h" | 24 #include "media/video/video_decode_accelerator.h" |
25 #include "third_party/webrtc/modules/video_coding/codecs/interface/video_codec_i
nterface.h" | 25 #include "third_party/webrtc/modules/video_coding/codecs/interface/video_codec_i
nterface.h" |
26 | 26 |
27 namespace base { | 27 namespace base { |
28 class MessageLoopProxy; | 28 class MessageLoopProxy; |
29 }; | 29 }; |
30 | 30 |
31 namespace media { | 31 namespace media { |
32 class DecoderBuffer; | 32 class DecoderBuffer; |
| 33 class GpuVideoDecoderFactories; |
33 } | 34 } |
34 | 35 |
35 namespace content { | 36 namespace content { |
36 | 37 |
37 // This class uses hardware accelerated video decoder to decode video for | 38 // This class uses hardware accelerated video decoder to decode video for |
38 // WebRTC. The message loop of RendererGpuVideoDecoderFactories is stored as | 39 // WebRTC. The message loop of RendererGpuVideoDecoderFactories is stored as |
39 // |vda_message_loop_|. It is the compositor thread, or the renderer thread if | 40 // |vda_message_loop_|. It is the compositor thread, or the renderer thread if |
40 // threaded compositing is disabled. VDA::Client methods run on | 41 // threaded compositing is disabled. VDA::Client methods run on |
41 // |vda_message_loop_|. webrtc::VideoDecoder methods run on WebRTC | 42 // |vda_message_loop_|. webrtc::VideoDecoder methods run on WebRTC |
42 // DecodingThread or Chrome_libJingle_WorkerThread, which are trampolined to | 43 // DecodingThread or Chrome_libJingle_WorkerThread, which are trampolined to |
43 // |vda_message_loop_|. Decode() is non-blocking and queues the buffers. Decoded | 44 // |vda_message_loop_|. Decode() is non-blocking and queues the buffers. Decoded |
44 // frames are delivered on |vda_message_loop_|. | 45 // frames are delivered on |vda_message_loop_|. |
45 class CONTENT_EXPORT RTCVideoDecoder | 46 class CONTENT_EXPORT RTCVideoDecoder |
46 : NON_EXPORTED_BASE(public webrtc::VideoDecoder), | 47 : NON_EXPORTED_BASE(public webrtc::VideoDecoder), |
47 public media::VideoDecodeAccelerator::Client, | 48 public media::VideoDecodeAccelerator::Client, |
48 public base::MessageLoop::DestructionObserver { | 49 public base::MessageLoop::DestructionObserver { |
49 public: | 50 public: |
50 virtual ~RTCVideoDecoder(); | 51 virtual ~RTCVideoDecoder(); |
51 | 52 |
52 // Creates a RTCVideoDecoder. Returns NULL if failed. | 53 // Creates a RTCVideoDecoder. Returns NULL if failed. |
53 static scoped_ptr<RTCVideoDecoder> Create( | 54 static scoped_ptr<RTCVideoDecoder> Create( |
54 const scoped_refptr<media::GpuVideoDecoder::Factories>& factories); | 55 const scoped_refptr<media::GpuVideoDecoderFactories>& factories); |
55 | 56 |
56 // webrtc::VideoDecoder implementation. | 57 // webrtc::VideoDecoder implementation. |
57 // Called on WebRTC DecodingThread. | 58 // Called on WebRTC DecodingThread. |
58 virtual int32_t InitDecode(const webrtc::VideoCodec* codecSettings, | 59 virtual int32_t InitDecode(const webrtc::VideoCodec* codecSettings, |
59 int32_t numberOfCores) OVERRIDE; | 60 int32_t numberOfCores) OVERRIDE; |
60 // Called on WebRTC DecodingThread. | 61 // Called on WebRTC DecodingThread. |
61 virtual int32_t Decode( | 62 virtual int32_t Decode( |
62 const webrtc::EncodedImage& inputImage, | 63 const webrtc::EncodedImage& inputImage, |
63 bool missingFrames, | 64 bool missingFrames, |
64 const webrtc::RTPFragmentationHeader* fragmentation, | 65 const webrtc::RTPFragmentationHeader* fragmentation, |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 int32 bitstream_buffer_id; | 105 int32 bitstream_buffer_id; |
105 uint32_t timestamp; // in 90KHz | 106 uint32_t timestamp; // in 90KHz |
106 uint32_t width; | 107 uint32_t width; |
107 uint32_t height; | 108 uint32_t height; |
108 size_t size; // buffer size | 109 size_t size; // buffer size |
109 }; | 110 }; |
110 | 111 |
111 FRIEND_TEST_ALL_PREFIXES(RTCVideoDecoderTest, IsBufferAfterReset); | 112 FRIEND_TEST_ALL_PREFIXES(RTCVideoDecoderTest, IsBufferAfterReset); |
112 | 113 |
113 RTCVideoDecoder( | 114 RTCVideoDecoder( |
114 const scoped_refptr<media::GpuVideoDecoder::Factories>& factories); | 115 const scoped_refptr<media::GpuVideoDecoderFactories>& factories); |
115 | 116 |
116 void Initialize(base::WaitableEvent* waiter); | 117 void Initialize(base::WaitableEvent* waiter); |
117 | 118 |
118 // Requests a buffer to be decoded by VDA. | 119 // Requests a buffer to be decoded by VDA. |
119 void RequestBufferDecode(); | 120 void RequestBufferDecode(); |
120 | 121 |
121 bool CanMoreDecodeWorkBeDone(); | 122 bool CanMoreDecodeWorkBeDone(); |
122 | 123 |
123 // Returns true if bitstream buffer id |id_buffer| comes after |id_reset|. | 124 // Returns true if bitstream buffer id |id_buffer| comes after |id_reset|. |
124 // This handles the wraparound. | 125 // This handles the wraparound. |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 // The hardware video decoder. | 189 // The hardware video decoder. |
189 scoped_ptr<media::VideoDecodeAccelerator> vda_; | 190 scoped_ptr<media::VideoDecodeAccelerator> vda_; |
190 | 191 |
191 // The size of the incoming video frames. | 192 // The size of the incoming video frames. |
192 gfx::Size frame_size_; | 193 gfx::Size frame_size_; |
193 | 194 |
194 // The weak pointer should live and die on the |vda_loop_proxy_|; | 195 // The weak pointer should live and die on the |vda_loop_proxy_|; |
195 base::WeakPtrFactory<RTCVideoDecoder> weak_factory_; | 196 base::WeakPtrFactory<RTCVideoDecoder> weak_factory_; |
196 base::WeakPtr<RTCVideoDecoder> weak_this_; | 197 base::WeakPtr<RTCVideoDecoder> weak_this_; |
197 | 198 |
198 scoped_refptr<media::GpuVideoDecoder::Factories> factories_; | 199 scoped_refptr<media::GpuVideoDecoderFactories> factories_; |
199 | 200 |
200 // The message loop to run callbacks on. This is should be the same as the one | 201 // The message loop to run callbacks on. This is should be the same as the one |
201 // of |factories_|. | 202 // of |factories_|. |
202 scoped_refptr<base::MessageLoopProxy> vda_loop_proxy_; | 203 scoped_refptr<base::MessageLoopProxy> vda_loop_proxy_; |
203 | 204 |
204 // The thread to create shared memory. Factories::CreateSharedMemory is | 205 // The thread to create shared memory. CreateSharedMemory is trampolined to |
205 // trampolined to the child thread. When |vda_loop_proxy_| is the compositor | 206 // the child thread. When |vda_loop_proxy_| is the compositor thread, blocking |
206 // thread, blocking on the child thread will deadlock. During WebRTC hang up, | 207 // on the child thread will deadlock. During WebRTC hang up, the child thread |
207 // the child thread waits for Chrome_libJingle_WorkerThread. libJingle thread | 208 // waits for Chrome_libJingle_WorkerThread. libJingle thread cannot finish |
208 // cannot finish when DecodingThread holds a WebRTC lock and blocks on the | 209 // when DecodingThread holds a WebRTC lock and blocks on the child thread. So |
209 // child thread. So we need to call CreateSharedMemory asynchronously from a | 210 // we need to call CreateSharedMemory asynchronously from a different thread. |
210 // different thread. | |
211 base::Thread create_shm_thread_; | 211 base::Thread create_shm_thread_; |
212 | 212 |
213 // The texture target used for decoded pictures. | 213 // The texture target used for decoded pictures. |
214 uint32 decoder_texture_target_; | 214 uint32 decoder_texture_target_; |
215 | 215 |
216 // Metadata of the buffers that have been sent for decode. | 216 // Metadata of the buffers that have been sent for decode. |
217 std::list<BufferData> input_buffer_data_; | 217 std::list<BufferData> input_buffer_data_; |
218 | 218 |
219 // A map from bitstream buffer IDs to bitstream buffers that are being | 219 // A map from bitstream buffer IDs to bitstream buffers that are being |
220 // processed by VDA. The map owns SHM buffers. | 220 // processed by VDA. The map owns SHM buffers. |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
268 // A buffer that has an id less than this should be dropped because Reset or | 268 // A buffer that has an id less than this should be dropped because Reset or |
269 // Release has been called. Guarded by |lock_|. | 269 // Release has been called. Guarded by |lock_|. |
270 int32 reset_bitstream_buffer_id_; | 270 int32 reset_bitstream_buffer_id_; |
271 | 271 |
272 DISALLOW_COPY_AND_ASSIGN(RTCVideoDecoder); | 272 DISALLOW_COPY_AND_ASSIGN(RTCVideoDecoder); |
273 }; | 273 }; |
274 | 274 |
275 } // namespace content | 275 } // namespace content |
276 | 276 |
277 #endif // CONTENT_RENDERER_MEDIA_RTC_VIDEO_DECODER_H_ | 277 #endif // CONTENT_RENDERER_MEDIA_RTC_VIDEO_DECODER_H_ |
OLD | NEW |