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.h" | 9 #include "base/stl_util.h" |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
500 return; | 500 return; |
501 } | 501 } |
502 if (format_context_->duration != static_cast<int64_t>(AV_NOPTS_VALUE)) { | 502 if (format_context_->duration != static_cast<int64_t>(AV_NOPTS_VALUE)) { |
503 // If there is a duration value in the container use that to find the | 503 // If there is a duration value in the container use that to find the |
504 // maximum between it and the duration from A/V streams. | 504 // maximum between it and the duration from A/V streams. |
505 const AVRational av_time_base = {1, AV_TIME_BASE}; | 505 const AVRational av_time_base = {1, AV_TIME_BASE}; |
506 max_duration = | 506 max_duration = |
507 std::max(max_duration, | 507 std::max(max_duration, |
508 ConvertFromTimeBase(av_time_base, format_context_->duration)); | 508 ConvertFromTimeBase(av_time_base, format_context_->duration)); |
509 } else { | 509 } else { |
510 // If the duration is not a valid value. Assume that this is a live stream | 510 // The duration is not a valid value. Assume that this is a live stream |
511 // and we set duration to the maximum int64 number to represent infinity. | 511 // and set duration to the maximum int64 number to represent infinity. |
512 max_duration = base::TimeDelta::FromMicroseconds( | 512 max_duration = base::TimeDelta::FromMicroseconds( |
513 Limits::kMaxTimeInMicroseconds); | 513 Limits::kMaxTimeInMicroseconds); |
514 } | 514 } |
515 | 515 |
516 // Some demuxers, like WAV, do not put timestamps on their frames. We | 516 // Some demuxers, like WAV, do not put timestamps on their frames. We |
517 // assume the the start time is 0. | 517 // assume the the start time is 0. |
518 if (start_time_ == kNoTimestamp) | 518 if (start_time_ == kNoTimestamp) |
519 start_time_ = base::TimeDelta(); | 519 start_time_ = base::TimeDelta(); |
520 | 520 |
521 // Good to go: set the duration and notify we're done initializing. | 521 // Good to go: set the duration and bitrate and notify we're done |
| 522 // initializing. |
522 if (host()) | 523 if (host()) |
523 host()->SetDuration(max_duration); | 524 host()->SetDuration(max_duration); |
524 max_duration_ = max_duration; | 525 max_duration_ = max_duration; |
| 526 |
| 527 int bitrate = GetBitrate(); |
| 528 if (bitrate > 0) |
| 529 data_source_->SetBitrate(bitrate); |
| 530 |
525 callback.Run(PIPELINE_OK); | 531 callback.Run(PIPELINE_OK); |
526 } | 532 } |
527 | 533 |
| 534 int FFmpegDemuxer::GetBitrate() { |
| 535 DCHECK(format_context_); |
| 536 |
| 537 // If there is a bitrate set on the container, use it. |
| 538 if (format_context_->bit_rate > 0) |
| 539 return format_context_->bit_rate; |
| 540 |
| 541 // Then try to sum the bitrates individually per stream. |
| 542 int bitrate = 0; |
| 543 for (size_t i = 0; i < format_context_->nb_streams; ++i) { |
| 544 AVCodecContext* codec_context = format_context_->streams[i]->codec; |
| 545 bitrate += codec_context->bit_rate; |
| 546 } |
| 547 if (bitrate > 0) |
| 548 return bitrate; |
| 549 |
| 550 // If there isn't a bitrate set in the container or streams, but there is a |
| 551 // valid duration, approximate the bitrate using the duration. |
| 552 if (max_duration_.InMilliseconds() > 0 && |
| 553 max_duration_.InMicroseconds() < Limits::kMaxTimeInMicroseconds) { |
| 554 int64 filesize_in_bytes; |
| 555 if (GetSize(&filesize_in_bytes)) |
| 556 return 8000 * filesize_in_bytes / max_duration_.InMilliseconds(); |
| 557 } |
| 558 |
| 559 // Bitrate could not be determined. |
| 560 return 0; |
| 561 } |
| 562 |
528 void FFmpegDemuxer::SeekTask(base::TimeDelta time, const FilterStatusCB& cb) { | 563 void FFmpegDemuxer::SeekTask(base::TimeDelta time, const FilterStatusCB& cb) { |
529 DCHECK_EQ(MessageLoop::current(), message_loop_); | 564 DCHECK_EQ(MessageLoop::current(), message_loop_); |
530 | 565 |
531 // TODO(scherkus): remove this by separating Seek() from Flush() from | 566 // TODO(scherkus): remove this by separating Seek() from Flush() from |
532 // Preroll() states (i.e., the implicit Seek(0) should really be a Preroll()). | 567 // Preroll() states (i.e., the implicit Seek(0) should really be a Preroll()). |
533 if (first_seek_hack_) { | 568 if (first_seek_hack_) { |
534 first_seek_hack_ = false; | 569 first_seek_hack_ = false; |
535 | 570 |
536 if (time == start_time_) { | 571 if (time == start_time_) { |
537 cb.Run(PIPELINE_OK); | 572 cb.Run(PIPELINE_OK); |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
679 read_event_.Wait(); | 714 read_event_.Wait(); |
680 return last_read_bytes_; | 715 return last_read_bytes_; |
681 } | 716 } |
682 | 717 |
683 void FFmpegDemuxer::SignalReadCompleted(size_t size) { | 718 void FFmpegDemuxer::SignalReadCompleted(size_t size) { |
684 last_read_bytes_ = size; | 719 last_read_bytes_ = size; |
685 read_event_.Signal(); | 720 read_event_.Signal(); |
686 } | 721 } |
687 | 722 |
688 } // namespace media | 723 } // namespace media |
OLD | NEW |