| 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 |