cc: Added inline to Tile::IsReadyToDraw
[chromium-blink-merge.git] / media / filters / video_frame_stream.cc
blob73b136c8b79d105a270badcd0d8895e5ab6f5f62
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.
5 #include "media/filters/video_frame_stream.h"
7 #include "base/bind.h"
8 #include "base/callback_helpers.h"
9 #include "base/location.h"
10 #include "base/logging.h"
11 #include "base/message_loop/message_loop_proxy.h"
12 #include "media/base/bind_to_loop.h"
13 #include "media/base/decoder_buffer.h"
14 #include "media/base/demuxer_stream.h"
15 #include "media/base/video_decoder_config.h"
16 #include "media/filters/decrypting_demuxer_stream.h"
17 #include "media/filters/video_decoder_selector.h"
19 namespace media {
21 VideoFrameStream::VideoFrameStream(
22 const scoped_refptr<base::MessageLoopProxy>& message_loop,
23 ScopedVector<VideoDecoder> decoders,
24 const SetDecryptorReadyCB& set_decryptor_ready_cb)
25 : message_loop_(message_loop),
26 weak_factory_(this),
27 state_(STATE_UNINITIALIZED),
28 stream_(NULL),
29 decoder_selector_(new VideoDecoderSelector(message_loop,
30 decoders.Pass(),
31 set_decryptor_ready_cb)) {}
33 VideoFrameStream::~VideoFrameStream() {
34 DCHECK(state_ == STATE_UNINITIALIZED || state_ == STATE_STOPPED) << state_;
37 void VideoFrameStream::Initialize(DemuxerStream* stream,
38 const StatisticsCB& statistics_cb,
39 const InitCB& init_cb) {
40 DCHECK(message_loop_->BelongsToCurrentThread());
41 DCHECK_EQ(state_, STATE_UNINITIALIZED) << state_;
42 DCHECK(init_cb_.is_null());
43 DCHECK(!init_cb.is_null());
45 weak_this_ = weak_factory_.GetWeakPtr();
47 statistics_cb_ = statistics_cb;
48 init_cb_ = init_cb;
49 stream_ = stream;
51 state_ = STATE_INITIALIZING;
52 // TODO(xhwang): VideoDecoderSelector only needs a config to select a decoder.
53 decoder_selector_->SelectVideoDecoder(
54 stream, base::Bind(&VideoFrameStream::OnDecoderSelected, weak_this_));
57 void VideoFrameStream::Read(const ReadCB& read_cb) {
58 DCHECK(message_loop_->BelongsToCurrentThread());
59 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER ||
60 state_ == STATE_ERROR) << state_;
61 // No two reads in the flight at any time.
62 DCHECK(read_cb_.is_null());
63 // No read during resetting or stopping process.
64 DCHECK(reset_cb_.is_null());
65 DCHECK(stop_cb_.is_null());
67 if (state_ == STATE_ERROR) {
68 message_loop_->PostTask(FROM_HERE, base::Bind(
69 read_cb, DECODE_ERROR, scoped_refptr<VideoFrame>()));
70 return;
73 read_cb_ = read_cb;
75 if (state_ == STATE_FLUSHING_DECODER) {
76 FlushDecoder();
77 return;
80 ReadFromDemuxerStream();
83 void VideoFrameStream::Reset(const base::Closure& closure) {
84 DCHECK(message_loop_->BelongsToCurrentThread());
85 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_STOPPED) << state_;
86 DCHECK(reset_cb_.is_null());
87 DCHECK(stop_cb_.is_null());
89 reset_cb_ = closure;
91 // During decoder reinitialization, VideoDecoder does not need to be and
92 // cannot be Reset(). |decrypting_demuxer_stream_| was reset before decoder
93 // reinitialization.
94 // During pending demuxer read, VideoDecoder will be reset after demuxer read
95 // is returned (in OnBufferReady()).
96 if (state_ == STATE_REINITIALIZING_DECODER ||
97 state_ == STATE_PENDING_DEMUXER_READ) {
98 return;
101 // VideoDecoder API guarantees that if VideoDecoder::Reset() is called during
102 // a pending decode, the decode callback must be fired before the reset
103 // callback is fired. Therefore, we can call VideoDecoder::Reset() regardless
104 // of if we have a pending decode and always satisfy the reset callback when
105 // the decoder reset is finished.
106 if (decrypting_demuxer_stream_) {
107 decrypting_demuxer_stream_->Reset(base::Bind(
108 &VideoFrameStream::ResetDecoder, weak_this_));
109 return;
112 ResetDecoder();
115 void VideoFrameStream::Stop(const base::Closure& closure) {
116 DCHECK(message_loop_->BelongsToCurrentThread());
117 DCHECK_NE(state_, STATE_STOPPED) << state_;
118 DCHECK(stop_cb_.is_null());
120 stop_cb_ = closure;
122 // The stopping process will continue after the pending operation is finished.
123 // TODO(xhwang): Now we cannot stop the initialization process through
124 // VideoDecoderSelector. Fix this. See: http://crbug.com/222054
125 if (state_ == STATE_INITIALIZING || state_ == STATE_PENDING_DEMUXER_READ)
126 return;
128 // VideoDecoder API guarantees that if VideoDecoder::Stop() is called during
129 // a pending reset or a pending decode, the callbacks are always fired in the
130 // decode -> reset -> stop order. Therefore, we can call VideoDecoder::Stop()
131 // regardless of if we have a pending decode or reset and always satisfy the
132 // stop callback when the decoder decode/reset is finished.
133 if (decrypting_demuxer_stream_) {
134 decrypting_demuxer_stream_->Reset(base::Bind(
135 &VideoFrameStream::StopDecoder, weak_this_));
136 return;
139 // We may not have a |decoder_| if Stop() was called during initialization.
140 if (decoder_) {
141 StopDecoder();
142 return;
145 state_ = STATE_STOPPED;
146 stream_ = NULL;
147 decoder_.reset();
148 decrypting_demuxer_stream_.reset();
149 message_loop_->PostTask(FROM_HERE, base::ResetAndReturn(&stop_cb_));
152 bool VideoFrameStream::CanReadWithoutStalling() const {
153 DCHECK(message_loop_->BelongsToCurrentThread());
154 return decoder_->CanReadWithoutStalling();
157 void VideoFrameStream::OnDecoderSelected(
158 scoped_ptr<VideoDecoder> selected_decoder,
159 scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) {
160 DCHECK(message_loop_->BelongsToCurrentThread());
161 DCHECK_EQ(state_, STATE_INITIALIZING) << state_;
162 DCHECK(!init_cb_.is_null());
163 DCHECK(read_cb_.is_null());
164 DCHECK(reset_cb_.is_null());
166 decoder_selector_.reset();
168 if (!selected_decoder) {
169 state_ = STATE_UNINITIALIZED;
170 base::ResetAndReturn(&init_cb_).Run(false, false);
171 } else {
172 state_ = STATE_NORMAL;
173 decrypting_demuxer_stream_ = decrypting_demuxer_stream.Pass();
174 if (decrypting_demuxer_stream_)
175 stream_ = decrypting_demuxer_stream_.get();
176 decoder_ = selected_decoder.Pass();
177 if (decoder_->NeedsBitstreamConversion())
178 stream_->EnableBitstreamConverter();
179 // TODO(xhwang): We assume |decoder_->HasAlpha()| does not change after
180 // reinitialization. Check this condition.
181 base::ResetAndReturn(&init_cb_).Run(true, decoder_->HasAlpha());
184 // Stop() called during initialization.
185 if (!stop_cb_.is_null()) {
186 Stop(base::ResetAndReturn(&stop_cb_));
187 return;
191 void VideoFrameStream::SatisfyRead(Status status,
192 const scoped_refptr<VideoFrame>& frame) {
193 DCHECK(!read_cb_.is_null());
194 base::ResetAndReturn(&read_cb_).Run(status, frame);
197 void VideoFrameStream::AbortRead() {
198 SatisfyRead(ABORTED, NULL);
201 void VideoFrameStream::Decode(const scoped_refptr<DecoderBuffer>& buffer) {
202 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_;
203 DCHECK(!read_cb_.is_null());
204 DCHECK(reset_cb_.is_null());
205 DCHECK(stop_cb_.is_null());
206 DCHECK(buffer);
208 int buffer_size = buffer->end_of_stream() ? 0 : buffer->data_size();
209 decoder_->Decode(buffer, base::Bind(&VideoFrameStream::OnFrameReady,
210 weak_this_, buffer_size));
213 void VideoFrameStream::FlushDecoder() {
214 Decode(DecoderBuffer::CreateEOSBuffer());
217 void VideoFrameStream::OnFrameReady(int buffer_size,
218 const VideoDecoder::Status status,
219 const scoped_refptr<VideoFrame>& frame) {
220 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_;
221 DCHECK(!read_cb_.is_null());
223 if (status == VideoDecoder::kDecodeError) {
224 DCHECK(!frame.get());
225 state_ = STATE_ERROR;
226 SatisfyRead(DECODE_ERROR, NULL);
227 return;
230 if (status == VideoDecoder::kDecryptError) {
231 DCHECK(!frame.get());
232 state_ = STATE_ERROR;
233 SatisfyRead(DECRYPT_ERROR, NULL);
234 return;
237 // Any successful decode counts!
238 if (buffer_size > 0) {
239 PipelineStatistics statistics;
240 statistics.video_bytes_decoded = buffer_size;
241 statistics_cb_.Run(statistics);
244 // Drop decoding result if Reset()/Stop() was called during decoding.
245 // The stopping/resetting process will be handled when the decoder is
246 // stopped/reset.
247 if (!stop_cb_.is_null() || !reset_cb_.is_null()) {
248 AbortRead();
249 return;
252 // Decoder flushed. Reinitialize the video decoder.
253 if (state_ == STATE_FLUSHING_DECODER &&
254 status == VideoDecoder::kOk && frame->IsEndOfStream()) {
255 ReinitializeDecoder();
256 return;
259 if (status == VideoDecoder::kNotEnoughData) {
260 if (state_ == STATE_NORMAL)
261 ReadFromDemuxerStream();
262 else if (state_ == STATE_FLUSHING_DECODER)
263 FlushDecoder();
264 return;
267 SatisfyRead(OK, frame);
270 void VideoFrameStream::ReadFromDemuxerStream() {
271 DCHECK_EQ(state_, STATE_NORMAL) << state_;
272 DCHECK(!read_cb_.is_null());
273 DCHECK(reset_cb_.is_null());
274 DCHECK(stop_cb_.is_null());
276 state_ = STATE_PENDING_DEMUXER_READ;
277 stream_->Read(base::Bind(&VideoFrameStream::OnBufferReady, weak_this_));
280 void VideoFrameStream::OnBufferReady(
281 DemuxerStream::Status status,
282 const scoped_refptr<DecoderBuffer>& buffer) {
283 DCHECK(message_loop_->BelongsToCurrentThread());
284 DCHECK_EQ(state_, STATE_PENDING_DEMUXER_READ) << state_;
285 DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status;
286 DCHECK(!read_cb_.is_null());
288 state_ = STATE_NORMAL;
290 // Reset()/Stop() was postponed during STATE_PENDING_DEMUXER_READ state.
291 // We need to handle them in this function.
293 if (!stop_cb_.is_null()) {
294 AbortRead();
295 if (!reset_cb_.is_null())
296 Reset(base::ResetAndReturn(&reset_cb_));
297 Stop(base::ResetAndReturn(&stop_cb_));
298 return;
301 if (status == DemuxerStream::kConfigChanged) {
302 state_ = STATE_FLUSHING_DECODER;
303 if (!reset_cb_.is_null()) {
304 AbortRead();
305 Reset(base::ResetAndReturn(&reset_cb_));
306 // Reinitialization will continue after Reset() is done.
307 } else {
308 FlushDecoder();
310 return;
313 if (!reset_cb_.is_null()) {
314 AbortRead();
315 Reset(base::ResetAndReturn(&reset_cb_));
316 return;
319 if (status == DemuxerStream::kAborted) {
320 SatisfyRead(DEMUXER_READ_ABORTED, NULL);
321 return;
324 DCHECK(status == DemuxerStream::kOk) << status;
325 Decode(buffer);
328 void VideoFrameStream::ReinitializeDecoder() {
329 DCHECK(message_loop_->BelongsToCurrentThread());
330 DCHECK_EQ(state_, STATE_FLUSHING_DECODER) << state_;
332 DCHECK(stream_->video_decoder_config().IsValidConfig());
333 state_ = STATE_REINITIALIZING_DECODER;
334 decoder_->Initialize(
335 stream_->video_decoder_config(),
336 base::Bind(&VideoFrameStream::OnDecoderReinitialized, weak_this_));
339 void VideoFrameStream::OnDecoderReinitialized(PipelineStatus status) {
340 DCHECK(message_loop_->BelongsToCurrentThread());
341 DCHECK_EQ(state_, STATE_REINITIALIZING_DECODER) << state_;
343 // ReinitializeDecoder() can be called in two cases:
344 // 1, Flushing decoder finished (see OnFrameReady()).
345 // 2, Reset() was called during flushing decoder (see OnDecoderReset()).
346 // Also, Reset()/Stop() can be called during pending ReinitializeDecoder().
347 // This function needs to handle them all!
349 state_ = (status == PIPELINE_OK) ? STATE_NORMAL : STATE_ERROR;
351 if (!read_cb_.is_null() && (!stop_cb_.is_null() || !reset_cb_.is_null()))
352 AbortRead();
354 if (!reset_cb_.is_null())
355 base::ResetAndReturn(&reset_cb_).Run();
357 // If !stop_cb_.is_null(), it will be handled in OnDecoderStopped().
359 if (read_cb_.is_null())
360 return;
362 if (!stop_cb_.is_null()) {
363 base::ResetAndReturn(&read_cb_).Run(ABORTED, NULL);
364 return;
367 if (state_ == STATE_ERROR) {
368 SatisfyRead(DECODE_ERROR, NULL);
369 return;
372 ReadFromDemuxerStream();
375 void VideoFrameStream::ResetDecoder() {
376 DCHECK(message_loop_->BelongsToCurrentThread());
377 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER ||
378 state_ == STATE_ERROR) << state_;
379 DCHECK(!reset_cb_.is_null());
381 decoder_->Reset(base::Bind(&VideoFrameStream::OnDecoderReset, weak_this_));
384 void VideoFrameStream::OnDecoderReset() {
385 DCHECK(message_loop_->BelongsToCurrentThread());
386 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER ||
387 state_ == STATE_ERROR) << state_;
388 // If Reset() was called during pending read, read callback should be fired
389 // before the reset callback is fired.
390 DCHECK(read_cb_.is_null());
391 DCHECK(!reset_cb_.is_null());
393 if (state_ != STATE_FLUSHING_DECODER || !stop_cb_.is_null()) {
394 base::ResetAndReturn(&reset_cb_).Run();
395 return;
398 // The resetting process will be continued in OnDecoderReinitialized().
399 ReinitializeDecoder();
402 void VideoFrameStream::StopDecoder() {
403 DCHECK(message_loop_->BelongsToCurrentThread());
404 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_STOPPED) << state_;
405 DCHECK(!stop_cb_.is_null());
407 decoder_->Stop(base::Bind(&VideoFrameStream::OnDecoderStopped, weak_this_));
410 void VideoFrameStream::OnDecoderStopped() {
411 DCHECK(message_loop_->BelongsToCurrentThread());
412 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_STOPPED) << state_;
413 // If Stop() was called during pending read/reset, read/reset callback should
414 // be fired before the stop callback is fired.
415 DCHECK(read_cb_.is_null());
416 DCHECK(reset_cb_.is_null());
417 DCHECK(!stop_cb_.is_null());
419 state_ = STATE_STOPPED;
420 stream_ = NULL;
421 decoder_.reset();
422 decrypting_demuxer_stream_.reset();
423 base::ResetAndReturn(&stop_cb_).Run();
426 } // namespace media