OLD | NEW |
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 Loading... |
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 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
354 base::TimeDelta FFmpegDemuxer::GetStartTime() const { | 354 base::TimeDelta FFmpegDemuxer::GetStartTime() const { |
355 return start_time_; | 355 return start_time_; |
356 } | 356 } |
357 | 357 |
358 int FFmpegDemuxer::Read(int size, uint8* data) { | 358 int FFmpegDemuxer::Read(int size, uint8* data) { |
359 DCHECK(data_source_); | 359 DCHECK(data_source_); |
360 | 360 |
361 // If read has ever failed, return with an error. | 361 // If read has ever failed, return with an error. |
362 // TODO(hclam): use a more meaningful constant as error. | 362 // TODO(hclam): use a more meaningful constant as error. |
363 if (read_has_failed_) | 363 if (read_has_failed_) |
364 return AVERROR_IO; | 364 return AVERROR(EIO); |
365 | 365 |
366 // Even though FFmpeg defines AVERROR_EOF, it's not to be used with I/O | 366 // Even though FFmpeg defines AVERROR_EOF, it's not to be used with I/O |
367 // routines. Instead return 0 for any read at or past EOF. | 367 // routines. Instead return 0 for any read at or past EOF. |
368 int64 file_size; | 368 int64 file_size; |
369 if (data_source_->GetSize(&file_size) && read_position_ >= file_size) | 369 if (data_source_->GetSize(&file_size) && read_position_ >= file_size) |
370 return 0; | 370 return 0; |
371 | 371 |
372 // Asynchronous read from data source. | 372 // Asynchronous read from data source. |
373 data_source_->Read(read_position_, size, data, | 373 data_source_->Read(read_position_, size, data, |
374 NewCallback(this, &FFmpegDemuxer::OnReadCompleted)); | 374 NewCallback(this, &FFmpegDemuxer::OnReadCompleted)); |
375 | 375 |
376 // TODO(hclam): The method is called on the demuxer thread and this method | 376 // TODO(hclam): The method is called on the demuxer thread and this method |
377 // call will block the thread. We need to implemented an additional thread to | 377 // call will block the thread. We need to implemented an additional thread to |
378 // let FFmpeg demuxer methods to run on. | 378 // let FFmpeg demuxer methods to run on. |
379 size_t last_read_bytes = WaitForRead(); | 379 size_t last_read_bytes = WaitForRead(); |
380 if (last_read_bytes == DataSource::kReadError) { | 380 if (last_read_bytes == DataSource::kReadError) { |
381 if (host()) | 381 if (host()) |
382 host()->SetError(PIPELINE_ERROR_READ); | 382 host()->SetError(PIPELINE_ERROR_READ); |
383 else | 383 else |
384 deferred_status_ = PIPELINE_ERROR_READ; | 384 deferred_status_ = PIPELINE_ERROR_READ; |
385 | 385 |
386 // Returns with a negative number to signal an error to FFmpeg. | 386 // Returns with a negative number to signal an error to FFmpeg. |
387 read_has_failed_ = true; | 387 read_has_failed_ = true; |
388 return AVERROR_IO; | 388 return AVERROR(EIO); |
389 } | 389 } |
390 read_position_ += last_read_bytes; | 390 read_position_ += last_read_bytes; |
391 | 391 |
392 if (host()) | 392 if (host()) |
393 host()->SetCurrentReadPosition(read_position_); | 393 host()->SetCurrentReadPosition(read_position_); |
394 | 394 |
395 return last_read_bytes; | 395 return last_read_bytes; |
396 } | 396 } |
397 | 397 |
398 bool FFmpegDemuxer::GetPosition(int64* position_out) { | 398 bool FFmpegDemuxer::GetPosition(int64* position_out) { |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
464 return; | 464 return; |
465 } | 465 } |
466 | 466 |
467 // Create demuxer streams for all supported streams. | 467 // Create demuxer streams for all supported streams. |
468 streams_.resize(DemuxerStream::NUM_TYPES); | 468 streams_.resize(DemuxerStream::NUM_TYPES); |
469 base::TimeDelta max_duration; | 469 base::TimeDelta max_duration; |
470 const bool kDemuxerIsWebm = !strcmp("webm", format_context_->iformat->name); | 470 const bool kDemuxerIsWebm = !strcmp("webm", format_context_->iformat->name); |
471 bool no_supported_streams = true; | 471 bool no_supported_streams = true; |
472 for (size_t i = 0; i < format_context_->nb_streams; ++i) { | 472 for (size_t i = 0; i < format_context_->nb_streams; ++i) { |
473 AVCodecContext* codec_context = format_context_->streams[i]->codec; | 473 AVCodecContext* codec_context = format_context_->streams[i]->codec; |
474 CodecType codec_type = codec_context->codec_type; | 474 AVMediaType codec_type = codec_context->codec_type; |
475 if (codec_type == CODEC_TYPE_AUDIO || codec_type == CODEC_TYPE_VIDEO) { | 475 if (codec_type == AVMEDIA_TYPE_AUDIO || codec_type == AVMEDIA_TYPE_VIDEO) { |
476 AVStream* stream = format_context_->streams[i]; | 476 AVStream* stream = format_context_->streams[i]; |
477 // WebM is currently strictly VP8 and Vorbis. | 477 // WebM is currently strictly VP8 and Vorbis. |
478 if (kDemuxerIsWebm && (stream->codec->codec_id != CODEC_ID_VP8 && | 478 if (kDemuxerIsWebm && (stream->codec->codec_id != CODEC_ID_VP8 && |
479 stream->codec->codec_id != CODEC_ID_VORBIS)) { | 479 stream->codec->codec_id != CODEC_ID_VORBIS)) { |
480 packet_streams_.push_back(NULL); | 480 packet_streams_.push_back(NULL); |
481 continue; | 481 continue; |
482 } | 482 } |
483 | 483 |
484 scoped_refptr<FFmpegDemuxerStream> demuxer_stream( | 484 scoped_refptr<FFmpegDemuxerStream> demuxer_stream( |
485 new FFmpegDemuxerStream(this, stream)); | 485 new FFmpegDemuxerStream(this, stream)); |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
640 | 640 |
641 StreamVector::iterator iter; | 641 StreamVector::iterator iter; |
642 for (size_t i = 0; i < packet_streams_.size(); ++i) { | 642 for (size_t i = 0; i < packet_streams_.size(); ++i) { |
643 if (!packet_streams_[i]) | 643 if (!packet_streams_[i]) |
644 continue; | 644 continue; |
645 | 645 |
646 // If the codec type is audio, remove the reference. DemuxTask() will | 646 // If the codec type is audio, remove the reference. DemuxTask() will |
647 // look for such reference, and this will result in deleting the | 647 // look for such reference, and this will result in deleting the |
648 // audio packets after they are demuxed. | 648 // audio packets after they are demuxed. |
649 if (packet_streams_[i]->GetAVStream()->codec->codec_type == | 649 if (packet_streams_[i]->GetAVStream()->codec->codec_type == |
650 CODEC_TYPE_AUDIO) { | 650 AVMEDIA_TYPE_AUDIO) { |
651 packet_streams_[i] = NULL; | 651 packet_streams_[i] = NULL; |
652 } | 652 } |
653 } | 653 } |
654 } | 654 } |
655 | 655 |
656 bool FFmpegDemuxer::StreamsHavePendingReads() { | 656 bool FFmpegDemuxer::StreamsHavePendingReads() { |
657 DCHECK_EQ(MessageLoop::current(), message_loop_); | 657 DCHECK_EQ(MessageLoop::current(), message_loop_); |
658 StreamVector::iterator iter; | 658 StreamVector::iterator iter; |
659 for (iter = streams_.begin(); iter != streams_.end(); ++iter) { | 659 for (iter = streams_.begin(); iter != streams_.end(); ++iter) { |
660 if (*iter && (*iter)->HasPendingReads()) { | 660 if (*iter && (*iter)->HasPendingReads()) { |
(...skipping 23 matching lines...) Expand all Loading... |
684 read_event_.Wait(); | 684 read_event_.Wait(); |
685 return last_read_bytes_; | 685 return last_read_bytes_; |
686 } | 686 } |
687 | 687 |
688 void FFmpegDemuxer::SignalReadCompleted(size_t size) { | 688 void FFmpegDemuxer::SignalReadCompleted(size_t size) { |
689 last_read_bytes_ = size; | 689 last_read_bytes_ = size; |
690 read_event_.Signal(); | 690 read_event_.Signal(); |
691 } | 691 } |
692 | 692 |
693 } // namespace media | 693 } // namespace media |
OLD | NEW |