Remove some suppressions which are no longer needed. BitmapPlatformDeviceData was...
[chromium-blink-merge.git] / media / filters / video_frame_stream.cc
blob4b13ac9a8e4a0663644da0eba10acb13a7d13361
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/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"
20 namespace media {
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),
27 weak_factory_(this),
28 state_(STATE_UNINITIALIZED),
29 stream_(NULL),
30 decoder_selector_(new VideoDecoderSelector(message_loop,
31 decoders.Pass(),
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;
49 init_cb_ = init_cb;
50 stream_ = stream;
52 state_ = STATE_INITIALIZING;
53 // TODO(xhwang): VideoDecoderSelector only needs a config to select a decoder.
54 decoder_selector_->SelectVideoDecoder(
55 stream,
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>()));
74 return;
77 read_cb_ = read_cb;
79 if (state_ == STATE_FLUSHING_DECODER) {
80 FlushDecoder();
81 return;
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());
94 reset_cb_ = closure;
96 // During decoder reinitialization, VideoDecoder does not need to be and
97 // cannot be Reset(). |decrypting_demuxer_stream_| was reset before decoder
98 // reinitialization.
99 if (state_ == STATE_REINITIALIZING_DECODER)
100 return;
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_)
106 return;
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()));
116 return;
119 ResetDecoder();
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());
128 stop_cb_ = closure;
130 if (state_ == STATE_INITIALIZING) {
131 decoder_selector_->Abort();
132 return;
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()));
150 return;
153 // We may not have a |decoder_| if Stop() was called during initialization.
154 if (decoder_) {
155 StopDecoder();
156 return;
159 state_ = STATE_STOPPED;
160 stream_ = NULL;
161 decoder_.reset();
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);
186 } else {
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_));
202 return;
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
217 // caller.
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());
228 DCHECK(buffer);
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);
255 return;
258 if (status == VideoDecoder::kDecryptError) {
259 DCHECK(!frame.get());
260 state_ = STATE_ERROR;
261 SatisfyRead(DECRYPT_ERROR, NULL);
262 return;
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()) {
275 AbortRead();
276 return;
279 // Decoder flushed. Reinitialize the video decoder.
280 if (state_ == STATE_FLUSHING_DECODER &&
281 status == VideoDecoder::kOk && frame->end_of_stream()) {
282 ReinitializeDecoder();
283 return;
286 if (status == VideoDecoder::kNotEnoughData) {
287 if (state_ == STATE_NORMAL)
288 ReadFromDemuxerStream();
289 else if (state_ == STATE_FLUSHING_DECODER)
290 FlushDecoder();
291 return;
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;
305 stream_->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()) {
324 AbortRead();
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.
330 } else {
331 FlushDecoder();
333 return;
336 if (!reset_cb_.is_null()) {
337 AbortRead();
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_));
342 return;
345 if (status == DemuxerStream::kAborted) {
346 SatisfyRead(DEMUXER_READ_ABORTED, NULL);
347 return;
350 DCHECK(status == DemuxerStream::kOk) << status;
351 Decode(buffer);
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())
382 AbortRead();
383 base::ResetAndReturn(&reset_cb_).Run();
386 if (read_cb_.is_null())
387 return;
389 if (state_ == STATE_ERROR) {
390 SatisfyRead(DECODE_ERROR, NULL);
391 return;
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();
421 return;
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;
449 stream_ = NULL;
450 decoder_.reset();
451 decrypting_demuxer_stream_.reset();
452 base::ResetAndReturn(&stop_cb_).Run();
455 } // namespace media