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 bitstream_converter_enabled_(false) {
73 bool is_encrypted = false;
75 // Determine our media format.
76 switch (stream->codec->codec_type) {
77 case AVMEDIA_TYPE_AUDIO:
79 AVStreamToAudioDecoderConfig(stream, &audio_config_, true);
80 is_encrypted = audio_config_.is_encrypted();
82 case AVMEDIA_TYPE_VIDEO:
84 AVStreamToVideoDecoderConfig(stream, &video_config_, true);
85 is_encrypted = video_config_.is_encrypted();
87 case AVMEDIA_TYPE_SUBTITLE:
95 // Calculate the duration.
96 duration_ = ConvertStreamTimestamp(stream->time_base, stream->duration);
98 #if defined(USE_PROPRIETARY_CODECS)
99 if (stream_->codec->codec_id == AV_CODEC_ID_H264) {
100 bitstream_converter_.reset(
101 new FFmpegH264ToAnnexBBitstreamConverter(stream_->codec));
106 AVDictionaryEntry* key = av_dict_get(stream->metadata, "enc_key_id", NULL,
110 if (!key || !key->value)
112 base::StringPiece base64_key_id(key->value);
113 std::string enc_key_id;
114 base::Base64Decode(base64_key_id, &enc_key_id);
115 DCHECK(!enc_key_id.empty());
116 if (enc_key_id.empty())
119 encryption_key_id_.assign(enc_key_id);
120 demuxer_->FireNeedKey(kWebMEncryptInitDataType, enc_key_id);
124 void FFmpegDemuxerStream::EnqueuePacket(ScopedAVPacket packet) {
125 DCHECK(task_runner_->BelongsToCurrentThread());
127 if (!demuxer_ || end_of_stream_) {
128 NOTREACHED() << "Attempted to enqueue packet on a stopped stream";
132 #if defined(USE_PROPRIETARY_CODECS)
133 // Convert the packet if there is a bitstream filter.
134 if (packet->data && bitstream_converter_enabled_ &&
135 !bitstream_converter_->ConvertPacket(packet.get())) {
136 LOG(ERROR) << "Format conversion failed.";
140 // Get side data if any. For now, the only type of side_data is VP8 Alpha. We
141 // keep this generic so that other side_data types in the future can be
142 // handled the same way as well.
143 av_packet_split_side_data(packet.get());
145 scoped_refptr<DecoderBuffer> buffer;
147 if (type() == DemuxerStream::TEXT) {
149 uint8* id_data = av_packet_get_side_data(
151 AV_PKT_DATA_WEBVTT_IDENTIFIER,
154 int settings_size = 0;
155 uint8* settings_data = av_packet_get_side_data(
157 AV_PKT_DATA_WEBVTT_SETTINGS,
160 std::vector<uint8> side_data;
161 MakeSideData(id_data, id_data + id_size,
162 settings_data, settings_data + settings_size,
165 buffer = DecoderBuffer::CopyFrom(packet.get()->data, packet.get()->size,
166 side_data.data(), side_data.size());
168 int side_data_size = 0;
169 uint8* side_data = av_packet_get_side_data(
171 AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL,
174 scoped_ptr<DecryptConfig> decrypt_config;
176 if ((type() == DemuxerStream::AUDIO && audio_config_.is_encrypted()) ||
177 (type() == DemuxerStream::VIDEO && video_config_.is_encrypted())) {
178 if (!WebMCreateDecryptConfig(
179 packet->data, packet->size,
180 reinterpret_cast<const uint8*>(encryption_key_id_.data()),
181 encryption_key_id_.size(),
184 LOG(ERROR) << "Creation of DecryptConfig failed.";
188 // If a packet is returned by FFmpeg's av_parser_parse2() the packet will
189 // reference inner memory of FFmpeg. As such we should transfer the packet
190 // into memory we control.
191 if (side_data_size > 0) {
192 buffer = DecoderBuffer::CopyFrom(packet.get()->data + data_offset,
193 packet.get()->size - data_offset,
194 side_data, side_data_size);
196 buffer = DecoderBuffer::CopyFrom(packet.get()->data + data_offset,
197 packet.get()->size - data_offset);
200 int skip_samples_size = 0;
201 const uint32* skip_samples_ptr =
202 reinterpret_cast<const uint32*>(av_packet_get_side_data(
203 packet.get(), AV_PKT_DATA_SKIP_SAMPLES, &skip_samples_size));
204 const int kSkipSamplesValidSize = 10;
205 const int kSkipEndSamplesOffset = 1;
206 if (skip_samples_size >= kSkipSamplesValidSize) {
207 // Because FFmpeg rolls codec delay and skip samples into one we can only
208 // allow front discard padding on the first buffer. Otherwise the discard
209 // helper can't figure out which data to discard. See AudioDiscardHelper.
210 int discard_front_samples = base::ByteSwapToLE32(*skip_samples_ptr);
211 if (last_packet_timestamp_ != kNoTimestamp()) {
212 DLOG(ERROR) << "Skip samples are only allowed for the first packet.";
213 discard_front_samples = 0;
216 const int discard_end_samples =
217 base::ByteSwapToLE32(*(skip_samples_ptr + kSkipEndSamplesOffset));
218 const int samples_per_second =
219 audio_decoder_config().samples_per_second();
220 buffer->set_discard_padding(std::make_pair(
221 FramesToTimeDelta(discard_front_samples, samples_per_second),
222 FramesToTimeDelta(discard_end_samples, samples_per_second)));
226 buffer->set_decrypt_config(decrypt_config.Pass());
229 buffer->set_timestamp(ConvertStreamTimestamp(
230 stream_->time_base, packet->pts));
231 buffer->set_duration(ConvertStreamTimestamp(
232 stream_->time_base, packet->duration));
233 if (buffer->timestamp() != kNoTimestamp() &&
234 last_packet_timestamp_ != kNoTimestamp() &&
235 last_packet_timestamp_ < buffer->timestamp()) {
236 buffered_ranges_.Add(last_packet_timestamp_, buffer->timestamp());
237 demuxer_->NotifyBufferingChanged();
239 last_packet_timestamp_ = buffer->timestamp();
241 buffer_queue_.Push(buffer);
242 SatisfyPendingRead();
245 void FFmpegDemuxerStream::SetEndOfStream() {
246 DCHECK(task_runner_->BelongsToCurrentThread());
247 end_of_stream_ = true;
248 SatisfyPendingRead();
251 void FFmpegDemuxerStream::FlushBuffers() {
252 DCHECK(task_runner_->BelongsToCurrentThread());
253 DCHECK(read_cb_.is_null()) << "There should be no pending read";
254 buffer_queue_.Clear();
255 end_of_stream_ = false;
256 last_packet_timestamp_ = kNoTimestamp();
259 void FFmpegDemuxerStream::Stop() {
260 DCHECK(task_runner_->BelongsToCurrentThread());
261 buffer_queue_.Clear();
262 if (!read_cb_.is_null()) {
263 base::ResetAndReturn(&read_cb_).Run(
264 DemuxerStream::kOk, DecoderBuffer::CreateEOSBuffer());
268 end_of_stream_ = true;
271 base::TimeDelta FFmpegDemuxerStream::duration() {
275 DemuxerStream::Type FFmpegDemuxerStream::type() {
276 DCHECK(task_runner_->BelongsToCurrentThread());
280 void FFmpegDemuxerStream::Read(const ReadCB& read_cb) {
281 DCHECK(task_runner_->BelongsToCurrentThread());
282 CHECK(read_cb_.is_null()) << "Overlapping reads are not supported";
283 read_cb_ = BindToCurrentLoop(read_cb);
285 // Don't accept any additional reads if we've been told to stop.
286 // The |demuxer_| may have been destroyed in the pipeline thread.
288 // TODO(scherkus): it would be cleaner to reply with an error message.
290 base::ResetAndReturn(&read_cb_).Run(
291 DemuxerStream::kOk, DecoderBuffer::CreateEOSBuffer());
295 SatisfyPendingRead();
298 void FFmpegDemuxerStream::EnableBitstreamConverter() {
299 DCHECK(task_runner_->BelongsToCurrentThread());
301 #if defined(USE_PROPRIETARY_CODECS)
302 CHECK(bitstream_converter_.get());
303 bitstream_converter_enabled_ = true;
305 NOTREACHED() << "Proprietary codecs not enabled.";
309 bool FFmpegDemuxerStream::SupportsConfigChanges() { return false; }
311 AudioDecoderConfig FFmpegDemuxerStream::audio_decoder_config() {
312 DCHECK(task_runner_->BelongsToCurrentThread());
313 CHECK_EQ(type_, AUDIO);
314 return audio_config_;
317 VideoDecoderConfig FFmpegDemuxerStream::video_decoder_config() {
318 DCHECK(task_runner_->BelongsToCurrentThread());
319 CHECK_EQ(type_, VIDEO);
320 return video_config_;
323 FFmpegDemuxerStream::~FFmpegDemuxerStream() {
325 DCHECK(read_cb_.is_null());
326 DCHECK(buffer_queue_.IsEmpty());
329 base::TimeDelta FFmpegDemuxerStream::GetElapsedTime() const {
330 return ConvertStreamTimestamp(stream_->time_base, stream_->cur_dts);
333 Ranges<base::TimeDelta> FFmpegDemuxerStream::GetBufferedRanges() const {
334 return buffered_ranges_;
337 void FFmpegDemuxerStream::SatisfyPendingRead() {
338 DCHECK(task_runner_->BelongsToCurrentThread());
339 if (!read_cb_.is_null()) {
340 if (!buffer_queue_.IsEmpty()) {
341 base::ResetAndReturn(&read_cb_).Run(
342 DemuxerStream::kOk, buffer_queue_.Pop());
343 } else if (end_of_stream_) {
344 base::ResetAndReturn(&read_cb_).Run(
345 DemuxerStream::kOk, DecoderBuffer::CreateEOSBuffer());
349 // Have capacity? Ask for more!
350 if (HasAvailableCapacity() && !end_of_stream_) {
351 demuxer_->NotifyCapacityAvailable();
355 bool FFmpegDemuxerStream::HasAvailableCapacity() {
356 // TODO(scherkus): Remove this return and reenable time-based capacity
357 // after our data sources support canceling/concurrent reads, see
358 // http://crbug.com/165762 for details.
360 return !read_cb_.is_null();
362 // Try to have one second's worth of encoded data per stream.
363 const base::TimeDelta kCapacity = base::TimeDelta::FromSeconds(1);
364 return buffer_queue_.IsEmpty() || buffer_queue_.Duration() < kCapacity;
368 size_t FFmpegDemuxerStream::MemoryUsage() const {
369 return buffer_queue_.data_size();
372 TextKind FFmpegDemuxerStream::GetTextKind() const {
373 DCHECK_EQ(type_, DemuxerStream::TEXT);
375 if (stream_->disposition & AV_DISPOSITION_CAPTIONS)
376 return kTextCaptions;
378 if (stream_->disposition & AV_DISPOSITION_DESCRIPTIONS)
379 return kTextDescriptions;
381 if (stream_->disposition & AV_DISPOSITION_METADATA)
382 return kTextMetadata;
384 return kTextSubtitles;
387 std::string FFmpegDemuxerStream::GetMetadata(const char* key) const {
388 const AVDictionaryEntry* entry =
389 av_dict_get(stream_->metadata, key, NULL, 0);
390 return (entry == NULL || entry->value == NULL) ? "" : entry->value;
394 base::TimeDelta FFmpegDemuxerStream::ConvertStreamTimestamp(
395 const AVRational& time_base, int64 timestamp) {
396 if (timestamp == static_cast<int64>(AV_NOPTS_VALUE))
397 return kNoTimestamp();
399 return ConvertFromTimeBase(time_base, timestamp);
405 FFmpegDemuxer::FFmpegDemuxer(
406 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
407 DataSource* data_source,
408 const NeedKeyCB& need_key_cb,
409 const scoped_refptr<MediaLog>& media_log)
411 task_runner_(task_runner),
412 blocking_thread_("FFmpegDemuxer"),
413 pending_read_(false),
414 pending_seek_(false),
415 data_source_(data_source),
416 media_log_(media_log),
418 start_time_(kNoTimestamp()),
419 liveness_(LIVENESS_UNKNOWN),
420 text_enabled_(false),
421 duration_known_(false),
422 need_key_cb_(need_key_cb),
423 weak_factory_(this) {
424 DCHECK(task_runner_.get());
425 DCHECK(data_source_);
428 FFmpegDemuxer::~FFmpegDemuxer() {}
430 void FFmpegDemuxer::Stop(const base::Closure& callback) {
431 DCHECK(task_runner_->BelongsToCurrentThread());
432 url_protocol_->Abort();
434 BindToCurrentLoop(base::Bind(&FFmpegDemuxer::OnDataSourceStopped,
435 weak_factory_.GetWeakPtr(),
436 BindToCurrentLoop(callback))));
440 void FFmpegDemuxer::Seek(base::TimeDelta time, const PipelineStatusCB& cb) {
441 DCHECK(task_runner_->BelongsToCurrentThread());
442 CHECK(!pending_seek_);
444 // TODO(scherkus): Inspect |pending_read_| and cancel IO via |blocking_url_|,
445 // otherwise we can end up waiting for a pre-seek read to complete even though
446 // we know we're going to drop it on the floor.
448 // Always seek to a timestamp less than or equal to the desired timestamp.
449 int flags = AVSEEK_FLAG_BACKWARD;
451 // Passing -1 as our stream index lets FFmpeg pick a default stream. FFmpeg
452 // will attempt to use the lowest-index video stream, if present, followed by
453 // the lowest-index audio stream.
454 pending_seek_ = true;
455 base::PostTaskAndReplyWithResult(
456 blocking_thread_.message_loop_proxy().get(),
458 base::Bind(&av_seek_frame,
459 glue_->format_context(),
461 time.InMicroseconds(),
464 &FFmpegDemuxer::OnSeekFrameDone, weak_factory_.GetWeakPtr(), cb));
467 void FFmpegDemuxer::Initialize(DemuxerHost* host,
468 const PipelineStatusCB& status_cb,
469 bool enable_text_tracks) {
470 DCHECK(task_runner_->BelongsToCurrentThread());
472 text_enabled_ = enable_text_tracks;
474 url_protocol_.reset(new BlockingUrlProtocol(data_source_, BindToCurrentLoop(
475 base::Bind(&FFmpegDemuxer::OnDataSourceError, base::Unretained(this)))));
476 glue_.reset(new FFmpegGlue(url_protocol_.get()));
477 AVFormatContext* format_context = glue_->format_context();
479 // Disable ID3v1 tag reading to avoid costly seeks to end of file for data we
480 // don't use. FFmpeg will only read ID3v1 tags if no other metadata is
481 // available, so add a metadata entry to ensure some is always present.
482 av_dict_set(&format_context->metadata, "skip_id3v1_tags", "", 0);
484 // Open the AVFormatContext using our glue layer.
485 CHECK(blocking_thread_.Start());
486 base::PostTaskAndReplyWithResult(
487 blocking_thread_.message_loop_proxy().get(),
489 base::Bind(&FFmpegGlue::OpenContext, base::Unretained(glue_.get())),
490 base::Bind(&FFmpegDemuxer::OnOpenContextDone,
491 weak_factory_.GetWeakPtr(),
495 DemuxerStream* FFmpegDemuxer::GetStream(DemuxerStream::Type type) {
496 DCHECK(task_runner_->BelongsToCurrentThread());
497 return GetFFmpegStream(type);
500 FFmpegDemuxerStream* FFmpegDemuxer::GetFFmpegStream(
501 DemuxerStream::Type type) const {
502 StreamVector::const_iterator iter;
503 for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
504 if (*iter && (*iter)->type() == type) {
511 base::TimeDelta FFmpegDemuxer::GetStartTime() const {
512 DCHECK(task_runner_->BelongsToCurrentThread());
516 base::Time FFmpegDemuxer::GetTimelineOffset() const {
517 return timeline_offset_;
520 Demuxer::Liveness FFmpegDemuxer::GetLiveness() const {
521 DCHECK(task_runner_->BelongsToCurrentThread());
525 void FFmpegDemuxer::AddTextStreams() {
526 DCHECK(task_runner_->BelongsToCurrentThread());
528 for (StreamVector::size_type idx = 0; idx < streams_.size(); ++idx) {
529 FFmpegDemuxerStream* stream = streams_[idx];
530 if (stream == NULL || stream->type() != DemuxerStream::TEXT)
533 TextKind kind = stream->GetTextKind();
534 std::string title = stream->GetMetadata("title");
535 std::string language = stream->GetMetadata("language");
537 // TODO: Implement "id" metadata in FFMPEG.
538 // See: http://crbug.com/323183
539 host_->AddTextStream(stream, TextTrackConfig(kind, title, language,
544 // Helper for calculating the bitrate of the media based on information stored
545 // in |format_context| or failing that the size and duration of the media.
547 // Returns 0 if a bitrate could not be determined.
548 static int CalculateBitrate(
549 AVFormatContext* format_context,
550 const base::TimeDelta& duration,
551 int64 filesize_in_bytes) {
552 // If there is a bitrate set on the container, use it.
553 if (format_context->bit_rate > 0)
554 return format_context->bit_rate;
556 // Then try to sum the bitrates individually per stream.
558 for (size_t i = 0; i < format_context->nb_streams; ++i) {
559 AVCodecContext* codec_context = format_context->streams[i]->codec;
560 bitrate += codec_context->bit_rate;
565 // See if we can approximate the bitrate as long as we have a filesize and
567 if (duration.InMicroseconds() <= 0 ||
568 duration == kInfiniteDuration() ||
569 filesize_in_bytes == 0) {
573 // Do math in floating point as we'd overflow an int64 if the filesize was
574 // larger than ~1073GB.
575 double bytes = filesize_in_bytes;
576 double duration_us = duration.InMicroseconds();
577 return bytes * 8000000.0 / duration_us;
580 void FFmpegDemuxer::OnOpenContextDone(const PipelineStatusCB& status_cb,
582 DCHECK(task_runner_->BelongsToCurrentThread());
583 if (!blocking_thread_.IsRunning()) {
584 status_cb.Run(PIPELINE_ERROR_ABORT);
589 status_cb.Run(DEMUXER_ERROR_COULD_NOT_OPEN);
593 // Fully initialize AVFormatContext by parsing the stream a little.
594 base::PostTaskAndReplyWithResult(
595 blocking_thread_.message_loop_proxy().get(),
597 base::Bind(&avformat_find_stream_info,
598 glue_->format_context(),
599 static_cast<AVDictionary**>(NULL)),
600 base::Bind(&FFmpegDemuxer::OnFindStreamInfoDone,
601 weak_factory_.GetWeakPtr(),
605 void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb,
607 DCHECK(task_runner_->BelongsToCurrentThread());
608 if (!blocking_thread_.IsRunning() || !data_source_) {
609 status_cb.Run(PIPELINE_ERROR_ABORT);
614 status_cb.Run(DEMUXER_ERROR_COULD_NOT_PARSE);
618 // Create demuxer stream entries for each possible AVStream. Each stream
619 // is examined to determine if it is supported or not (is the codec enabled
620 // for it in this release?). Unsupported streams are skipped, allowing for
621 // partial playback. At least one audio or video stream must be playable.
622 AVFormatContext* format_context = glue_->format_context();
623 streams_.resize(format_context->nb_streams);
625 AVStream* audio_stream = NULL;
626 AudioDecoderConfig audio_config;
628 AVStream* video_stream = NULL;
629 VideoDecoderConfig video_config;
631 base::TimeDelta max_duration;
632 for (size_t i = 0; i < format_context->nb_streams; ++i) {
633 AVStream* stream = format_context->streams[i];
634 AVCodecContext* codec_context = stream->codec;
635 AVMediaType codec_type = codec_context->codec_type;
637 if (codec_type == AVMEDIA_TYPE_AUDIO) {
641 // Log the codec detected, whether it is supported or not.
642 UMA_HISTOGRAM_SPARSE_SLOWLY("Media.DetectedAudioCodec",
643 codec_context->codec_id);
644 // Ensure the codec is supported. IsValidConfig() also checks that the
645 // channel layout and sample format are valid.
646 AVStreamToAudioDecoderConfig(stream, &audio_config, false);
647 if (!audio_config.IsValidConfig())
649 audio_stream = stream;
650 } else if (codec_type == AVMEDIA_TYPE_VIDEO) {
654 // Log the codec detected, whether it is supported or not.
655 UMA_HISTOGRAM_SPARSE_SLOWLY("Media.DetectedVideoCodec",
656 codec_context->codec_id);
657 // Ensure the codec is supported. IsValidConfig() also checks that the
658 // frame size and visible size are valid.
659 AVStreamToVideoDecoderConfig(stream, &video_config, false);
661 if (!video_config.IsValidConfig())
663 video_stream = stream;
664 } else if (codec_type == AVMEDIA_TYPE_SUBTITLE) {
665 if (codec_context->codec_id != AV_CODEC_ID_WEBVTT || !text_enabled_) {
672 streams_[i] = new FFmpegDemuxerStream(this, stream);
673 max_duration = std::max(max_duration, streams_[i]->duration());
675 if (stream->first_dts != static_cast<int64_t>(AV_NOPTS_VALUE)) {
676 const base::TimeDelta first_dts = ConvertFromTimeBase(
677 stream->time_base, stream->first_dts);
678 if (start_time_ == kNoTimestamp() || first_dts < start_time_)
679 start_time_ = first_dts;
683 if (!audio_stream && !video_stream) {
684 status_cb.Run(DEMUXER_ERROR_NO_SUPPORTED_STREAMS);
691 if (format_context->duration != static_cast<int64_t>(AV_NOPTS_VALUE)) {
692 // If there is a duration value in the container use that to find the
693 // maximum between it and the duration from A/V streams.
694 const AVRational av_time_base = {1, AV_TIME_BASE};
696 std::max(max_duration,
697 ConvertFromTimeBase(av_time_base, format_context->duration));
699 // The duration is unknown, in which case this is likely a live stream.
700 max_duration = kInfiniteDuration();
703 // Some demuxers, like WAV, do not put timestamps on their frames. We
704 // assume the the start time is 0.
705 if (start_time_ == kNoTimestamp())
706 start_time_ = base::TimeDelta();
708 // MPEG-4 B-frames cause grief for a simple container like AVI. Enable PTS
709 // generation so we always get timestamps, see http://crbug.com/169570
710 if (strcmp(format_context->iformat->name, "avi") == 0)
711 format_context->flags |= AVFMT_FLAG_GENPTS;
713 timeline_offset_ = ExtractTimelineOffset(format_context);
715 if (max_duration == kInfiniteDuration() && !timeline_offset_.is_null()) {
716 liveness_ = LIVENESS_LIVE;
717 } else if (max_duration != kInfiniteDuration()) {
718 liveness_ = LIVENESS_RECORDED;
720 liveness_ = LIVENESS_UNKNOWN;
723 // Good to go: set the duration and bitrate and notify we're done
725 host_->SetDuration(max_duration);
726 duration_known_ = (max_duration != kInfiniteDuration());
728 int64 filesize_in_bytes = 0;
729 url_protocol_->GetSize(&filesize_in_bytes);
730 bitrate_ = CalculateBitrate(format_context, max_duration, filesize_in_bytes);
732 data_source_->SetBitrate(bitrate_);
736 AVCodecContext* audio_codec = audio_stream->codec;
737 media_log_->SetBooleanProperty("found_audio_stream", true);
739 SampleFormat sample_format = audio_config.sample_format();
740 std::string sample_name = SampleFormatToString(sample_format);
742 media_log_->SetStringProperty("audio_sample_format", sample_name);
744 AVCodec* codec = avcodec_find_decoder(audio_codec->codec_id);
746 media_log_->SetStringProperty("audio_codec_name", codec->name);
749 media_log_->SetIntegerProperty("audio_channels_count",
750 audio_codec->channels);
751 media_log_->SetIntegerProperty("audio_samples_per_second",
752 audio_config.samples_per_second());
754 media_log_->SetBooleanProperty("found_audio_stream", false);
759 AVCodecContext* video_codec = video_stream->codec;
760 media_log_->SetBooleanProperty("found_video_stream", true);
762 AVCodec* codec = avcodec_find_decoder(video_codec->codec_id);
764 media_log_->SetStringProperty("video_codec_name", codec->name);
767 media_log_->SetIntegerProperty("width", video_codec->width);
768 media_log_->SetIntegerProperty("height", video_codec->height);
769 media_log_->SetIntegerProperty("coded_width",
770 video_codec->coded_width);
771 media_log_->SetIntegerProperty("coded_height",
772 video_codec->coded_height);
773 media_log_->SetStringProperty(
775 base::StringPrintf("%d/%d",
776 video_codec->time_base.num,
777 video_codec->time_base.den));
778 media_log_->SetStringProperty(
779 "video_format", VideoFrame::FormatToString(video_config.format()));
780 media_log_->SetBooleanProperty("video_is_encrypted",
781 video_config.is_encrypted());
783 media_log_->SetBooleanProperty("found_video_stream", false);
787 media_log_->SetTimeProperty("max_duration", max_duration);
788 media_log_->SetTimeProperty("start_time", start_time_);
789 media_log_->SetIntegerProperty("bitrate", bitrate_);
791 status_cb.Run(PIPELINE_OK);
794 void FFmpegDemuxer::OnSeekFrameDone(const PipelineStatusCB& cb, int result) {
795 DCHECK(task_runner_->BelongsToCurrentThread());
796 CHECK(pending_seek_);
797 pending_seek_ = false;
799 if (!blocking_thread_.IsRunning()) {
800 cb.Run(PIPELINE_ERROR_ABORT);
805 // Use VLOG(1) instead of NOTIMPLEMENTED() to prevent the message being
806 // captured from stdout and contaminates testing.
807 // TODO(scherkus): Implement this properly and signal error (BUG=23447).
808 VLOG(1) << "Not implemented";
811 // Tell streams to flush buffers due to seeking.
812 StreamVector::iterator iter;
813 for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
815 (*iter)->FlushBuffers();
818 // Resume reading until capacity.
821 // Notify we're finished seeking.
825 void FFmpegDemuxer::ReadFrameIfNeeded() {
826 DCHECK(task_runner_->BelongsToCurrentThread());
828 // Make sure we have work to do before reading.
829 if (!blocking_thread_.IsRunning() || !StreamsHaveAvailableCapacity() ||
830 pending_read_ || pending_seek_) {
834 // Allocate and read an AVPacket from the media. Save |packet_ptr| since
835 // evaluation order of packet.get() and base::Passed(&packet) is
837 ScopedAVPacket packet(new AVPacket());
838 AVPacket* packet_ptr = packet.get();
840 pending_read_ = true;
841 base::PostTaskAndReplyWithResult(
842 blocking_thread_.message_loop_proxy().get(),
844 base::Bind(&av_read_frame, glue_->format_context(), packet_ptr),
845 base::Bind(&FFmpegDemuxer::OnReadFrameDone,
846 weak_factory_.GetWeakPtr(),
847 base::Passed(&packet)));
850 void FFmpegDemuxer::OnReadFrameDone(ScopedAVPacket packet, int result) {
851 DCHECK(task_runner_->BelongsToCurrentThread());
852 DCHECK(pending_read_);
853 pending_read_ = false;
855 if (!blocking_thread_.IsRunning() || pending_seek_) {
859 // Consider the stream as ended if:
860 // - either underlying ffmpeg returned an error
861 // - or FFMpegDemuxer reached the maximum allowed memory usage.
862 if (result < 0 || IsMaxMemoryUsageReached()) {
863 // Update the duration based on the highest elapsed time across all streams
864 // if it was previously unknown.
865 if (!duration_known_) {
866 base::TimeDelta max_duration;
868 for (StreamVector::iterator iter = streams_.begin();
869 iter != streams_.end();
874 base::TimeDelta duration = (*iter)->GetElapsedTime();
875 if (duration != kNoTimestamp() && duration > max_duration)
876 max_duration = duration;
879 if (max_duration > base::TimeDelta()) {
880 host_->SetDuration(max_duration);
881 duration_known_ = true;
884 // If we have reached the end of stream, tell the downstream filters about
890 // Queue the packet with the appropriate stream.
891 DCHECK_GE(packet->stream_index, 0);
892 DCHECK_LT(packet->stream_index, static_cast<int>(streams_.size()));
894 // Defend against ffmpeg giving us a bad stream index.
895 if (packet->stream_index >= 0 &&
896 packet->stream_index < static_cast<int>(streams_.size()) &&
897 streams_[packet->stream_index]) {
898 // TODO(scherkus): Fix demuxing upstream to never return packets w/o data
899 // when av_read_frame() returns success code. See bug comment for ideas:
901 // https://code.google.com/p/chromium/issues/detail?id=169133#c10
903 ScopedAVPacket new_packet(new AVPacket());
904 av_new_packet(new_packet.get(), 0);
905 av_packet_copy_props(new_packet.get(), packet.get());
906 packet.swap(new_packet);
909 // Special case for opus in ogg. FFmpeg is pre-trimming the codec delay
910 // from the packet timestamp. Chrome expects to handle this itself inside
911 // the decoder, so shift timestamps by the delay in this case.
912 // TODO(dalecurtis): Try to get fixed upstream. See http://crbug.com/328207
913 if (strcmp(glue_->format_context()->iformat->name, "ogg") == 0) {
914 const AVCodecContext* codec_context =
915 glue_->format_context()->streams[packet->stream_index]->codec;
916 if (codec_context->codec_id == AV_CODEC_ID_OPUS &&
917 codec_context->delay > 0) {
918 packet->pts += codec_context->delay;
922 FFmpegDemuxerStream* demuxer_stream = streams_[packet->stream_index];
923 demuxer_stream->EnqueuePacket(packet.Pass());
926 // Keep reading until we've reached capacity.
930 void FFmpegDemuxer::OnDataSourceStopped(const base::Closure& callback) {
931 // This will block until all tasks complete. Note that after this returns it's
932 // possible for reply tasks (e.g., OnReadFrameDone()) to be queued on this
933 // thread. Each of the reply task methods must check whether we've stopped the
934 // thread and drop their results on the floor.
935 DCHECK(task_runner_->BelongsToCurrentThread());
936 blocking_thread_.Stop();
938 StreamVector::iterator iter;
939 for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
947 bool FFmpegDemuxer::StreamsHaveAvailableCapacity() {
948 DCHECK(task_runner_->BelongsToCurrentThread());
949 StreamVector::iterator iter;
950 for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
951 if (*iter && (*iter)->HasAvailableCapacity()) {
958 bool FFmpegDemuxer::IsMaxMemoryUsageReached() const {
959 DCHECK(task_runner_->BelongsToCurrentThread());
961 // Max allowed memory usage, all streams combined.
962 const size_t kDemuxerMemoryLimit = 150 * 1024 * 1024;
964 size_t memory_left = kDemuxerMemoryLimit;
965 for (StreamVector::const_iterator iter = streams_.begin();
966 iter != streams_.end(); ++iter) {
970 size_t stream_memory_usage = (*iter)->MemoryUsage();
971 if (stream_memory_usage > memory_left)
973 memory_left -= stream_memory_usage;
978 void FFmpegDemuxer::StreamHasEnded() {
979 DCHECK(task_runner_->BelongsToCurrentThread());
980 StreamVector::iterator iter;
981 for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
984 (*iter)->SetEndOfStream();
988 void FFmpegDemuxer::FireNeedKey(const std::string& init_data_type,
989 const std::string& encryption_key_id) {
990 std::vector<uint8> key_id_local(encryption_key_id.begin(),
991 encryption_key_id.end());
992 need_key_cb_.Run(init_data_type, key_id_local);
995 void FFmpegDemuxer::NotifyCapacityAvailable() {
996 DCHECK(task_runner_->BelongsToCurrentThread());
1000 void FFmpegDemuxer::NotifyBufferingChanged() {
1001 DCHECK(task_runner_->BelongsToCurrentThread());
1002 Ranges<base::TimeDelta> buffered;
1003 FFmpegDemuxerStream* audio = GetFFmpegStream(DemuxerStream::AUDIO);
1004 FFmpegDemuxerStream* video = GetFFmpegStream(DemuxerStream::VIDEO);
1005 if (audio && video) {
1006 buffered = audio->GetBufferedRanges().IntersectionWith(
1007 video->GetBufferedRanges());
1009 buffered = audio->GetBufferedRanges();
1011 buffered = video->GetBufferedRanges();
1013 for (size_t i = 0; i < buffered.size(); ++i)
1014 host_->AddBufferedTimeRange(buffered.start(i), buffered.end(i));
1017 void FFmpegDemuxer::OnDataSourceError() {
1018 host_->OnDemuxerError(PIPELINE_ERROR_READ);
1021 } // namespace media