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
3 // found in the LICENSE file.
5 #include "media/filters/ffmpeg_demuxer.h"
10 #include "base/base64.h"
11 #include "base/bind.h"
12 #include "base/callback.h"
13 #include "base/callback_helpers.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/message_loop/message_loop_proxy.h"
16 #include "base/metrics/sparse_histogram.h"
17 #include "base/strings/string_util.h"
18 #include "base/strings/stringprintf.h"
19 #include "base/sys_byteorder.h"
20 #include "base/task_runner_util.h"
21 #include "base/time/time.h"
22 #include "media/base/audio_decoder_config.h"
23 #include "media/base/bind_to_current_loop.h"
24 #include "media/base/decoder_buffer.h"
25 #include "media/base/decrypt_config.h"
26 #include "media/base/limits.h"
27 #include "media/base/media_log.h"
28 #include "media/base/video_decoder_config.h"
29 #include "media/ffmpeg/ffmpeg_common.h"
30 #include "media/filters/ffmpeg_glue.h"
31 #include "media/filters/ffmpeg_h264_to_annex_b_bitstream_converter.h"
32 #include "media/filters/webvtt_util.h"
33 #include "media/formats/webm/webm_crypto_helpers.h"
37 static base::Time ExtractTimelineOffset(AVFormatContext* format_context) {
38 if (strstr(format_context->iformat->name, "webm") ||
39 strstr(format_context->iformat->name, "matroska")) {
40 const AVDictionaryEntry* entry =
41 av_dict_get(format_context->metadata, "creation_time", NULL, 0);
43 base::Time timeline_offset;
44 if (entry != NULL && entry->value != NULL &&
45 FFmpegUTCDateToTime(entry->value, &timeline_offset)) {
46 return timeline_offset;
53 static base::TimeDelta FramesToTimeDelta(int frames, double sample_rate) {
54 return base::TimeDelta::FromMicroseconds(
55 frames * base::Time::kMicrosecondsPerSecond / sample_rate);
59 // FFmpegDemuxerStream
61 FFmpegDemuxerStream::FFmpegDemuxerStream(
62 FFmpegDemuxer* demuxer,
65 task_runner_(base::MessageLoopProxy::current()),
68 end_of_stream_(false),
69 last_packet_timestamp_(kNoTimestamp()),
70 last_packet_duration_(kNoTimestamp()),
71 bitstream_converter_enabled_(false) {
74 bool is_encrypted = false;
76 // Determine our media format.
77 switch (stream->codec->codec_type) {
78 case AVMEDIA_TYPE_AUDIO:
80 AVStreamToAudioDecoderConfig(stream, &audio_config_, true);
81 is_encrypted = audio_config_.is_encrypted();
83 case AVMEDIA_TYPE_VIDEO:
85 AVStreamToVideoDecoderConfig(stream, &video_config_, true);
86 is_encrypted = video_config_.is_encrypted();
88 case AVMEDIA_TYPE_SUBTITLE:
96 // Calculate the duration.
97 duration_ = ConvertStreamTimestamp(stream->time_base, stream->duration);
99 #if defined(USE_PROPRIETARY_CODECS)
100 if (stream_->codec->codec_id == AV_CODEC_ID_H264) {
101 bitstream_converter_.reset(
102 new FFmpegH264ToAnnexBBitstreamConverter(stream_->codec));
107 AVDictionaryEntry* key = av_dict_get(stream->metadata, "enc_key_id", NULL,
111 if (!key || !key->value)
113 base::StringPiece base64_key_id(key->value);
114 std::string enc_key_id;
115 base::Base64Decode(base64_key_id, &enc_key_id);
116 DCHECK(!enc_key_id.empty());
117 if (enc_key_id.empty())
120 encryption_key_id_.assign(enc_key_id);
121 demuxer_->FireNeedKey(kWebMEncryptInitDataType, enc_key_id);
125 void FFmpegDemuxerStream::EnqueuePacket(ScopedAVPacket packet) {
126 DCHECK(task_runner_->BelongsToCurrentThread());
128 if (!demuxer_ || end_of_stream_) {
129 NOTREACHED() << "Attempted to enqueue packet on a stopped stream";
133 #if defined(USE_PROPRIETARY_CODECS)
134 // Convert the packet if there is a bitstream filter.
135 if (packet->data && bitstream_converter_enabled_ &&
136 !bitstream_converter_->ConvertPacket(packet.get())) {
137 LOG(ERROR) << "Format conversion failed.";
141 // Get side data if any. For now, the only type of side_data is VP8 Alpha. We
142 // keep this generic so that other side_data types in the future can be
143 // handled the same way as well.
144 av_packet_split_side_data(packet.get());
146 scoped_refptr<DecoderBuffer> buffer;
148 if (type() == DemuxerStream::TEXT) {
150 uint8* id_data = av_packet_get_side_data(
152 AV_PKT_DATA_WEBVTT_IDENTIFIER,
155 int settings_size = 0;
156 uint8* settings_data = av_packet_get_side_data(
158 AV_PKT_DATA_WEBVTT_SETTINGS,
161 std::vector<uint8> side_data;
162 MakeSideData(id_data, id_data + id_size,
163 settings_data, settings_data + settings_size,
166 buffer = DecoderBuffer::CopyFrom(packet.get()->data, packet.get()->size,
167 side_data.data(), side_data.size());
169 int side_data_size = 0;
170 uint8* side_data = av_packet_get_side_data(
172 AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL,
175 scoped_ptr<DecryptConfig> decrypt_config;
177 if ((type() == DemuxerStream::AUDIO && audio_config_.is_encrypted()) ||
178 (type() == DemuxerStream::VIDEO && video_config_.is_encrypted())) {
179 if (!WebMCreateDecryptConfig(
180 packet->data, packet->size,
181 reinterpret_cast<const uint8*>(encryption_key_id_.data()),
182 encryption_key_id_.size(),
185 LOG(ERROR) << "Creation of DecryptConfig failed.";
189 // If a packet is returned by FFmpeg's av_parser_parse2() the packet will
190 // reference inner memory of FFmpeg. As such we should transfer the packet
191 // into memory we control.
192 if (side_data_size > 0) {
193 buffer = DecoderBuffer::CopyFrom(packet.get()->data + data_offset,
194 packet.get()->size - data_offset,
195 side_data, side_data_size);
197 buffer = DecoderBuffer::CopyFrom(packet.get()->data + data_offset,
198 packet.get()->size - data_offset);
201 int skip_samples_size = 0;
202 const uint32* skip_samples_ptr =
203 reinterpret_cast<const uint32*>(av_packet_get_side_data(
204 packet.get(), AV_PKT_DATA_SKIP_SAMPLES, &skip_samples_size));
205 const int kSkipSamplesValidSize = 10;
206 const int kSkipEndSamplesOffset = 1;
207 if (skip_samples_size >= kSkipSamplesValidSize) {
208 // Because FFmpeg rolls codec delay and skip samples into one we can only
209 // allow front discard padding on the first buffer. Otherwise the discard
210 // helper can't figure out which data to discard. See AudioDiscardHelper.
211 int discard_front_samples = base::ByteSwapToLE32(*skip_samples_ptr);
212 if (last_packet_timestamp_ != kNoTimestamp()) {
213 DLOG(ERROR) << "Skip samples are only allowed for the first packet.";
214 discard_front_samples = 0;
217 const int discard_end_samples =
218 base::ByteSwapToLE32(*(skip_samples_ptr + kSkipEndSamplesOffset));
219 const int samples_per_second =
220 audio_decoder_config().samples_per_second();
221 buffer->set_discard_padding(std::make_pair(
222 FramesToTimeDelta(discard_front_samples, samples_per_second),
223 FramesToTimeDelta(discard_end_samples, samples_per_second)));
227 buffer->set_decrypt_config(decrypt_config.Pass());
230 buffer->set_timestamp(ConvertStreamTimestamp(
231 stream_->time_base, packet->pts));
232 buffer->set_duration(ConvertStreamTimestamp(
233 stream_->time_base, packet->duration));
235 if (last_packet_timestamp_ != kNoTimestamp()) {
236 // FFmpeg doesn't support chained ogg correctly. Instead of guaranteeing
237 // continuity across links in the chain it uses the timestamp information
238 // from each link directly. Doing so can lead to timestamps which appear to
239 // go backwards in time.
241 // If the new link starts with a negative timestamp or a timestamp less than
242 // the original (positive) |start_time|, we will get a negative timestamp
243 // here. It's also possible FFmpeg returns kNoTimestamp() here if it's not
244 // able to work out a timestamp using the previous link and the next.
246 // Fixing chained ogg is non-trivial, so for now just reuse the last good
247 // timestamp. The decoder will rewrite the timestamps to be sample accurate
248 // later. See http://crbug.com/396864.
249 if (buffer->timestamp() == kNoTimestamp() ||
250 buffer->timestamp() < last_packet_timestamp_) {
251 buffer->set_timestamp(last_packet_timestamp_ +
252 (last_packet_duration_ != kNoTimestamp()
253 ? last_packet_duration_
254 : base::TimeDelta::FromMicroseconds(1)));
257 // The demuxer should always output positive timestamps.
258 DCHECK(buffer->timestamp() >= base::TimeDelta());
259 DCHECK(buffer->timestamp() != kNoTimestamp());
261 if (last_packet_timestamp_ < buffer->timestamp()) {
262 buffered_ranges_.Add(last_packet_timestamp_, buffer->timestamp());
263 demuxer_->NotifyBufferingChanged();
267 last_packet_timestamp_ = buffer->timestamp();
268 last_packet_duration_ = buffer->duration();
270 buffer_queue_.Push(buffer);
271 SatisfyPendingRead();
274 void FFmpegDemuxerStream::SetEndOfStream() {
275 DCHECK(task_runner_->BelongsToCurrentThread());
276 end_of_stream_ = true;
277 SatisfyPendingRead();
280 void FFmpegDemuxerStream::FlushBuffers() {
281 DCHECK(task_runner_->BelongsToCurrentThread());
282 DCHECK(read_cb_.is_null()) << "There should be no pending read";
283 buffer_queue_.Clear();
284 end_of_stream_ = false;
285 last_packet_timestamp_ = kNoTimestamp();
286 last_packet_duration_ = kNoTimestamp();
289 void FFmpegDemuxerStream::Stop() {
290 DCHECK(task_runner_->BelongsToCurrentThread());
291 buffer_queue_.Clear();
292 if (!read_cb_.is_null()) {
293 base::ResetAndReturn(&read_cb_).Run(
294 DemuxerStream::kOk, DecoderBuffer::CreateEOSBuffer());
298 end_of_stream_ = true;
301 base::TimeDelta FFmpegDemuxerStream::duration() {
305 DemuxerStream::Type FFmpegDemuxerStream::type() {
306 DCHECK(task_runner_->BelongsToCurrentThread());
310 void FFmpegDemuxerStream::Read(const ReadCB& read_cb) {
311 DCHECK(task_runner_->BelongsToCurrentThread());
312 CHECK(read_cb_.is_null()) << "Overlapping reads are not supported";
313 read_cb_ = BindToCurrentLoop(read_cb);
315 // Don't accept any additional reads if we've been told to stop.
316 // The |demuxer_| may have been destroyed in the pipeline thread.
318 // TODO(scherkus): it would be cleaner to reply with an error message.
320 base::ResetAndReturn(&read_cb_).Run(
321 DemuxerStream::kOk, DecoderBuffer::CreateEOSBuffer());
325 SatisfyPendingRead();
328 void FFmpegDemuxerStream::EnableBitstreamConverter() {
329 DCHECK(task_runner_->BelongsToCurrentThread());
331 #if defined(USE_PROPRIETARY_CODECS)
332 CHECK(bitstream_converter_.get());
333 bitstream_converter_enabled_ = true;
335 NOTREACHED() << "Proprietary codecs not enabled.";
339 bool FFmpegDemuxerStream::SupportsConfigChanges() { return false; }
341 AudioDecoderConfig FFmpegDemuxerStream::audio_decoder_config() {
342 DCHECK(task_runner_->BelongsToCurrentThread());
343 CHECK_EQ(type_, AUDIO);
344 return audio_config_;
347 VideoDecoderConfig FFmpegDemuxerStream::video_decoder_config() {
348 DCHECK(task_runner_->BelongsToCurrentThread());
349 CHECK_EQ(type_, VIDEO);
350 return video_config_;
353 FFmpegDemuxerStream::~FFmpegDemuxerStream() {
355 DCHECK(read_cb_.is_null());
356 DCHECK(buffer_queue_.IsEmpty());
359 base::TimeDelta FFmpegDemuxerStream::GetElapsedTime() const {
360 return ConvertStreamTimestamp(stream_->time_base, stream_->cur_dts);
363 Ranges<base::TimeDelta> FFmpegDemuxerStream::GetBufferedRanges() const {
364 return buffered_ranges_;
367 void FFmpegDemuxerStream::SatisfyPendingRead() {
368 DCHECK(task_runner_->BelongsToCurrentThread());
369 if (!read_cb_.is_null()) {
370 if (!buffer_queue_.IsEmpty()) {
371 base::ResetAndReturn(&read_cb_).Run(
372 DemuxerStream::kOk, buffer_queue_.Pop());
373 } else if (end_of_stream_) {
374 base::ResetAndReturn(&read_cb_).Run(
375 DemuxerStream::kOk, DecoderBuffer::CreateEOSBuffer());
379 // Have capacity? Ask for more!
380 if (HasAvailableCapacity() && !end_of_stream_) {
381 demuxer_->NotifyCapacityAvailable();
385 bool FFmpegDemuxerStream::HasAvailableCapacity() {
386 // TODO(scherkus): Remove this return and reenable time-based capacity
387 // after our data sources support canceling/concurrent reads, see
388 // http://crbug.com/165762 for details.
390 return !read_cb_.is_null();
392 // Try to have one second's worth of encoded data per stream.
393 const base::TimeDelta kCapacity = base::TimeDelta::FromSeconds(1);
394 return buffer_queue_.IsEmpty() || buffer_queue_.Duration() < kCapacity;
398 size_t FFmpegDemuxerStream::MemoryUsage() const {
399 return buffer_queue_.data_size();
402 TextKind FFmpegDemuxerStream::GetTextKind() const {
403 DCHECK_EQ(type_, DemuxerStream::TEXT);
405 if (stream_->disposition & AV_DISPOSITION_CAPTIONS)
406 return kTextCaptions;
408 if (stream_->disposition & AV_DISPOSITION_DESCRIPTIONS)
409 return kTextDescriptions;
411 if (stream_->disposition & AV_DISPOSITION_METADATA)
412 return kTextMetadata;
414 return kTextSubtitles;
417 std::string FFmpegDemuxerStream::GetMetadata(const char* key) const {
418 const AVDictionaryEntry* entry =
419 av_dict_get(stream_->metadata, key, NULL, 0);
420 return (entry == NULL || entry->value == NULL) ? "" : entry->value;
424 base::TimeDelta FFmpegDemuxerStream::ConvertStreamTimestamp(
425 const AVRational& time_base, int64 timestamp) {
426 if (timestamp == static_cast<int64>(AV_NOPTS_VALUE))
427 return kNoTimestamp();
429 return ConvertFromTimeBase(time_base, timestamp);
435 FFmpegDemuxer::FFmpegDemuxer(
436 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
437 DataSource* data_source,
438 const NeedKeyCB& need_key_cb,
439 const scoped_refptr<MediaLog>& media_log)
441 task_runner_(task_runner),
442 blocking_thread_("FFmpegDemuxer"),
443 pending_read_(false),
444 pending_seek_(false),
445 data_source_(data_source),
446 media_log_(media_log),
448 start_time_(kNoTimestamp()),
449 liveness_(LIVENESS_UNKNOWN),
450 text_enabled_(false),
451 duration_known_(false),
452 need_key_cb_(need_key_cb),
453 weak_factory_(this) {
454 DCHECK(task_runner_.get());
455 DCHECK(data_source_);
458 FFmpegDemuxer::~FFmpegDemuxer() {}
460 void FFmpegDemuxer::Stop(const base::Closure& callback) {
461 DCHECK(task_runner_->BelongsToCurrentThread());
462 url_protocol_->Abort();
464 BindToCurrentLoop(base::Bind(&FFmpegDemuxer::OnDataSourceStopped,
465 weak_factory_.GetWeakPtr(),
466 BindToCurrentLoop(callback))));
470 void FFmpegDemuxer::Seek(base::TimeDelta time, const PipelineStatusCB& cb) {
471 DCHECK(task_runner_->BelongsToCurrentThread());
472 CHECK(!pending_seek_);
474 // TODO(scherkus): Inspect |pending_read_| and cancel IO via |blocking_url_|,
475 // otherwise we can end up waiting for a pre-seek read to complete even though
476 // we know we're going to drop it on the floor.
478 // Always seek to a timestamp less than or equal to the desired timestamp.
479 int flags = AVSEEK_FLAG_BACKWARD;
481 // Passing -1 as our stream index lets FFmpeg pick a default stream. FFmpeg
482 // will attempt to use the lowest-index video stream, if present, followed by
483 // the lowest-index audio stream.
484 pending_seek_ = true;
485 base::PostTaskAndReplyWithResult(
486 blocking_thread_.message_loop_proxy().get(),
488 base::Bind(&av_seek_frame,
489 glue_->format_context(),
491 time.InMicroseconds(),
494 &FFmpegDemuxer::OnSeekFrameDone, weak_factory_.GetWeakPtr(), cb));
497 void FFmpegDemuxer::Initialize(DemuxerHost* host,
498 const PipelineStatusCB& status_cb,
499 bool enable_text_tracks) {
500 DCHECK(task_runner_->BelongsToCurrentThread());
502 text_enabled_ = enable_text_tracks;
504 url_protocol_.reset(new BlockingUrlProtocol(data_source_, BindToCurrentLoop(
505 base::Bind(&FFmpegDemuxer::OnDataSourceError, base::Unretained(this)))));
506 glue_.reset(new FFmpegGlue(url_protocol_.get()));
507 AVFormatContext* format_context = glue_->format_context();
509 // Disable ID3v1 tag reading to avoid costly seeks to end of file for data we
510 // don't use. FFmpeg will only read ID3v1 tags if no other metadata is
511 // available, so add a metadata entry to ensure some is always present.
512 av_dict_set(&format_context->metadata, "skip_id3v1_tags", "", 0);
514 // Open the AVFormatContext using our glue layer.
515 CHECK(blocking_thread_.Start());
516 base::PostTaskAndReplyWithResult(
517 blocking_thread_.message_loop_proxy().get(),
519 base::Bind(&FFmpegGlue::OpenContext, base::Unretained(glue_.get())),
520 base::Bind(&FFmpegDemuxer::OnOpenContextDone,
521 weak_factory_.GetWeakPtr(),
525 DemuxerStream* FFmpegDemuxer::GetStream(DemuxerStream::Type type) {
526 DCHECK(task_runner_->BelongsToCurrentThread());
527 return GetFFmpegStream(type);
530 FFmpegDemuxerStream* FFmpegDemuxer::GetFFmpegStream(
531 DemuxerStream::Type type) const {
532 StreamVector::const_iterator iter;
533 for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
534 if (*iter && (*iter)->type() == type) {
541 base::TimeDelta FFmpegDemuxer::GetStartTime() const {
542 DCHECK(task_runner_->BelongsToCurrentThread());
546 base::Time FFmpegDemuxer::GetTimelineOffset() const {
547 return timeline_offset_;
550 Demuxer::Liveness FFmpegDemuxer::GetLiveness() const {
551 DCHECK(task_runner_->BelongsToCurrentThread());
555 void FFmpegDemuxer::AddTextStreams() {
556 DCHECK(task_runner_->BelongsToCurrentThread());
558 for (StreamVector::size_type idx = 0; idx < streams_.size(); ++idx) {
559 FFmpegDemuxerStream* stream = streams_[idx];
560 if (stream == NULL || stream->type() != DemuxerStream::TEXT)
563 TextKind kind = stream->GetTextKind();
564 std::string title = stream->GetMetadata("title");
565 std::string language = stream->GetMetadata("language");
567 // TODO: Implement "id" metadata in FFMPEG.
568 // See: http://crbug.com/323183
569 host_->AddTextStream(stream, TextTrackConfig(kind, title, language,
574 // Helper for calculating the bitrate of the media based on information stored
575 // in |format_context| or failing that the size and duration of the media.
577 // Returns 0 if a bitrate could not be determined.
578 static int CalculateBitrate(
579 AVFormatContext* format_context,
580 const base::TimeDelta& duration,
581 int64 filesize_in_bytes) {
582 // If there is a bitrate set on the container, use it.
583 if (format_context->bit_rate > 0)
584 return format_context->bit_rate;
586 // Then try to sum the bitrates individually per stream.
588 for (size_t i = 0; i < format_context->nb_streams; ++i) {
589 AVCodecContext* codec_context = format_context->streams[i]->codec;
590 bitrate += codec_context->bit_rate;
595 // See if we can approximate the bitrate as long as we have a filesize and
597 if (duration.InMicroseconds() <= 0 ||
598 duration == kInfiniteDuration() ||
599 filesize_in_bytes == 0) {
603 // Do math in floating point as we'd overflow an int64 if the filesize was
604 // larger than ~1073GB.
605 double bytes = filesize_in_bytes;
606 double duration_us = duration.InMicroseconds();
607 return bytes * 8000000.0 / duration_us;
610 void FFmpegDemuxer::OnOpenContextDone(const PipelineStatusCB& status_cb,
612 DCHECK(task_runner_->BelongsToCurrentThread());
613 if (!blocking_thread_.IsRunning()) {
614 status_cb.Run(PIPELINE_ERROR_ABORT);
619 status_cb.Run(DEMUXER_ERROR_COULD_NOT_OPEN);
623 // Fully initialize AVFormatContext by parsing the stream a little.
624 base::PostTaskAndReplyWithResult(
625 blocking_thread_.message_loop_proxy().get(),
627 base::Bind(&avformat_find_stream_info,
628 glue_->format_context(),
629 static_cast<AVDictionary**>(NULL)),
630 base::Bind(&FFmpegDemuxer::OnFindStreamInfoDone,
631 weak_factory_.GetWeakPtr(),
635 void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb,
637 DCHECK(task_runner_->BelongsToCurrentThread());
638 if (!blocking_thread_.IsRunning() || !data_source_) {
639 status_cb.Run(PIPELINE_ERROR_ABORT);
644 status_cb.Run(DEMUXER_ERROR_COULD_NOT_PARSE);
648 // Create demuxer stream entries for each possible AVStream. Each stream
649 // is examined to determine if it is supported or not (is the codec enabled
650 // for it in this release?). Unsupported streams are skipped, allowing for
651 // partial playback. At least one audio or video stream must be playable.
652 AVFormatContext* format_context = glue_->format_context();
653 streams_.resize(format_context->nb_streams);
655 AVStream* audio_stream = NULL;
656 AudioDecoderConfig audio_config;
658 AVStream* video_stream = NULL;
659 VideoDecoderConfig video_config;
661 base::TimeDelta max_duration;
662 for (size_t i = 0; i < format_context->nb_streams; ++i) {
663 AVStream* stream = format_context->streams[i];
664 AVCodecContext* codec_context = stream->codec;
665 AVMediaType codec_type = codec_context->codec_type;
667 if (codec_type == AVMEDIA_TYPE_AUDIO) {
671 // Log the codec detected, whether it is supported or not.
672 UMA_HISTOGRAM_SPARSE_SLOWLY("Media.DetectedAudioCodec",
673 codec_context->codec_id);
674 // Ensure the codec is supported. IsValidConfig() also checks that the
675 // channel layout and sample format are valid.
676 AVStreamToAudioDecoderConfig(stream, &audio_config, false);
677 if (!audio_config.IsValidConfig())
679 audio_stream = stream;
680 } else if (codec_type == AVMEDIA_TYPE_VIDEO) {
684 // Log the codec detected, whether it is supported or not.
685 UMA_HISTOGRAM_SPARSE_SLOWLY("Media.DetectedVideoCodec",
686 codec_context->codec_id);
687 // Ensure the codec is supported. IsValidConfig() also checks that the
688 // frame size and visible size are valid.
689 AVStreamToVideoDecoderConfig(stream, &video_config, false);
691 if (!video_config.IsValidConfig())
693 video_stream = stream;
694 } else if (codec_type == AVMEDIA_TYPE_SUBTITLE) {
695 if (codec_context->codec_id != AV_CODEC_ID_WEBVTT || !text_enabled_) {
702 streams_[i] = new FFmpegDemuxerStream(this, stream);
703 max_duration = std::max(max_duration, streams_[i]->duration());
705 if (stream->first_dts != static_cast<int64_t>(AV_NOPTS_VALUE)) {
706 const base::TimeDelta first_dts = ConvertFromTimeBase(
707 stream->time_base, stream->first_dts);
708 if (start_time_ == kNoTimestamp() || first_dts < start_time_)
709 start_time_ = first_dts;
713 if (!audio_stream && !video_stream) {
714 status_cb.Run(DEMUXER_ERROR_NO_SUPPORTED_STREAMS);
721 if (format_context->duration != static_cast<int64_t>(AV_NOPTS_VALUE)) {
722 // If there is a duration value in the container use that to find the
723 // maximum between it and the duration from A/V streams.
724 const AVRational av_time_base = {1, AV_TIME_BASE};
726 std::max(max_duration,
727 ConvertFromTimeBase(av_time_base, format_context->duration));
729 // The duration is unknown, in which case this is likely a live stream.
730 max_duration = kInfiniteDuration();
733 // Some demuxers, like WAV, do not put timestamps on their frames. We
734 // assume the the start time is 0.
735 if (start_time_ == kNoTimestamp())
736 start_time_ = base::TimeDelta();
738 // MPEG-4 B-frames cause grief for a simple container like AVI. Enable PTS
739 // generation so we always get timestamps, see http://crbug.com/169570
740 if (strcmp(format_context->iformat->name, "avi") == 0)
741 format_context->flags |= AVFMT_FLAG_GENPTS;
743 timeline_offset_ = ExtractTimelineOffset(format_context);
745 if (max_duration == kInfiniteDuration() && !timeline_offset_.is_null()) {
746 liveness_ = LIVENESS_LIVE;
747 } else if (max_duration != kInfiniteDuration()) {
748 liveness_ = LIVENESS_RECORDED;
750 liveness_ = LIVENESS_UNKNOWN;
753 // Good to go: set the duration and bitrate and notify we're done
755 host_->SetDuration(max_duration);
756 duration_known_ = (max_duration != kInfiniteDuration());
758 int64 filesize_in_bytes = 0;
759 url_protocol_->GetSize(&filesize_in_bytes);
760 bitrate_ = CalculateBitrate(format_context, max_duration, filesize_in_bytes);
762 data_source_->SetBitrate(bitrate_);
766 AVCodecContext* audio_codec = audio_stream->codec;
767 media_log_->SetBooleanProperty("found_audio_stream", true);
769 SampleFormat sample_format = audio_config.sample_format();
770 std::string sample_name = SampleFormatToString(sample_format);
772 media_log_->SetStringProperty("audio_sample_format", sample_name);
774 AVCodec* codec = avcodec_find_decoder(audio_codec->codec_id);
776 media_log_->SetStringProperty("audio_codec_name", codec->name);
779 media_log_->SetIntegerProperty("audio_channels_count",
780 audio_codec->channels);
781 media_log_->SetIntegerProperty("audio_samples_per_second",
782 audio_config.samples_per_second());
784 media_log_->SetBooleanProperty("found_audio_stream", false);
789 AVCodecContext* video_codec = video_stream->codec;
790 media_log_->SetBooleanProperty("found_video_stream", true);
792 AVCodec* codec = avcodec_find_decoder(video_codec->codec_id);
794 media_log_->SetStringProperty("video_codec_name", codec->name);
797 media_log_->SetIntegerProperty("width", video_codec->width);
798 media_log_->SetIntegerProperty("height", video_codec->height);
799 media_log_->SetIntegerProperty("coded_width",
800 video_codec->coded_width);
801 media_log_->SetIntegerProperty("coded_height",
802 video_codec->coded_height);
803 media_log_->SetStringProperty(
805 base::StringPrintf("%d/%d",
806 video_codec->time_base.num,
807 video_codec->time_base.den));
808 media_log_->SetStringProperty(
809 "video_format", VideoFrame::FormatToString(video_config.format()));
810 media_log_->SetBooleanProperty("video_is_encrypted",
811 video_config.is_encrypted());
813 media_log_->SetBooleanProperty("found_video_stream", false);
817 media_log_->SetTimeProperty("max_duration", max_duration);
818 media_log_->SetTimeProperty("start_time", start_time_);
819 media_log_->SetIntegerProperty("bitrate", bitrate_);
821 status_cb.Run(PIPELINE_OK);
824 void FFmpegDemuxer::OnSeekFrameDone(const PipelineStatusCB& cb, int result) {
825 DCHECK(task_runner_->BelongsToCurrentThread());
826 CHECK(pending_seek_);
827 pending_seek_ = false;
829 if (!blocking_thread_.IsRunning()) {
830 cb.Run(PIPELINE_ERROR_ABORT);
835 // Use VLOG(1) instead of NOTIMPLEMENTED() to prevent the message being
836 // captured from stdout and contaminates testing.
837 // TODO(scherkus): Implement this properly and signal error (BUG=23447).
838 VLOG(1) << "Not implemented";
841 // Tell streams to flush buffers due to seeking.
842 StreamVector::iterator iter;
843 for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
845 (*iter)->FlushBuffers();
848 // Resume reading until capacity.
851 // Notify we're finished seeking.
855 void FFmpegDemuxer::ReadFrameIfNeeded() {
856 DCHECK(task_runner_->BelongsToCurrentThread());
858 // Make sure we have work to do before reading.
859 if (!blocking_thread_.IsRunning() || !StreamsHaveAvailableCapacity() ||
860 pending_read_ || pending_seek_) {
864 // Allocate and read an AVPacket from the media. Save |packet_ptr| since
865 // evaluation order of packet.get() and base::Passed(&packet) is
867 ScopedAVPacket packet(new AVPacket());
868 AVPacket* packet_ptr = packet.get();
870 pending_read_ = true;
871 base::PostTaskAndReplyWithResult(
872 blocking_thread_.message_loop_proxy().get(),
874 base::Bind(&av_read_frame, glue_->format_context(), packet_ptr),
875 base::Bind(&FFmpegDemuxer::OnReadFrameDone,
876 weak_factory_.GetWeakPtr(),
877 base::Passed(&packet)));
880 void FFmpegDemuxer::OnReadFrameDone(ScopedAVPacket packet, int result) {
881 DCHECK(task_runner_->BelongsToCurrentThread());
882 DCHECK(pending_read_);
883 pending_read_ = false;
885 if (!blocking_thread_.IsRunning() || pending_seek_) {
889 // Consider the stream as ended if:
890 // - either underlying ffmpeg returned an error
891 // - or FFMpegDemuxer reached the maximum allowed memory usage.
892 if (result < 0 || IsMaxMemoryUsageReached()) {
893 // Update the duration based on the highest elapsed time across all streams
894 // if it was previously unknown.
895 if (!duration_known_) {
896 base::TimeDelta max_duration;
898 for (StreamVector::iterator iter = streams_.begin();
899 iter != streams_.end();
904 base::TimeDelta duration = (*iter)->GetElapsedTime();
905 if (duration != kNoTimestamp() && duration > max_duration)
906 max_duration = duration;
909 if (max_duration > base::TimeDelta()) {
910 host_->SetDuration(max_duration);
911 duration_known_ = true;
914 // If we have reached the end of stream, tell the downstream filters about
920 // Queue the packet with the appropriate stream.
921 DCHECK_GE(packet->stream_index, 0);
922 DCHECK_LT(packet->stream_index, static_cast<int>(streams_.size()));
924 // Defend against ffmpeg giving us a bad stream index.
925 if (packet->stream_index >= 0 &&
926 packet->stream_index < static_cast<int>(streams_.size()) &&
927 streams_[packet->stream_index]) {
928 // TODO(scherkus): Fix demuxing upstream to never return packets w/o data
929 // when av_read_frame() returns success code. See bug comment for ideas:
931 // https://code.google.com/p/chromium/issues/detail?id=169133#c10
933 ScopedAVPacket new_packet(new AVPacket());
934 av_new_packet(new_packet.get(), 0);
935 av_packet_copy_props(new_packet.get(), packet.get());
936 packet.swap(new_packet);
939 // Special case for opus in ogg. FFmpeg is pre-trimming the codec delay
940 // from the packet timestamp. Chrome expects to handle this itself inside
941 // the decoder, so shift timestamps by the delay in this case.
942 // TODO(dalecurtis): Try to get fixed upstream. See http://crbug.com/328207
943 if (strcmp(glue_->format_context()->iformat->name, "ogg") == 0) {
944 const AVCodecContext* codec_context =
945 glue_->format_context()->streams[packet->stream_index]->codec;
946 if (codec_context->codec_id == AV_CODEC_ID_OPUS &&
947 codec_context->delay > 0) {
948 packet->pts += codec_context->delay;
952 FFmpegDemuxerStream* demuxer_stream = streams_[packet->stream_index];
953 demuxer_stream->EnqueuePacket(packet.Pass());
956 // Keep reading until we've reached capacity.
960 void FFmpegDemuxer::OnDataSourceStopped(const base::Closure& callback) {
961 // This will block until all tasks complete. Note that after this returns it's
962 // possible for reply tasks (e.g., OnReadFrameDone()) to be queued on this
963 // thread. Each of the reply task methods must check whether we've stopped the
964 // thread and drop their results on the floor.
965 DCHECK(task_runner_->BelongsToCurrentThread());
966 blocking_thread_.Stop();
968 StreamVector::iterator iter;
969 for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
977 bool FFmpegDemuxer::StreamsHaveAvailableCapacity() {
978 DCHECK(task_runner_->BelongsToCurrentThread());
979 StreamVector::iterator iter;
980 for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
981 if (*iter && (*iter)->HasAvailableCapacity()) {
988 bool FFmpegDemuxer::IsMaxMemoryUsageReached() const {
989 DCHECK(task_runner_->BelongsToCurrentThread());
991 // Max allowed memory usage, all streams combined.
992 const size_t kDemuxerMemoryLimit = 150 * 1024 * 1024;
994 size_t memory_left = kDemuxerMemoryLimit;
995 for (StreamVector::const_iterator iter = streams_.begin();
996 iter != streams_.end(); ++iter) {
1000 size_t stream_memory_usage = (*iter)->MemoryUsage();
1001 if (stream_memory_usage > memory_left)
1003 memory_left -= stream_memory_usage;
1008 void FFmpegDemuxer::StreamHasEnded() {
1009 DCHECK(task_runner_->BelongsToCurrentThread());
1010 StreamVector::iterator iter;
1011 for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
1014 (*iter)->SetEndOfStream();
1018 void FFmpegDemuxer::FireNeedKey(const std::string& init_data_type,
1019 const std::string& encryption_key_id) {
1020 std::vector<uint8> key_id_local(encryption_key_id.begin(),
1021 encryption_key_id.end());
1022 need_key_cb_.Run(init_data_type, key_id_local);
1025 void FFmpegDemuxer::NotifyCapacityAvailable() {
1026 DCHECK(task_runner_->BelongsToCurrentThread());
1027 ReadFrameIfNeeded();
1030 void FFmpegDemuxer::NotifyBufferingChanged() {
1031 DCHECK(task_runner_->BelongsToCurrentThread());
1032 Ranges<base::TimeDelta> buffered;
1033 FFmpegDemuxerStream* audio = GetFFmpegStream(DemuxerStream::AUDIO);
1034 FFmpegDemuxerStream* video = GetFFmpegStream(DemuxerStream::VIDEO);
1035 if (audio && video) {
1036 buffered = audio->GetBufferedRanges().IntersectionWith(
1037 video->GetBufferedRanges());
1039 buffered = audio->GetBufferedRanges();
1041 buffered = video->GetBufferedRanges();
1043 for (size_t i = 0; i < buffered.size(); ++i)
1044 host_->AddBufferedTimeRange(buffered.start(i), buffered.end(i));
1047 void FFmpegDemuxer::OnDataSourceError() {
1048 host_->OnDemuxerError(PIPELINE_ERROR_READ);
1051 } // namespace media