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/debug/trace_event.h"
10 #include "base/location.h"
11 #include "base/logging.h"
12 #include "base/message_loop/message_loop_proxy.h"
13 #include "media/base/bind_to_loop.h"
14 #include "media/base/decoder_buffer.h"
15 #include "media/base/demuxer_stream.h"
16 #include "media/base/video_decoder_config.h"
17 #include "media/filters/decrypting_demuxer_stream.h"
18 #include "media/filters/video_decoder_selector.h"
22 VideoFrameStream::VideoFrameStream(
23 const scoped_refptr
<base::MessageLoopProxy
>& message_loop
,
24 ScopedVector
<VideoDecoder
> decoders
,
25 const SetDecryptorReadyCB
& set_decryptor_ready_cb
)
26 : message_loop_(message_loop
),
28 state_(STATE_UNINITIALIZED
),
30 decoder_selector_(new VideoDecoderSelector(message_loop
,
32 set_decryptor_ready_cb
)) {
35 VideoFrameStream::~VideoFrameStream() {
36 DCHECK(state_
== STATE_UNINITIALIZED
|| state_
== STATE_STOPPED
) << state_
;
39 void VideoFrameStream::Initialize(DemuxerStream
* stream
,
40 const StatisticsCB
& statistics_cb
,
41 const InitCB
& init_cb
) {
42 DVLOG(2) << __FUNCTION__
;
43 DCHECK(message_loop_
->BelongsToCurrentThread());
44 DCHECK_EQ(state_
, STATE_UNINITIALIZED
) << state_
;
45 DCHECK(init_cb_
.is_null());
46 DCHECK(!init_cb
.is_null());
48 statistics_cb_
= statistics_cb
;
52 state_
= STATE_INITIALIZING
;
53 // TODO(xhwang): VideoDecoderSelector only needs a config to select a decoder.
54 decoder_selector_
->SelectVideoDecoder(
56 base::Bind(&VideoFrameStream::OnDecoderSelected
,
57 weak_factory_
.GetWeakPtr()));
60 void VideoFrameStream::Read(const ReadCB
& read_cb
) {
61 DVLOG(2) << __FUNCTION__
;
62 DCHECK(message_loop_
->BelongsToCurrentThread());
63 DCHECK(state_
== STATE_NORMAL
|| state_
== STATE_FLUSHING_DECODER
||
64 state_
== STATE_ERROR
) << state_
;
65 // No two reads in the flight at any time.
66 DCHECK(read_cb_
.is_null());
67 // No read during resetting or stopping process.
68 DCHECK(reset_cb_
.is_null());
69 DCHECK(stop_cb_
.is_null());
71 if (state_
== STATE_ERROR
) {
72 message_loop_
->PostTask(FROM_HERE
, base::Bind(
73 read_cb
, DECODE_ERROR
, scoped_refptr
<VideoFrame
>()));
79 if (state_
== STATE_FLUSHING_DECODER
) {
84 ReadFromDemuxerStream();
87 void VideoFrameStream::Reset(const base::Closure
& closure
) {
88 DVLOG(2) << __FUNCTION__
;
89 DCHECK(message_loop_
->BelongsToCurrentThread());
90 DCHECK(state_
!= STATE_UNINITIALIZED
&& state_
!= STATE_STOPPED
) << state_
;
91 DCHECK(reset_cb_
.is_null());
92 DCHECK(stop_cb_
.is_null());
96 // During decoder reinitialization, VideoDecoder does not need to be and
97 // cannot be Reset(). |decrypting_demuxer_stream_| was reset before decoder
99 if (state_
== STATE_REINITIALIZING_DECODER
)
102 // During pending demuxer read and when not using DecryptingDemuxerStream,
103 // VideoDecoder will be reset after demuxer read is returned
104 // (in OnBufferReady()).
105 if (state_
== STATE_PENDING_DEMUXER_READ
&& !decrypting_demuxer_stream_
)
108 // VideoDecoder API guarantees that if VideoDecoder::Reset() is called during
109 // a pending decode, the decode callback must be fired before the reset
110 // callback is fired. Therefore, we can call VideoDecoder::Reset() regardless
111 // of if we have a pending decode and always satisfy the reset callback when
112 // the decoder reset is finished.
113 if (decrypting_demuxer_stream_
) {
114 decrypting_demuxer_stream_
->Reset(base::Bind(
115 &VideoFrameStream::ResetDecoder
, weak_factory_
.GetWeakPtr()));
122 void VideoFrameStream::Stop(const base::Closure
& closure
) {
123 DVLOG(2) << __FUNCTION__
;
124 DCHECK(message_loop_
->BelongsToCurrentThread());
125 DCHECK_NE(state_
, STATE_STOPPED
) << state_
;
126 DCHECK(stop_cb_
.is_null());
130 if (state_
== STATE_INITIALIZING
) {
131 decoder_selector_
->Abort();
135 DCHECK(init_cb_
.is_null());
137 // All pending callbacks will be dropped.
138 weak_factory_
.InvalidateWeakPtrs();
140 // Post callbacks to prevent reentrance into this object.
141 if (!read_cb_
.is_null())
142 message_loop_
->PostTask(FROM_HERE
, base::Bind(
143 base::ResetAndReturn(&read_cb_
), ABORTED
, scoped_refptr
<VideoFrame
>()));
144 if (!reset_cb_
.is_null())
145 message_loop_
->PostTask(FROM_HERE
, base::ResetAndReturn(&reset_cb_
));
147 if (decrypting_demuxer_stream_
) {
148 decrypting_demuxer_stream_
->Reset(base::Bind(
149 &VideoFrameStream::StopDecoder
, weak_factory_
.GetWeakPtr()));
153 // We may not have a |decoder_| if Stop() was called during initialization.
159 state_
= STATE_STOPPED
;
162 decrypting_demuxer_stream_
.reset();
163 message_loop_
->PostTask(FROM_HERE
, base::ResetAndReturn(&stop_cb_
));
166 bool VideoFrameStream::CanReadWithoutStalling() const {
167 DCHECK(message_loop_
->BelongsToCurrentThread());
168 return decoder_
->CanReadWithoutStalling();
171 void VideoFrameStream::OnDecoderSelected(
172 scoped_ptr
<VideoDecoder
> selected_decoder
,
173 scoped_ptr
<DecryptingDemuxerStream
> decrypting_demuxer_stream
) {
174 DVLOG(2) << __FUNCTION__
;
175 DCHECK(message_loop_
->BelongsToCurrentThread());
176 DCHECK_EQ(state_
, STATE_INITIALIZING
) << state_
;
177 DCHECK(!init_cb_
.is_null());
178 DCHECK(read_cb_
.is_null());
179 DCHECK(reset_cb_
.is_null());
181 decoder_selector_
.reset();
183 if (!selected_decoder
) {
184 state_
= STATE_UNINITIALIZED
;
185 base::ResetAndReturn(&init_cb_
).Run(false, false);
187 state_
= STATE_NORMAL
;
188 decrypting_demuxer_stream_
= decrypting_demuxer_stream
.Pass();
189 if (decrypting_demuxer_stream_
)
190 stream_
= decrypting_demuxer_stream_
.get();
191 decoder_
= selected_decoder
.Pass();
192 if (decoder_
->NeedsBitstreamConversion())
193 stream_
->EnableBitstreamConverter();
194 // TODO(xhwang): We assume |decoder_->HasAlpha()| does not change after
195 // reinitialization. Check this condition.
196 base::ResetAndReturn(&init_cb_
).Run(true, decoder_
->HasAlpha());
199 // Stop() called during initialization.
200 if (!stop_cb_
.is_null()) {
201 Stop(base::ResetAndReturn(&stop_cb_
));
206 void VideoFrameStream::SatisfyRead(Status status
,
207 const scoped_refptr
<VideoFrame
>& frame
) {
208 DCHECK(!read_cb_
.is_null());
209 base::ResetAndReturn(&read_cb_
).Run(status
, frame
);
212 void VideoFrameStream::AbortRead() {
213 // Abort read during pending reset. It is safe to fire the |read_cb_| directly
214 // instead of posting it because VideoRenderBase won't call into this class
215 // again when it's in kFlushing state.
216 // TODO(xhwang): Improve the resetting process to avoid this dependency on the
218 DCHECK(!reset_cb_
.is_null());
219 SatisfyRead(ABORTED
, NULL
);
222 void VideoFrameStream::Decode(const scoped_refptr
<DecoderBuffer
>& buffer
) {
223 DVLOG(2) << __FUNCTION__
;
224 DCHECK(state_
== STATE_NORMAL
|| state_
== STATE_FLUSHING_DECODER
) << state_
;
225 DCHECK(!read_cb_
.is_null());
226 DCHECK(reset_cb_
.is_null());
227 DCHECK(stop_cb_
.is_null());
230 int buffer_size
= buffer
->end_of_stream() ? 0 : buffer
->data_size();
232 TRACE_EVENT_ASYNC_BEGIN0("media", "VideoFrameStream::Decode", this);
233 decoder_
->Decode(buffer
, base::Bind(&VideoFrameStream::OnFrameReady
,
234 weak_factory_
.GetWeakPtr(), buffer_size
));
237 void VideoFrameStream::FlushDecoder() {
238 Decode(DecoderBuffer::CreateEOSBuffer());
241 void VideoFrameStream::OnFrameReady(int buffer_size
,
242 const VideoDecoder::Status status
,
243 const scoped_refptr
<VideoFrame
>& frame
) {
244 DVLOG(2) << __FUNCTION__
;
245 DCHECK(state_
== STATE_NORMAL
|| state_
== STATE_FLUSHING_DECODER
) << state_
;
246 DCHECK(!read_cb_
.is_null());
247 DCHECK(stop_cb_
.is_null());
249 TRACE_EVENT_ASYNC_END0("media", "VideoFrameStream::Decode", this);
251 if (status
== VideoDecoder::kDecodeError
) {
252 DCHECK(!frame
.get());
253 state_
= STATE_ERROR
;
254 SatisfyRead(DECODE_ERROR
, NULL
);
258 if (status
== VideoDecoder::kDecryptError
) {
259 DCHECK(!frame
.get());
260 state_
= STATE_ERROR
;
261 SatisfyRead(DECRYPT_ERROR
, NULL
);
265 // Any successful decode counts!
266 if (buffer_size
> 0) {
267 PipelineStatistics statistics
;
268 statistics
.video_bytes_decoded
= buffer_size
;
269 statistics_cb_
.Run(statistics
);
272 // Drop decoding result if Reset() was called during decoding.
273 // The resetting process will be handled when the decoder is reset.
274 if (!reset_cb_
.is_null()) {
279 // Decoder flushed. Reinitialize the video decoder.
280 if (state_
== STATE_FLUSHING_DECODER
&&
281 status
== VideoDecoder::kOk
&& frame
->end_of_stream()) {
282 ReinitializeDecoder();
286 if (status
== VideoDecoder::kNotEnoughData
) {
287 if (state_
== STATE_NORMAL
)
288 ReadFromDemuxerStream();
289 else if (state_
== STATE_FLUSHING_DECODER
)
294 SatisfyRead(OK
, frame
);
297 void VideoFrameStream::ReadFromDemuxerStream() {
298 DVLOG(2) << __FUNCTION__
;
299 DCHECK_EQ(state_
, STATE_NORMAL
) << state_
;
300 DCHECK(!read_cb_
.is_null());
301 DCHECK(reset_cb_
.is_null());
302 DCHECK(stop_cb_
.is_null());
304 state_
= STATE_PENDING_DEMUXER_READ
;
306 base::Bind(&VideoFrameStream::OnBufferReady
, weak_factory_
.GetWeakPtr()));
309 void VideoFrameStream::OnBufferReady(
310 DemuxerStream::Status status
,
311 const scoped_refptr
<DecoderBuffer
>& buffer
) {
312 DVLOG(2) << __FUNCTION__
;
313 DCHECK(message_loop_
->BelongsToCurrentThread());
314 DCHECK_EQ(state_
, STATE_PENDING_DEMUXER_READ
) << state_
;
315 DCHECK_EQ(buffer
.get() != NULL
, status
== DemuxerStream::kOk
) << status
;
316 DCHECK(!read_cb_
.is_null());
317 DCHECK(stop_cb_
.is_null());
319 state_
= STATE_NORMAL
;
321 if (status
== DemuxerStream::kConfigChanged
) {
322 state_
= STATE_FLUSHING_DECODER
;
323 if (!reset_cb_
.is_null()) {
325 // If we are using DecryptingDemuxerStream, we already called DDS::Reset()
326 // which will continue the resetting process in it's callback.
327 if (!decrypting_demuxer_stream_
)
328 Reset(base::ResetAndReturn(&reset_cb_
));
329 // Reinitialization will continue after Reset() is done.
336 if (!reset_cb_
.is_null()) {
338 // If we are using DecryptingDemuxerStream, we already called DDS::Reset()
339 // which will continue the resetting process in it's callback.
340 if (!decrypting_demuxer_stream_
)
341 Reset(base::ResetAndReturn(&reset_cb_
));
345 if (status
== DemuxerStream::kAborted
) {
346 SatisfyRead(DEMUXER_READ_ABORTED
, NULL
);
350 DCHECK(status
== DemuxerStream::kOk
) << status
;
354 void VideoFrameStream::ReinitializeDecoder() {
355 DVLOG(2) << __FUNCTION__
;
356 DCHECK(message_loop_
->BelongsToCurrentThread());
357 DCHECK_EQ(state_
, STATE_FLUSHING_DECODER
) << state_
;
359 DCHECK(stream_
->video_decoder_config().IsValidConfig());
360 state_
= STATE_REINITIALIZING_DECODER
;
361 decoder_
->Initialize(stream_
->video_decoder_config(),
362 base::Bind(&VideoFrameStream::OnDecoderReinitialized
,
363 weak_factory_
.GetWeakPtr()));
366 void VideoFrameStream::OnDecoderReinitialized(PipelineStatus status
) {
367 DVLOG(2) << __FUNCTION__
;
368 DCHECK(message_loop_
->BelongsToCurrentThread());
369 DCHECK_EQ(state_
, STATE_REINITIALIZING_DECODER
) << state_
;
370 DCHECK(stop_cb_
.is_null());
372 // ReinitializeDecoder() can be called in two cases:
373 // 1, Flushing decoder finished (see OnFrameReady()).
374 // 2, Reset() was called during flushing decoder (see OnDecoderReset()).
375 // Also, Reset() can be called during pending ReinitializeDecoder().
376 // This function needs to handle them all!
378 state_
= (status
== PIPELINE_OK
) ? STATE_NORMAL
: STATE_ERROR
;
380 if (!reset_cb_
.is_null()) {
381 if (!read_cb_
.is_null())
383 base::ResetAndReturn(&reset_cb_
).Run();
386 if (read_cb_
.is_null())
389 if (state_
== STATE_ERROR
) {
390 SatisfyRead(DECODE_ERROR
, NULL
);
394 ReadFromDemuxerStream();
397 void VideoFrameStream::ResetDecoder() {
398 DVLOG(2) << __FUNCTION__
;
399 DCHECK(message_loop_
->BelongsToCurrentThread());
400 DCHECK(state_
== STATE_NORMAL
|| state_
== STATE_FLUSHING_DECODER
||
401 state_
== STATE_ERROR
) << state_
;
402 DCHECK(!reset_cb_
.is_null());
404 decoder_
->Reset(base::Bind(&VideoFrameStream::OnDecoderReset
,
405 weak_factory_
.GetWeakPtr()));
408 void VideoFrameStream::OnDecoderReset() {
409 DVLOG(2) << __FUNCTION__
;
410 DCHECK(message_loop_
->BelongsToCurrentThread());
411 DCHECK(state_
== STATE_NORMAL
|| state_
== STATE_FLUSHING_DECODER
||
412 state_
== STATE_ERROR
) << state_
;
413 // If Reset() was called during pending read, read callback should be fired
414 // before the reset callback is fired.
415 DCHECK(read_cb_
.is_null());
416 DCHECK(!reset_cb_
.is_null());
417 DCHECK(stop_cb_
.is_null());
419 if (state_
!= STATE_FLUSHING_DECODER
) {
420 base::ResetAndReturn(&reset_cb_
).Run();
424 // The resetting process will be continued in OnDecoderReinitialized().
425 ReinitializeDecoder();
428 void VideoFrameStream::StopDecoder() {
429 DVLOG(2) << __FUNCTION__
;
430 DCHECK(message_loop_
->BelongsToCurrentThread());
431 DCHECK(state_
!= STATE_UNINITIALIZED
&& state_
!= STATE_STOPPED
) << state_
;
432 DCHECK(!stop_cb_
.is_null());
434 decoder_
->Stop(base::Bind(&VideoFrameStream::OnDecoderStopped
,
435 weak_factory_
.GetWeakPtr()));
438 void VideoFrameStream::OnDecoderStopped() {
439 DVLOG(2) << __FUNCTION__
;
440 DCHECK(message_loop_
->BelongsToCurrentThread());
441 DCHECK(state_
!= STATE_UNINITIALIZED
&& state_
!= STATE_STOPPED
) << state_
;
442 // If Stop() was called during pending read/reset, read/reset callback should
443 // be fired before the stop callback is fired.
444 DCHECK(read_cb_
.is_null());
445 DCHECK(reset_cb_
.is_null());
446 DCHECK(!stop_cb_
.is_null());
448 state_
= STATE_STOPPED
;
451 decrypting_demuxer_stream_
.reset();
452 base::ResetAndReturn(&stop_cb_
).Run();