OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 MEDIA_FILTERS_VIDEO_RENDERER_BASE_H_ | 5 #ifndef MEDIA_FILTERS_VIDEO_RENDERER_BASE_H_ |
6 #define MEDIA_FILTERS_VIDEO_RENDERER_BASE_H_ | 6 #define MEDIA_FILTERS_VIDEO_RENDERER_BASE_H_ |
7 | 7 |
8 #include <deque> | 8 #include <deque> |
9 | 9 |
10 #include "base/memory/ref_counted.h" | 10 #include "base/memory/ref_counted.h" |
11 #include "base/synchronization/condition_variable.h" | 11 #include "base/synchronization/condition_variable.h" |
12 #include "base/synchronization/lock.h" | 12 #include "base/synchronization/lock.h" |
13 #include "base/threading/platform_thread.h" | 13 #include "base/threading/platform_thread.h" |
14 #include "media/base/demuxer_stream.h" | 14 #include "media/base/demuxer_stream.h" |
15 #include "media/base/pipeline_status.h" | 15 #include "media/base/pipeline_status.h" |
16 #include "media/base/video_decoder.h" | 16 #include "media/base/video_decoder.h" |
17 #include "media/base/video_frame.h" | 17 #include "media/base/video_frame.h" |
18 #include "media/base/video_renderer.h" | 18 #include "media/base/video_renderer.h" |
19 | 19 |
| 20 namespace base { |
| 21 class MessageLoopProxy; |
| 22 } |
| 23 |
20 namespace media { | 24 namespace media { |
21 | 25 |
22 // VideoRendererBase creates its own thread for the sole purpose of timing frame | 26 // VideoRendererBase creates its own thread for the sole purpose of timing frame |
23 // presentation. It handles reading from the decoder and stores the results in | 27 // presentation. It handles reading from the decoder and stores the results in |
24 // a queue of decoded frames and executing a callback when a frame is ready for | 28 // a queue of decoded frames and executing a callback when a frame is ready for |
25 // rendering. | 29 // rendering. |
26 class MEDIA_EXPORT VideoRendererBase | 30 class MEDIA_EXPORT VideoRendererBase |
27 : public VideoRenderer, | 31 : public VideoRenderer, |
28 public base::PlatformThread::Delegate { | 32 public base::PlatformThread::Delegate { |
29 public: | 33 public: |
30 typedef base::Callback<void(bool)> SetOpaqueCB; | 34 typedef base::Callback<void(bool)> SetOpaqueCB; |
31 | 35 |
32 // Maximum duration of the last frame. | 36 // Maximum duration of the last frame. |
33 static base::TimeDelta kMaxLastFrameDuration(); | 37 static base::TimeDelta kMaxLastFrameDuration(); |
34 | 38 |
35 // |paint_cb| is executed on the video frame timing thread whenever a new | 39 // |paint_cb| is executed on the video frame timing thread whenever a new |
36 // frame is available for painting via GetCurrentFrame(). | 40 // frame is available for painting via GetCurrentFrame(). |
37 // | 41 // |
38 // |set_opaque_cb| is executed when the renderer is initialized to inform | 42 // |set_opaque_cb| is executed when the renderer is initialized to inform |
39 // the player whether the decoder's output will be opaque or not. | 43 // the player whether the decoder's output will be opaque or not. |
40 // | 44 // |
41 // Implementors should avoid doing any sort of heavy work in this method and | 45 // Implementors should avoid doing any sort of heavy work in this method and |
42 // instead post a task to a common/worker thread to handle rendering. Slowing | 46 // instead post a task to a common/worker thread to handle rendering. Slowing |
43 // down the video thread may result in losing synchronization with audio. | 47 // down the video thread may result in losing synchronization with audio. |
44 // | 48 // |
45 // Setting |drop_frames_| to true causes the renderer to drop expired frames. | 49 // Setting |drop_frames_| to true causes the renderer to drop expired frames. |
46 // | 50 // |
47 // TODO(scherkus): pass the VideoFrame* to this callback and remove | 51 // TODO(scherkus): pass the VideoFrame* to this callback and remove |
48 // Get/PutCurrentFrame() http://crbug.com/108435 | 52 // Get/PutCurrentFrame() http://crbug.com/108435 |
49 VideoRendererBase(const base::Closure& paint_cb, | 53 VideoRendererBase(const scoped_refptr<base::MessageLoopProxy>& message_loop, |
| 54 const base::Closure& paint_cb, |
50 const SetOpaqueCB& set_opaque_cb, | 55 const SetOpaqueCB& set_opaque_cb, |
51 bool drop_frames); | 56 bool drop_frames); |
52 | 57 |
53 // VideoRenderer implementation. | 58 // VideoRenderer implementation. |
54 virtual void Initialize(const scoped_refptr<DemuxerStream>& stream, | 59 virtual void Initialize(const scoped_refptr<DemuxerStream>& stream, |
55 const VideoDecoderList& decoders, | 60 const VideoDecoderList& decoders, |
56 const PipelineStatusCB& init_cb, | 61 const PipelineStatusCB& init_cb, |
57 const StatisticsCB& statistics_cb, | 62 const StatisticsCB& statistics_cb, |
58 const TimeCB& max_time_cb, | 63 const TimeCB& max_time_cb, |
59 const NaturalSizeChangedCB& size_changed_cb, | 64 const NaturalSizeChangedCB& size_changed_cb, |
(...skipping 28 matching lines...) Expand all Loading... |
88 // Callback from the video decoder delivering decoded video frames and | 93 // Callback from the video decoder delivering decoded video frames and |
89 // reporting video decoder status. | 94 // reporting video decoder status. |
90 void FrameReady(VideoDecoder::Status status, | 95 void FrameReady(VideoDecoder::Status status, |
91 const scoped_refptr<VideoFrame>& frame); | 96 const scoped_refptr<VideoFrame>& frame); |
92 | 97 |
93 // Helper method for adding a frame to |ready_frames_| | 98 // Helper method for adding a frame to |ready_frames_| |
94 void AddReadyFrame(const scoped_refptr<VideoFrame>& frame); | 99 void AddReadyFrame(const scoped_refptr<VideoFrame>& frame); |
95 | 100 |
96 // Helper method that schedules an asynchronous read from the decoder as long | 101 // Helper method that schedules an asynchronous read from the decoder as long |
97 // as there isn't a pending read and we have capacity. | 102 // as there isn't a pending read and we have capacity. |
| 103 void AttemptRead(); |
98 void AttemptRead_Locked(); | 104 void AttemptRead_Locked(); |
99 | 105 |
100 // Called when the VideoDecoder Flush() completes. | 106 // Called when VideoDecoder::Reset() completes. |
101 void OnDecoderFlushDone(); | 107 void OnDecoderResetDone(); |
102 | 108 |
103 // Attempts to complete flushing and transition into the flushed state. | 109 // Attempts to complete flushing and transition into the flushed state. |
104 void AttemptFlush_Locked(); | 110 void AttemptFlush_Locked(); |
105 | 111 |
106 // Calculates the duration to sleep for based on |current_frame_|'s timestamp, | 112 // Calculates the duration to sleep for based on |current_frame_|'s timestamp, |
107 // the next frame timestamp (may be NULL), and the provided playback rate. | 113 // the next frame timestamp (may be NULL), and the provided playback rate. |
108 // | 114 // |
109 // We don't use |playback_rate_| to avoid locking. | 115 // We don't use |playback_rate_| to avoid locking. |
110 base::TimeDelta CalculateSleepDuration( | 116 base::TimeDelta CalculateSleepDuration( |
111 const scoped_refptr<VideoFrame>& next_frame, | 117 const scoped_refptr<VideoFrame>& next_frame, |
(...skipping 14 matching lines...) Expand all Loading... |
126 void InitializeNextDecoder(const scoped_refptr<DemuxerStream>& demuxer_stream, | 132 void InitializeNextDecoder(const scoped_refptr<DemuxerStream>& demuxer_stream, |
127 scoped_ptr<VideoDecoderList> decoders); | 133 scoped_ptr<VideoDecoderList> decoders); |
128 | 134 |
129 // Called when |decoder_| initialization completes. | 135 // Called when |decoder_| initialization completes. |
130 // |demuxer_stream| & |decoders| are used if initialization failed and | 136 // |demuxer_stream| & |decoders| are used if initialization failed and |
131 // InitializeNextDecoder() needs to be called again. | 137 // InitializeNextDecoder() needs to be called again. |
132 void OnDecoderInitDone(const scoped_refptr<DemuxerStream>& demuxer_stream, | 138 void OnDecoderInitDone(const scoped_refptr<DemuxerStream>& demuxer_stream, |
133 scoped_ptr<VideoDecoderList> decoders, | 139 scoped_ptr<VideoDecoderList> decoders, |
134 PipelineStatus status); | 140 PipelineStatus status); |
135 | 141 |
| 142 scoped_refptr<base::MessageLoopProxy> message_loop_; |
| 143 |
136 // Used for accessing data members. | 144 // Used for accessing data members. |
137 base::Lock lock_; | 145 base::Lock lock_; |
138 | 146 |
139 scoped_refptr<VideoDecoder> decoder_; | 147 scoped_refptr<VideoDecoder> decoder_; |
140 | 148 |
141 // Queue of incoming frames as well as the current frame since the last time | 149 // Queue of incoming frames as well as the current frame since the last time |
142 // OnFrameAvailable() was called. | 150 // OnFrameAvailable() was called. |
143 typedef std::deque<scoped_refptr<VideoFrame> > VideoFrameQueue; | 151 typedef std::deque<scoped_refptr<VideoFrame> > VideoFrameQueue; |
144 VideoFrameQueue ready_frames_; | 152 VideoFrameQueue ready_frames_; |
145 | 153 |
(...skipping 12 matching lines...) Expand all Loading... |
158 | 166 |
159 // Used to signal |thread_| as frames are added to |frames_|. Rule of thumb: | 167 // Used to signal |thread_| as frames are added to |frames_|. Rule of thumb: |
160 // always check |state_| to see if it was set to STOPPED after waking up! | 168 // always check |state_| to see if it was set to STOPPED after waking up! |
161 base::ConditionVariable frame_available_; | 169 base::ConditionVariable frame_available_; |
162 | 170 |
163 // State transition Diagram of this class: | 171 // State transition Diagram of this class: |
164 // [kUninitialized] -------> [kError] | 172 // [kUninitialized] -------> [kError] |
165 // | | 173 // | |
166 // | Initialize() | 174 // | Initialize() |
167 // V All frames returned | 175 // V All frames returned |
168 // +------[kFlushed]<-----[kFlushing]<--- OnDecoderFlushDone() | 176 // +------[kFlushed]<-----[kFlushing]<--- OnDecoderResetDone() |
169 // | | Preroll() or upon ^ | 177 // | | Preroll() or upon ^ |
170 // | V got first frame [kFlushingDecoder] | 178 // | V got first frame [kFlushingDecoder] |
171 // | [kPrerolling] ^ | 179 // | [kPrerolling] ^ |
172 // | | | Flush() | 180 // | | | Flush() |
173 // | V Got enough frames | | 181 // | V Got enough frames | |
174 // | [kPrerolled]---------------------->[kPaused] | 182 // | [kPrerolled]---------------------->[kPaused] |
175 // | | Pause() ^ | 183 // | | Pause() ^ |
176 // | V Play() | | 184 // | V Play() | |
177 // | [kPlaying]---------------------------| | 185 // | [kPlaying]---------------------------| |
178 // | | Pause() ^ | 186 // | | Pause() ^ |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 | 256 |
249 // The last natural size |size_changed_cb_| was called with. | 257 // The last natural size |size_changed_cb_| was called with. |
250 gfx::Size last_natural_size_; | 258 gfx::Size last_natural_size_; |
251 | 259 |
252 DISALLOW_COPY_AND_ASSIGN(VideoRendererBase); | 260 DISALLOW_COPY_AND_ASSIGN(VideoRendererBase); |
253 }; | 261 }; |
254 | 262 |
255 } // namespace media | 263 } // namespace media |
256 | 264 |
257 #endif // MEDIA_FILTERS_VIDEO_RENDERER_BASE_H_ | 265 #endif // MEDIA_FILTERS_VIDEO_RENDERER_BASE_H_ |
OLD | NEW |