Home | History | Annotate | Download | only in filters
      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.
      4 
      5 #include "media/filters/video_frame_stream.h"
      6 
      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"
     18 
     19 namespace media {
     20 
     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)) {}
     32 
     33 VideoFrameStream::~VideoFrameStream() {
     34   DCHECK(state_ == STATE_UNINITIALIZED || state_ == STATE_STOPPED) << state_;
     35 }
     36 
     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());
     44 
     45   weak_this_ = weak_factory_.GetWeakPtr();
     46 
     47   statistics_cb_ = statistics_cb;
     48   init_cb_ = init_cb;
     49   stream_ = stream;
     50 
     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_));
     55 }
     56 
     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());
     66 
     67   if (state_ == STATE_ERROR) {
     68     message_loop_->PostTask(FROM_HERE, base::Bind(
     69         read_cb, DECODE_ERROR, scoped_refptr<VideoFrame>()));
     70     return;
     71   }
     72 
     73   read_cb_ = read_cb;
     74 
     75   if (state_ == STATE_FLUSHING_DECODER) {
     76     FlushDecoder();
     77     return;
     78   }
     79 
     80   ReadFromDemuxerStream();
     81 }
     82 
     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());
     88 
     89   reset_cb_ = closure;
     90 
     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;
     99   }
    100 
    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;
    110   }
    111 
    112   ResetDecoder();
    113 }
    114 
    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());
    119 
    120   stop_cb_ = closure;
    121 
    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;
    127 
    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;
    137   }
    138 
    139   // We may not have a |decoder_| if Stop() was called during initialization.
    140   if (decoder_) {
    141     StopDecoder();
    142     return;
    143   }
    144 
    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_));
    150 }
    151 
    152 bool VideoFrameStream::CanReadWithoutStalling() const {
    153   DCHECK(message_loop_->BelongsToCurrentThread());
    154   return decoder_->CanReadWithoutStalling();
    155 }
    156 
    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());
    165 
    166   decoder_selector_.reset();
    167 
    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());
    182   }
    183 
    184   // Stop() called during initialization.
    185   if (!stop_cb_.is_null()) {
    186     Stop(base::ResetAndReturn(&stop_cb_));
    187     return;
    188   }
    189 }
    190 
    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);
    195 }
    196 
    197 void VideoFrameStream::AbortRead() {
    198   SatisfyRead(ABORTED, NULL);
    199 }
    200 
    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);
    207 
    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));
    211 }
    212 
    213 void VideoFrameStream::FlushDecoder() {
    214   Decode(DecoderBuffer::CreateEOSBuffer());
    215 }
    216 
    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());
    222 
    223   if (status == VideoDecoder::kDecodeError) {
    224     DCHECK(!frame.get());
    225     state_ = STATE_ERROR;
    226     SatisfyRead(DECODE_ERROR, NULL);
    227     return;
    228   }
    229 
    230   if (status == VideoDecoder::kDecryptError) {
    231     DCHECK(!frame.get());
    232     state_ = STATE_ERROR;
    233     SatisfyRead(DECRYPT_ERROR, NULL);
    234     return;
    235   }
    236 
    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);
    242   }
    243 
    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;
    250   }
    251 
    252   // Decoder flushed. Reinitialize the video decoder.
    253   if (state_ == STATE_FLUSHING_DECODER &&
    254       status == VideoDecoder::kOk && frame->IsEndOfStream()) {
    255     ReinitializeDecoder();
    256     return;
    257   }
    258 
    259   if (status == VideoDecoder::kNotEnoughData) {
    260     if (state_ == STATE_NORMAL)
    261       ReadFromDemuxerStream();
    262     else if (state_ == STATE_FLUSHING_DECODER)
    263       FlushDecoder();
    264     return;
    265   }
    266 
    267   SatisfyRead(OK, frame);
    268 }
    269 
    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());
    275 
    276   state_ = STATE_PENDING_DEMUXER_READ;
    277   stream_->Read(base::Bind(&VideoFrameStream::OnBufferReady, weak_this_));
    278 }
    279 
    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());
    287 
    288   state_ = STATE_NORMAL;
    289 
    290   // Reset()/Stop() was postponed during STATE_PENDING_DEMUXER_READ state.
    291   // We need to handle them in this function.
    292 
    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;
    299   }
    300 
    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();
    309     }
    310     return;
    311   }
    312 
    313   if (!reset_cb_.is_null()) {
    314     AbortRead();
    315     Reset(base::ResetAndReturn(&reset_cb_));
    316     return;
    317   }
    318 
    319   if (status == DemuxerStream::kAborted) {
    320     SatisfyRead(DEMUXER_READ_ABORTED, NULL);
    321     return;
    322   }
    323 
    324   DCHECK(status == DemuxerStream::kOk) << status;
    325   Decode(buffer);
    326 }
    327 
    328 void VideoFrameStream::ReinitializeDecoder() {
    329   DCHECK(message_loop_->BelongsToCurrentThread());
    330   DCHECK_EQ(state_, STATE_FLUSHING_DECODER) << state_;
    331 
    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_));
    337 }
    338 
    339 void VideoFrameStream::OnDecoderReinitialized(PipelineStatus status) {
    340   DCHECK(message_loop_->BelongsToCurrentThread());
    341   DCHECK_EQ(state_, STATE_REINITIALIZING_DECODER) << state_;
    342 
    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!
    348 
    349   state_ = (status == PIPELINE_OK) ? STATE_NORMAL : STATE_ERROR;
    350 
    351   if (!read_cb_.is_null() && (!stop_cb_.is_null() || !reset_cb_.is_null()))
    352     AbortRead();
    353 
    354   if (!reset_cb_.is_null())
    355     base::ResetAndReturn(&reset_cb_).Run();
    356 
    357   // If !stop_cb_.is_null(), it will be handled in OnDecoderStopped().
    358 
    359   if (read_cb_.is_null())
    360     return;
    361 
    362   if (!stop_cb_.is_null()) {
    363     base::ResetAndReturn(&read_cb_).Run(ABORTED, NULL);
    364     return;
    365   }
    366 
    367   if (state_ == STATE_ERROR) {
    368     SatisfyRead(DECODE_ERROR, NULL);
    369     return;
    370   }
    371 
    372   ReadFromDemuxerStream();
    373 }
    374 
    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());
    380 
    381   decoder_->Reset(base::Bind(&VideoFrameStream::OnDecoderReset, weak_this_));
    382 }
    383 
    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());
    392 
    393   if (state_ != STATE_FLUSHING_DECODER || !stop_cb_.is_null()) {
    394     base::ResetAndReturn(&reset_cb_).Run();
    395     return;
    396   }
    397 
    398   // The resetting process will be continued in OnDecoderReinitialized().
    399   ReinitializeDecoder();
    400 }
    401 
    402 void VideoFrameStream::StopDecoder() {
    403   DCHECK(message_loop_->BelongsToCurrentThread());
    404   DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_STOPPED) << state_;
    405   DCHECK(!stop_cb_.is_null());
    406 
    407   decoder_->Stop(base::Bind(&VideoFrameStream::OnDecoderStopped, weak_this_));
    408 }
    409 
    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());
    418 
    419   state_ = STATE_STOPPED;
    420   stream_ = NULL;
    421   decoder_.reset();
    422   decrypting_demuxer_stream_.reset();
    423   base::ResetAndReturn(&stop_cb_).Run();
    424 }
    425 
    426 }  // namespace media
    427