Support for unpacked ARM packed relocations.
[chromium-blink-merge.git] / media / filters / ffmpeg_demuxer.cc
blob92c438ea3a7dfea48b5674c50fccf4014aba73a9
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"
7 #include <algorithm>
8 #include <string>
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"
35 namespace media {
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;
50 return base::Time();
53 static base::TimeDelta FramesToTimeDelta(int frames, double sample_rate) {
54 return base::TimeDelta::FromMicroseconds(
55 frames * base::Time::kMicrosecondsPerSecond / sample_rate);
58 static base::TimeDelta ExtractStartTime(AVStream* stream,
59 base::TimeDelta start_time_estimate) {
60 DCHECK(start_time_estimate != kNoTimestamp());
61 if (stream->start_time == static_cast<int64_t>(AV_NOPTS_VALUE)) {
62 return start_time_estimate == kInfiniteDuration() ? kNoTimestamp()
63 : start_time_estimate;
66 // First try the lower of the estimate and the |start_time| value.
67 base::TimeDelta start_time =
68 std::min(ConvertFromTimeBase(stream->time_base, stream->start_time),
69 start_time_estimate);
71 // Next see if the first buffered pts value is usable.
72 if (stream->pts_buffer[0] != static_cast<int64_t>(AV_NOPTS_VALUE)) {
73 const base::TimeDelta buffered_pts =
74 ConvertFromTimeBase(stream->time_base, stream->pts_buffer[0]);
75 if (buffered_pts < start_time)
76 start_time = buffered_pts;
79 // NOTE: Do not use AVStream->first_dts since |start_time| should be a
80 // presentation timestamp.
81 return start_time;
85 // FFmpegDemuxerStream
87 FFmpegDemuxerStream::FFmpegDemuxerStream(
88 FFmpegDemuxer* demuxer,
89 AVStream* stream,
90 bool discard_negative_timestamps)
91 : demuxer_(demuxer),
92 task_runner_(base::MessageLoopProxy::current()),
93 stream_(stream),
94 type_(UNKNOWN),
95 end_of_stream_(false),
96 last_packet_timestamp_(kNoTimestamp()),
97 bitstream_converter_enabled_(false),
98 discard_negative_timestamps_(discard_negative_timestamps) {
99 DCHECK(demuxer_);
101 bool is_encrypted = false;
103 // Determine our media format.
104 switch (stream->codec->codec_type) {
105 case AVMEDIA_TYPE_AUDIO:
106 type_ = AUDIO;
107 AVStreamToAudioDecoderConfig(stream, &audio_config_, true);
108 is_encrypted = audio_config_.is_encrypted();
109 break;
110 case AVMEDIA_TYPE_VIDEO:
111 type_ = VIDEO;
112 AVStreamToVideoDecoderConfig(stream, &video_config_, true);
113 is_encrypted = video_config_.is_encrypted();
114 break;
115 case AVMEDIA_TYPE_SUBTITLE:
116 type_ = TEXT;
117 break;
118 default:
119 NOTREACHED();
120 break;
123 // Calculate the duration.
124 duration_ = ConvertStreamTimestamp(stream->time_base, stream->duration);
126 #if defined(USE_PROPRIETARY_CODECS)
127 if (stream_->codec->codec_id == AV_CODEC_ID_H264) {
128 bitstream_converter_.reset(
129 new FFmpegH264ToAnnexBBitstreamConverter(stream_->codec));
131 #endif
133 if (is_encrypted) {
134 AVDictionaryEntry* key = av_dict_get(stream->metadata, "enc_key_id", NULL,
136 DCHECK(key);
137 DCHECK(key->value);
138 if (!key || !key->value)
139 return;
140 base::StringPiece base64_key_id(key->value);
141 std::string enc_key_id;
142 base::Base64Decode(base64_key_id, &enc_key_id);
143 DCHECK(!enc_key_id.empty());
144 if (enc_key_id.empty())
145 return;
147 encryption_key_id_.assign(enc_key_id);
148 demuxer_->FireNeedKey(kWebMEncryptInitDataType, enc_key_id);
152 void FFmpegDemuxerStream::EnqueuePacket(ScopedAVPacket packet) {
153 DCHECK(task_runner_->BelongsToCurrentThread());
155 if (!demuxer_ || end_of_stream_) {
156 NOTREACHED() << "Attempted to enqueue packet on a stopped stream";
157 return;
160 #if defined(USE_PROPRIETARY_CODECS)
161 // Convert the packet if there is a bitstream filter.
162 if (packet->data && bitstream_converter_enabled_ &&
163 !bitstream_converter_->ConvertPacket(packet.get())) {
164 LOG(ERROR) << "Format conversion failed.";
166 #endif
168 // Get side data if any. For now, the only type of side_data is VP8 Alpha. We
169 // keep this generic so that other side_data types in the future can be
170 // handled the same way as well.
171 av_packet_split_side_data(packet.get());
173 scoped_refptr<DecoderBuffer> buffer;
175 if (type() == DemuxerStream::TEXT) {
176 int id_size = 0;
177 uint8* id_data = av_packet_get_side_data(
178 packet.get(),
179 AV_PKT_DATA_WEBVTT_IDENTIFIER,
180 &id_size);
182 int settings_size = 0;
183 uint8* settings_data = av_packet_get_side_data(
184 packet.get(),
185 AV_PKT_DATA_WEBVTT_SETTINGS,
186 &settings_size);
188 std::vector<uint8> side_data;
189 MakeSideData(id_data, id_data + id_size,
190 settings_data, settings_data + settings_size,
191 &side_data);
193 buffer = DecoderBuffer::CopyFrom(packet.get()->data, packet.get()->size,
194 side_data.data(), side_data.size());
195 } else {
196 int side_data_size = 0;
197 uint8* side_data = av_packet_get_side_data(
198 packet.get(),
199 AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL,
200 &side_data_size);
202 scoped_ptr<DecryptConfig> decrypt_config;
203 int data_offset = 0;
204 if ((type() == DemuxerStream::AUDIO && audio_config_.is_encrypted()) ||
205 (type() == DemuxerStream::VIDEO && video_config_.is_encrypted())) {
206 if (!WebMCreateDecryptConfig(
207 packet->data, packet->size,
208 reinterpret_cast<const uint8*>(encryption_key_id_.data()),
209 encryption_key_id_.size(),
210 &decrypt_config,
211 &data_offset)) {
212 LOG(ERROR) << "Creation of DecryptConfig failed.";
216 // If a packet is returned by FFmpeg's av_parser_parse2() the packet will
217 // reference inner memory of FFmpeg. As such we should transfer the packet
218 // into memory we control.
219 if (side_data_size > 0) {
220 buffer = DecoderBuffer::CopyFrom(packet.get()->data + data_offset,
221 packet.get()->size - data_offset,
222 side_data, side_data_size);
223 } else {
224 buffer = DecoderBuffer::CopyFrom(packet.get()->data + data_offset,
225 packet.get()->size - data_offset);
228 int skip_samples_size = 0;
229 const uint32* skip_samples_ptr =
230 reinterpret_cast<const uint32*>(av_packet_get_side_data(
231 packet.get(), AV_PKT_DATA_SKIP_SAMPLES, &skip_samples_size));
232 const int kSkipSamplesValidSize = 10;
233 const int kSkipEndSamplesOffset = 1;
234 if (skip_samples_size >= kSkipSamplesValidSize) {
235 // Because FFmpeg rolls codec delay and skip samples into one we can only
236 // allow front discard padding on the first buffer. Otherwise the discard
237 // helper can't figure out which data to discard. See AudioDiscardHelper.
238 int discard_front_samples = base::ByteSwapToLE32(*skip_samples_ptr);
239 if (last_packet_timestamp_ != kNoTimestamp()) {
240 DLOG(ERROR) << "Skip samples are only allowed for the first packet.";
241 discard_front_samples = 0;
244 const int discard_end_samples =
245 base::ByteSwapToLE32(*(skip_samples_ptr + kSkipEndSamplesOffset));
246 const int samples_per_second =
247 audio_decoder_config().samples_per_second();
248 buffer->set_discard_padding(std::make_pair(
249 FramesToTimeDelta(discard_front_samples, samples_per_second),
250 FramesToTimeDelta(discard_end_samples, samples_per_second)));
253 if (decrypt_config)
254 buffer->set_decrypt_config(decrypt_config.Pass());
257 buffer->set_duration(
258 ConvertStreamTimestamp(stream_->time_base, packet->duration));
260 // Note: If pts is AV_NOPTS_VALUE, stream_timestamp will be kNoTimestamp().
261 const base::TimeDelta stream_timestamp =
262 ConvertStreamTimestamp(stream_->time_base, packet->pts);
264 if (stream_timestamp != kNoTimestamp()) {
265 buffer->set_timestamp(stream_timestamp - demuxer_->start_time());
267 // If enabled, mark packets with negative timestamps for post-decode
268 // discard.
269 if (discard_negative_timestamps_ && stream_timestamp < base::TimeDelta()) {
270 if (stream_timestamp + buffer->duration() < base::TimeDelta()) {
271 // Discard the entire packet if it's entirely before zero.
272 buffer->set_discard_padding(
273 std::make_pair(kInfiniteDuration(), base::TimeDelta()));
274 } else {
275 // Only discard part of the frame if it overlaps zero.
276 buffer->set_discard_padding(
277 std::make_pair(-stream_timestamp, base::TimeDelta()));
281 if (last_packet_timestamp_ != kNoTimestamp() &&
282 last_packet_timestamp_ < buffer->timestamp()) {
283 buffered_ranges_.Add(last_packet_timestamp_, buffer->timestamp());
284 demuxer_->NotifyBufferingChanged();
287 // The demuxer should always output positive timestamps.
288 DCHECK(buffer->timestamp() >= base::TimeDelta());
289 } else {
290 buffer->set_timestamp(kNoTimestamp());
293 // TODO(dalecurtis): This allows transitions from <valid ts> -> <no timestamp>
294 // which shouldn't be allowed. See http://crbug.com/384532
295 last_packet_timestamp_ = buffer->timestamp();
297 buffer_queue_.Push(buffer);
298 SatisfyPendingRead();
301 void FFmpegDemuxerStream::SetEndOfStream() {
302 DCHECK(task_runner_->BelongsToCurrentThread());
303 end_of_stream_ = true;
304 SatisfyPendingRead();
307 void FFmpegDemuxerStream::FlushBuffers() {
308 DCHECK(task_runner_->BelongsToCurrentThread());
309 DCHECK(read_cb_.is_null()) << "There should be no pending read";
310 buffer_queue_.Clear();
311 end_of_stream_ = false;
312 last_packet_timestamp_ = kNoTimestamp();
315 void FFmpegDemuxerStream::Stop() {
316 DCHECK(task_runner_->BelongsToCurrentThread());
317 buffer_queue_.Clear();
318 if (!read_cb_.is_null()) {
319 base::ResetAndReturn(&read_cb_).Run(
320 DemuxerStream::kOk, DecoderBuffer::CreateEOSBuffer());
322 demuxer_ = NULL;
323 stream_ = NULL;
324 end_of_stream_ = true;
327 DemuxerStream::Type FFmpegDemuxerStream::type() {
328 DCHECK(task_runner_->BelongsToCurrentThread());
329 return type_;
332 void FFmpegDemuxerStream::Read(const ReadCB& read_cb) {
333 DCHECK(task_runner_->BelongsToCurrentThread());
334 CHECK(read_cb_.is_null()) << "Overlapping reads are not supported";
335 read_cb_ = BindToCurrentLoop(read_cb);
337 // Don't accept any additional reads if we've been told to stop.
338 // The |demuxer_| may have been destroyed in the pipeline thread.
340 // TODO(scherkus): it would be cleaner to reply with an error message.
341 if (!demuxer_) {
342 base::ResetAndReturn(&read_cb_).Run(
343 DemuxerStream::kOk, DecoderBuffer::CreateEOSBuffer());
344 return;
347 SatisfyPendingRead();
350 void FFmpegDemuxerStream::EnableBitstreamConverter() {
351 DCHECK(task_runner_->BelongsToCurrentThread());
353 #if defined(USE_PROPRIETARY_CODECS)
354 CHECK(bitstream_converter_.get());
355 bitstream_converter_enabled_ = true;
356 #else
357 NOTREACHED() << "Proprietary codecs not enabled.";
358 #endif
361 bool FFmpegDemuxerStream::SupportsConfigChanges() { return false; }
363 AudioDecoderConfig FFmpegDemuxerStream::audio_decoder_config() {
364 DCHECK(task_runner_->BelongsToCurrentThread());
365 CHECK_EQ(type_, AUDIO);
366 return audio_config_;
369 VideoDecoderConfig FFmpegDemuxerStream::video_decoder_config() {
370 DCHECK(task_runner_->BelongsToCurrentThread());
371 CHECK_EQ(type_, VIDEO);
372 return video_config_;
375 FFmpegDemuxerStream::~FFmpegDemuxerStream() {
376 DCHECK(!demuxer_);
377 DCHECK(read_cb_.is_null());
378 DCHECK(buffer_queue_.IsEmpty());
381 base::TimeDelta FFmpegDemuxerStream::GetElapsedTime() const {
382 return ConvertStreamTimestamp(stream_->time_base, stream_->cur_dts);
385 Ranges<base::TimeDelta> FFmpegDemuxerStream::GetBufferedRanges() const {
386 return buffered_ranges_;
389 void FFmpegDemuxerStream::SatisfyPendingRead() {
390 DCHECK(task_runner_->BelongsToCurrentThread());
391 if (!read_cb_.is_null()) {
392 if (!buffer_queue_.IsEmpty()) {
393 base::ResetAndReturn(&read_cb_).Run(
394 DemuxerStream::kOk, buffer_queue_.Pop());
395 } else if (end_of_stream_) {
396 base::ResetAndReturn(&read_cb_).Run(
397 DemuxerStream::kOk, DecoderBuffer::CreateEOSBuffer());
401 // Have capacity? Ask for more!
402 if (HasAvailableCapacity() && !end_of_stream_) {
403 demuxer_->NotifyCapacityAvailable();
407 bool FFmpegDemuxerStream::HasAvailableCapacity() {
408 // TODO(scherkus): Remove this return and reenable time-based capacity
409 // after our data sources support canceling/concurrent reads, see
410 // http://crbug.com/165762 for details.
411 #if 1
412 return !read_cb_.is_null();
413 #else
414 // Try to have one second's worth of encoded data per stream.
415 const base::TimeDelta kCapacity = base::TimeDelta::FromSeconds(1);
416 return buffer_queue_.IsEmpty() || buffer_queue_.Duration() < kCapacity;
417 #endif
420 size_t FFmpegDemuxerStream::MemoryUsage() const {
421 return buffer_queue_.data_size();
424 TextKind FFmpegDemuxerStream::GetTextKind() const {
425 DCHECK_EQ(type_, DemuxerStream::TEXT);
427 if (stream_->disposition & AV_DISPOSITION_CAPTIONS)
428 return kTextCaptions;
430 if (stream_->disposition & AV_DISPOSITION_DESCRIPTIONS)
431 return kTextDescriptions;
433 if (stream_->disposition & AV_DISPOSITION_METADATA)
434 return kTextMetadata;
436 return kTextSubtitles;
439 std::string FFmpegDemuxerStream::GetMetadata(const char* key) const {
440 const AVDictionaryEntry* entry =
441 av_dict_get(stream_->metadata, key, NULL, 0);
442 return (entry == NULL || entry->value == NULL) ? "" : entry->value;
445 // static
446 base::TimeDelta FFmpegDemuxerStream::ConvertStreamTimestamp(
447 const AVRational& time_base, int64 timestamp) {
448 if (timestamp == static_cast<int64>(AV_NOPTS_VALUE))
449 return kNoTimestamp();
451 return ConvertFromTimeBase(time_base, timestamp);
455 // FFmpegDemuxer
457 FFmpegDemuxer::FFmpegDemuxer(
458 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
459 DataSource* data_source,
460 const NeedKeyCB& need_key_cb,
461 const scoped_refptr<MediaLog>& media_log)
462 : host_(NULL),
463 task_runner_(task_runner),
464 blocking_thread_("FFmpegDemuxer"),
465 pending_read_(false),
466 pending_seek_(false),
467 data_source_(data_source),
468 media_log_(media_log),
469 bitrate_(0),
470 start_time_(kNoTimestamp()),
471 preferred_stream_for_seeking_(-1, kNoTimestamp()),
472 fallback_stream_for_seeking_(-1, kNoTimestamp()),
473 liveness_(LIVENESS_UNKNOWN),
474 text_enabled_(false),
475 duration_known_(false),
476 need_key_cb_(need_key_cb),
477 weak_factory_(this) {
478 DCHECK(task_runner_.get());
479 DCHECK(data_source_);
482 FFmpegDemuxer::~FFmpegDemuxer() {}
484 void FFmpegDemuxer::Stop(const base::Closure& callback) {
485 DCHECK(task_runner_->BelongsToCurrentThread());
486 url_protocol_->Abort();
487 data_source_->Stop(
488 BindToCurrentLoop(base::Bind(&FFmpegDemuxer::OnDataSourceStopped,
489 weak_factory_.GetWeakPtr(),
490 BindToCurrentLoop(callback))));
491 data_source_ = NULL;
494 void FFmpegDemuxer::Seek(base::TimeDelta time, const PipelineStatusCB& cb) {
495 DCHECK(task_runner_->BelongsToCurrentThread());
496 CHECK(!pending_seek_);
498 // TODO(scherkus): Inspect |pending_read_| and cancel IO via |blocking_url_|,
499 // otherwise we can end up waiting for a pre-seek read to complete even though
500 // we know we're going to drop it on the floor.
502 // FFmpeg requires seeks to be adjusted according to the lowest starting time.
503 const base::TimeDelta seek_time = time + start_time_;
505 // Choose the preferred stream if |seek_time| occurs after its starting time,
506 // otherwise use the fallback stream.
507 DCHECK(preferred_stream_for_seeking_.second != kNoTimestamp());
508 const int stream_index = seek_time >= preferred_stream_for_seeking_.second
509 ? preferred_stream_for_seeking_.first
510 : fallback_stream_for_seeking_.first;
511 DCHECK_NE(stream_index, -1);
513 const AVStream* seeking_stream =
514 glue_->format_context()->streams[stream_index];
516 pending_seek_ = true;
517 base::PostTaskAndReplyWithResult(
518 blocking_thread_.message_loop_proxy().get(),
519 FROM_HERE,
520 base::Bind(&av_seek_frame,
521 glue_->format_context(),
522 seeking_stream->index,
523 ConvertToTimeBase(seeking_stream->time_base, seek_time),
524 // Always seek to a timestamp <= to the desired timestamp.
525 AVSEEK_FLAG_BACKWARD),
526 base::Bind(
527 &FFmpegDemuxer::OnSeekFrameDone, weak_factory_.GetWeakPtr(), cb));
530 void FFmpegDemuxer::Initialize(DemuxerHost* host,
531 const PipelineStatusCB& status_cb,
532 bool enable_text_tracks) {
533 DCHECK(task_runner_->BelongsToCurrentThread());
534 host_ = host;
535 text_enabled_ = enable_text_tracks;
537 url_protocol_.reset(new BlockingUrlProtocol(data_source_, BindToCurrentLoop(
538 base::Bind(&FFmpegDemuxer::OnDataSourceError, base::Unretained(this)))));
539 glue_.reset(new FFmpegGlue(url_protocol_.get()));
540 AVFormatContext* format_context = glue_->format_context();
542 // Disable ID3v1 tag reading to avoid costly seeks to end of file for data we
543 // don't use. FFmpeg will only read ID3v1 tags if no other metadata is
544 // available, so add a metadata entry to ensure some is always present.
545 av_dict_set(&format_context->metadata, "skip_id3v1_tags", "", 0);
547 // Open the AVFormatContext using our glue layer.
548 CHECK(blocking_thread_.Start());
549 base::PostTaskAndReplyWithResult(
550 blocking_thread_.message_loop_proxy().get(),
551 FROM_HERE,
552 base::Bind(&FFmpegGlue::OpenContext, base::Unretained(glue_.get())),
553 base::Bind(&FFmpegDemuxer::OnOpenContextDone,
554 weak_factory_.GetWeakPtr(),
555 status_cb));
558 DemuxerStream* FFmpegDemuxer::GetStream(DemuxerStream::Type type) {
559 DCHECK(task_runner_->BelongsToCurrentThread());
560 return GetFFmpegStream(type);
563 FFmpegDemuxerStream* FFmpegDemuxer::GetFFmpegStream(
564 DemuxerStream::Type type) const {
565 StreamVector::const_iterator iter;
566 for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
567 if (*iter && (*iter)->type() == type) {
568 return *iter;
571 return NULL;
574 base::Time FFmpegDemuxer::GetTimelineOffset() const {
575 return timeline_offset_;
578 Demuxer::Liveness FFmpegDemuxer::GetLiveness() const {
579 DCHECK(task_runner_->BelongsToCurrentThread());
580 return liveness_;
583 void FFmpegDemuxer::AddTextStreams() {
584 DCHECK(task_runner_->BelongsToCurrentThread());
586 for (StreamVector::size_type idx = 0; idx < streams_.size(); ++idx) {
587 FFmpegDemuxerStream* stream = streams_[idx];
588 if (stream == NULL || stream->type() != DemuxerStream::TEXT)
589 continue;
591 TextKind kind = stream->GetTextKind();
592 std::string title = stream->GetMetadata("title");
593 std::string language = stream->GetMetadata("language");
595 // TODO: Implement "id" metadata in FFMPEG.
596 // See: http://crbug.com/323183
597 host_->AddTextStream(stream, TextTrackConfig(kind, title, language,
598 std::string()));
602 // Helper for calculating the bitrate of the media based on information stored
603 // in |format_context| or failing that the size and duration of the media.
605 // Returns 0 if a bitrate could not be determined.
606 static int CalculateBitrate(
607 AVFormatContext* format_context,
608 const base::TimeDelta& duration,
609 int64 filesize_in_bytes) {
610 // If there is a bitrate set on the container, use it.
611 if (format_context->bit_rate > 0)
612 return format_context->bit_rate;
614 // Then try to sum the bitrates individually per stream.
615 int bitrate = 0;
616 for (size_t i = 0; i < format_context->nb_streams; ++i) {
617 AVCodecContext* codec_context = format_context->streams[i]->codec;
618 bitrate += codec_context->bit_rate;
620 if (bitrate > 0)
621 return bitrate;
623 // See if we can approximate the bitrate as long as we have a filesize and
624 // valid duration.
625 if (duration.InMicroseconds() <= 0 ||
626 duration == kInfiniteDuration() ||
627 filesize_in_bytes == 0) {
628 return 0;
631 // Do math in floating point as we'd overflow an int64 if the filesize was
632 // larger than ~1073GB.
633 double bytes = filesize_in_bytes;
634 double duration_us = duration.InMicroseconds();
635 return bytes * 8000000.0 / duration_us;
638 void FFmpegDemuxer::OnOpenContextDone(const PipelineStatusCB& status_cb,
639 bool result) {
640 DCHECK(task_runner_->BelongsToCurrentThread());
641 if (!blocking_thread_.IsRunning()) {
642 status_cb.Run(PIPELINE_ERROR_ABORT);
643 return;
646 if (!result) {
647 status_cb.Run(DEMUXER_ERROR_COULD_NOT_OPEN);
648 return;
651 // Fully initialize AVFormatContext by parsing the stream a little.
652 base::PostTaskAndReplyWithResult(
653 blocking_thread_.message_loop_proxy().get(),
654 FROM_HERE,
655 base::Bind(&avformat_find_stream_info,
656 glue_->format_context(),
657 static_cast<AVDictionary**>(NULL)),
658 base::Bind(&FFmpegDemuxer::OnFindStreamInfoDone,
659 weak_factory_.GetWeakPtr(),
660 status_cb));
663 void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb,
664 int result) {
665 DCHECK(task_runner_->BelongsToCurrentThread());
666 if (!blocking_thread_.IsRunning() || !data_source_) {
667 status_cb.Run(PIPELINE_ERROR_ABORT);
668 return;
671 if (result < 0) {
672 status_cb.Run(DEMUXER_ERROR_COULD_NOT_PARSE);
673 return;
676 // Create demuxer stream entries for each possible AVStream. Each stream
677 // is examined to determine if it is supported or not (is the codec enabled
678 // for it in this release?). Unsupported streams are skipped, allowing for
679 // partial playback. At least one audio or video stream must be playable.
680 AVFormatContext* format_context = glue_->format_context();
681 streams_.resize(format_context->nb_streams);
683 // Estimate the start time for each stream by looking through the packets
684 // buffered during avformat_find_stream_info(). These values will be
685 // considered later when determining the actual stream start time.
687 // These packets haven't been completely processed yet, so only look through
688 // these values if the AVFormatContext has a valid start time.
690 // If no estimate is found, the stream entry will be kInfiniteDuration().
691 std::vector<base::TimeDelta> start_time_estimates(format_context->nb_streams,
692 kInfiniteDuration());
693 if (format_context->packet_buffer &&
694 format_context->start_time != static_cast<int64>(AV_NOPTS_VALUE)) {
695 struct AVPacketList* packet_buffer = format_context->packet_buffer;
696 while (packet_buffer != format_context->packet_buffer_end) {
697 DCHECK_LT(static_cast<size_t>(packet_buffer->pkt.stream_index),
698 start_time_estimates.size());
699 const AVStream* stream =
700 format_context->streams[packet_buffer->pkt.stream_index];
701 if (packet_buffer->pkt.pts != static_cast<int64>(AV_NOPTS_VALUE)) {
702 const base::TimeDelta packet_pts =
703 ConvertFromTimeBase(stream->time_base, packet_buffer->pkt.pts);
704 if (packet_pts < start_time_estimates[stream->index])
705 start_time_estimates[stream->index] = packet_pts;
707 packet_buffer = packet_buffer->next;
711 AVStream* audio_stream = NULL;
712 AudioDecoderConfig audio_config;
714 AVStream* video_stream = NULL;
715 VideoDecoderConfig video_config;
717 // If available, |start_time_| will be set to the lowest stream start time.
718 start_time_ = kInfiniteDuration();
720 base::TimeDelta max_duration;
721 for (size_t i = 0; i < format_context->nb_streams; ++i) {
722 AVStream* stream = format_context->streams[i];
723 const AVCodecContext* codec_context = stream->codec;
724 const AVMediaType codec_type = codec_context->codec_type;
725 bool discard_negative_timestamps = false;
727 if (codec_type == AVMEDIA_TYPE_AUDIO) {
728 if (audio_stream)
729 continue;
731 // Log the codec detected, whether it is supported or not.
732 UMA_HISTOGRAM_SPARSE_SLOWLY("Media.DetectedAudioCodec",
733 codec_context->codec_id);
734 // Ensure the codec is supported. IsValidConfig() also checks that the
735 // channel layout and sample format are valid.
736 AVStreamToAudioDecoderConfig(stream, &audio_config, false);
737 if (!audio_config.IsValidConfig())
738 continue;
739 audio_stream = stream;
741 // Enable post-decode frame dropping for packets with negative timestamps
742 // as outlined in section A.2 in the Ogg Vorbis spec:
743 // http://xiph.org/vorbis/doc/Vorbis_I_spec.html
744 discard_negative_timestamps =
745 audio_config.codec() == kCodecVorbis &&
746 strcmp(glue_->format_context()->iformat->name, "ogg") == 0;
747 } else if (codec_type == AVMEDIA_TYPE_VIDEO) {
748 if (video_stream)
749 continue;
751 // Log the codec detected, whether it is supported or not.
752 UMA_HISTOGRAM_SPARSE_SLOWLY("Media.DetectedVideoCodec",
753 codec_context->codec_id);
754 // Ensure the codec is supported. IsValidConfig() also checks that the
755 // frame size and visible size are valid.
756 AVStreamToVideoDecoderConfig(stream, &video_config, false);
758 if (!video_config.IsValidConfig())
759 continue;
760 video_stream = stream;
761 } else if (codec_type == AVMEDIA_TYPE_SUBTITLE) {
762 if (codec_context->codec_id != AV_CODEC_ID_WEBVTT || !text_enabled_) {
763 continue;
765 } else {
766 continue;
769 streams_[i] =
770 new FFmpegDemuxerStream(this, stream, discard_negative_timestamps);
771 max_duration = std::max(max_duration, streams_[i]->duration());
773 const base::TimeDelta start_time =
774 ExtractStartTime(stream, start_time_estimates[i]);
775 if (start_time == kNoTimestamp())
776 continue;
778 if (start_time < start_time_) {
779 start_time_ = start_time;
781 // Choose the stream with the lowest starting time as the fallback stream
782 // for seeking. Video should always be preferred.
783 fallback_stream_for_seeking_ = std::make_pair(i, start_time);
786 // Always prefer the video stream for seeking. If none exists, we'll swap
787 // the fallback stream with the preferred stream below.
788 if (codec_type == AVMEDIA_TYPE_VIDEO)
789 preferred_stream_for_seeking_ = std::make_pair(i, start_time);
792 if (!audio_stream && !video_stream) {
793 status_cb.Run(DEMUXER_ERROR_NO_SUPPORTED_STREAMS);
794 return;
797 if (text_enabled_)
798 AddTextStreams();
800 if (format_context->duration != static_cast<int64_t>(AV_NOPTS_VALUE)) {
801 // If there is a duration value in the container use that to find the
802 // maximum between it and the duration from A/V streams.
803 const AVRational av_time_base = {1, AV_TIME_BASE};
804 max_duration =
805 std::max(max_duration,
806 ConvertFromTimeBase(av_time_base, format_context->duration));
807 } else {
808 // The duration is unknown, in which case this is likely a live stream.
809 max_duration = kInfiniteDuration();
812 // If no start time could be determined, default to zero and prefer the video
813 // stream over the audio stream for seeking. E.g., The WAV demuxer does not
814 // put timestamps on its frames.
815 if (start_time_ == kInfiniteDuration()) {
816 start_time_ = base::TimeDelta();
817 preferred_stream_for_seeking_ = std::make_pair(
818 video_stream ? video_stream->index : audio_stream->index, start_time_);
819 } else if (!video_stream) {
820 // If no video stream exists, use the audio or text stream found above.
821 preferred_stream_for_seeking_ = fallback_stream_for_seeking_;
824 // MPEG-4 B-frames cause grief for a simple container like AVI. Enable PTS
825 // generation so we always get timestamps, see http://crbug.com/169570
826 if (strcmp(format_context->iformat->name, "avi") == 0)
827 format_context->flags |= AVFMT_FLAG_GENPTS;
829 // For testing purposes, don't overwrite the timeline offset if set already.
830 if (timeline_offset_.is_null())
831 timeline_offset_ = ExtractTimelineOffset(format_context);
833 // Since we're shifting the externally visible start time to zero, we need to
834 // adjust the timeline offset to compensate.
835 if (!timeline_offset_.is_null())
836 timeline_offset_ += start_time_;
838 if (max_duration == kInfiniteDuration() && !timeline_offset_.is_null()) {
839 liveness_ = LIVENESS_LIVE;
840 } else if (max_duration != kInfiniteDuration()) {
841 liveness_ = LIVENESS_RECORDED;
842 } else {
843 liveness_ = LIVENESS_UNKNOWN;
846 // Good to go: set the duration and bitrate and notify we're done
847 // initializing.
848 host_->SetDuration(max_duration);
849 duration_known_ = (max_duration != kInfiniteDuration());
851 int64 filesize_in_bytes = 0;
852 url_protocol_->GetSize(&filesize_in_bytes);
853 bitrate_ = CalculateBitrate(format_context, max_duration, filesize_in_bytes);
854 if (bitrate_ > 0)
855 data_source_->SetBitrate(bitrate_);
857 // Audio logging
858 if (audio_stream) {
859 AVCodecContext* audio_codec = audio_stream->codec;
860 media_log_->SetBooleanProperty("found_audio_stream", true);
862 SampleFormat sample_format = audio_config.sample_format();
863 std::string sample_name = SampleFormatToString(sample_format);
865 media_log_->SetStringProperty("audio_sample_format", sample_name);
867 AVCodec* codec = avcodec_find_decoder(audio_codec->codec_id);
868 if (codec) {
869 media_log_->SetStringProperty("audio_codec_name", codec->name);
872 media_log_->SetIntegerProperty("audio_channels_count",
873 audio_codec->channels);
874 media_log_->SetIntegerProperty("audio_samples_per_second",
875 audio_config.samples_per_second());
876 } else {
877 media_log_->SetBooleanProperty("found_audio_stream", false);
880 // Video logging
881 if (video_stream) {
882 AVCodecContext* video_codec = video_stream->codec;
883 media_log_->SetBooleanProperty("found_video_stream", true);
885 AVCodec* codec = avcodec_find_decoder(video_codec->codec_id);
886 if (codec) {
887 media_log_->SetStringProperty("video_codec_name", codec->name);
890 media_log_->SetIntegerProperty("width", video_codec->width);
891 media_log_->SetIntegerProperty("height", video_codec->height);
892 media_log_->SetIntegerProperty("coded_width",
893 video_codec->coded_width);
894 media_log_->SetIntegerProperty("coded_height",
895 video_codec->coded_height);
896 media_log_->SetStringProperty(
897 "time_base",
898 base::StringPrintf("%d/%d",
899 video_codec->time_base.num,
900 video_codec->time_base.den));
901 media_log_->SetStringProperty(
902 "video_format", VideoFrame::FormatToString(video_config.format()));
903 media_log_->SetBooleanProperty("video_is_encrypted",
904 video_config.is_encrypted());
905 } else {
906 media_log_->SetBooleanProperty("found_video_stream", false);
909 media_log_->SetTimeProperty("max_duration", max_duration);
910 media_log_->SetTimeProperty("start_time", start_time_);
911 media_log_->SetIntegerProperty("bitrate", bitrate_);
913 status_cb.Run(PIPELINE_OK);
916 void FFmpegDemuxer::OnSeekFrameDone(const PipelineStatusCB& cb, int result) {
917 DCHECK(task_runner_->BelongsToCurrentThread());
918 CHECK(pending_seek_);
919 pending_seek_ = false;
921 if (!blocking_thread_.IsRunning()) {
922 cb.Run(PIPELINE_ERROR_ABORT);
923 return;
926 if (result < 0) {
927 // Use VLOG(1) instead of NOTIMPLEMENTED() to prevent the message being
928 // captured from stdout and contaminates testing.
929 // TODO(scherkus): Implement this properly and signal error (BUG=23447).
930 VLOG(1) << "Not implemented";
933 // Tell streams to flush buffers due to seeking.
934 StreamVector::iterator iter;
935 for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
936 if (*iter)
937 (*iter)->FlushBuffers();
940 // Resume reading until capacity.
941 ReadFrameIfNeeded();
943 // Notify we're finished seeking.
944 cb.Run(PIPELINE_OK);
947 void FFmpegDemuxer::ReadFrameIfNeeded() {
948 DCHECK(task_runner_->BelongsToCurrentThread());
950 // Make sure we have work to do before reading.
951 if (!blocking_thread_.IsRunning() || !StreamsHaveAvailableCapacity() ||
952 pending_read_ || pending_seek_) {
953 return;
956 // Allocate and read an AVPacket from the media. Save |packet_ptr| since
957 // evaluation order of packet.get() and base::Passed(&packet) is
958 // undefined.
959 ScopedAVPacket packet(new AVPacket());
960 AVPacket* packet_ptr = packet.get();
962 pending_read_ = true;
963 base::PostTaskAndReplyWithResult(
964 blocking_thread_.message_loop_proxy().get(),
965 FROM_HERE,
966 base::Bind(&av_read_frame, glue_->format_context(), packet_ptr),
967 base::Bind(&FFmpegDemuxer::OnReadFrameDone,
968 weak_factory_.GetWeakPtr(),
969 base::Passed(&packet)));
972 void FFmpegDemuxer::OnReadFrameDone(ScopedAVPacket packet, int result) {
973 DCHECK(task_runner_->BelongsToCurrentThread());
974 DCHECK(pending_read_);
975 pending_read_ = false;
977 if (!blocking_thread_.IsRunning() || pending_seek_) {
978 return;
981 // Consider the stream as ended if:
982 // - either underlying ffmpeg returned an error
983 // - or FFMpegDemuxer reached the maximum allowed memory usage.
984 if (result < 0 || IsMaxMemoryUsageReached()) {
985 // Update the duration based on the highest elapsed time across all streams
986 // if it was previously unknown.
987 if (!duration_known_) {
988 base::TimeDelta max_duration;
990 for (StreamVector::iterator iter = streams_.begin();
991 iter != streams_.end();
992 ++iter) {
993 if (!*iter)
994 continue;
996 base::TimeDelta duration = (*iter)->GetElapsedTime();
997 if (duration != kNoTimestamp() && duration > max_duration)
998 max_duration = duration;
1001 if (max_duration > base::TimeDelta()) {
1002 host_->SetDuration(max_duration);
1003 duration_known_ = true;
1006 // If we have reached the end of stream, tell the downstream filters about
1007 // the event.
1008 StreamHasEnded();
1009 return;
1012 // Queue the packet with the appropriate stream.
1013 DCHECK_GE(packet->stream_index, 0);
1014 DCHECK_LT(packet->stream_index, static_cast<int>(streams_.size()));
1016 // Defend against ffmpeg giving us a bad stream index.
1017 if (packet->stream_index >= 0 &&
1018 packet->stream_index < static_cast<int>(streams_.size()) &&
1019 streams_[packet->stream_index]) {
1020 // TODO(scherkus): Fix demuxing upstream to never return packets w/o data
1021 // when av_read_frame() returns success code. See bug comment for ideas:
1023 // https://code.google.com/p/chromium/issues/detail?id=169133#c10
1024 if (!packet->data) {
1025 ScopedAVPacket new_packet(new AVPacket());
1026 av_new_packet(new_packet.get(), 0);
1027 av_packet_copy_props(new_packet.get(), packet.get());
1028 packet.swap(new_packet);
1031 // Special case for opus in ogg. FFmpeg is pre-trimming the codec delay
1032 // from the packet timestamp. Chrome expects to handle this itself inside
1033 // the decoder, so shift timestamps by the delay in this case.
1034 // TODO(dalecurtis): Try to get fixed upstream. See http://crbug.com/328207
1035 if (strcmp(glue_->format_context()->iformat->name, "ogg") == 0) {
1036 const AVCodecContext* codec_context =
1037 glue_->format_context()->streams[packet->stream_index]->codec;
1038 if (codec_context->codec_id == AV_CODEC_ID_OPUS &&
1039 codec_context->delay > 0) {
1040 packet->pts += codec_context->delay;
1044 FFmpegDemuxerStream* demuxer_stream = streams_[packet->stream_index];
1045 demuxer_stream->EnqueuePacket(packet.Pass());
1048 // Keep reading until we've reached capacity.
1049 ReadFrameIfNeeded();
1052 void FFmpegDemuxer::OnDataSourceStopped(const base::Closure& callback) {
1053 // This will block until all tasks complete. Note that after this returns it's
1054 // possible for reply tasks (e.g., OnReadFrameDone()) to be queued on this
1055 // thread. Each of the reply task methods must check whether we've stopped the
1056 // thread and drop their results on the floor.
1057 DCHECK(task_runner_->BelongsToCurrentThread());
1058 blocking_thread_.Stop();
1060 StreamVector::iterator iter;
1061 for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
1062 if (*iter)
1063 (*iter)->Stop();
1066 callback.Run();
1069 bool FFmpegDemuxer::StreamsHaveAvailableCapacity() {
1070 DCHECK(task_runner_->BelongsToCurrentThread());
1071 StreamVector::iterator iter;
1072 for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
1073 if (*iter && (*iter)->HasAvailableCapacity()) {
1074 return true;
1077 return false;
1080 bool FFmpegDemuxer::IsMaxMemoryUsageReached() const {
1081 DCHECK(task_runner_->BelongsToCurrentThread());
1083 // Max allowed memory usage, all streams combined.
1084 const size_t kDemuxerMemoryLimit = 150 * 1024 * 1024;
1086 size_t memory_left = kDemuxerMemoryLimit;
1087 for (StreamVector::const_iterator iter = streams_.begin();
1088 iter != streams_.end(); ++iter) {
1089 if (!(*iter))
1090 continue;
1092 size_t stream_memory_usage = (*iter)->MemoryUsage();
1093 if (stream_memory_usage > memory_left)
1094 return true;
1095 memory_left -= stream_memory_usage;
1097 return false;
1100 void FFmpegDemuxer::StreamHasEnded() {
1101 DCHECK(task_runner_->BelongsToCurrentThread());
1102 StreamVector::iterator iter;
1103 for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
1104 if (!*iter)
1105 continue;
1106 (*iter)->SetEndOfStream();
1110 void FFmpegDemuxer::FireNeedKey(const std::string& init_data_type,
1111 const std::string& encryption_key_id) {
1112 std::vector<uint8> key_id_local(encryption_key_id.begin(),
1113 encryption_key_id.end());
1114 need_key_cb_.Run(init_data_type, key_id_local);
1117 void FFmpegDemuxer::NotifyCapacityAvailable() {
1118 DCHECK(task_runner_->BelongsToCurrentThread());
1119 ReadFrameIfNeeded();
1122 void FFmpegDemuxer::NotifyBufferingChanged() {
1123 DCHECK(task_runner_->BelongsToCurrentThread());
1124 Ranges<base::TimeDelta> buffered;
1125 FFmpegDemuxerStream* audio = GetFFmpegStream(DemuxerStream::AUDIO);
1126 FFmpegDemuxerStream* video = GetFFmpegStream(DemuxerStream::VIDEO);
1127 if (audio && video) {
1128 buffered = audio->GetBufferedRanges().IntersectionWith(
1129 video->GetBufferedRanges());
1130 } else if (audio) {
1131 buffered = audio->GetBufferedRanges();
1132 } else if (video) {
1133 buffered = video->GetBufferedRanges();
1135 for (size_t i = 0; i < buffered.size(); ++i)
1136 host_->AddBufferedTimeRange(buffered.start(i), buffered.end(i));
1139 void FFmpegDemuxer::OnDataSourceError() {
1140 host_->OnDemuxerError(PIPELINE_ERROR_READ);
1143 } // namespace media