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
)) {
34 VideoFrameStream::~VideoFrameStream() {
35 DCHECK(state_
== STATE_UNINITIALIZED
|| state_
== STATE_STOPPED
) << state_
;
38 void VideoFrameStream::Initialize(DemuxerStream
* stream
,
39 const StatisticsCB
& statistics_cb
,
40 const InitCB
& init_cb
) {
41 DVLOG(2) << __FUNCTION__
;
42 DCHECK(message_loop_
->BelongsToCurrentThread());
43 DCHECK_EQ(state_
, STATE_UNINITIALIZED
) << state_
;
44 DCHECK(init_cb_
.is_null());
45 DCHECK(!init_cb
.is_null());
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(
55 base::Bind(&VideoFrameStream::OnDecoderSelected
,
56 weak_factory_
.GetWeakPtr()));
59 void VideoFrameStream::Read(const ReadCB
& read_cb
) {
60 DVLOG(2) << __FUNCTION__
;
61 DCHECK(message_loop_
->BelongsToCurrentThread());
62 DCHECK(state_
== STATE_NORMAL
|| state_
== STATE_FLUSHING_DECODER
||
63 state_
== STATE_ERROR
) << state_
;
64 // No two reads in the flight at any time.
65 DCHECK(read_cb_
.is_null());
66 // No read during resetting or stopping process.
67 DCHECK(reset_cb_
.is_null());
68 DCHECK(stop_cb_
.is_null());
70 if (state_
== STATE_ERROR
) {
71 message_loop_
->PostTask(FROM_HERE
, base::Bind(
72 read_cb
, DECODE_ERROR
, scoped_refptr
<VideoFrame
>()));
78 if (state_
== STATE_FLUSHING_DECODER
) {
83 ReadFromDemuxerStream();
86 void VideoFrameStream::Reset(const base::Closure
& closure
) {
87 DVLOG(2) << __FUNCTION__
;
88 DCHECK(message_loop_
->BelongsToCurrentThread());
89 DCHECK(state_
!= STATE_UNINITIALIZED
&& state_
!= STATE_STOPPED
) << state_
;
90 DCHECK(reset_cb_
.is_null());
91 DCHECK(stop_cb_
.is_null());
95 // During decoder reinitialization, VideoDecoder does not need to be and
96 // cannot be Reset(). |decrypting_demuxer_stream_| was reset before decoder
98 if (state_
== STATE_REINITIALIZING_DECODER
)
101 // During pending demuxer read and when not using DecryptingDemuxerStream,
102 // VideoDecoder will be reset after demuxer read is returned
103 // (in OnBufferReady()).
104 if (state_
== STATE_PENDING_DEMUXER_READ
&& !decrypting_demuxer_stream_
)
107 // VideoDecoder API guarantees that if VideoDecoder::Reset() is called during
108 // a pending decode, the decode callback must be fired before the reset
109 // callback is fired. Therefore, we can call VideoDecoder::Reset() regardless
110 // of if we have a pending decode and always satisfy the reset callback when
111 // the decoder reset is finished.
112 if (decrypting_demuxer_stream_
) {
113 decrypting_demuxer_stream_
->Reset(base::Bind(
114 &VideoFrameStream::ResetDecoder
, weak_factory_
.GetWeakPtr()));
121 void VideoFrameStream::Stop(const base::Closure
& closure
) {
122 DVLOG(2) << __FUNCTION__
;
123 DCHECK(message_loop_
->BelongsToCurrentThread());
124 DCHECK_NE(state_
, STATE_STOPPED
) << state_
;
125 DCHECK(stop_cb_
.is_null());
129 if (state_
== STATE_INITIALIZING
) {
130 decoder_selector_
->Abort();
134 DCHECK(init_cb_
.is_null());
136 // All pending callbacks will be dropped.
137 weak_factory_
.InvalidateWeakPtrs();
139 // Post callbacks to prevent reentrance into this object.
140 if (!read_cb_
.is_null())
141 message_loop_
->PostTask(FROM_HERE
, base::Bind(
142 base::ResetAndReturn(&read_cb_
), ABORTED
, scoped_refptr
<VideoFrame
>()));
143 if (!reset_cb_
.is_null())
144 message_loop_
->PostTask(FROM_HERE
, base::ResetAndReturn(&reset_cb_
));
146 if (decrypting_demuxer_stream_
) {
147 decrypting_demuxer_stream_
->Reset(base::Bind(
148 &VideoFrameStream::StopDecoder
, weak_factory_
.GetWeakPtr()));
152 // We may not have a |decoder_| if Stop() was called during initialization.
158 state_
= STATE_STOPPED
;
161 decrypting_demuxer_stream_
.reset();
162 message_loop_
->PostTask(FROM_HERE
, base::ResetAndReturn(&stop_cb_
));
165 bool VideoFrameStream::CanReadWithoutStalling() const {
166 DCHECK(message_loop_
->BelongsToCurrentThread());
167 return decoder_
->CanReadWithoutStalling();
170 void VideoFrameStream::OnDecoderSelected(
171 scoped_ptr
<VideoDecoder
> selected_decoder
,
172 scoped_ptr
<DecryptingDemuxerStream
> decrypting_demuxer_stream
) {
173 DVLOG(2) << __FUNCTION__
;
174 DCHECK(message_loop_
->BelongsToCurrentThread());
175 DCHECK_EQ(state_
, STATE_INITIALIZING
) << state_
;
176 DCHECK(!init_cb_
.is_null());
177 DCHECK(read_cb_
.is_null());
178 DCHECK(reset_cb_
.is_null());
180 decoder_selector_
.reset();
182 if (!selected_decoder
) {
183 state_
= STATE_UNINITIALIZED
;
184 base::ResetAndReturn(&init_cb_
).Run(false, false);
186 state_
= STATE_NORMAL
;
187 decrypting_demuxer_stream_
= decrypting_demuxer_stream
.Pass();
188 if (decrypting_demuxer_stream_
)
189 stream_
= decrypting_demuxer_stream_
.get();
190 decoder_
= selected_decoder
.Pass();
191 if (decoder_
->NeedsBitstreamConversion())
192 stream_
->EnableBitstreamConverter();
193 // TODO(xhwang): We assume |decoder_->HasAlpha()| does not change after
194 // reinitialization. Check this condition.
195 base::ResetAndReturn(&init_cb_
).Run(true, decoder_
->HasAlpha());
198 // Stop() called during initialization.
199 if (!stop_cb_
.is_null()) {
200 Stop(base::ResetAndReturn(&stop_cb_
));
205 void VideoFrameStream::SatisfyRead(Status status
,
206 const scoped_refptr
<VideoFrame
>& frame
) {
207 DCHECK(!read_cb_
.is_null());
208 base::ResetAndReturn(&read_cb_
).Run(status
, frame
);
211 void VideoFrameStream::AbortRead() {
212 // Abort read during pending reset. It is safe to fire the |read_cb_| directly
213 // instead of posting it because VideoRenderBase won't call into this class
214 // again when it's in kFlushing state.
215 // TODO(xhwang): Improve the resetting process to avoid this dependency on the
217 DCHECK(!reset_cb_
.is_null());
218 SatisfyRead(ABORTED
, NULL
);
221 void VideoFrameStream::Decode(const scoped_refptr
<DecoderBuffer
>& buffer
) {
222 DVLOG(2) << __FUNCTION__
;
223 DCHECK(state_
== STATE_NORMAL
|| state_
== STATE_FLUSHING_DECODER
) << state_
;
224 DCHECK(!read_cb_
.is_null());
225 DCHECK(reset_cb_
.is_null());
226 DCHECK(stop_cb_
.is_null());
229 int buffer_size
= buffer
->end_of_stream() ? 0 : buffer
->data_size();
230 decoder_
->Decode(buffer
, base::Bind(&VideoFrameStream::OnFrameReady
,
231 weak_factory_
.GetWeakPtr(), buffer_size
));
234 void VideoFrameStream::FlushDecoder() {
235 Decode(DecoderBuffer::CreateEOSBuffer());
238 void VideoFrameStream::OnFrameReady(int buffer_size
,
239 const VideoDecoder::Status status
,
240 const scoped_refptr
<VideoFrame
>& frame
) {
241 DVLOG(2) << __FUNCTION__
;
242 DCHECK(state_
== STATE_NORMAL
|| state_
== STATE_FLUSHING_DECODER
) << state_
;
243 DCHECK(!read_cb_
.is_null());
244 DCHECK(stop_cb_
.is_null());
246 if (status
== VideoDecoder::kDecodeError
) {
247 DCHECK(!frame
.get());
248 state_
= STATE_ERROR
;
249 SatisfyRead(DECODE_ERROR
, NULL
);
253 if (status
== VideoDecoder::kDecryptError
) {
254 DCHECK(!frame
.get());
255 state_
= STATE_ERROR
;
256 SatisfyRead(DECRYPT_ERROR
, NULL
);
260 // Any successful decode counts!
261 if (buffer_size
> 0) {
262 PipelineStatistics statistics
;
263 statistics
.video_bytes_decoded
= buffer_size
;
264 statistics_cb_
.Run(statistics
);
267 // Drop decoding result if Reset() was called during decoding.
268 // The resetting process will be handled when the decoder is reset.
269 if (!reset_cb_
.is_null()) {
274 // Decoder flushed. Reinitialize the video decoder.
275 if (state_
== STATE_FLUSHING_DECODER
&&
276 status
== VideoDecoder::kOk
&& frame
->IsEndOfStream()) {
277 ReinitializeDecoder();
281 if (status
== VideoDecoder::kNotEnoughData
) {
282 if (state_
== STATE_NORMAL
)
283 ReadFromDemuxerStream();
284 else if (state_
== STATE_FLUSHING_DECODER
)
289 SatisfyRead(OK
, frame
);
292 void VideoFrameStream::ReadFromDemuxerStream() {
293 DVLOG(2) << __FUNCTION__
;
294 DCHECK_EQ(state_
, STATE_NORMAL
) << state_
;
295 DCHECK(!read_cb_
.is_null());
296 DCHECK(reset_cb_
.is_null());
297 DCHECK(stop_cb_
.is_null());
299 state_
= STATE_PENDING_DEMUXER_READ
;
301 base::Bind(&VideoFrameStream::OnBufferReady
, weak_factory_
.GetWeakPtr()));
304 void VideoFrameStream::OnBufferReady(
305 DemuxerStream::Status status
,
306 const scoped_refptr
<DecoderBuffer
>& buffer
) {
307 DVLOG(2) << __FUNCTION__
;
308 DCHECK(message_loop_
->BelongsToCurrentThread());
309 DCHECK_EQ(state_
, STATE_PENDING_DEMUXER_READ
) << state_
;
310 DCHECK_EQ(buffer
.get() != NULL
, status
== DemuxerStream::kOk
) << status
;
311 DCHECK(!read_cb_
.is_null());
312 DCHECK(stop_cb_
.is_null());
314 state_
= STATE_NORMAL
;
316 if (status
== DemuxerStream::kConfigChanged
) {
317 state_
= STATE_FLUSHING_DECODER
;
318 if (!reset_cb_
.is_null()) {
320 // If we are using DecryptingDemuxerStream, we already called DDS::Reset()
321 // which will continue the resetting process in it's callback.
322 if (!decrypting_demuxer_stream_
)
323 Reset(base::ResetAndReturn(&reset_cb_
));
324 // Reinitialization will continue after Reset() is done.
331 if (!reset_cb_
.is_null()) {
333 // If we are using DecryptingDemuxerStream, we already called DDS::Reset()
334 // which will continue the resetting process in it's callback.
335 if (!decrypting_demuxer_stream_
)
336 Reset(base::ResetAndReturn(&reset_cb_
));
340 if (status
== DemuxerStream::kAborted
) {
341 SatisfyRead(DEMUXER_READ_ABORTED
, NULL
);
345 DCHECK(status
== DemuxerStream::kOk
) << status
;
349 void VideoFrameStream::ReinitializeDecoder() {
350 DVLOG(2) << __FUNCTION__
;
351 DCHECK(message_loop_
->BelongsToCurrentThread());
352 DCHECK_EQ(state_
, STATE_FLUSHING_DECODER
) << state_
;
354 DCHECK(stream_
->video_decoder_config().IsValidConfig());
355 state_
= STATE_REINITIALIZING_DECODER
;
356 decoder_
->Initialize(stream_
->video_decoder_config(),
357 base::Bind(&VideoFrameStream::OnDecoderReinitialized
,
358 weak_factory_
.GetWeakPtr()));
361 void VideoFrameStream::OnDecoderReinitialized(PipelineStatus status
) {
362 DVLOG(2) << __FUNCTION__
;
363 DCHECK(message_loop_
->BelongsToCurrentThread());
364 DCHECK_EQ(state_
, STATE_REINITIALIZING_DECODER
) << state_
;
365 DCHECK(stop_cb_
.is_null());
367 // ReinitializeDecoder() can be called in two cases:
368 // 1, Flushing decoder finished (see OnFrameReady()).
369 // 2, Reset() was called during flushing decoder (see OnDecoderReset()).
370 // Also, Reset() can be called during pending ReinitializeDecoder().
371 // This function needs to handle them all!
373 state_
= (status
== PIPELINE_OK
) ? STATE_NORMAL
: STATE_ERROR
;
375 if (!reset_cb_
.is_null()) {
376 if (!read_cb_
.is_null())
378 base::ResetAndReturn(&reset_cb_
).Run();
381 if (read_cb_
.is_null())
384 if (state_
== STATE_ERROR
) {
385 SatisfyRead(DECODE_ERROR
, NULL
);
389 ReadFromDemuxerStream();
392 void VideoFrameStream::ResetDecoder() {
393 DVLOG(2) << __FUNCTION__
;
394 DCHECK(message_loop_
->BelongsToCurrentThread());
395 DCHECK(state_
== STATE_NORMAL
|| state_
== STATE_FLUSHING_DECODER
||
396 state_
== STATE_ERROR
) << state_
;
397 DCHECK(!reset_cb_
.is_null());
399 decoder_
->Reset(base::Bind(&VideoFrameStream::OnDecoderReset
,
400 weak_factory_
.GetWeakPtr()));
403 void VideoFrameStream::OnDecoderReset() {
404 DVLOG(2) << __FUNCTION__
;
405 DCHECK(message_loop_
->BelongsToCurrentThread());
406 DCHECK(state_
== STATE_NORMAL
|| state_
== STATE_FLUSHING_DECODER
||
407 state_
== STATE_ERROR
) << state_
;
408 // If Reset() was called during pending read, read callback should be fired
409 // before the reset callback is fired.
410 DCHECK(read_cb_
.is_null());
411 DCHECK(!reset_cb_
.is_null());
412 DCHECK(stop_cb_
.is_null());
414 if (state_
!= STATE_FLUSHING_DECODER
) {
415 base::ResetAndReturn(&reset_cb_
).Run();
419 // The resetting process will be continued in OnDecoderReinitialized().
420 ReinitializeDecoder();
423 void VideoFrameStream::StopDecoder() {
424 DVLOG(2) << __FUNCTION__
;
425 DCHECK(message_loop_
->BelongsToCurrentThread());
426 DCHECK(state_
!= STATE_UNINITIALIZED
&& state_
!= STATE_STOPPED
) << state_
;
427 DCHECK(!stop_cb_
.is_null());
429 decoder_
->Stop(base::Bind(&VideoFrameStream::OnDecoderStopped
,
430 weak_factory_
.GetWeakPtr()));
433 void VideoFrameStream::OnDecoderStopped() {
434 DVLOG(2) << __FUNCTION__
;
435 DCHECK(message_loop_
->BelongsToCurrentThread());
436 DCHECK(state_
!= STATE_UNINITIALIZED
&& state_
!= STATE_STOPPED
) << state_
;
437 // If Stop() was called during pending read/reset, read/reset callback should
438 // be fired before the stop callback is fired.
439 DCHECK(read_cb_
.is_null());
440 DCHECK(reset_cb_
.is_null());
441 DCHECK(!stop_cb_
.is_null());
443 state_
= STATE_STOPPED
;
446 decrypting_demuxer_stream_
.reset();
447 base::ResetAndReturn(&stop_cb_
).Run();