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

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

Issue 2158923004: Convert media constants to constexpr. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 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
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_demuxer.h" 5 #include "media/filters/ffmpeg_demuxer.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <memory> 8 #include <memory>
9 #include <utility> 9 #include <utility>
10 10
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 return base::Time(); 62 return base::Time();
63 } 63 }
64 64
65 static base::TimeDelta FramesToTimeDelta(int frames, double sample_rate) { 65 static base::TimeDelta FramesToTimeDelta(int frames, double sample_rate) {
66 return base::TimeDelta::FromMicroseconds( 66 return base::TimeDelta::FromMicroseconds(
67 frames * base::Time::kMicrosecondsPerSecond / sample_rate); 67 frames * base::Time::kMicrosecondsPerSecond / sample_rate);
68 } 68 }
69 69
70 static base::TimeDelta ExtractStartTime(AVStream* stream, 70 static base::TimeDelta ExtractStartTime(AVStream* stream,
71 base::TimeDelta start_time_estimate) { 71 base::TimeDelta start_time_estimate) {
72 DCHECK(start_time_estimate != kNoTimestamp()); 72 DCHECK(start_time_estimate != kNoTimestamp);
73 if (stream->start_time == static_cast<int64_t>(AV_NOPTS_VALUE)) { 73 if (stream->start_time == static_cast<int64_t>(AV_NOPTS_VALUE)) {
74 return start_time_estimate == kInfiniteDuration() ? kNoTimestamp() 74 return start_time_estimate == kInfiniteDuration ? kNoTimestamp
75 : start_time_estimate; 75 : start_time_estimate;
76 } 76 }
77 77
78 // First try the lower of the estimate and the |start_time| value. 78 // First try the lower of the estimate and the |start_time| value.
79 base::TimeDelta start_time = 79 base::TimeDelta start_time =
80 std::min(ConvertFromTimeBase(stream->time_base, stream->start_time), 80 std::min(ConvertFromTimeBase(stream->time_base, stream->start_time),
81 start_time_estimate); 81 start_time_estimate);
82 82
83 // Next see if the first buffered pts value is usable. 83 // Next see if the first buffered pts value is usable.
84 if (stream->pts_buffer[0] != static_cast<int64_t>(AV_NOPTS_VALUE)) { 84 if (stream->pts_buffer[0] != static_cast<int64_t>(AV_NOPTS_VALUE)) {
85 const base::TimeDelta buffered_pts = 85 const base::TimeDelta buffered_pts =
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 return context->codec_descriptor->name; 187 return context->codec_descriptor->name;
188 const AVCodecDescriptor* codec_descriptor = 188 const AVCodecDescriptor* codec_descriptor =
189 avcodec_descriptor_get(context->codec_id); 189 avcodec_descriptor_get(context->codec_id);
190 // If the codec name can't be determined, return none for tracking. 190 // If the codec name can't be determined, return none for tracking.
191 return codec_descriptor ? codec_descriptor->name : kCodecNone; 191 return codec_descriptor ? codec_descriptor->name : kCodecNone;
192 } 192 }
193 193
194 static void SetTimeProperty(MediaLogEvent* event, 194 static void SetTimeProperty(MediaLogEvent* event,
195 const std::string& key, 195 const std::string& key,
196 base::TimeDelta value) { 196 base::TimeDelta value) {
197 if (value == kInfiniteDuration()) 197 if (value == kInfiniteDuration)
198 event->params.SetString(key, "kInfiniteDuration"); 198 event->params.SetString(key, "kInfiniteDuration");
199 else if (value == kNoTimestamp()) 199 else if (value == kNoTimestamp)
200 event->params.SetString(key, "kNoTimestamp"); 200 event->params.SetString(key, "kNoTimestamp");
201 else 201 else
202 event->params.SetDouble(key, value.InSecondsF()); 202 event->params.SetDouble(key, value.InSecondsF());
203 } 203 }
204 204
205 std::unique_ptr<FFmpegDemuxerStream> FFmpegDemuxerStream::Create( 205 std::unique_ptr<FFmpegDemuxerStream> FFmpegDemuxerStream::Create(
206 FFmpegDemuxer* demuxer, 206 FFmpegDemuxer* demuxer,
207 AVStream* stream, 207 AVStream* stream,
208 const scoped_refptr<MediaLog>& media_log) { 208 const scoped_refptr<MediaLog>& media_log) {
209 if (!demuxer || !stream) 209 if (!demuxer || !stream)
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 std::unique_ptr<AudioDecoderConfig> audio_config, 262 std::unique_ptr<AudioDecoderConfig> audio_config,
263 std::unique_ptr<VideoDecoderConfig> video_config) 263 std::unique_ptr<VideoDecoderConfig> video_config)
264 : demuxer_(demuxer), 264 : demuxer_(demuxer),
265 task_runner_(base::ThreadTaskRunnerHandle::Get()), 265 task_runner_(base::ThreadTaskRunnerHandle::Get()),
266 stream_(stream), 266 stream_(stream),
267 audio_config_(audio_config.release()), 267 audio_config_(audio_config.release()),
268 video_config_(video_config.release()), 268 video_config_(video_config.release()),
269 type_(UNKNOWN), 269 type_(UNKNOWN),
270 liveness_(LIVENESS_UNKNOWN), 270 liveness_(LIVENESS_UNKNOWN),
271 end_of_stream_(false), 271 end_of_stream_(false),
272 last_packet_timestamp_(kNoTimestamp()), 272 last_packet_timestamp_(kNoTimestamp),
273 last_packet_duration_(kNoTimestamp()), 273 last_packet_duration_(kNoTimestamp),
274 video_rotation_(VIDEO_ROTATION_0), 274 video_rotation_(VIDEO_ROTATION_0),
275 is_enabled_(true), 275 is_enabled_(true),
276 waiting_for_keyframe_(false), 276 waiting_for_keyframe_(false),
277 fixup_negative_timestamps_(false) { 277 fixup_negative_timestamps_(false) {
278 DCHECK(demuxer_); 278 DCHECK(demuxer_);
279 279
280 bool is_encrypted = false; 280 bool is_encrypted = false;
281 int rotation = 0; 281 int rotation = 0;
282 AVDictionaryEntry* rotation_entry = NULL; 282 AVDictionaryEntry* rotation_entry = NULL;
283 283
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 const uint32_t* skip_samples_ptr = 433 const uint32_t* skip_samples_ptr =
434 reinterpret_cast<const uint32_t*>(av_packet_get_side_data( 434 reinterpret_cast<const uint32_t*>(av_packet_get_side_data(
435 packet.get(), AV_PKT_DATA_SKIP_SAMPLES, &skip_samples_size)); 435 packet.get(), AV_PKT_DATA_SKIP_SAMPLES, &skip_samples_size));
436 const int kSkipSamplesValidSize = 10; 436 const int kSkipSamplesValidSize = 10;
437 const int kSkipEndSamplesOffset = 1; 437 const int kSkipEndSamplesOffset = 1;
438 if (skip_samples_size >= kSkipSamplesValidSize) { 438 if (skip_samples_size >= kSkipSamplesValidSize) {
439 // Because FFmpeg rolls codec delay and skip samples into one we can only 439 // Because FFmpeg rolls codec delay and skip samples into one we can only
440 // allow front discard padding on the first buffer. Otherwise the discard 440 // allow front discard padding on the first buffer. Otherwise the discard
441 // helper can't figure out which data to discard. See AudioDiscardHelper. 441 // helper can't figure out which data to discard. See AudioDiscardHelper.
442 int discard_front_samples = base::ByteSwapToLE32(*skip_samples_ptr); 442 int discard_front_samples = base::ByteSwapToLE32(*skip_samples_ptr);
443 if (last_packet_timestamp_ != kNoTimestamp() && discard_front_samples) { 443 if (last_packet_timestamp_ != kNoTimestamp && discard_front_samples) {
444 DLOG(ERROR) << "Skip samples are only allowed for the first packet."; 444 DLOG(ERROR) << "Skip samples are only allowed for the first packet.";
445 discard_front_samples = 0; 445 discard_front_samples = 0;
446 } 446 }
447 447
448 const int discard_end_samples = 448 const int discard_end_samples =
449 base::ByteSwapToLE32(*(skip_samples_ptr + kSkipEndSamplesOffset)); 449 base::ByteSwapToLE32(*(skip_samples_ptr + kSkipEndSamplesOffset));
450 const int samples_per_second = 450 const int samples_per_second =
451 audio_decoder_config().samples_per_second(); 451 audio_decoder_config().samples_per_second();
452 buffer->set_discard_padding(std::make_pair( 452 buffer->set_discard_padding(std::make_pair(
453 FramesToTimeDelta(discard_front_samples, samples_per_second), 453 FramesToTimeDelta(discard_front_samples, samples_per_second),
454 FramesToTimeDelta(discard_end_samples, samples_per_second))); 454 FramesToTimeDelta(discard_end_samples, samples_per_second)));
455 } 455 }
456 456
457 if (decrypt_config) 457 if (decrypt_config)
458 buffer->set_decrypt_config(std::move(decrypt_config)); 458 buffer->set_decrypt_config(std::move(decrypt_config));
459 } 459 }
460 460
461 if (packet->duration >= 0) { 461 if (packet->duration >= 0) {
462 buffer->set_duration( 462 buffer->set_duration(
463 ConvertStreamTimestamp(stream_->time_base, packet->duration)); 463 ConvertStreamTimestamp(stream_->time_base, packet->duration));
464 } else { 464 } else {
465 // TODO(wolenetz): Remove when FFmpeg stops returning negative durations. 465 // TODO(wolenetz): Remove when FFmpeg stops returning negative durations.
466 // https://crbug.com/394418 466 // https://crbug.com/394418
467 DVLOG(1) << "FFmpeg returned a buffer with a negative duration! " 467 DVLOG(1) << "FFmpeg returned a buffer with a negative duration! "
468 << packet->duration; 468 << packet->duration;
469 buffer->set_duration(kNoTimestamp()); 469 buffer->set_duration(kNoTimestamp);
470 } 470 }
471 471
472 // Note: If pts is AV_NOPTS_VALUE, stream_timestamp will be kNoTimestamp(). 472 // Note: If pts is AV_NOPTS_VALUE, stream_timestamp will be kNoTimestamp.
473 const base::TimeDelta stream_timestamp = 473 const base::TimeDelta stream_timestamp =
474 ConvertStreamTimestamp(stream_->time_base, packet->pts); 474 ConvertStreamTimestamp(stream_->time_base, packet->pts);
475 475
476 if (stream_timestamp != kNoTimestamp()) { 476 if (stream_timestamp != kNoTimestamp) {
477 const bool is_audio = type() == AUDIO; 477 const bool is_audio = type() == AUDIO;
478 478
479 // If this file has negative timestamps don't rebase any other stream types 479 // If this file has negative timestamps don't rebase any other stream types
480 // against the negative starting time. 480 // against the negative starting time.
481 base::TimeDelta start_time = demuxer_->start_time(); 481 base::TimeDelta start_time = demuxer_->start_time();
482 if (fixup_negative_timestamps_ && !is_audio && 482 if (fixup_negative_timestamps_ && !is_audio &&
483 start_time < base::TimeDelta()) { 483 start_time < base::TimeDelta()) {
484 start_time = base::TimeDelta(); 484 start_time = base::TimeDelta();
485 } 485 }
486 486
487 // Don't rebase timestamps for positive start times, the HTML Media Spec 487 // Don't rebase timestamps for positive start times, the HTML Media Spec
488 // details this in section "4.8.10.6 Offsets into the media resource." We 488 // details this in section "4.8.10.6 Offsets into the media resource." We
489 // will still need to rebase timestamps before seeking with FFmpeg though. 489 // will still need to rebase timestamps before seeking with FFmpeg though.
490 if (start_time > base::TimeDelta()) 490 if (start_time > base::TimeDelta())
491 start_time = base::TimeDelta(); 491 start_time = base::TimeDelta();
492 492
493 buffer->set_timestamp(stream_timestamp - start_time); 493 buffer->set_timestamp(stream_timestamp - start_time);
494 494
495 // If enabled, and no codec delay is present, mark audio packets with 495 // If enabled, and no codec delay is present, mark audio packets with
496 // negative timestamps for post-decode discard. 496 // negative timestamps for post-decode discard.
497 if (fixup_negative_timestamps_ && is_audio && 497 if (fixup_negative_timestamps_ && is_audio &&
498 stream_timestamp < base::TimeDelta() && 498 stream_timestamp < base::TimeDelta() &&
499 buffer->duration() != kNoTimestamp()) { 499 buffer->duration() != kNoTimestamp) {
500 if (!stream_->codec->delay) { 500 if (!stream_->codec->delay) {
501 DCHECK_EQ(buffer->discard_padding().first, base::TimeDelta()); 501 DCHECK_EQ(buffer->discard_padding().first, base::TimeDelta());
502 502
503 if (stream_timestamp + buffer->duration() < base::TimeDelta()) { 503 if (stream_timestamp + buffer->duration() < base::TimeDelta()) {
504 DCHECK_EQ(buffer->discard_padding().second, base::TimeDelta()); 504 DCHECK_EQ(buffer->discard_padding().second, base::TimeDelta());
505 505
506 // Discard the entire packet if it's entirely before zero. 506 // Discard the entire packet if it's entirely before zero.
507 buffer->set_discard_padding( 507 buffer->set_discard_padding(
508 std::make_pair(kInfiniteDuration(), base::TimeDelta())); 508 std::make_pair(kInfiniteDuration, base::TimeDelta()));
509 } else { 509 } else {
510 // Only discard part of the frame if it overlaps zero. 510 // Only discard part of the frame if it overlaps zero.
511 buffer->set_discard_padding(std::make_pair( 511 buffer->set_discard_padding(std::make_pair(
512 -stream_timestamp, buffer->discard_padding().second)); 512 -stream_timestamp, buffer->discard_padding().second));
513 } 513 }
514 } else { 514 } else {
515 // Verify that codec delay would cover discard and that we don't need to 515 // Verify that codec delay would cover discard and that we don't need to
516 // mark the packet for post decode discard. Since timestamps may be in 516 // mark the packet for post decode discard. Since timestamps may be in
517 // milliseconds and codec delay in nanosecond precision, round up to the 517 // milliseconds and codec delay in nanosecond precision, round up to the
518 // nearest millisecond. See enable_negative_timestamp_fixups(). 518 // nearest millisecond. See enable_negative_timestamp_fixups().
519 DCHECK_LE(-std::ceil(FramesToTimeDelta( 519 DCHECK_LE(-std::ceil(FramesToTimeDelta(
520 audio_decoder_config().codec_delay(), 520 audio_decoder_config().codec_delay(),
521 audio_decoder_config().samples_per_second()) 521 audio_decoder_config().samples_per_second())
522 .InMillisecondsF()), 522 .InMillisecondsF()),
523 stream_timestamp.InMillisecondsF()); 523 stream_timestamp.InMillisecondsF());
524 } 524 }
525 } 525 }
526 } else { 526 } else {
527 // If this happens on the first packet, decoders will throw an error. 527 // If this happens on the first packet, decoders will throw an error.
528 buffer->set_timestamp(kNoTimestamp()); 528 buffer->set_timestamp(kNoTimestamp);
529 } 529 }
530 530
531 if (last_packet_timestamp_ != kNoTimestamp()) { 531 if (last_packet_timestamp_ != kNoTimestamp) {
532 // FFmpeg doesn't support chained ogg correctly. Instead of guaranteeing 532 // FFmpeg doesn't support chained ogg correctly. Instead of guaranteeing
533 // continuity across links in the chain it uses the timestamp information 533 // continuity across links in the chain it uses the timestamp information
534 // from each link directly. Doing so can lead to timestamps which appear to 534 // from each link directly. Doing so can lead to timestamps which appear to
535 // go backwards in time. 535 // go backwards in time.
536 // 536 //
537 // If the new link starts with a negative timestamp or a timestamp less than 537 // If the new link starts with a negative timestamp or a timestamp less than
538 // the original (positive) |start_time|, we will get a negative timestamp 538 // the original (positive) |start_time|, we will get a negative timestamp
539 // here. It's also possible FFmpeg returns kNoTimestamp() here if it's not 539 // here. It's also possible FFmpeg returns kNoTimestamp here if it's not
540 // able to work out a timestamp using the previous link and the next. 540 // able to work out a timestamp using the previous link and the next.
541 // 541 //
542 // Fixing chained ogg is non-trivial, so for now just reuse the last good 542 // Fixing chained ogg is non-trivial, so for now just reuse the last good
543 // timestamp. The decoder will rewrite the timestamps to be sample accurate 543 // timestamp. The decoder will rewrite the timestamps to be sample accurate
544 // later. See http://crbug.com/396864. 544 // later. See http://crbug.com/396864.
545 if (fixup_negative_timestamps_ && 545 if (fixup_negative_timestamps_ &&
546 (buffer->timestamp() == kNoTimestamp() || 546 (buffer->timestamp() == kNoTimestamp ||
547 buffer->timestamp() < last_packet_timestamp_)) { 547 buffer->timestamp() < last_packet_timestamp_)) {
548 buffer->set_timestamp(last_packet_timestamp_ + 548 buffer->set_timestamp(last_packet_timestamp_ +
549 (last_packet_duration_ != kNoTimestamp() 549 (last_packet_duration_ != kNoTimestamp
550 ? last_packet_duration_ 550 ? last_packet_duration_
551 : base::TimeDelta::FromMicroseconds(1))); 551 : base::TimeDelta::FromMicroseconds(1)));
552 } 552 }
553 553
554 // The demuxer should always output positive timestamps. 554 // The demuxer should always output positive timestamps.
555 DCHECK(buffer->timestamp() >= base::TimeDelta()); 555 DCHECK(buffer->timestamp() >= base::TimeDelta());
556 DCHECK(buffer->timestamp() != kNoTimestamp()); 556 DCHECK(buffer->timestamp() != kNoTimestamp);
557 557
558 if (last_packet_timestamp_ < buffer->timestamp()) { 558 if (last_packet_timestamp_ < buffer->timestamp()) {
559 buffered_ranges_.Add(last_packet_timestamp_, buffer->timestamp()); 559 buffered_ranges_.Add(last_packet_timestamp_, buffer->timestamp());
560 demuxer_->NotifyBufferingChanged(); 560 demuxer_->NotifyBufferingChanged();
561 } 561 }
562 } 562 }
563 563
564 if (packet.get()->flags & AV_PKT_FLAG_KEY) 564 if (packet.get()->flags & AV_PKT_FLAG_KEY)
565 buffer->set_is_key_frame(true); 565 buffer->set_is_key_frame(true);
566 566
(...skipping 14 matching lines...) Expand all
581 DCHECK(task_runner_->BelongsToCurrentThread()); 581 DCHECK(task_runner_->BelongsToCurrentThread());
582 DCHECK(read_cb_.is_null()) << "There should be no pending read"; 582 DCHECK(read_cb_.is_null()) << "There should be no pending read";
583 583
584 // H264 and AAC require that we resend the header after flush. 584 // H264 and AAC require that we resend the header after flush.
585 // Reset bitstream for converter to do so. 585 // Reset bitstream for converter to do so.
586 // This is related to chromium issue 140371 (http://crbug.com/140371). 586 // This is related to chromium issue 140371 (http://crbug.com/140371).
587 ResetBitstreamConverter(); 587 ResetBitstreamConverter();
588 588
589 buffer_queue_.Clear(); 589 buffer_queue_.Clear();
590 end_of_stream_ = false; 590 end_of_stream_ = false;
591 last_packet_timestamp_ = kNoTimestamp(); 591 last_packet_timestamp_ = kNoTimestamp;
592 last_packet_duration_ = kNoTimestamp(); 592 last_packet_duration_ = kNoTimestamp;
593 } 593 }
594 594
595 void FFmpegDemuxerStream::Stop() { 595 void FFmpegDemuxerStream::Stop() {
596 DCHECK(task_runner_->BelongsToCurrentThread()); 596 DCHECK(task_runner_->BelongsToCurrentThread());
597 buffer_queue_.Clear(); 597 buffer_queue_.Clear();
598 if (!read_cb_.is_null()) { 598 if (!read_cb_.is_null()) {
599 base::ResetAndReturn(&read_cb_).Run( 599 base::ResetAndReturn(&read_cb_).Run(
600 DemuxerStream::kOk, DecoderBuffer::CreateEOSBuffer()); 600 DemuxerStream::kOk, DecoderBuffer::CreateEOSBuffer());
601 } 601 }
602 demuxer_ = NULL; 602 demuxer_ = NULL;
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 const AVDictionaryEntry* entry = 794 const AVDictionaryEntry* entry =
795 av_dict_get(stream_->metadata, key, NULL, 0); 795 av_dict_get(stream_->metadata, key, NULL, 0);
796 return (entry == NULL || entry->value == NULL) ? "" : entry->value; 796 return (entry == NULL || entry->value == NULL) ? "" : entry->value;
797 } 797 }
798 798
799 // static 799 // static
800 base::TimeDelta FFmpegDemuxerStream::ConvertStreamTimestamp( 800 base::TimeDelta FFmpegDemuxerStream::ConvertStreamTimestamp(
801 const AVRational& time_base, 801 const AVRational& time_base,
802 int64_t timestamp) { 802 int64_t timestamp) {
803 if (timestamp == static_cast<int64_t>(AV_NOPTS_VALUE)) 803 if (timestamp == static_cast<int64_t>(AV_NOPTS_VALUE))
804 return kNoTimestamp(); 804 return kNoTimestamp;
805 805
806 return ConvertFromTimeBase(time_base, timestamp); 806 return ConvertFromTimeBase(time_base, timestamp);
807 } 807 }
808 808
809 // 809 //
810 // FFmpegDemuxer 810 // FFmpegDemuxer
811 // 811 //
812 FFmpegDemuxer::FFmpegDemuxer( 812 FFmpegDemuxer::FFmpegDemuxer(
813 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, 813 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
814 DataSource* data_source, 814 DataSource* data_source,
815 const EncryptedMediaInitDataCB& encrypted_media_init_data_cb, 815 const EncryptedMediaInitDataCB& encrypted_media_init_data_cb,
816 const MediaTracksUpdatedCB& media_tracks_updated_cb, 816 const MediaTracksUpdatedCB& media_tracks_updated_cb,
817 const scoped_refptr<MediaLog>& media_log) 817 const scoped_refptr<MediaLog>& media_log)
818 : host_(NULL), 818 : host_(NULL),
819 task_runner_(task_runner), 819 task_runner_(task_runner),
820 blocking_thread_("FFmpegDemuxer"), 820 blocking_thread_("FFmpegDemuxer"),
821 pending_read_(false), 821 pending_read_(false),
822 pending_seek_(false), 822 pending_seek_(false),
823 data_source_(data_source), 823 data_source_(data_source),
824 media_log_(media_log), 824 media_log_(media_log),
825 bitrate_(0), 825 bitrate_(0),
826 start_time_(kNoTimestamp()), 826 start_time_(kNoTimestamp),
827 preferred_stream_for_seeking_(-1, kNoTimestamp()), 827 preferred_stream_for_seeking_(-1, kNoTimestamp),
828 fallback_stream_for_seeking_(-1, kNoTimestamp()), 828 fallback_stream_for_seeking_(-1, kNoTimestamp),
829 text_enabled_(false), 829 text_enabled_(false),
830 duration_known_(false), 830 duration_known_(false),
831 encrypted_media_init_data_cb_(encrypted_media_init_data_cb), 831 encrypted_media_init_data_cb_(encrypted_media_init_data_cb),
832 media_tracks_updated_cb_(media_tracks_updated_cb), 832 media_tracks_updated_cb_(media_tracks_updated_cb),
833 weak_factory_(this) { 833 weak_factory_(this) {
834 DCHECK(task_runner_.get()); 834 DCHECK(task_runner_.get());
835 DCHECK(data_source_); 835 DCHECK(data_source_);
836 DCHECK(!media_tracks_updated_cb_.is_null()); 836 DCHECK(!media_tracks_updated_cb_.is_null());
837 } 837 }
838 838
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
943 943
944 // Choose the seeking stream based on whether it contains the seek time, if no 944 // Choose the seeking stream based on whether it contains the seek time, if no
945 // match can be found prefer the preferred stream. 945 // match can be found prefer the preferred stream.
946 // 946 //
947 // TODO(dalecurtis): Currently FFmpeg does not ensure that all streams in a 947 // TODO(dalecurtis): Currently FFmpeg does not ensure that all streams in a
948 // given container will demux all packets after the seek point. Instead it 948 // given container will demux all packets after the seek point. Instead it
949 // only guarantees that all packets after the file position of the seek will 949 // only guarantees that all packets after the file position of the seek will
950 // be demuxed. It's an open question whether FFmpeg should fix this: 950 // be demuxed. It's an open question whether FFmpeg should fix this:
951 // http://lists.ffmpeg.org/pipermail/ffmpeg-devel/2014-June/159212.html 951 // http://lists.ffmpeg.org/pipermail/ffmpeg-devel/2014-June/159212.html
952 // Tracked by http://crbug.com/387996. 952 // Tracked by http://crbug.com/387996.
953 DCHECK(preferred_stream_for_seeking_.second != kNoTimestamp()); 953 DCHECK(preferred_stream_for_seeking_.second != kNoTimestamp);
954 const int stream_index = 954 const int stream_index =
955 seek_time < preferred_stream_for_seeking_.second && 955 seek_time < preferred_stream_for_seeking_.second &&
956 seek_time >= fallback_stream_for_seeking_.second 956 seek_time >= fallback_stream_for_seeking_.second
957 ? fallback_stream_for_seeking_.first 957 ? fallback_stream_for_seeking_.first
958 : preferred_stream_for_seeking_.first; 958 : preferred_stream_for_seeking_.first;
959 DCHECK_NE(stream_index, -1); 959 DCHECK_NE(stream_index, -1);
960 960
961 const AVStream* seeking_stream = 961 const AVStream* seeking_stream =
962 glue_->format_context()->streams[stream_index]; 962 glue_->format_context()->streams[stream_index];
963 963
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1071 int bitrate = 0; 1071 int bitrate = 0;
1072 for (size_t i = 0; i < format_context->nb_streams; ++i) { 1072 for (size_t i = 0; i < format_context->nb_streams; ++i) {
1073 AVCodecContext* codec_context = format_context->streams[i]->codec; 1073 AVCodecContext* codec_context = format_context->streams[i]->codec;
1074 bitrate += codec_context->bit_rate; 1074 bitrate += codec_context->bit_rate;
1075 } 1075 }
1076 if (bitrate > 0) 1076 if (bitrate > 0)
1077 return bitrate; 1077 return bitrate;
1078 1078
1079 // See if we can approximate the bitrate as long as we have a filesize and 1079 // See if we can approximate the bitrate as long as we have a filesize and
1080 // valid duration. 1080 // valid duration.
1081 if (duration.InMicroseconds() <= 0 || 1081 if (duration.InMicroseconds() <= 0 || duration == kInfiniteDuration ||
1082 duration == kInfiniteDuration() ||
1083 filesize_in_bytes == 0) { 1082 filesize_in_bytes == 0) {
1084 return 0; 1083 return 0;
1085 } 1084 }
1086 1085
1087 // Do math in floating point as we'd overflow an int64_t if the filesize was 1086 // Do math in floating point as we'd overflow an int64_t if the filesize was
1088 // larger than ~1073GB. 1087 // larger than ~1073GB.
1089 double bytes = filesize_in_bytes; 1088 double bytes = filesize_in_bytes;
1090 double duration_us = duration.InMicroseconds(); 1089 double duration_us = duration.InMicroseconds();
1091 return bytes * 8000000.0 / duration_us; 1090 return bytes * 8000000.0 / duration_us;
1092 } 1091 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1141 AVFormatContext* format_context = glue_->format_context(); 1140 AVFormatContext* format_context = glue_->format_context();
1142 streams_.resize(format_context->nb_streams); 1141 streams_.resize(format_context->nb_streams);
1143 1142
1144 // Estimate the start time for each stream by looking through the packets 1143 // Estimate the start time for each stream by looking through the packets
1145 // buffered during avformat_find_stream_info(). These values will be 1144 // buffered during avformat_find_stream_info(). These values will be
1146 // considered later when determining the actual stream start time. 1145 // considered later when determining the actual stream start time.
1147 // 1146 //
1148 // These packets haven't been completely processed yet, so only look through 1147 // These packets haven't been completely processed yet, so only look through
1149 // these values if the AVFormatContext has a valid start time. 1148 // these values if the AVFormatContext has a valid start time.
1150 // 1149 //
1151 // If no estimate is found, the stream entry will be kInfiniteDuration(). 1150 // If no estimate is found, the stream entry will be kInfiniteDuration.
1152 std::vector<base::TimeDelta> start_time_estimates(format_context->nb_streams, 1151 std::vector<base::TimeDelta> start_time_estimates(format_context->nb_streams,
1153 kInfiniteDuration()); 1152 kInfiniteDuration);
1154 const AVFormatInternal* internal = format_context->internal; 1153 const AVFormatInternal* internal = format_context->internal;
1155 if (internal && internal->packet_buffer && 1154 if (internal && internal->packet_buffer &&
1156 format_context->start_time != static_cast<int64_t>(AV_NOPTS_VALUE)) { 1155 format_context->start_time != static_cast<int64_t>(AV_NOPTS_VALUE)) {
1157 struct AVPacketList* packet_buffer = internal->packet_buffer; 1156 struct AVPacketList* packet_buffer = internal->packet_buffer;
1158 while (packet_buffer != internal->packet_buffer_end) { 1157 while (packet_buffer != internal->packet_buffer_end) {
1159 DCHECK_LT(static_cast<size_t>(packet_buffer->pkt.stream_index), 1158 DCHECK_LT(static_cast<size_t>(packet_buffer->pkt.stream_index),
1160 start_time_estimates.size()); 1159 start_time_estimates.size());
1161 const AVStream* stream = 1160 const AVStream* stream =
1162 format_context->streams[packet_buffer->pkt.stream_index]; 1161 format_context->streams[packet_buffer->pkt.stream_index];
1163 if (packet_buffer->pkt.pts != static_cast<int64_t>(AV_NOPTS_VALUE)) { 1162 if (packet_buffer->pkt.pts != static_cast<int64_t>(AV_NOPTS_VALUE)) {
1164 const base::TimeDelta packet_pts = 1163 const base::TimeDelta packet_pts =
1165 ConvertFromTimeBase(stream->time_base, packet_buffer->pkt.pts); 1164 ConvertFromTimeBase(stream->time_base, packet_buffer->pkt.pts);
1166 if (packet_pts < start_time_estimates[stream->index]) 1165 if (packet_pts < start_time_estimates[stream->index])
1167 start_time_estimates[stream->index] = packet_pts; 1166 start_time_estimates[stream->index] = packet_pts;
1168 } 1167 }
1169 packet_buffer = packet_buffer->next; 1168 packet_buffer = packet_buffer->next;
1170 } 1169 }
1171 } 1170 }
1172 1171
1173 std::unique_ptr<MediaTracks> media_tracks(new MediaTracks()); 1172 std::unique_ptr<MediaTracks> media_tracks(new MediaTracks());
1174 AVStream* audio_stream = NULL; 1173 AVStream* audio_stream = NULL;
1175 AudioDecoderConfig audio_config; 1174 AudioDecoderConfig audio_config;
1176 AVStream* video_stream = NULL; 1175 AVStream* video_stream = NULL;
1177 VideoDecoderConfig video_config; 1176 VideoDecoderConfig video_config;
1178 1177
1179 DCHECK(track_id_to_demux_stream_map_.empty()); 1178 DCHECK(track_id_to_demux_stream_map_.empty());
1180 1179
1181 // If available, |start_time_| will be set to the lowest stream start time. 1180 // If available, |start_time_| will be set to the lowest stream start time.
1182 start_time_ = kInfiniteDuration(); 1181 start_time_ = kInfiniteDuration;
1183 1182
1184 base::TimeDelta max_duration; 1183 base::TimeDelta max_duration;
1185 int detected_audio_track_count = 0; 1184 int detected_audio_track_count = 0;
1186 int detected_video_track_count = 0; 1185 int detected_video_track_count = 0;
1187 int detected_text_track_count = 0; 1186 int detected_text_track_count = 0;
1188 for (size_t i = 0; i < format_context->nb_streams; ++i) { 1187 for (size_t i = 0; i < format_context->nb_streams; ++i) {
1189 AVStream* stream = format_context->streams[i]; 1188 AVStream* stream = format_context->streams[i];
1190 const AVCodecContext* codec_context = stream->codec; 1189 const AVCodecContext* codec_context = stream->codec;
1191 const AVMediaType codec_type = codec_context->codec_type; 1190 const AVMediaType codec_type = codec_context->codec_type;
1192 1191
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
1309 media_track->set_id(base::UintToString(track_id)); 1308 media_track->set_id(base::UintToString(track_id));
1310 DCHECK(track_id_to_demux_stream_map_.find(media_track->id()) == 1309 DCHECK(track_id_to_demux_stream_map_.find(media_track->id()) ==
1311 track_id_to_demux_stream_map_.end()); 1310 track_id_to_demux_stream_map_.end());
1312 track_id_to_demux_stream_map_[media_track->id()] = streams_[i]; 1311 track_id_to_demux_stream_map_[media_track->id()] = streams_[i];
1313 } 1312 }
1314 1313
1315 max_duration = std::max(max_duration, streams_[i]->duration()); 1314 max_duration = std::max(max_duration, streams_[i]->duration());
1316 1315
1317 const base::TimeDelta start_time = 1316 const base::TimeDelta start_time =
1318 ExtractStartTime(stream, start_time_estimates[i]); 1317 ExtractStartTime(stream, start_time_estimates[i]);
1319 const bool has_start_time = start_time != kNoTimestamp(); 1318 const bool has_start_time = start_time != kNoTimestamp;
1320 1319
1321 // Always prefer the video stream for seeking. If none exists, we'll swap 1320 // Always prefer the video stream for seeking. If none exists, we'll swap
1322 // the fallback stream with the preferred stream below. 1321 // the fallback stream with the preferred stream below.
1323 if (codec_type == AVMEDIA_TYPE_VIDEO) { 1322 if (codec_type == AVMEDIA_TYPE_VIDEO) {
1324 preferred_stream_for_seeking_ = 1323 preferred_stream_for_seeking_ =
1325 StreamSeekInfo(i, has_start_time ? start_time : base::TimeDelta()); 1324 StreamSeekInfo(i, has_start_time ? start_time : base::TimeDelta());
1326 } 1325 }
1327 1326
1328 if (!has_start_time) 1327 if (!has_start_time)
1329 continue; 1328 continue;
(...skipping 23 matching lines...) Expand all
1353 1352
1354 if (format_context->duration != static_cast<int64_t>(AV_NOPTS_VALUE)) { 1353 if (format_context->duration != static_cast<int64_t>(AV_NOPTS_VALUE)) {
1355 // If there is a duration value in the container use that to find the 1354 // If there is a duration value in the container use that to find the
1356 // maximum between it and the duration from A/V streams. 1355 // maximum between it and the duration from A/V streams.
1357 const AVRational av_time_base = {1, AV_TIME_BASE}; 1356 const AVRational av_time_base = {1, AV_TIME_BASE};
1358 max_duration = 1357 max_duration =
1359 std::max(max_duration, 1358 std::max(max_duration,
1360 ConvertFromTimeBase(av_time_base, format_context->duration)); 1359 ConvertFromTimeBase(av_time_base, format_context->duration));
1361 } else { 1360 } else {
1362 // The duration is unknown, in which case this is likely a live stream. 1361 // The duration is unknown, in which case this is likely a live stream.
1363 max_duration = kInfiniteDuration(); 1362 max_duration = kInfiniteDuration;
1364 } 1363 }
1365 1364
1366 // FFmpeg represents audio data marked as before the beginning of stream as 1365 // FFmpeg represents audio data marked as before the beginning of stream as
1367 // having negative timestamps. This data must be discarded after it has been 1366 // having negative timestamps. This data must be discarded after it has been
1368 // decoded, not before since it is used to warmup the decoder. There are 1367 // decoded, not before since it is used to warmup the decoder. There are
1369 // currently two known cases for this: vorbis in ogg and opus in ogg and webm. 1368 // currently two known cases for this: vorbis in ogg and opus in ogg and webm.
1370 // 1369 //
1371 // For API clarity, it was decided that the rest of the media pipeline should 1370 // For API clarity, it was decided that the rest of the media pipeline should
1372 // not be exposed to negative timestamps. Which means we need to rebase these 1371 // not be exposed to negative timestamps. Which means we need to rebase these
1373 // negative timestamps and mark them for discard post decoding. 1372 // negative timestamps and mark them for discard post decoding.
(...skipping 17 matching lines...) Expand all
1391 // because it has a lower starting time. 1390 // because it has a lower starting time.
1392 if (fallback_stream_for_seeking_.first == audio_stream->index && 1391 if (fallback_stream_for_seeking_.first == audio_stream->index &&
1393 fallback_stream_for_seeking_.second < base::TimeDelta()) { 1392 fallback_stream_for_seeking_.second < base::TimeDelta()) {
1394 fallback_stream_for_seeking_.second = base::TimeDelta(); 1393 fallback_stream_for_seeking_.second = base::TimeDelta();
1395 } 1394 }
1396 } 1395 }
1397 1396
1398 // If no start time could be determined, default to zero and prefer the video 1397 // If no start time could be determined, default to zero and prefer the video
1399 // stream over the audio stream for seeking. E.g., The WAV demuxer does not 1398 // stream over the audio stream for seeking. E.g., The WAV demuxer does not
1400 // put timestamps on its frames. 1399 // put timestamps on its frames.
1401 if (start_time_ == kInfiniteDuration()) { 1400 if (start_time_ == kInfiniteDuration) {
1402 start_time_ = base::TimeDelta(); 1401 start_time_ = base::TimeDelta();
1403 preferred_stream_for_seeking_ = StreamSeekInfo( 1402 preferred_stream_for_seeking_ = StreamSeekInfo(
1404 video_stream ? video_stream->index : audio_stream->index, start_time_); 1403 video_stream ? video_stream->index : audio_stream->index, start_time_);
1405 } else if (!video_stream) { 1404 } else if (!video_stream) {
1406 // If no video stream exists, use the audio or text stream found above. 1405 // If no video stream exists, use the audio or text stream found above.
1407 preferred_stream_for_seeking_ = fallback_stream_for_seeking_; 1406 preferred_stream_for_seeking_ = fallback_stream_for_seeking_;
1408 } 1407 }
1409 1408
1410 // MPEG-4 B-frames cause grief for a simple container like AVI. Enable PTS 1409 // MPEG-4 B-frames cause grief for a simple container like AVI. Enable PTS
1411 // generation so we always get timestamps, see http://crbug.com/169570 1410 // generation so we always get timestamps, see http://crbug.com/169570
1412 if (strcmp(format_context->iformat->name, "avi") == 0) 1411 if (strcmp(format_context->iformat->name, "avi") == 0)
1413 format_context->flags |= AVFMT_FLAG_GENPTS; 1412 format_context->flags |= AVFMT_FLAG_GENPTS;
1414 1413
1415 // For testing purposes, don't overwrite the timeline offset if set already. 1414 // For testing purposes, don't overwrite the timeline offset if set already.
1416 if (timeline_offset_.is_null()) 1415 if (timeline_offset_.is_null())
1417 timeline_offset_ = ExtractTimelineOffset(format_context); 1416 timeline_offset_ = ExtractTimelineOffset(format_context);
1418 1417
1419 // Since we're shifting the externally visible start time to zero, we need to 1418 // Since we're shifting the externally visible start time to zero, we need to
1420 // adjust the timeline offset to compensate. 1419 // adjust the timeline offset to compensate.
1421 if (!timeline_offset_.is_null() && start_time_ < base::TimeDelta()) 1420 if (!timeline_offset_.is_null() && start_time_ < base::TimeDelta())
1422 timeline_offset_ += start_time_; 1421 timeline_offset_ += start_time_;
1423 1422
1424 if (max_duration == kInfiniteDuration() && !timeline_offset_.is_null()) { 1423 if (max_duration == kInfiniteDuration && !timeline_offset_.is_null()) {
1425 SetLiveness(DemuxerStream::LIVENESS_LIVE); 1424 SetLiveness(DemuxerStream::LIVENESS_LIVE);
1426 } else if (max_duration != kInfiniteDuration()) { 1425 } else if (max_duration != kInfiniteDuration) {
1427 SetLiveness(DemuxerStream::LIVENESS_RECORDED); 1426 SetLiveness(DemuxerStream::LIVENESS_RECORDED);
1428 } else { 1427 } else {
1429 SetLiveness(DemuxerStream::LIVENESS_UNKNOWN); 1428 SetLiveness(DemuxerStream::LIVENESS_UNKNOWN);
1430 } 1429 }
1431 1430
1432 // Good to go: set the duration and bitrate and notify we're done 1431 // Good to go: set the duration and bitrate and notify we're done
1433 // initializing. 1432 // initializing.
1434 host_->SetDuration(max_duration); 1433 host_->SetDuration(max_duration);
1435 duration_known_ = (max_duration != kInfiniteDuration()); 1434 duration_known_ = (max_duration != kInfiniteDuration);
1436 1435
1437 int64_t filesize_in_bytes = 0; 1436 int64_t filesize_in_bytes = 0;
1438 url_protocol_->GetSize(&filesize_in_bytes); 1437 url_protocol_->GetSize(&filesize_in_bytes);
1439 bitrate_ = CalculateBitrate(format_context, max_duration, filesize_in_bytes); 1438 bitrate_ = CalculateBitrate(format_context, max_duration, filesize_in_bytes);
1440 if (bitrate_ > 0) 1439 if (bitrate_ > 0)
1441 data_source_->SetBitrate(bitrate_); 1440 data_source_->SetBitrate(bitrate_);
1442 1441
1443 // Use a single MediaLogEvent to batch all parameter updates at once; this 1442 // Use a single MediaLogEvent to batch all parameter updates at once; this
1444 // prevents throttling of events due to the large number of updates here. 1443 // prevents throttling of events due to the large number of updates here.
1445 std::unique_ptr<MediaLogEvent> metadata_event = 1444 std::unique_ptr<MediaLogEvent> metadata_event =
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
1599 if (!duration_known_) { 1598 if (!duration_known_) {
1600 base::TimeDelta max_duration; 1599 base::TimeDelta max_duration;
1601 1600
1602 for (StreamVector::iterator iter = streams_.begin(); 1601 for (StreamVector::iterator iter = streams_.begin();
1603 iter != streams_.end(); 1602 iter != streams_.end();
1604 ++iter) { 1603 ++iter) {
1605 if (!*iter) 1604 if (!*iter)
1606 continue; 1605 continue;
1607 1606
1608 base::TimeDelta duration = (*iter)->GetElapsedTime(); 1607 base::TimeDelta duration = (*iter)->GetElapsedTime();
1609 if (duration != kNoTimestamp() && duration > max_duration) 1608 if (duration != kNoTimestamp && duration > max_duration)
1610 max_duration = duration; 1609 max_duration = duration;
1611 } 1610 }
1612 1611
1613 if (max_duration > base::TimeDelta()) { 1612 if (max_duration > base::TimeDelta()) {
1614 host_->SetDuration(max_duration); 1613 host_->SetDuration(max_duration);
1615 duration_known_ = true; 1614 duration_known_ = true;
1616 } 1615 }
1617 } 1616 }
1618 // If we have reached the end of stream, tell the downstream filters about 1617 // If we have reached the end of stream, tell the downstream filters about
1619 // the event. 1618 // the event.
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1697 1696
1698 void FFmpegDemuxer::SetLiveness(DemuxerStream::Liveness liveness) { 1697 void FFmpegDemuxer::SetLiveness(DemuxerStream::Liveness liveness) {
1699 DCHECK(task_runner_->BelongsToCurrentThread()); 1698 DCHECK(task_runner_->BelongsToCurrentThread());
1700 for (auto* stream : streams_) { 1699 for (auto* stream : streams_) {
1701 if (stream) 1700 if (stream)
1702 stream->SetLiveness(liveness); 1701 stream->SetLiveness(liveness);
1703 } 1702 }
1704 } 1703 }
1705 1704
1706 } // namespace media 1705 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698