Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(597)

Side by Side Diff: media/filters/ffmpeg_video_decoder.cc

Issue 10669022: Add status parameter to DemuxerStream::ReadCB (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/filters/ffmpeg_video_decoder.h ('k') | media/filters/ffmpeg_video_decoder_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/filters/ffmpeg_video_decoder.h" 5 #include "media/filters/ffmpeg_video_decoder.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 void FFmpegVideoDecoder::ReadFromDemuxerStream() { 275 void FFmpegVideoDecoder::ReadFromDemuxerStream() {
276 DCHECK_NE(state_, kUninitialized); 276 DCHECK_NE(state_, kUninitialized);
277 DCHECK_NE(state_, kDecodeFinished); 277 DCHECK_NE(state_, kDecodeFinished);
278 DCHECK(!read_cb_.is_null()); 278 DCHECK(!read_cb_.is_null());
279 279
280 demuxer_stream_->Read(base::Bind(&FFmpegVideoDecoder::DecryptOrDecodeBuffer, 280 demuxer_stream_->Read(base::Bind(&FFmpegVideoDecoder::DecryptOrDecodeBuffer,
281 this)); 281 this));
282 } 282 }
283 283
284 void FFmpegVideoDecoder::DecryptOrDecodeBuffer( 284 void FFmpegVideoDecoder::DecryptOrDecodeBuffer(
285 DemuxerStream::Status status,
285 const scoped_refptr<DecoderBuffer>& buffer) { 286 const scoped_refptr<DecoderBuffer>& buffer) {
287 DCHECK_EQ(status != DemuxerStream::kOk, !buffer) << status;
286 // TODO(scherkus): fix FFmpegDemuxerStream::Read() to not execute our read 288 // TODO(scherkus): fix FFmpegDemuxerStream::Read() to not execute our read
287 // callback on the same execution stack so we can get rid of forced task post. 289 // callback on the same execution stack so we can get rid of forced task post.
288 message_loop_->PostTask(FROM_HERE, base::Bind( 290 message_loop_->PostTask(FROM_HERE, base::Bind(
289 &FFmpegVideoDecoder::DoDecryptOrDecodeBuffer, this, buffer)); 291 &FFmpegVideoDecoder::DoDecryptOrDecodeBuffer, this, status, buffer));
290 } 292 }
291 293
292 void FFmpegVideoDecoder::DoDecryptOrDecodeBuffer( 294 void FFmpegVideoDecoder::DoDecryptOrDecodeBuffer(
295 DemuxerStream::Status status,
293 const scoped_refptr<DecoderBuffer>& buffer) { 296 const scoped_refptr<DecoderBuffer>& buffer) {
294 DCHECK_EQ(MessageLoop::current(), message_loop_); 297 DCHECK_EQ(MessageLoop::current(), message_loop_);
295 DCHECK_NE(state_, kUninitialized); 298 DCHECK_NE(state_, kUninitialized);
296 DCHECK_NE(state_, kDecodeFinished); 299 DCHECK_NE(state_, kDecodeFinished);
297 DCHECK(!read_cb_.is_null()); 300 DCHECK(!read_cb_.is_null());
298 301
299 if (!reset_cb_.is_null()) { 302 if (!reset_cb_.is_null()) {
300 DeliverFrame(NULL); 303 base::ResetAndReturn(&read_cb_).Run(kOk, NULL);
301 DoReset(); 304 DoReset();
302 return; 305 return;
303 } 306 }
304 307
305 if (!buffer) { 308 if (status != DemuxerStream::kOk) {
306 DeliverFrame(NULL); 309 DecoderStatus decoder_status =
310 (status == DemuxerStream::kAborted) ? kOk : kDecodeError;
311 base::ResetAndReturn(&read_cb_).Run(decoder_status, NULL);
307 return; 312 return;
308 } 313 }
309 314
315 DCHECK_EQ(status, DemuxerStream::kOk);
316
310 if (buffer->GetDecryptConfig() && buffer->GetDataSize()) { 317 if (buffer->GetDecryptConfig() && buffer->GetDataSize()) {
311 decryptor_->Decrypt(buffer, 318 decryptor_->Decrypt(buffer,
312 base::Bind(&FFmpegVideoDecoder::BufferDecrypted, this)); 319 base::Bind(&FFmpegVideoDecoder::BufferDecrypted, this));
313 return; 320 return;
314 } 321 }
315 322
316 DecodeBuffer(buffer); 323 DecodeBuffer(buffer);
317 } 324 }
318 325
319 void FFmpegVideoDecoder::BufferDecrypted( 326 void FFmpegVideoDecoder::BufferDecrypted(
320 Decryptor::DecryptStatus decrypt_status, 327 Decryptor::DecryptStatus decrypt_status,
321 const scoped_refptr<DecoderBuffer>& buffer) { 328 const scoped_refptr<DecoderBuffer>& buffer) {
322 message_loop_->PostTask(FROM_HERE, base::Bind( 329 message_loop_->PostTask(FROM_HERE, base::Bind(
323 &FFmpegVideoDecoder::DoBufferDecrypted, this, decrypt_status, buffer)); 330 &FFmpegVideoDecoder::DoBufferDecrypted, this, decrypt_status, buffer));
324 } 331 }
325 332
326 void FFmpegVideoDecoder::DoBufferDecrypted( 333 void FFmpegVideoDecoder::DoBufferDecrypted(
327 Decryptor::DecryptStatus decrypt_status, 334 Decryptor::DecryptStatus decrypt_status,
328 const scoped_refptr<DecoderBuffer>& buffer) { 335 const scoped_refptr<DecoderBuffer>& buffer) {
329 DCHECK_EQ(MessageLoop::current(), message_loop_); 336 DCHECK_EQ(MessageLoop::current(), message_loop_);
330 DCHECK_NE(state_, kUninitialized); 337 DCHECK_NE(state_, kUninitialized);
331 DCHECK_NE(state_, kDecodeFinished); 338 DCHECK_NE(state_, kDecodeFinished);
332 DCHECK(!read_cb_.is_null()); 339 DCHECK(!read_cb_.is_null());
333 340
334 if (!reset_cb_.is_null()) { 341 if (!reset_cb_.is_null()) {
335 DeliverFrame(NULL); 342 base::ResetAndReturn(&read_cb_).Run(kOk, NULL);
336 DoReset(); 343 DoReset();
337 return; 344 return;
338 } 345 }
339 346
340 if (decrypt_status == Decryptor::kError) { 347 if (decrypt_status == Decryptor::kError) {
341 state_ = kDecodeFinished; 348 state_ = kDecodeFinished;
342 base::ResetAndReturn(&read_cb_).Run(kDecryptError, NULL); 349 base::ResetAndReturn(&read_cb_).Run(kDecryptError, NULL);
343 return; 350 return;
344 } 351 }
345 352
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 PipelineStatistics statistics; 408 PipelineStatistics statistics;
402 statistics.video_bytes_decoded = buffer->GetDataSize(); 409 statistics.video_bytes_decoded = buffer->GetDataSize();
403 statistics_cb_.Run(statistics); 410 statistics_cb_.Run(statistics);
404 } 411 }
405 412
406 // If we didn't get a frame then we've either completely finished decoding or 413 // If we didn't get a frame then we've either completely finished decoding or
407 // we need more data. 414 // we need more data.
408 if (!video_frame) { 415 if (!video_frame) {
409 if (state_ == kFlushCodec) { 416 if (state_ == kFlushCodec) {
410 state_ = kDecodeFinished; 417 state_ = kDecodeFinished;
411 DeliverFrame(VideoFrame::CreateEmptyFrame()); 418 base::ResetAndReturn(&read_cb_).Run(kOk, VideoFrame::CreateEmptyFrame());
412 return; 419 return;
413 } 420 }
414 421
415 ReadFromDemuxerStream(); 422 ReadFromDemuxerStream();
416 return; 423 return;
417 } 424 }
418 425
419 DeliverFrame(video_frame); 426 base::ResetAndReturn(&read_cb_).Run(kOk, video_frame);
420 } 427 }
421 428
422 bool FFmpegVideoDecoder::Decode( 429 bool FFmpegVideoDecoder::Decode(
423 const scoped_refptr<DecoderBuffer>& buffer, 430 const scoped_refptr<DecoderBuffer>& buffer,
424 scoped_refptr<VideoFrame>* video_frame) { 431 scoped_refptr<VideoFrame>* video_frame) {
425 DCHECK(video_frame); 432 DCHECK(video_frame);
426 433
427 // Create a packet for input data. 434 // Create a packet for input data.
428 // Due to FFmpeg API changes we no longer have const read-only pointers. 435 // Due to FFmpeg API changes we no longer have const read-only pointers.
429 AVPacket packet; 436 AVPacket packet;
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
504 doubled_time_base.den = frame_rate_numerator_ * 2; 511 doubled_time_base.den = frame_rate_numerator_ * 2;
505 512
506 (*video_frame)->SetTimestamp( 513 (*video_frame)->SetTimestamp(
507 base::TimeDelta::FromMicroseconds(av_frame_->reordered_opaque)); 514 base::TimeDelta::FromMicroseconds(av_frame_->reordered_opaque));
508 (*video_frame)->SetDuration( 515 (*video_frame)->SetDuration(
509 ConvertFromTimeBase(doubled_time_base, 2 + av_frame_->repeat_pict)); 516 ConvertFromTimeBase(doubled_time_base, 2 + av_frame_->repeat_pict));
510 517
511 return true; 518 return true;
512 } 519 }
513 520
514 void FFmpegVideoDecoder::DeliverFrame(
515 const scoped_refptr<VideoFrame>& video_frame) {
516 // Reset the callback before running to protect against reentrancy.
517 base::ResetAndReturn(&read_cb_).Run(kOk, video_frame);
518 }
519
520 void FFmpegVideoDecoder::ReleaseFFmpegResources() { 521 void FFmpegVideoDecoder::ReleaseFFmpegResources() {
521 if (codec_context_) { 522 if (codec_context_) {
522 av_free(codec_context_->extradata); 523 av_free(codec_context_->extradata);
523 avcodec_close(codec_context_); 524 avcodec_close(codec_context_);
524 av_free(codec_context_); 525 av_free(codec_context_);
525 codec_context_ = NULL; 526 codec_context_ = NULL;
526 } 527 }
527 if (av_frame_) { 528 if (av_frame_) {
528 av_free(av_frame_); 529 av_free(av_frame_);
529 av_frame_ = NULL; 530 av_frame_ = NULL;
530 } 531 }
531 } 532 }
532 533
533 } // namespace media 534 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/ffmpeg_video_decoder.h ('k') | media/filters/ffmpeg_video_decoder_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698