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"
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"
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
),
27 state_(STATE_UNINITIALIZED
),
29 decoder_selector_(new VideoDecoderSelector(message_loop
,
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
;
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
>()));
75 if (state_
== STATE_FLUSHING_DECODER
) {
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());
91 // During decoder reinitialization, VideoDecoder does not need to be and
92 // cannot be Reset(). |decrypting_demuxer_stream_| was reset before decoder
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
) {
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_
));
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());
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
)
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_
));
139 // We may not have a |decoder_| if Stop() was called during initialization.
145 state_
= STATE_STOPPED
;
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);
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_
));
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());
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
);
230 if (status
== VideoDecoder::kDecryptError
) {
231 DCHECK(!frame
.get());
232 state_
= STATE_ERROR
;
233 SatisfyRead(DECRYPT_ERROR
, NULL
);
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
247 if (!stop_cb_
.is_null() || !reset_cb_
.is_null()) {
252 // Decoder flushed. Reinitialize the video decoder.
253 if (state_
== STATE_FLUSHING_DECODER
&&
254 status
== VideoDecoder::kOk
&& frame
->IsEndOfStream()) {
255 ReinitializeDecoder();
259 if (status
== VideoDecoder::kNotEnoughData
) {
260 if (state_
== STATE_NORMAL
)
261 ReadFromDemuxerStream();
262 else if (state_
== STATE_FLUSHING_DECODER
)
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()) {
295 if (!reset_cb_
.is_null())
296 Reset(base::ResetAndReturn(&reset_cb_
));
297 Stop(base::ResetAndReturn(&stop_cb_
));
301 if (status
== DemuxerStream::kConfigChanged
) {
302 state_
= STATE_FLUSHING_DECODER
;
303 if (!reset_cb_
.is_null()) {
305 Reset(base::ResetAndReturn(&reset_cb_
));
306 // Reinitialization will continue after Reset() is done.
313 if (!reset_cb_
.is_null()) {
315 Reset(base::ResetAndReturn(&reset_cb_
));
319 if (status
== DemuxerStream::kAborted
) {
320 SatisfyRead(DEMUXER_READ_ABORTED
, NULL
);
324 DCHECK(status
== DemuxerStream::kOk
) << status
;
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()))
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())
362 if (!stop_cb_
.is_null()) {
363 base::ResetAndReturn(&read_cb_
).Run(ABORTED
, NULL
);
367 if (state_
== STATE_ERROR
) {
368 SatisfyRead(DECODE_ERROR
, NULL
);
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();
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
;
422 decrypting_demuxer_stream_
.reset();
423 base::ResetAndReturn(&stop_cb_
).Run();