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

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

Issue 6993042: ffmpeg chromium glue (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 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
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "base/callback.h" 5 #include "base/callback.h"
6 #include "base/command_line.h" 6 #include "base/command_line.h"
7 #include "base/memory/scoped_ptr.h" 7 #include "base/memory/scoped_ptr.h"
8 #include "base/message_loop.h" 8 #include "base/message_loop.h"
9 #include "base/stl_util-inl.h" 9 #include "base/stl_util-inl.h"
10 #include "base/string_util.h" 10 #include "base/string_util.h"
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 AVStream* stream) 58 AVStream* stream)
59 : demuxer_(demuxer), 59 : demuxer_(demuxer),
60 stream_(stream), 60 stream_(stream),
61 type_(UNKNOWN), 61 type_(UNKNOWN),
62 discontinuous_(false), 62 discontinuous_(false),
63 stopped_(false) { 63 stopped_(false) {
64 DCHECK(demuxer_); 64 DCHECK(demuxer_);
65 65
66 // Determine our media format. 66 // Determine our media format.
67 switch (stream->codec->codec_type) { 67 switch (stream->codec->codec_type) {
68 case CODEC_TYPE_AUDIO: 68 case AVMEDIA_TYPE_AUDIO:
69 type_ = AUDIO; 69 type_ = AUDIO;
70 break; 70 break;
71 case CODEC_TYPE_VIDEO: 71 case AVMEDIA_TYPE_VIDEO:
72 type_ = VIDEO; 72 type_ = VIDEO;
73 break; 73 break;
74 default: 74 default:
75 NOTREACHED(); 75 NOTREACHED();
76 break; 76 break;
77 } 77 }
78 78
79 // Calculate the duration. 79 // Calculate the duration.
80 duration_ = ConvertStreamTimestamp(stream->time_base, stream->duration); 80 duration_ = ConvertStreamTimestamp(stream->time_base, stream->duration);
81 } 81 }
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 base::TimeDelta FFmpegDemuxer::GetStartTime() const { 372 base::TimeDelta FFmpegDemuxer::GetStartTime() const {
373 return start_time_; 373 return start_time_;
374 } 374 }
375 375
376 int FFmpegDemuxer::Read(int size, uint8* data) { 376 int FFmpegDemuxer::Read(int size, uint8* data) {
377 DCHECK(data_source_); 377 DCHECK(data_source_);
378 378
379 // If read has ever failed, return with an error. 379 // If read has ever failed, return with an error.
380 // TODO(hclam): use a more meaningful constant as error. 380 // TODO(hclam): use a more meaningful constant as error.
381 if (read_has_failed_) 381 if (read_has_failed_)
382 return AVERROR_IO; 382 return AVERROR(EIO);
383 383
384 // Even though FFmpeg defines AVERROR_EOF, it's not to be used with I/O 384 // Even though FFmpeg defines AVERROR_EOF, it's not to be used with I/O
385 // routines. Instead return 0 for any read at or past EOF. 385 // routines. Instead return 0 for any read at or past EOF.
386 int64 file_size; 386 int64 file_size;
387 if (data_source_->GetSize(&file_size) && read_position_ >= file_size) 387 if (data_source_->GetSize(&file_size) && read_position_ >= file_size)
388 return 0; 388 return 0;
389 389
390 // Asynchronous read from data source. 390 // Asynchronous read from data source.
391 data_source_->Read(read_position_, size, data, 391 data_source_->Read(read_position_, size, data,
392 NewCallback(this, &FFmpegDemuxer::OnReadCompleted)); 392 NewCallback(this, &FFmpegDemuxer::OnReadCompleted));
393 393
394 // TODO(hclam): The method is called on the demuxer thread and this method 394 // TODO(hclam): The method is called on the demuxer thread and this method
395 // call will block the thread. We need to implemented an additional thread to 395 // call will block the thread. We need to implemented an additional thread to
396 // let FFmpeg demuxer methods to run on. 396 // let FFmpeg demuxer methods to run on.
397 size_t last_read_bytes = WaitForRead(); 397 size_t last_read_bytes = WaitForRead();
398 if (last_read_bytes == DataSource::kReadError) { 398 if (last_read_bytes == DataSource::kReadError) {
399 if (host()) 399 if (host())
400 host()->SetError(PIPELINE_ERROR_READ); 400 host()->SetError(PIPELINE_ERROR_READ);
401 else 401 else
402 deferred_status_ = PIPELINE_ERROR_READ; 402 deferred_status_ = PIPELINE_ERROR_READ;
403 403
404 // Returns with a negative number to signal an error to FFmpeg. 404 // Returns with a negative number to signal an error to FFmpeg.
405 read_has_failed_ = true; 405 read_has_failed_ = true;
406 return AVERROR_IO; 406 return AVERROR(EIO);
407 } 407 }
408 read_position_ += last_read_bytes; 408 read_position_ += last_read_bytes;
409 409
410 if (host()) 410 if (host())
411 host()->SetCurrentReadPosition(read_position_); 411 host()->SetCurrentReadPosition(read_position_);
412 412
413 return last_read_bytes; 413 return last_read_bytes;
414 } 414 }
415 415
416 bool FFmpegDemuxer::GetPosition(int64* position_out) { 416 bool FFmpegDemuxer::GetPosition(int64* position_out) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 if (host()) 456 if (host())
457 data_source_->set_host(host()); 457 data_source_->set_host(host());
458 458
459 // Add ourself to Protocol list and get our unique key. 459 // Add ourself to Protocol list and get our unique key.
460 std::string key = FFmpegGlue::GetInstance()->AddProtocol(this); 460 std::string key = FFmpegGlue::GetInstance()->AddProtocol(this);
461 461
462 // Open FFmpeg AVFormatContext. 462 // Open FFmpeg AVFormatContext.
463 DCHECK(!format_context_); 463 DCHECK(!format_context_);
464 AVFormatContext* context = NULL; 464 AVFormatContext* context = NULL;
465 int result = av_open_input_file(&context, key.c_str(), NULL, 0, NULL); 465 int result = av_open_input_file(&context, key.c_str(), NULL, 0, NULL);
466
467 // Remove ourself from protocol list. 466 // Remove ourself from protocol list.
scherkus (not reviewing) 2011/06/29 17:00:36 could you add back this blank line?
ilja 2011/06/29 21:40:05 Done.
468 FFmpegGlue::GetInstance()->RemoveProtocol(this); 467 FFmpegGlue::GetInstance()->RemoveProtocol(this);
469 468
470 if (result < 0) { 469 if (result < 0) {
471 callback->Run(DEMUXER_ERROR_COULD_NOT_OPEN); 470 callback->Run(DEMUXER_ERROR_COULD_NOT_OPEN);
472 return; 471 return;
473 } 472 }
474 473
475 DCHECK(context); 474 DCHECK(context);
476 format_context_ = context; 475 format_context_ = context;
477 476
478 // Fully initialize AVFormatContext by parsing the stream a little. 477 // Fully initialize AVFormatContext by parsing the stream a little.
479 result = av_find_stream_info(format_context_); 478 result = av_find_stream_info(format_context_);
480 if (result < 0) { 479 if (result < 0) {
481 callback->Run(DEMUXER_ERROR_COULD_NOT_PARSE); 480 callback->Run(DEMUXER_ERROR_COULD_NOT_PARSE);
482 return; 481 return;
483 } 482 }
484 483
485 // Create demuxer streams for all supported streams. 484 // Create demuxer streams for all supported streams.
486 streams_.resize(DemuxerStream::NUM_TYPES); 485 streams_.resize(DemuxerStream::NUM_TYPES);
487 base::TimeDelta max_duration; 486 base::TimeDelta max_duration;
488 const bool kDemuxerIsWebm = !strcmp("webm", format_context_->iformat->name); 487 const bool kDemuxerIsWebm = !strcmp("webm", format_context_->iformat->name);
489 bool no_supported_streams = true; 488 bool no_supported_streams = true;
490 for (size_t i = 0; i < format_context_->nb_streams; ++i) { 489 for (size_t i = 0; i < format_context_->nb_streams; ++i) {
491 AVCodecContext* codec_context = format_context_->streams[i]->codec; 490 AVCodecContext* codec_context = format_context_->streams[i]->codec;
492 CodecType codec_type = codec_context->codec_type; 491 AVMediaType codec_type = codec_context->codec_type;
493 if (codec_type == CODEC_TYPE_AUDIO || codec_type == CODEC_TYPE_VIDEO) { 492 if (codec_type == AVMEDIA_TYPE_AUDIO || codec_type == AVMEDIA_TYPE_VIDEO) {
494 AVStream* stream = format_context_->streams[i]; 493 AVStream* stream = format_context_->streams[i];
495 // WebM is currently strictly VP8 and Vorbis. 494 // WebM is currently strictly VP8 and Vorbis.
496 if (kDemuxerIsWebm && (stream->codec->codec_id != CODEC_ID_VP8 && 495 if (kDemuxerIsWebm && (stream->codec->codec_id != CODEC_ID_VP8 &&
497 stream->codec->codec_id != CODEC_ID_VORBIS)) { 496 stream->codec->codec_id != CODEC_ID_VORBIS)) {
498 packet_streams_.push_back(NULL); 497 packet_streams_.push_back(NULL);
499 continue; 498 continue;
500 } 499 }
501 500
502 scoped_refptr<FFmpegDemuxerStream> demuxer_stream( 501 scoped_refptr<FFmpegDemuxerStream> demuxer_stream(
503 new FFmpegDemuxerStream(this, stream)); 502 new FFmpegDemuxerStream(this, stream));
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
658 657
659 StreamVector::iterator iter; 658 StreamVector::iterator iter;
660 for (size_t i = 0; i < packet_streams_.size(); ++i) { 659 for (size_t i = 0; i < packet_streams_.size(); ++i) {
661 if (!packet_streams_[i]) 660 if (!packet_streams_[i])
662 continue; 661 continue;
663 662
664 // If the codec type is audio, remove the reference. DemuxTask() will 663 // If the codec type is audio, remove the reference. DemuxTask() will
665 // look for such reference, and this will result in deleting the 664 // look for such reference, and this will result in deleting the
666 // audio packets after they are demuxed. 665 // audio packets after they are demuxed.
667 if (packet_streams_[i]->GetAVStream()->codec->codec_type == 666 if (packet_streams_[i]->GetAVStream()->codec->codec_type ==
668 CODEC_TYPE_AUDIO) { 667 AVMEDIA_TYPE_AUDIO) {
669 packet_streams_[i] = NULL; 668 packet_streams_[i] = NULL;
670 } 669 }
671 } 670 }
672 } 671 }
673 672
674 bool FFmpegDemuxer::StreamsHavePendingReads() { 673 bool FFmpegDemuxer::StreamsHavePendingReads() {
675 DCHECK_EQ(MessageLoop::current(), message_loop_); 674 DCHECK_EQ(MessageLoop::current(), message_loop_);
676 StreamVector::iterator iter; 675 StreamVector::iterator iter;
677 for (iter = streams_.begin(); iter != streams_.end(); ++iter) { 676 for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
678 if (*iter && (*iter)->HasPendingReads()) { 677 if (*iter && (*iter)->HasPendingReads()) {
(...skipping 23 matching lines...) Expand all
702 read_event_.Wait(); 701 read_event_.Wait();
703 return last_read_bytes_; 702 return last_read_bytes_;
704 } 703 }
705 704
706 void FFmpegDemuxer::SignalReadCompleted(size_t size) { 705 void FFmpegDemuxer::SignalReadCompleted(size_t size) {
707 last_read_bytes_ = size; 706 last_read_bytes_ = size;
708 read_event_.Signal(); 707 read_event_.Signal();
709 } 708 }
710 709
711 } // namespace media 710 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698