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