Exclude TrayIMETest.PerformActionOnDetailedView under valgrind, where it crashes.
[chromium-blink-merge.git] / media / filters / ffmpeg_demuxer.cc
blobfbc16f5977d3f19302b5a571b34068cb95366f94
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>
9 #include "base/base64.h"
10 #include "base/bind.h"
11 #include "base/callback_helpers.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/metrics/sparse_histogram.h"
14 #include "base/single_thread_task_runner.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "base/strings/string_util.h"
17 #include "base/strings/stringprintf.h"
18 #include "base/sys_byteorder.h"
19 #include "base/task_runner_util.h"
20 #include "base/thread_task_runner_handle.h"
21 #include "base/time/time.h"
22 #include "media/base/bind_to_current_loop.h"
23 #include "media/base/decrypt_config.h"
24 #include "media/base/limits.h"
25 #include "media/base/media_log.h"
26 #include "media/ffmpeg/ffmpeg_common.h"
27 #include "media/filters/ffmpeg_aac_bitstream_converter.h"
28 #include "media/filters/ffmpeg_bitstream_converter.h"
29 #include "media/filters/ffmpeg_glue.h"
30 #include "media/filters/ffmpeg_h264_to_annex_b_bitstream_converter.h"
31 #include "media/filters/webvtt_util.h"
32 #include "media/formats/webm/webm_crypto_helpers.h"
34 namespace media {
36 static base::Time ExtractTimelineOffset(AVFormatContext* format_context) {
37 if (strstr(format_context->iformat->name, "webm") ||
38 strstr(format_context->iformat->name, "matroska")) {
39 const AVDictionaryEntry* entry =
40 av_dict_get(format_context->metadata, "creation_time", NULL, 0);
42 base::Time timeline_offset;
43 if (entry != NULL && entry->value != NULL &&
44 FFmpegUTCDateToTime(entry->value, &timeline_offset)) {
45 return timeline_offset;
49 return base::Time();
52 static base::TimeDelta FramesToTimeDelta(int frames, double sample_rate) {
53 return base::TimeDelta::FromMicroseconds(
54 frames * base::Time::kMicrosecondsPerSecond / sample_rate);
57 static base::TimeDelta ExtractStartTime(AVStream* stream,
58 base::TimeDelta start_time_estimate) {
59 DCHECK(start_time_estimate != kNoTimestamp());
60 if (stream->start_time == static_cast<int64_t>(AV_NOPTS_VALUE)) {
61 return start_time_estimate == kInfiniteDuration() ? kNoTimestamp()
62 : start_time_estimate;
65 // First try the lower of the estimate and the |start_time| value.
66 base::TimeDelta start_time =
67 std::min(ConvertFromTimeBase(stream->time_base, stream->start_time),
68 start_time_estimate);
70 // Next see if the first buffered pts value is usable.
71 if (stream->pts_buffer[0] != static_cast<int64_t>(AV_NOPTS_VALUE)) {
72 const base::TimeDelta buffered_pts =
73 ConvertFromTimeBase(stream->time_base, stream->pts_buffer[0]);
74 if (buffered_pts < start_time)
75 start_time = buffered_pts;
78 // NOTE: Do not use AVStream->first_dts since |start_time| should be a
79 // presentation timestamp.
80 return start_time;
84 // FFmpegDemuxerStream
86 FFmpegDemuxerStream::FFmpegDemuxerStream(FFmpegDemuxer* demuxer,
87 AVStream* stream)
88 : demuxer_(demuxer),
89 task_runner_(base::ThreadTaskRunnerHandle::Get()),
90 stream_(stream),
91 type_(UNKNOWN),
92 liveness_(LIVENESS_UNKNOWN),
93 end_of_stream_(false),
94 last_packet_timestamp_(kNoTimestamp()),
95 last_packet_duration_(kNoTimestamp()),
96 video_rotation_(VIDEO_ROTATION_0),
97 fixup_negative_timestamps_(false) {
98 DCHECK(demuxer_);
100 bool is_encrypted = false;
101 int rotation = 0;
102 AVDictionaryEntry* rotation_entry = NULL;
104 // Determine our media format.
105 switch (stream->codec->codec_type) {
106 case AVMEDIA_TYPE_AUDIO:
107 type_ = AUDIO;
108 AVStreamToAudioDecoderConfig(stream, &audio_config_, true);
109 is_encrypted = audio_config_.is_encrypted();
110 break;
111 case AVMEDIA_TYPE_VIDEO:
112 type_ = VIDEO;
113 AVStreamToVideoDecoderConfig(stream, &video_config_, true);
114 is_encrypted = video_config_.is_encrypted();
116 rotation_entry = av_dict_get(stream->metadata, "rotate", NULL, 0);
117 if (rotation_entry && rotation_entry->value && rotation_entry->value[0])
118 base::StringToInt(rotation_entry->value, &rotation);
120 switch (rotation) {
121 case 0:
122 break;
123 case 90:
124 video_rotation_ = VIDEO_ROTATION_90;
125 break;
126 case 180:
127 video_rotation_ = VIDEO_ROTATION_180;
128 break;
129 case 270:
130 video_rotation_ = VIDEO_ROTATION_270;
131 break;
132 default:
133 LOG(ERROR) << "Unsupported video rotation metadata: " << rotation;
134 break;
137 break;
138 case AVMEDIA_TYPE_SUBTITLE:
139 type_ = TEXT;
140 break;
141 default:
142 NOTREACHED();
143 break;
146 // Calculate the duration.
147 duration_ = ConvertStreamTimestamp(stream->time_base, stream->duration);
149 if (is_encrypted) {
150 AVDictionaryEntry* key = av_dict_get(stream->metadata, "enc_key_id", NULL,
152 DCHECK(key);
153 DCHECK(key->value);
154 if (!key || !key->value)
155 return;
156 base::StringPiece base64_key_id(key->value);
157 std::string enc_key_id;
158 base::Base64Decode(base64_key_id, &enc_key_id);
159 DCHECK(!enc_key_id.empty());
160 if (enc_key_id.empty())
161 return;
163 encryption_key_id_.assign(enc_key_id);
164 demuxer_->OnEncryptedMediaInitData(EmeInitDataType::WEBM, enc_key_id);
168 FFmpegDemuxerStream::~FFmpegDemuxerStream() {
169 DCHECK(!demuxer_);
170 DCHECK(read_cb_.is_null());
171 DCHECK(buffer_queue_.IsEmpty());
174 void FFmpegDemuxerStream::EnqueuePacket(ScopedAVPacket packet) {
175 DCHECK(task_runner_->BelongsToCurrentThread());
177 if (!demuxer_ || end_of_stream_) {
178 NOTREACHED() << "Attempted to enqueue packet on a stopped stream";
179 return;
182 #if defined(USE_PROPRIETARY_CODECS)
183 // Convert the packet if there is a bitstream filter.
184 if (packet->data && bitstream_converter_ &&
185 !bitstream_converter_->ConvertPacket(packet.get())) {
186 LOG(ERROR) << "Format conversion failed.";
188 #endif
190 // Get side data if any. For now, the only type of side_data is VP8 Alpha. We
191 // keep this generic so that other side_data types in the future can be
192 // handled the same way as well.
193 av_packet_split_side_data(packet.get());
195 scoped_refptr<DecoderBuffer> buffer;
197 if (type() == DemuxerStream::TEXT) {
198 int id_size = 0;
199 uint8* id_data = av_packet_get_side_data(
200 packet.get(),
201 AV_PKT_DATA_WEBVTT_IDENTIFIER,
202 &id_size);
204 int settings_size = 0;
205 uint8* settings_data = av_packet_get_side_data(
206 packet.get(),
207 AV_PKT_DATA_WEBVTT_SETTINGS,
208 &settings_size);
210 std::vector<uint8> side_data;
211 MakeSideData(id_data, id_data + id_size,
212 settings_data, settings_data + settings_size,
213 &side_data);
215 buffer = DecoderBuffer::CopyFrom(packet.get()->data, packet.get()->size,
216 side_data.data(), side_data.size());
217 } else {
218 int side_data_size = 0;
219 uint8* side_data = av_packet_get_side_data(
220 packet.get(),
221 AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL,
222 &side_data_size);
224 scoped_ptr<DecryptConfig> decrypt_config;
225 int data_offset = 0;
226 if ((type() == DemuxerStream::AUDIO && audio_config_.is_encrypted()) ||
227 (type() == DemuxerStream::VIDEO && video_config_.is_encrypted())) {
228 if (!WebMCreateDecryptConfig(
229 packet->data, packet->size,
230 reinterpret_cast<const uint8*>(encryption_key_id_.data()),
231 encryption_key_id_.size(),
232 &decrypt_config,
233 &data_offset)) {
234 LOG(ERROR) << "Creation of DecryptConfig failed.";
238 // If a packet is returned by FFmpeg's av_parser_parse2() the packet will
239 // reference inner memory of FFmpeg. As such we should transfer the packet
240 // into memory we control.
241 if (side_data_size > 0) {
242 buffer = DecoderBuffer::CopyFrom(packet.get()->data + data_offset,
243 packet.get()->size - data_offset,
244 side_data, side_data_size);
245 } else {
246 buffer = DecoderBuffer::CopyFrom(packet.get()->data + data_offset,
247 packet.get()->size - data_offset);
250 int skip_samples_size = 0;
251 const uint32* skip_samples_ptr =
252 reinterpret_cast<const uint32*>(av_packet_get_side_data(
253 packet.get(), AV_PKT_DATA_SKIP_SAMPLES, &skip_samples_size));
254 const int kSkipSamplesValidSize = 10;
255 const int kSkipEndSamplesOffset = 1;
256 if (skip_samples_size >= kSkipSamplesValidSize) {
257 // Because FFmpeg rolls codec delay and skip samples into one we can only
258 // allow front discard padding on the first buffer. Otherwise the discard
259 // helper can't figure out which data to discard. See AudioDiscardHelper.
260 int discard_front_samples = base::ByteSwapToLE32(*skip_samples_ptr);
261 if (last_packet_timestamp_ != kNoTimestamp() && discard_front_samples) {
262 DLOG(ERROR) << "Skip samples are only allowed for the first packet.";
263 discard_front_samples = 0;
266 const int discard_end_samples =
267 base::ByteSwapToLE32(*(skip_samples_ptr + kSkipEndSamplesOffset));
268 const int samples_per_second =
269 audio_decoder_config().samples_per_second();
270 buffer->set_discard_padding(std::make_pair(
271 FramesToTimeDelta(discard_front_samples, samples_per_second),
272 FramesToTimeDelta(discard_end_samples, samples_per_second)));
275 if (decrypt_config)
276 buffer->set_decrypt_config(decrypt_config.Pass());
279 if (packet->duration >= 0) {
280 buffer->set_duration(
281 ConvertStreamTimestamp(stream_->time_base, packet->duration));
282 } else {
283 // TODO(wolenetz): Remove when FFmpeg stops returning negative durations.
284 // https://crbug.com/394418
285 DVLOG(1) << "FFmpeg returned a buffer with a negative duration! "
286 << packet->duration;
287 buffer->set_duration(kNoTimestamp());
290 // Note: If pts is AV_NOPTS_VALUE, stream_timestamp will be kNoTimestamp().
291 const base::TimeDelta stream_timestamp =
292 ConvertStreamTimestamp(stream_->time_base, packet->pts);
294 if (stream_timestamp != kNoTimestamp()) {
295 const bool is_audio = type() == AUDIO;
297 // If this file has negative timestamps don't rebase any other stream types
298 // against the negative starting time.
299 base::TimeDelta start_time = demuxer_->start_time();
300 if (fixup_negative_timestamps_ && !is_audio &&
301 start_time < base::TimeDelta()) {
302 start_time = base::TimeDelta();
305 // Don't rebase timestamps for positive start times, the HTML Media Spec
306 // details this in section "4.8.10.6 Offsets into the media resource." We
307 // will still need to rebase timestamps before seeking with FFmpeg though.
308 if (start_time > base::TimeDelta())
309 start_time = base::TimeDelta();
311 buffer->set_timestamp(stream_timestamp - start_time);
313 // If enabled, and no codec delay is present, mark audio packets with
314 // negative timestamps for post-decode discard.
315 if (fixup_negative_timestamps_ && is_audio &&
316 stream_timestamp < base::TimeDelta() &&
317 buffer->duration() != kNoTimestamp()) {
318 if (!stream_->codec->delay) {
319 DCHECK_EQ(buffer->discard_padding().first, base::TimeDelta());
321 if (stream_timestamp + buffer->duration() < base::TimeDelta()) {
322 DCHECK_EQ(buffer->discard_padding().second, base::TimeDelta());
324 // Discard the entire packet if it's entirely before zero.
325 buffer->set_discard_padding(
326 std::make_pair(kInfiniteDuration(), base::TimeDelta()));
327 } else {
328 // Only discard part of the frame if it overlaps zero.
329 buffer->set_discard_padding(std::make_pair(
330 -stream_timestamp, buffer->discard_padding().second));
332 } else {
333 // Verify that codec delay would cover discard and that we don't need to
334 // mark the packet for post decode discard. Since timestamps may be in
335 // milliseconds and codec delay in nanosecond precision, round up to the
336 // nearest millisecond. See enable_negative_timestamp_fixups().
337 DCHECK_LE(-std::ceil(FramesToTimeDelta(
338 audio_decoder_config().codec_delay(),
339 audio_decoder_config().samples_per_second())
340 .InMillisecondsF()),
341 stream_timestamp.InMillisecondsF());
344 } else {
345 // If this happens on the first packet, decoders will throw an error.
346 buffer->set_timestamp(kNoTimestamp());
349 if (last_packet_timestamp_ != kNoTimestamp()) {
350 // FFmpeg doesn't support chained ogg correctly. Instead of guaranteeing
351 // continuity across links in the chain it uses the timestamp information
352 // from each link directly. Doing so can lead to timestamps which appear to
353 // go backwards in time.
355 // If the new link starts with a negative timestamp or a timestamp less than
356 // the original (positive) |start_time|, we will get a negative timestamp
357 // here. It's also possible FFmpeg returns kNoTimestamp() here if it's not
358 // able to work out a timestamp using the previous link and the next.
360 // Fixing chained ogg is non-trivial, so for now just reuse the last good
361 // timestamp. The decoder will rewrite the timestamps to be sample accurate
362 // later. See http://crbug.com/396864.
363 if (fixup_negative_timestamps_ &&
364 (buffer->timestamp() == kNoTimestamp() ||
365 buffer->timestamp() < last_packet_timestamp_)) {
366 buffer->set_timestamp(last_packet_timestamp_ +
367 (last_packet_duration_ != kNoTimestamp()
368 ? last_packet_duration_
369 : base::TimeDelta::FromMicroseconds(1)));
372 // The demuxer should always output positive timestamps.
373 DCHECK(buffer->timestamp() >= base::TimeDelta());
374 DCHECK(buffer->timestamp() != kNoTimestamp());
376 if (last_packet_timestamp_ < buffer->timestamp()) {
377 buffered_ranges_.Add(last_packet_timestamp_, buffer->timestamp());
378 demuxer_->NotifyBufferingChanged();
382 if (packet.get()->flags & AV_PKT_FLAG_KEY)
383 buffer->set_is_key_frame(true);
385 last_packet_timestamp_ = buffer->timestamp();
386 last_packet_duration_ = buffer->duration();
388 buffer_queue_.Push(buffer);
389 SatisfyPendingRead();
392 void FFmpegDemuxerStream::SetEndOfStream() {
393 DCHECK(task_runner_->BelongsToCurrentThread());
394 end_of_stream_ = true;
395 SatisfyPendingRead();
398 void FFmpegDemuxerStream::FlushBuffers() {
399 DCHECK(task_runner_->BelongsToCurrentThread());
400 DCHECK(read_cb_.is_null()) << "There should be no pending read";
402 // H264 and AAC require that we resend the header after flush.
403 // Reset bitstream for converter to do so.
404 // This is related to chromium issue 140371 (http://crbug.com/140371).
405 ResetBitstreamConverter();
407 buffer_queue_.Clear();
408 end_of_stream_ = false;
409 last_packet_timestamp_ = kNoTimestamp();
410 last_packet_duration_ = kNoTimestamp();
413 void FFmpegDemuxerStream::Stop() {
414 DCHECK(task_runner_->BelongsToCurrentThread());
415 buffer_queue_.Clear();
416 if (!read_cb_.is_null()) {
417 base::ResetAndReturn(&read_cb_).Run(
418 DemuxerStream::kOk, DecoderBuffer::CreateEOSBuffer());
420 demuxer_ = NULL;
421 stream_ = NULL;
422 end_of_stream_ = true;
425 DemuxerStream::Type FFmpegDemuxerStream::type() const {
426 DCHECK(task_runner_->BelongsToCurrentThread());
427 return type_;
430 DemuxerStream::Liveness FFmpegDemuxerStream::liveness() const {
431 DCHECK(task_runner_->BelongsToCurrentThread());
432 return liveness_;
435 void FFmpegDemuxerStream::Read(const ReadCB& read_cb) {
436 DCHECK(task_runner_->BelongsToCurrentThread());
437 CHECK(read_cb_.is_null()) << "Overlapping reads are not supported";
438 read_cb_ = BindToCurrentLoop(read_cb);
440 // Don't accept any additional reads if we've been told to stop.
441 // The |demuxer_| may have been destroyed in the pipeline thread.
443 // TODO(scherkus): it would be cleaner to reply with an error message.
444 if (!demuxer_) {
445 base::ResetAndReturn(&read_cb_).Run(
446 DemuxerStream::kOk, DecoderBuffer::CreateEOSBuffer());
447 return;
450 SatisfyPendingRead();
453 void FFmpegDemuxerStream::EnableBitstreamConverter() {
454 DCHECK(task_runner_->BelongsToCurrentThread());
456 #if defined(USE_PROPRIETARY_CODECS)
457 InitBitstreamConverter();
458 #else
459 NOTREACHED() << "Proprietary codecs not enabled.";
460 #endif
463 void FFmpegDemuxerStream::ResetBitstreamConverter() {
464 #if defined(USE_PROPRIETARY_CODECS)
465 if (bitstream_converter_)
466 InitBitstreamConverter();
467 #endif // defined(USE_PROPRIETARY_CODECS)
470 void FFmpegDemuxerStream::InitBitstreamConverter() {
471 #if defined(USE_PROPRIETARY_CODECS)
472 if (stream_->codec->codec_id == AV_CODEC_ID_H264) {
473 bitstream_converter_.reset(
474 new FFmpegH264ToAnnexBBitstreamConverter(stream_->codec));
475 } else if (stream_->codec->codec_id == AV_CODEC_ID_AAC) {
476 bitstream_converter_.reset(
477 new FFmpegAACBitstreamConverter(stream_->codec));
479 #endif // defined(USE_PROPRIETARY_CODECS)
482 bool FFmpegDemuxerStream::SupportsConfigChanges() { return false; }
484 AudioDecoderConfig FFmpegDemuxerStream::audio_decoder_config() {
485 DCHECK(task_runner_->BelongsToCurrentThread());
486 CHECK_EQ(type_, AUDIO);
487 return audio_config_;
490 VideoDecoderConfig FFmpegDemuxerStream::video_decoder_config() {
491 DCHECK(task_runner_->BelongsToCurrentThread());
492 CHECK_EQ(type_, VIDEO);
493 return video_config_;
496 VideoRotation FFmpegDemuxerStream::video_rotation() {
497 return video_rotation_;
500 void FFmpegDemuxerStream::SetLiveness(Liveness liveness) {
501 DCHECK(task_runner_->BelongsToCurrentThread());
502 DCHECK_EQ(liveness_, LIVENESS_UNKNOWN);
503 liveness_ = liveness;
506 base::TimeDelta FFmpegDemuxerStream::GetElapsedTime() const {
507 return ConvertStreamTimestamp(stream_->time_base, stream_->cur_dts);
510 Ranges<base::TimeDelta> FFmpegDemuxerStream::GetBufferedRanges() const {
511 return buffered_ranges_;
514 void FFmpegDemuxerStream::SatisfyPendingRead() {
515 DCHECK(task_runner_->BelongsToCurrentThread());
516 if (!read_cb_.is_null()) {
517 if (!buffer_queue_.IsEmpty()) {
518 base::ResetAndReturn(&read_cb_).Run(
519 DemuxerStream::kOk, buffer_queue_.Pop());
520 } else if (end_of_stream_) {
521 base::ResetAndReturn(&read_cb_).Run(
522 DemuxerStream::kOk, DecoderBuffer::CreateEOSBuffer());
526 // Have capacity? Ask for more!
527 if (HasAvailableCapacity() && !end_of_stream_) {
528 demuxer_->NotifyCapacityAvailable();
532 bool FFmpegDemuxerStream::HasAvailableCapacity() {
533 // TODO(scherkus): Remove this return and reenable time-based capacity
534 // after our data sources support canceling/concurrent reads, see
535 // http://crbug.com/165762 for details.
536 #if 1
537 return !read_cb_.is_null();
538 #else
539 // Try to have one second's worth of encoded data per stream.
540 const base::TimeDelta kCapacity = base::TimeDelta::FromSeconds(1);
541 return buffer_queue_.IsEmpty() || buffer_queue_.Duration() < kCapacity;
542 #endif
545 size_t FFmpegDemuxerStream::MemoryUsage() const {
546 return buffer_queue_.data_size();
549 TextKind FFmpegDemuxerStream::GetTextKind() const {
550 DCHECK_EQ(type_, DemuxerStream::TEXT);
552 if (stream_->disposition & AV_DISPOSITION_CAPTIONS)
553 return kTextCaptions;
555 if (stream_->disposition & AV_DISPOSITION_DESCRIPTIONS)
556 return kTextDescriptions;
558 if (stream_->disposition & AV_DISPOSITION_METADATA)
559 return kTextMetadata;
561 return kTextSubtitles;
564 std::string FFmpegDemuxerStream::GetMetadata(const char* key) const {
565 const AVDictionaryEntry* entry =
566 av_dict_get(stream_->metadata, key, NULL, 0);
567 return (entry == NULL || entry->value == NULL) ? "" : entry->value;
570 // static
571 base::TimeDelta FFmpegDemuxerStream::ConvertStreamTimestamp(
572 const AVRational& time_base, int64 timestamp) {
573 if (timestamp == static_cast<int64>(AV_NOPTS_VALUE))
574 return kNoTimestamp();
576 return ConvertFromTimeBase(time_base, timestamp);
580 // FFmpegDemuxer
582 FFmpegDemuxer::FFmpegDemuxer(
583 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
584 DataSource* data_source,
585 const EncryptedMediaInitDataCB& encrypted_media_init_data_cb,
586 const scoped_refptr<MediaLog>& media_log)
587 : host_(NULL),
588 task_runner_(task_runner),
589 blocking_thread_("FFmpegDemuxer"),
590 pending_read_(false),
591 pending_seek_(false),
592 data_source_(data_source),
593 media_log_(media_log),
594 bitrate_(0),
595 start_time_(kNoTimestamp()),
596 preferred_stream_for_seeking_(-1, kNoTimestamp()),
597 fallback_stream_for_seeking_(-1, kNoTimestamp()),
598 text_enabled_(false),
599 duration_known_(false),
600 encrypted_media_init_data_cb_(encrypted_media_init_data_cb),
601 weak_factory_(this) {
602 DCHECK(task_runner_.get());
603 DCHECK(data_source_);
606 FFmpegDemuxer::~FFmpegDemuxer() {}
608 void FFmpegDemuxer::Stop() {
609 DCHECK(task_runner_->BelongsToCurrentThread());
611 // The order of Stop() and Abort() is important here. If Abort() is called
612 // first, control may pass into FFmpeg where it can destruct buffers that are
613 // in the process of being fulfilled by the DataSource.
614 data_source_->Stop();
615 url_protocol_->Abort();
617 // This will block until all tasks complete. Note that after this returns it's
618 // possible for reply tasks (e.g., OnReadFrameDone()) to be queued on this
619 // thread. Each of the reply task methods must check whether we've stopped the
620 // thread and drop their results on the floor.
621 blocking_thread_.Stop();
623 StreamVector::iterator iter;
624 for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
625 if (*iter)
626 (*iter)->Stop();
629 data_source_ = NULL;
632 void FFmpegDemuxer::Seek(base::TimeDelta time, const PipelineStatusCB& cb) {
633 DCHECK(task_runner_->BelongsToCurrentThread());
634 CHECK(!pending_seek_);
636 // TODO(scherkus): Inspect |pending_read_| and cancel IO via |blocking_url_|,
637 // otherwise we can end up waiting for a pre-seek read to complete even though
638 // we know we're going to drop it on the floor.
640 // FFmpeg requires seeks to be adjusted according to the lowest starting time.
641 // Since EnqueuePacket() rebased negative timestamps by the start time, we
642 // must correct the shift here.
644 // Additionally, to workaround limitations in how we expose seekable ranges to
645 // Blink (http://crbug.com/137275), we also want to clamp seeks before the
646 // start time to the start time.
647 base::TimeDelta seek_time = start_time_ < base::TimeDelta()
648 ? time + start_time_
649 : time < start_time_ ? start_time_ : time;
651 // When seeking in an opus stream we need to ensure we deliver enough data to
652 // satisfy the seek preroll; otherwise the audio at the actual seek time will
653 // not be entirely accurate.
654 FFmpegDemuxerStream* audio_stream = GetFFmpegStream(DemuxerStream::AUDIO);
655 if (audio_stream) {
656 const AudioDecoderConfig& config = audio_stream->audio_decoder_config();
657 if (config.codec() == kCodecOpus)
658 seek_time = std::max(start_time_, seek_time - config.seek_preroll());
661 // Choose the seeking stream based on whether it contains the seek time, if no
662 // match can be found prefer the preferred stream.
664 // TODO(dalecurtis): Currently FFmpeg does not ensure that all streams in a
665 // given container will demux all packets after the seek point. Instead it
666 // only guarantees that all packets after the file position of the seek will
667 // be demuxed. It's an open question whether FFmpeg should fix this:
668 // http://lists.ffmpeg.org/pipermail/ffmpeg-devel/2014-June/159212.html
669 // Tracked by http://crbug.com/387996.
670 DCHECK(preferred_stream_for_seeking_.second != kNoTimestamp());
671 const int stream_index =
672 seek_time < preferred_stream_for_seeking_.second &&
673 seek_time >= fallback_stream_for_seeking_.second
674 ? fallback_stream_for_seeking_.first
675 : preferred_stream_for_seeking_.first;
676 DCHECK_NE(stream_index, -1);
678 const AVStream* seeking_stream =
679 glue_->format_context()->streams[stream_index];
681 pending_seek_ = true;
682 base::PostTaskAndReplyWithResult(
683 blocking_thread_.task_runner().get(),
684 FROM_HERE,
685 base::Bind(&av_seek_frame,
686 glue_->format_context(),
687 seeking_stream->index,
688 ConvertToTimeBase(seeking_stream->time_base, seek_time),
689 // Always seek to a timestamp <= to the desired timestamp.
690 AVSEEK_FLAG_BACKWARD),
691 base::Bind(
692 &FFmpegDemuxer::OnSeekFrameDone, weak_factory_.GetWeakPtr(), cb));
695 std::string FFmpegDemuxer::GetDisplayName() const {
696 return "FFmpegDemuxer";
699 void FFmpegDemuxer::Initialize(DemuxerHost* host,
700 const PipelineStatusCB& status_cb,
701 bool enable_text_tracks) {
702 DCHECK(task_runner_->BelongsToCurrentThread());
703 host_ = host;
704 text_enabled_ = enable_text_tracks;
706 url_protocol_.reset(new BlockingUrlProtocol(data_source_, BindToCurrentLoop(
707 base::Bind(&FFmpegDemuxer::OnDataSourceError, base::Unretained(this)))));
708 glue_.reset(new FFmpegGlue(url_protocol_.get()));
709 AVFormatContext* format_context = glue_->format_context();
711 // Disable ID3v1 tag reading to avoid costly seeks to end of file for data we
712 // don't use. FFmpeg will only read ID3v1 tags if no other metadata is
713 // available, so add a metadata entry to ensure some is always present.
714 av_dict_set(&format_context->metadata, "skip_id3v1_tags", "", 0);
716 // Ensure ffmpeg doesn't give up too early while looking for stream params;
717 // this does not increase the amount of data downloaded. The default value
718 // is 5 AV_TIME_BASE units (1 second each), which prevents some oddly muxed
719 // streams from being detected properly; this value was chosen arbitrarily.
720 format_context->max_analyze_duration2 = 60 * AV_TIME_BASE;
722 // Open the AVFormatContext using our glue layer.
723 CHECK(blocking_thread_.Start());
724 base::PostTaskAndReplyWithResult(
725 blocking_thread_.task_runner().get(),
726 FROM_HERE,
727 base::Bind(&FFmpegGlue::OpenContext, base::Unretained(glue_.get())),
728 base::Bind(&FFmpegDemuxer::OnOpenContextDone,
729 weak_factory_.GetWeakPtr(),
730 status_cb));
733 base::Time FFmpegDemuxer::GetTimelineOffset() const {
734 return timeline_offset_;
737 DemuxerStream* FFmpegDemuxer::GetStream(DemuxerStream::Type type) {
738 DCHECK(task_runner_->BelongsToCurrentThread());
739 return GetFFmpegStream(type);
742 FFmpegDemuxerStream* FFmpegDemuxer::GetFFmpegStream(
743 DemuxerStream::Type type) const {
744 StreamVector::const_iterator iter;
745 for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
746 if (*iter && (*iter)->type() == type) {
747 return *iter;
750 return NULL;
753 base::TimeDelta FFmpegDemuxer::GetStartTime() const {
754 return std::max(start_time_, base::TimeDelta());
757 void FFmpegDemuxer::AddTextStreams() {
758 DCHECK(task_runner_->BelongsToCurrentThread());
760 for (StreamVector::size_type idx = 0; idx < streams_.size(); ++idx) {
761 FFmpegDemuxerStream* stream = streams_[idx];
762 if (stream == NULL || stream->type() != DemuxerStream::TEXT)
763 continue;
765 TextKind kind = stream->GetTextKind();
766 std::string title = stream->GetMetadata("title");
767 std::string language = stream->GetMetadata("language");
769 // TODO: Implement "id" metadata in FFMPEG.
770 // See: http://crbug.com/323183
771 host_->AddTextStream(stream, TextTrackConfig(kind, title, language,
772 std::string()));
776 // Helper for calculating the bitrate of the media based on information stored
777 // in |format_context| or failing that the size and duration of the media.
779 // Returns 0 if a bitrate could not be determined.
780 static int CalculateBitrate(
781 AVFormatContext* format_context,
782 const base::TimeDelta& duration,
783 int64 filesize_in_bytes) {
784 // If there is a bitrate set on the container, use it.
785 if (format_context->bit_rate > 0)
786 return format_context->bit_rate;
788 // Then try to sum the bitrates individually per stream.
789 int bitrate = 0;
790 for (size_t i = 0; i < format_context->nb_streams; ++i) {
791 AVCodecContext* codec_context = format_context->streams[i]->codec;
792 bitrate += codec_context->bit_rate;
794 if (bitrate > 0)
795 return bitrate;
797 // See if we can approximate the bitrate as long as we have a filesize and
798 // valid duration.
799 if (duration.InMicroseconds() <= 0 ||
800 duration == kInfiniteDuration() ||
801 filesize_in_bytes == 0) {
802 return 0;
805 // Do math in floating point as we'd overflow an int64 if the filesize was
806 // larger than ~1073GB.
807 double bytes = filesize_in_bytes;
808 double duration_us = duration.InMicroseconds();
809 return bytes * 8000000.0 / duration_us;
812 void FFmpegDemuxer::OnOpenContextDone(const PipelineStatusCB& status_cb,
813 bool result) {
814 DCHECK(task_runner_->BelongsToCurrentThread());
815 if (!blocking_thread_.IsRunning()) {
816 MEDIA_LOG(ERROR, media_log_) << GetDisplayName() << ": bad state";
817 status_cb.Run(PIPELINE_ERROR_ABORT);
818 return;
821 if (!result) {
822 MEDIA_LOG(ERROR, media_log_) << GetDisplayName() << ": open context failed";
823 status_cb.Run(DEMUXER_ERROR_COULD_NOT_OPEN);
824 return;
827 // Fully initialize AVFormatContext by parsing the stream a little.
828 base::PostTaskAndReplyWithResult(
829 blocking_thread_.task_runner().get(),
830 FROM_HERE,
831 base::Bind(&avformat_find_stream_info,
832 glue_->format_context(),
833 static_cast<AVDictionary**>(NULL)),
834 base::Bind(&FFmpegDemuxer::OnFindStreamInfoDone,
835 weak_factory_.GetWeakPtr(),
836 status_cb));
839 void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb,
840 int result) {
841 DCHECK(task_runner_->BelongsToCurrentThread());
842 if (!blocking_thread_.IsRunning() || !data_source_) {
843 MEDIA_LOG(ERROR, media_log_) << GetDisplayName() << ": bad state";
844 status_cb.Run(PIPELINE_ERROR_ABORT);
845 return;
848 if (result < 0) {
849 MEDIA_LOG(ERROR, media_log_) << GetDisplayName()
850 << ": find stream info failed";
851 status_cb.Run(DEMUXER_ERROR_COULD_NOT_PARSE);
852 return;
855 // Create demuxer stream entries for each possible AVStream. Each stream
856 // is examined to determine if it is supported or not (is the codec enabled
857 // for it in this release?). Unsupported streams are skipped, allowing for
858 // partial playback. At least one audio or video stream must be playable.
859 AVFormatContext* format_context = glue_->format_context();
860 streams_.resize(format_context->nb_streams);
862 // Estimate the start time for each stream by looking through the packets
863 // buffered during avformat_find_stream_info(). These values will be
864 // considered later when determining the actual stream start time.
866 // These packets haven't been completely processed yet, so only look through
867 // these values if the AVFormatContext has a valid start time.
869 // If no estimate is found, the stream entry will be kInfiniteDuration().
870 std::vector<base::TimeDelta> start_time_estimates(format_context->nb_streams,
871 kInfiniteDuration());
872 const AVFormatInternal* internal = format_context->internal;
873 if (internal && internal->packet_buffer &&
874 format_context->start_time != static_cast<int64>(AV_NOPTS_VALUE)) {
875 struct AVPacketList* packet_buffer = internal->packet_buffer;
876 while (packet_buffer != internal->packet_buffer_end) {
877 DCHECK_LT(static_cast<size_t>(packet_buffer->pkt.stream_index),
878 start_time_estimates.size());
879 const AVStream* stream =
880 format_context->streams[packet_buffer->pkt.stream_index];
881 if (packet_buffer->pkt.pts != static_cast<int64>(AV_NOPTS_VALUE)) {
882 const base::TimeDelta packet_pts =
883 ConvertFromTimeBase(stream->time_base, packet_buffer->pkt.pts);
884 if (packet_pts < start_time_estimates[stream->index])
885 start_time_estimates[stream->index] = packet_pts;
887 packet_buffer = packet_buffer->next;
891 AVStream* audio_stream = NULL;
892 AudioDecoderConfig audio_config;
894 AVStream* video_stream = NULL;
895 VideoDecoderConfig video_config;
897 // If available, |start_time_| will be set to the lowest stream start time.
898 start_time_ = kInfiniteDuration();
900 base::TimeDelta max_duration;
901 for (size_t i = 0; i < format_context->nb_streams; ++i) {
902 AVStream* stream = format_context->streams[i];
903 const AVCodecContext* codec_context = stream->codec;
904 const AVMediaType codec_type = codec_context->codec_type;
906 if (codec_type == AVMEDIA_TYPE_AUDIO) {
907 if (audio_stream)
908 continue;
910 // Log the codec detected, whether it is supported or not.
911 UMA_HISTOGRAM_SPARSE_SLOWLY("Media.DetectedAudioCodec",
912 codec_context->codec_id);
913 // Ensure the codec is supported. IsValidConfig() also checks that the
914 // channel layout and sample format are valid.
915 AVStreamToAudioDecoderConfig(stream, &audio_config, false);
916 if (!audio_config.IsValidConfig())
917 continue;
918 audio_stream = stream;
919 } else if (codec_type == AVMEDIA_TYPE_VIDEO) {
920 if (video_stream)
921 continue;
923 // Log the codec detected, whether it is supported or not.
924 UMA_HISTOGRAM_SPARSE_SLOWLY("Media.DetectedVideoCodec",
925 codec_context->codec_id);
926 // Ensure the codec is supported. IsValidConfig() also checks that the
927 // frame size and visible size are valid.
928 AVStreamToVideoDecoderConfig(stream, &video_config, false);
930 if (!video_config.IsValidConfig())
931 continue;
932 video_stream = stream;
933 } else if (codec_type == AVMEDIA_TYPE_SUBTITLE) {
934 if (codec_context->codec_id != AV_CODEC_ID_WEBVTT || !text_enabled_) {
935 continue;
937 } else {
938 continue;
941 streams_[i] = new FFmpegDemuxerStream(this, stream);
942 max_duration = std::max(max_duration, streams_[i]->duration());
944 const base::TimeDelta start_time =
945 ExtractStartTime(stream, start_time_estimates[i]);
946 const bool has_start_time = start_time != kNoTimestamp();
948 // Always prefer the video stream for seeking. If none exists, we'll swap
949 // the fallback stream with the preferred stream below.
950 if (codec_type == AVMEDIA_TYPE_VIDEO) {
951 preferred_stream_for_seeking_ =
952 StreamSeekInfo(i, has_start_time ? start_time : base::TimeDelta());
955 if (!has_start_time)
956 continue;
958 if (start_time < start_time_) {
959 start_time_ = start_time;
961 // Choose the stream with the lowest starting time as the fallback stream
962 // for seeking. Video should always be preferred.
963 fallback_stream_for_seeking_ = StreamSeekInfo(i, start_time);
967 if (!audio_stream && !video_stream) {
968 MEDIA_LOG(ERROR, media_log_) << GetDisplayName()
969 << ": no supported streams";
970 status_cb.Run(DEMUXER_ERROR_NO_SUPPORTED_STREAMS);
971 return;
974 if (text_enabled_)
975 AddTextStreams();
977 if (format_context->duration != static_cast<int64_t>(AV_NOPTS_VALUE)) {
978 // If there is a duration value in the container use that to find the
979 // maximum between it and the duration from A/V streams.
980 const AVRational av_time_base = {1, AV_TIME_BASE};
981 max_duration =
982 std::max(max_duration,
983 ConvertFromTimeBase(av_time_base, format_context->duration));
984 } else {
985 // The duration is unknown, in which case this is likely a live stream.
986 max_duration = kInfiniteDuration();
989 // FFmpeg represents audio data marked as before the beginning of stream as
990 // having negative timestamps. This data must be discarded after it has been
991 // decoded, not before since it is used to warmup the decoder. There are
992 // currently two known cases for this: vorbis in ogg and opus in ogg and webm.
994 // For API clarity, it was decided that the rest of the media pipeline should
995 // not be exposed to negative timestamps. Which means we need to rebase these
996 // negative timestamps and mark them for discard post decoding.
998 // Post-decode frame dropping for packets with negative timestamps is outlined
999 // in section A.2 in the Ogg Vorbis spec:
1000 // http://xiph.org/vorbis/doc/Vorbis_I_spec.html
1002 // FFmpeg's use of negative timestamps for opus pre-skip is nonstandard, but
1003 // for more information on pre-skip see section 4.2 of the Ogg Opus spec:
1004 // https://tools.ietf.org/html/draft-ietf-codec-oggopus-08#section-4.2
1005 if (audio_stream && (audio_stream->codec->codec_id == AV_CODEC_ID_OPUS ||
1006 (strcmp(format_context->iformat->name, "ogg") == 0 &&
1007 audio_stream->codec->codec_id == AV_CODEC_ID_VORBIS))) {
1008 for (size_t i = 0; i < streams_.size(); ++i) {
1009 if (streams_[i])
1010 streams_[i]->enable_negative_timestamp_fixups();
1013 // Fixup the seeking information to avoid selecting the audio stream simply
1014 // because it has a lower starting time.
1015 if (fallback_stream_for_seeking_.first == audio_stream->index &&
1016 fallback_stream_for_seeking_.second < base::TimeDelta()) {
1017 fallback_stream_for_seeking_.second = base::TimeDelta();
1021 // If no start time could be determined, default to zero and prefer the video
1022 // stream over the audio stream for seeking. E.g., The WAV demuxer does not
1023 // put timestamps on its frames.
1024 if (start_time_ == kInfiniteDuration()) {
1025 start_time_ = base::TimeDelta();
1026 preferred_stream_for_seeking_ = StreamSeekInfo(
1027 video_stream ? video_stream->index : audio_stream->index, start_time_);
1028 } else if (!video_stream) {
1029 // If no video stream exists, use the audio or text stream found above.
1030 preferred_stream_for_seeking_ = fallback_stream_for_seeking_;
1033 // MPEG-4 B-frames cause grief for a simple container like AVI. Enable PTS
1034 // generation so we always get timestamps, see http://crbug.com/169570
1035 if (strcmp(format_context->iformat->name, "avi") == 0)
1036 format_context->flags |= AVFMT_FLAG_GENPTS;
1038 // For testing purposes, don't overwrite the timeline offset if set already.
1039 if (timeline_offset_.is_null())
1040 timeline_offset_ = ExtractTimelineOffset(format_context);
1042 // Since we're shifting the externally visible start time to zero, we need to
1043 // adjust the timeline offset to compensate.
1044 if (!timeline_offset_.is_null() && start_time_ < base::TimeDelta())
1045 timeline_offset_ += start_time_;
1047 if (max_duration == kInfiniteDuration() && !timeline_offset_.is_null()) {
1048 SetLiveness(DemuxerStream::LIVENESS_LIVE);
1049 } else if (max_duration != kInfiniteDuration()) {
1050 SetLiveness(DemuxerStream::LIVENESS_RECORDED);
1051 } else {
1052 SetLiveness(DemuxerStream::LIVENESS_UNKNOWN);
1055 // Good to go: set the duration and bitrate and notify we're done
1056 // initializing.
1057 host_->SetDuration(max_duration);
1058 duration_known_ = (max_duration != kInfiniteDuration());
1060 int64 filesize_in_bytes = 0;
1061 url_protocol_->GetSize(&filesize_in_bytes);
1062 bitrate_ = CalculateBitrate(format_context, max_duration, filesize_in_bytes);
1063 if (bitrate_ > 0)
1064 data_source_->SetBitrate(bitrate_);
1066 // Audio logging
1067 if (audio_stream) {
1068 AVCodecContext* audio_codec = audio_stream->codec;
1069 media_log_->SetBooleanProperty("found_audio_stream", true);
1071 SampleFormat sample_format = audio_config.sample_format();
1072 std::string sample_name = SampleFormatToString(sample_format);
1074 media_log_->SetStringProperty("audio_sample_format", sample_name);
1076 AVCodec* codec = avcodec_find_decoder(audio_codec->codec_id);
1077 if (codec) {
1078 media_log_->SetStringProperty("audio_codec_name", codec->name);
1081 media_log_->SetIntegerProperty("audio_channels_count",
1082 audio_codec->channels);
1083 media_log_->SetIntegerProperty("audio_samples_per_second",
1084 audio_config.samples_per_second());
1085 } else {
1086 media_log_->SetBooleanProperty("found_audio_stream", false);
1089 // Video logging
1090 if (video_stream) {
1091 AVCodecContext* video_codec = video_stream->codec;
1092 media_log_->SetBooleanProperty("found_video_stream", true);
1094 AVCodec* codec = avcodec_find_decoder(video_codec->codec_id);
1095 if (codec) {
1096 media_log_->SetStringProperty("video_codec_name", codec->name);
1097 } else if (video_codec->codec_id == AV_CODEC_ID_VP9) {
1098 // ffmpeg doesn't know about VP9 decoder. So we need to log it explicitly.
1099 media_log_->SetStringProperty("video_codec_name", "vp9");
1102 media_log_->SetIntegerProperty("width", video_codec->width);
1103 media_log_->SetIntegerProperty("height", video_codec->height);
1104 media_log_->SetIntegerProperty("coded_width",
1105 video_codec->coded_width);
1106 media_log_->SetIntegerProperty("coded_height",
1107 video_codec->coded_height);
1108 media_log_->SetStringProperty(
1109 "time_base",
1110 base::StringPrintf("%d/%d",
1111 video_codec->time_base.num,
1112 video_codec->time_base.den));
1113 media_log_->SetStringProperty(
1114 "video_format", VideoPixelFormatToString(video_config.format()));
1115 media_log_->SetBooleanProperty("video_is_encrypted",
1116 video_config.is_encrypted());
1117 } else {
1118 media_log_->SetBooleanProperty("found_video_stream", false);
1121 media_log_->SetTimeProperty("max_duration", max_duration);
1122 media_log_->SetTimeProperty("start_time", start_time_);
1123 media_log_->SetIntegerProperty("bitrate", bitrate_);
1125 status_cb.Run(PIPELINE_OK);
1128 void FFmpegDemuxer::OnSeekFrameDone(const PipelineStatusCB& cb, int result) {
1129 DCHECK(task_runner_->BelongsToCurrentThread());
1130 CHECK(pending_seek_);
1131 pending_seek_ = false;
1133 if (!blocking_thread_.IsRunning()) {
1134 MEDIA_LOG(ERROR, media_log_) << GetDisplayName() << ": bad state";
1135 cb.Run(PIPELINE_ERROR_ABORT);
1136 return;
1139 if (result < 0) {
1140 // Use VLOG(1) instead of NOTIMPLEMENTED() to prevent the message being
1141 // captured from stdout and contaminates testing.
1142 // TODO(scherkus): Implement this properly and signal error (BUG=23447).
1143 VLOG(1) << "Not implemented";
1146 // Tell streams to flush buffers due to seeking.
1147 StreamVector::iterator iter;
1148 for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
1149 if (*iter)
1150 (*iter)->FlushBuffers();
1153 // Resume reading until capacity.
1154 ReadFrameIfNeeded();
1156 // Notify we're finished seeking.
1157 cb.Run(PIPELINE_OK);
1160 void FFmpegDemuxer::ReadFrameIfNeeded() {
1161 DCHECK(task_runner_->BelongsToCurrentThread());
1163 // Make sure we have work to do before reading.
1164 if (!blocking_thread_.IsRunning() || !StreamsHaveAvailableCapacity() ||
1165 pending_read_ || pending_seek_) {
1166 return;
1169 // Allocate and read an AVPacket from the media. Save |packet_ptr| since
1170 // evaluation order of packet.get() and base::Passed(&packet) is
1171 // undefined.
1172 ScopedAVPacket packet(new AVPacket());
1173 AVPacket* packet_ptr = packet.get();
1175 pending_read_ = true;
1176 base::PostTaskAndReplyWithResult(
1177 blocking_thread_.task_runner().get(),
1178 FROM_HERE,
1179 base::Bind(&av_read_frame, glue_->format_context(), packet_ptr),
1180 base::Bind(&FFmpegDemuxer::OnReadFrameDone,
1181 weak_factory_.GetWeakPtr(),
1182 base::Passed(&packet)));
1185 void FFmpegDemuxer::OnReadFrameDone(ScopedAVPacket packet, int result) {
1186 DCHECK(task_runner_->BelongsToCurrentThread());
1187 DCHECK(pending_read_);
1188 pending_read_ = false;
1190 if (!blocking_thread_.IsRunning() || pending_seek_) {
1191 return;
1194 // Consider the stream as ended if:
1195 // - either underlying ffmpeg returned an error
1196 // - or FFMpegDemuxer reached the maximum allowed memory usage.
1197 if (result < 0 || IsMaxMemoryUsageReached()) {
1198 // Update the duration based on the highest elapsed time across all streams
1199 // if it was previously unknown.
1200 if (!duration_known_) {
1201 base::TimeDelta max_duration;
1203 for (StreamVector::iterator iter = streams_.begin();
1204 iter != streams_.end();
1205 ++iter) {
1206 if (!*iter)
1207 continue;
1209 base::TimeDelta duration = (*iter)->GetElapsedTime();
1210 if (duration != kNoTimestamp() && duration > max_duration)
1211 max_duration = duration;
1214 if (max_duration > base::TimeDelta()) {
1215 host_->SetDuration(max_duration);
1216 duration_known_ = true;
1219 // If we have reached the end of stream, tell the downstream filters about
1220 // the event.
1221 StreamHasEnded();
1222 return;
1225 // Queue the packet with the appropriate stream.
1226 DCHECK_GE(packet->stream_index, 0);
1227 DCHECK_LT(packet->stream_index, static_cast<int>(streams_.size()));
1229 // Defend against ffmpeg giving us a bad stream index.
1230 if (packet->stream_index >= 0 &&
1231 packet->stream_index < static_cast<int>(streams_.size()) &&
1232 streams_[packet->stream_index]) {
1233 // TODO(scherkus): Fix demuxing upstream to never return packets w/o data
1234 // when av_read_frame() returns success code. See bug comment for ideas:
1236 // https://code.google.com/p/chromium/issues/detail?id=169133#c10
1237 if (!packet->data) {
1238 ScopedAVPacket new_packet(new AVPacket());
1239 av_new_packet(new_packet.get(), 0);
1240 av_packet_copy_props(new_packet.get(), packet.get());
1241 packet.swap(new_packet);
1244 FFmpegDemuxerStream* demuxer_stream = streams_[packet->stream_index];
1245 demuxer_stream->EnqueuePacket(packet.Pass());
1248 // Keep reading until we've reached capacity.
1249 ReadFrameIfNeeded();
1252 bool FFmpegDemuxer::StreamsHaveAvailableCapacity() {
1253 DCHECK(task_runner_->BelongsToCurrentThread());
1254 StreamVector::iterator iter;
1255 for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
1256 if (*iter && (*iter)->HasAvailableCapacity()) {
1257 return true;
1260 return false;
1263 bool FFmpegDemuxer::IsMaxMemoryUsageReached() const {
1264 DCHECK(task_runner_->BelongsToCurrentThread());
1266 // Max allowed memory usage, all streams combined.
1267 const size_t kDemuxerMemoryLimit = 150 * 1024 * 1024;
1269 size_t memory_left = kDemuxerMemoryLimit;
1270 for (StreamVector::const_iterator iter = streams_.begin();
1271 iter != streams_.end(); ++iter) {
1272 if (!(*iter))
1273 continue;
1275 size_t stream_memory_usage = (*iter)->MemoryUsage();
1276 if (stream_memory_usage > memory_left)
1277 return true;
1278 memory_left -= stream_memory_usage;
1280 return false;
1283 void FFmpegDemuxer::StreamHasEnded() {
1284 DCHECK(task_runner_->BelongsToCurrentThread());
1285 StreamVector::iterator iter;
1286 for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
1287 if (!*iter)
1288 continue;
1289 (*iter)->SetEndOfStream();
1293 void FFmpegDemuxer::OnEncryptedMediaInitData(
1294 EmeInitDataType init_data_type,
1295 const std::string& encryption_key_id) {
1296 std::vector<uint8> key_id_local(encryption_key_id.begin(),
1297 encryption_key_id.end());
1298 encrypted_media_init_data_cb_.Run(init_data_type, key_id_local);
1301 void FFmpegDemuxer::NotifyCapacityAvailable() {
1302 DCHECK(task_runner_->BelongsToCurrentThread());
1303 ReadFrameIfNeeded();
1306 void FFmpegDemuxer::NotifyBufferingChanged() {
1307 DCHECK(task_runner_->BelongsToCurrentThread());
1308 Ranges<base::TimeDelta> buffered;
1309 FFmpegDemuxerStream* audio = GetFFmpegStream(DemuxerStream::AUDIO);
1310 FFmpegDemuxerStream* video = GetFFmpegStream(DemuxerStream::VIDEO);
1311 if (audio && video) {
1312 buffered = audio->GetBufferedRanges().IntersectionWith(
1313 video->GetBufferedRanges());
1314 } else if (audio) {
1315 buffered = audio->GetBufferedRanges();
1316 } else if (video) {
1317 buffered = video->GetBufferedRanges();
1319 for (size_t i = 0; i < buffered.size(); ++i)
1320 host_->AddBufferedTimeRange(buffered.start(i), buffered.end(i));
1323 void FFmpegDemuxer::OnDataSourceError() {
1324 MEDIA_LOG(ERROR, media_log_) << GetDisplayName() << ": data source error";
1325 host_->OnDemuxerError(PIPELINE_ERROR_READ);
1328 void FFmpegDemuxer::SetLiveness(DemuxerStream::Liveness liveness) {
1329 DCHECK(task_runner_->BelongsToCurrentThread());
1330 for (const auto& stream : streams_) { // |stream| is a ref to a pointer.
1331 if (stream)
1332 stream->SetLiveness(liveness);
1336 } // namespace media