[MD settings] moving attached() code
[chromium-blink-merge.git] / media / filters / ffmpeg_demuxer.cc
blob84b02c4a35db1de55d4f9f620d79e0b8af5798a4
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/histogram_macros.h"
14 #include "base/metrics/sparse_histogram.h"
15 #include "base/single_thread_task_runner.h"
16 #include "base/strings/string_number_conversions.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/thread_task_runner_handle.h"
22 #include "base/time/time.h"
23 #include "media/audio/sample_rates.h"
24 #include "media/base/bind_to_current_loop.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/timestamp_constants.h"
29 #include "media/ffmpeg/ffmpeg_common.h"
30 #include "media/filters/ffmpeg_aac_bitstream_converter.h"
31 #include "media/filters/ffmpeg_bitstream_converter.h"
32 #include "media/filters/ffmpeg_glue.h"
33 #include "media/filters/ffmpeg_h264_to_annex_b_bitstream_converter.h"
34 #include "media/filters/webvtt_util.h"
35 #include "media/formats/webm/webm_crypto_helpers.h"
37 #if defined(ENABLE_HEVC_DEMUXING)
38 #include "media/filters/ffmpeg_h265_to_annex_b_bitstream_converter.h"
39 #endif
41 namespace media {
43 static base::Time ExtractTimelineOffset(AVFormatContext* format_context) {
44 if (strstr(format_context->iformat->name, "webm") ||
45 strstr(format_context->iformat->name, "matroska")) {
46 const AVDictionaryEntry* entry =
47 av_dict_get(format_context->metadata, "creation_time", NULL, 0);
49 base::Time timeline_offset;
50 if (entry != NULL && entry->value != NULL &&
51 FFmpegUTCDateToTime(entry->value, &timeline_offset)) {
52 return timeline_offset;
56 return base::Time();
59 static base::TimeDelta FramesToTimeDelta(int frames, double sample_rate) {
60 return base::TimeDelta::FromMicroseconds(
61 frames * base::Time::kMicrosecondsPerSecond / sample_rate);
64 static base::TimeDelta ExtractStartTime(AVStream* stream,
65 base::TimeDelta start_time_estimate) {
66 DCHECK(start_time_estimate != kNoTimestamp());
67 if (stream->start_time == static_cast<int64_t>(AV_NOPTS_VALUE)) {
68 return start_time_estimate == kInfiniteDuration() ? kNoTimestamp()
69 : start_time_estimate;
72 // First try the lower of the estimate and the |start_time| value.
73 base::TimeDelta start_time =
74 std::min(ConvertFromTimeBase(stream->time_base, stream->start_time),
75 start_time_estimate);
77 // Next see if the first buffered pts value is usable.
78 if (stream->pts_buffer[0] != static_cast<int64_t>(AV_NOPTS_VALUE)) {
79 const base::TimeDelta buffered_pts =
80 ConvertFromTimeBase(stream->time_base, stream->pts_buffer[0]);
81 if (buffered_pts < start_time)
82 start_time = buffered_pts;
85 // NOTE: Do not use AVStream->first_dts since |start_time| should be a
86 // presentation timestamp.
87 return start_time;
90 // Some videos just want to watch the world burn, with a height of 0; cap the
91 // "infinite" aspect ratio resulting.
92 const int kInfiniteRatio = 99999;
94 // Common aspect ratios (multiplied by 100 and truncated) used for histogramming
95 // video sizes. These were taken on 20111103 from
96 // http://wikipedia.org/wiki/Aspect_ratio_(image)#Previous_and_currently_used_aspect_ratios
97 const int kCommonAspectRatios100[] = {
98 100, 115, 133, 137, 143, 150, 155, 160, 166,
99 175, 177, 185, 200, 210, 220, 221, 235, 237,
100 240, 255, 259, 266, 276, 293, 400, 1200, kInfiniteRatio,
103 template <class T> // T has int width() & height() methods.
104 static void UmaHistogramAspectRatio(const char* name, const T& size) {
105 UMA_HISTOGRAM_CUSTOM_ENUMERATION(
106 name,
107 // Intentionally use integer division to truncate the result.
108 size.height() ? (size.width() * 100) / size.height() : kInfiniteRatio,
109 base::CustomHistogram::ArrayToCustomRanges(
110 kCommonAspectRatios100, arraysize(kCommonAspectRatios100)));
113 // Record audio decoder config UMA stats corresponding to a src= playback.
114 static void RecordAudioCodecStats(const AudioDecoderConfig& audio_config) {
115 UMA_HISTOGRAM_ENUMERATION("Media.AudioCodec", audio_config.codec(),
116 kAudioCodecMax + 1);
117 UMA_HISTOGRAM_ENUMERATION("Media.AudioSampleFormat",
118 audio_config.sample_format(), kSampleFormatMax + 1);
119 UMA_HISTOGRAM_ENUMERATION("Media.AudioChannelLayout",
120 audio_config.channel_layout(),
121 CHANNEL_LAYOUT_MAX + 1);
122 AudioSampleRate asr;
123 if (ToAudioSampleRate(audio_config.samples_per_second(), &asr)) {
124 UMA_HISTOGRAM_ENUMERATION("Media.AudioSamplesPerSecond", asr,
125 kAudioSampleRateMax + 1);
126 } else {
127 UMA_HISTOGRAM_COUNTS("Media.AudioSamplesPerSecondUnexpected",
128 audio_config.samples_per_second());
132 // Record video decoder config UMA stats corresponding to a src= playback.
133 static void RecordVideoCodecStats(const VideoDecoderConfig& video_config,
134 AVColorRange color_range) {
135 UMA_HISTOGRAM_ENUMERATION("Media.VideoCodec", video_config.codec(),
136 kVideoCodecMax + 1);
138 // Drop UNKNOWN because U_H_E() uses one bucket for all values less than 1.
139 if (video_config.profile() >= 0) {
140 UMA_HISTOGRAM_ENUMERATION("Media.VideoCodecProfile", video_config.profile(),
141 VIDEO_CODEC_PROFILE_MAX + 1);
143 UMA_HISTOGRAM_COUNTS_10000("Media.VideoCodedWidth",
144 video_config.coded_size().width());
145 UmaHistogramAspectRatio("Media.VideoCodedAspectRatio",
146 video_config.coded_size());
147 UMA_HISTOGRAM_COUNTS_10000("Media.VideoVisibleWidth",
148 video_config.visible_rect().width());
149 UmaHistogramAspectRatio("Media.VideoVisibleAspectRatio",
150 video_config.visible_rect());
151 UMA_HISTOGRAM_ENUMERATION("Media.VideoPixelFormatUnion",
152 video_config.format(), PIXEL_FORMAT_MAX + 1);
153 UMA_HISTOGRAM_ENUMERATION("Media.VideoFrameColorSpace",
154 video_config.color_space(), COLOR_SPACE_MAX + 1);
156 // Note the PRESUBMIT_IGNORE_UMA_MAX below, this silences the PRESUBMIT.py
157 // check for uma enum max usage, since we're abusing
158 // UMA_HISTOGRAM_ENUMERATION to report a discrete value.
159 UMA_HISTOGRAM_ENUMERATION("Media.VideoColorRange", color_range,
160 AVCOL_RANGE_NB); // PRESUBMIT_IGNORE_UMA_MAX
163 static int32_t GetCodecHash(const AVCodecContext* context) {
164 if (context->codec_descriptor)
165 return HashCodecName(context->codec_descriptor->name);
166 const AVCodecDescriptor* codec_descriptor =
167 avcodec_descriptor_get(context->codec_id);
168 if (codec_descriptor)
169 return HashCodecName(codec_descriptor->name);
171 // If the codec name can't be determined, return none for tracking.
172 return HashCodecName("none");
176 // FFmpegDemuxerStream
178 FFmpegDemuxerStream::FFmpegDemuxerStream(FFmpegDemuxer* demuxer,
179 AVStream* stream)
180 : demuxer_(demuxer),
181 task_runner_(base::ThreadTaskRunnerHandle::Get()),
182 stream_(stream),
183 type_(UNKNOWN),
184 liveness_(LIVENESS_UNKNOWN),
185 end_of_stream_(false),
186 last_packet_timestamp_(kNoTimestamp()),
187 last_packet_duration_(kNoTimestamp()),
188 video_rotation_(VIDEO_ROTATION_0),
189 fixup_negative_timestamps_(false) {
190 DCHECK(demuxer_);
192 bool is_encrypted = false;
193 int rotation = 0;
194 AVDictionaryEntry* rotation_entry = NULL;
196 // Determine our media format.
197 switch (stream->codec->codec_type) {
198 case AVMEDIA_TYPE_AUDIO:
199 type_ = AUDIO;
200 AVStreamToAudioDecoderConfig(stream, &audio_config_);
201 is_encrypted = audio_config_.is_encrypted();
202 break;
203 case AVMEDIA_TYPE_VIDEO:
204 type_ = VIDEO;
205 AVStreamToVideoDecoderConfig(stream, &video_config_);
206 is_encrypted = video_config_.is_encrypted();
208 rotation_entry = av_dict_get(stream->metadata, "rotate", NULL, 0);
209 if (rotation_entry && rotation_entry->value && rotation_entry->value[0])
210 base::StringToInt(rotation_entry->value, &rotation);
212 switch (rotation) {
213 case 0:
214 break;
215 case 90:
216 video_rotation_ = VIDEO_ROTATION_90;
217 break;
218 case 180:
219 video_rotation_ = VIDEO_ROTATION_180;
220 break;
221 case 270:
222 video_rotation_ = VIDEO_ROTATION_270;
223 break;
224 default:
225 LOG(ERROR) << "Unsupported video rotation metadata: " << rotation;
226 break;
229 break;
230 case AVMEDIA_TYPE_SUBTITLE:
231 type_ = TEXT;
232 break;
233 default:
234 NOTREACHED();
235 break;
238 // Calculate the duration.
239 duration_ = ConvertStreamTimestamp(stream->time_base, stream->duration);
241 if (is_encrypted) {
242 AVDictionaryEntry* key = av_dict_get(stream->metadata, "enc_key_id", NULL,
244 DCHECK(key);
245 DCHECK(key->value);
246 if (!key || !key->value)
247 return;
248 base::StringPiece base64_key_id(key->value);
249 std::string enc_key_id;
250 base::Base64Decode(base64_key_id, &enc_key_id);
251 DCHECK(!enc_key_id.empty());
252 if (enc_key_id.empty())
253 return;
255 encryption_key_id_.assign(enc_key_id);
256 demuxer_->OnEncryptedMediaInitData(EmeInitDataType::WEBM, enc_key_id);
260 FFmpegDemuxerStream::~FFmpegDemuxerStream() {
261 DCHECK(!demuxer_);
262 DCHECK(read_cb_.is_null());
263 DCHECK(buffer_queue_.IsEmpty());
266 void FFmpegDemuxerStream::EnqueuePacket(ScopedAVPacket packet) {
267 DCHECK(task_runner_->BelongsToCurrentThread());
269 if (!demuxer_ || end_of_stream_) {
270 NOTREACHED() << "Attempted to enqueue packet on a stopped stream";
271 return;
274 #if defined(USE_PROPRIETARY_CODECS)
275 // Convert the packet if there is a bitstream filter.
276 if (packet->data && bitstream_converter_ &&
277 !bitstream_converter_->ConvertPacket(packet.get())) {
278 LOG(ERROR) << "Format conversion failed.";
280 #endif
282 // Get side data if any. For now, the only type of side_data is VP8 Alpha. We
283 // keep this generic so that other side_data types in the future can be
284 // handled the same way as well.
285 av_packet_split_side_data(packet.get());
287 scoped_refptr<DecoderBuffer> buffer;
289 if (type() == DemuxerStream::TEXT) {
290 int id_size = 0;
291 uint8* id_data = av_packet_get_side_data(
292 packet.get(),
293 AV_PKT_DATA_WEBVTT_IDENTIFIER,
294 &id_size);
296 int settings_size = 0;
297 uint8* settings_data = av_packet_get_side_data(
298 packet.get(),
299 AV_PKT_DATA_WEBVTT_SETTINGS,
300 &settings_size);
302 std::vector<uint8> side_data;
303 MakeSideData(id_data, id_data + id_size,
304 settings_data, settings_data + settings_size,
305 &side_data);
307 buffer = DecoderBuffer::CopyFrom(packet.get()->data, packet.get()->size,
308 side_data.data(), side_data.size());
309 } else {
310 int side_data_size = 0;
311 uint8* side_data = av_packet_get_side_data(
312 packet.get(),
313 AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL,
314 &side_data_size);
316 scoped_ptr<DecryptConfig> decrypt_config;
317 int data_offset = 0;
318 if ((type() == DemuxerStream::AUDIO && audio_config_.is_encrypted()) ||
319 (type() == DemuxerStream::VIDEO && video_config_.is_encrypted())) {
320 if (!WebMCreateDecryptConfig(
321 packet->data, packet->size,
322 reinterpret_cast<const uint8*>(encryption_key_id_.data()),
323 encryption_key_id_.size(),
324 &decrypt_config,
325 &data_offset)) {
326 LOG(ERROR) << "Creation of DecryptConfig failed.";
330 // If a packet is returned by FFmpeg's av_parser_parse2() the packet will
331 // reference inner memory of FFmpeg. As such we should transfer the packet
332 // into memory we control.
333 if (side_data_size > 0) {
334 buffer = DecoderBuffer::CopyFrom(packet.get()->data + data_offset,
335 packet.get()->size - data_offset,
336 side_data, side_data_size);
337 } else {
338 buffer = DecoderBuffer::CopyFrom(packet.get()->data + data_offset,
339 packet.get()->size - data_offset);
342 int skip_samples_size = 0;
343 const uint32* skip_samples_ptr =
344 reinterpret_cast<const uint32*>(av_packet_get_side_data(
345 packet.get(), AV_PKT_DATA_SKIP_SAMPLES, &skip_samples_size));
346 const int kSkipSamplesValidSize = 10;
347 const int kSkipEndSamplesOffset = 1;
348 if (skip_samples_size >= kSkipSamplesValidSize) {
349 // Because FFmpeg rolls codec delay and skip samples into one we can only
350 // allow front discard padding on the first buffer. Otherwise the discard
351 // helper can't figure out which data to discard. See AudioDiscardHelper.
352 int discard_front_samples = base::ByteSwapToLE32(*skip_samples_ptr);
353 if (last_packet_timestamp_ != kNoTimestamp() && discard_front_samples) {
354 DLOG(ERROR) << "Skip samples are only allowed for the first packet.";
355 discard_front_samples = 0;
358 const int discard_end_samples =
359 base::ByteSwapToLE32(*(skip_samples_ptr + kSkipEndSamplesOffset));
360 const int samples_per_second =
361 audio_decoder_config().samples_per_second();
362 buffer->set_discard_padding(std::make_pair(
363 FramesToTimeDelta(discard_front_samples, samples_per_second),
364 FramesToTimeDelta(discard_end_samples, samples_per_second)));
367 if (decrypt_config)
368 buffer->set_decrypt_config(decrypt_config.Pass());
371 if (packet->duration >= 0) {
372 buffer->set_duration(
373 ConvertStreamTimestamp(stream_->time_base, packet->duration));
374 } else {
375 // TODO(wolenetz): Remove when FFmpeg stops returning negative durations.
376 // https://crbug.com/394418
377 DVLOG(1) << "FFmpeg returned a buffer with a negative duration! "
378 << packet->duration;
379 buffer->set_duration(kNoTimestamp());
382 // Note: If pts is AV_NOPTS_VALUE, stream_timestamp will be kNoTimestamp().
383 const base::TimeDelta stream_timestamp =
384 ConvertStreamTimestamp(stream_->time_base, packet->pts);
386 if (stream_timestamp != kNoTimestamp()) {
387 const bool is_audio = type() == AUDIO;
389 // If this file has negative timestamps don't rebase any other stream types
390 // against the negative starting time.
391 base::TimeDelta start_time = demuxer_->start_time();
392 if (fixup_negative_timestamps_ && !is_audio &&
393 start_time < base::TimeDelta()) {
394 start_time = base::TimeDelta();
397 // Don't rebase timestamps for positive start times, the HTML Media Spec
398 // details this in section "4.8.10.6 Offsets into the media resource." We
399 // will still need to rebase timestamps before seeking with FFmpeg though.
400 if (start_time > base::TimeDelta())
401 start_time = base::TimeDelta();
403 buffer->set_timestamp(stream_timestamp - start_time);
405 // If enabled, and no codec delay is present, mark audio packets with
406 // negative timestamps for post-decode discard.
407 if (fixup_negative_timestamps_ && is_audio &&
408 stream_timestamp < base::TimeDelta() &&
409 buffer->duration() != kNoTimestamp()) {
410 if (!stream_->codec->delay) {
411 DCHECK_EQ(buffer->discard_padding().first, base::TimeDelta());
413 if (stream_timestamp + buffer->duration() < base::TimeDelta()) {
414 DCHECK_EQ(buffer->discard_padding().second, base::TimeDelta());
416 // Discard the entire packet if it's entirely before zero.
417 buffer->set_discard_padding(
418 std::make_pair(kInfiniteDuration(), base::TimeDelta()));
419 } else {
420 // Only discard part of the frame if it overlaps zero.
421 buffer->set_discard_padding(std::make_pair(
422 -stream_timestamp, buffer->discard_padding().second));
424 } else {
425 // Verify that codec delay would cover discard and that we don't need to
426 // mark the packet for post decode discard. Since timestamps may be in
427 // milliseconds and codec delay in nanosecond precision, round up to the
428 // nearest millisecond. See enable_negative_timestamp_fixups().
429 DCHECK_LE(-std::ceil(FramesToTimeDelta(
430 audio_decoder_config().codec_delay(),
431 audio_decoder_config().samples_per_second())
432 .InMillisecondsF()),
433 stream_timestamp.InMillisecondsF());
436 } else {
437 // If this happens on the first packet, decoders will throw an error.
438 buffer->set_timestamp(kNoTimestamp());
441 if (last_packet_timestamp_ != kNoTimestamp()) {
442 // FFmpeg doesn't support chained ogg correctly. Instead of guaranteeing
443 // continuity across links in the chain it uses the timestamp information
444 // from each link directly. Doing so can lead to timestamps which appear to
445 // go backwards in time.
447 // If the new link starts with a negative timestamp or a timestamp less than
448 // the original (positive) |start_time|, we will get a negative timestamp
449 // here. It's also possible FFmpeg returns kNoTimestamp() here if it's not
450 // able to work out a timestamp using the previous link and the next.
452 // Fixing chained ogg is non-trivial, so for now just reuse the last good
453 // timestamp. The decoder will rewrite the timestamps to be sample accurate
454 // later. See http://crbug.com/396864.
455 if (fixup_negative_timestamps_ &&
456 (buffer->timestamp() == kNoTimestamp() ||
457 buffer->timestamp() < last_packet_timestamp_)) {
458 buffer->set_timestamp(last_packet_timestamp_ +
459 (last_packet_duration_ != kNoTimestamp()
460 ? last_packet_duration_
461 : base::TimeDelta::FromMicroseconds(1)));
464 // The demuxer should always output positive timestamps.
465 DCHECK(buffer->timestamp() >= base::TimeDelta());
466 DCHECK(buffer->timestamp() != kNoTimestamp());
468 if (last_packet_timestamp_ < buffer->timestamp()) {
469 buffered_ranges_.Add(last_packet_timestamp_, buffer->timestamp());
470 demuxer_->NotifyBufferingChanged();
474 if (packet.get()->flags & AV_PKT_FLAG_KEY)
475 buffer->set_is_key_frame(true);
477 last_packet_timestamp_ = buffer->timestamp();
478 last_packet_duration_ = buffer->duration();
480 buffer_queue_.Push(buffer);
481 SatisfyPendingRead();
484 void FFmpegDemuxerStream::SetEndOfStream() {
485 DCHECK(task_runner_->BelongsToCurrentThread());
486 end_of_stream_ = true;
487 SatisfyPendingRead();
490 void FFmpegDemuxerStream::FlushBuffers() {
491 DCHECK(task_runner_->BelongsToCurrentThread());
492 DCHECK(read_cb_.is_null()) << "There should be no pending read";
494 // H264 and AAC require that we resend the header after flush.
495 // Reset bitstream for converter to do so.
496 // This is related to chromium issue 140371 (http://crbug.com/140371).
497 ResetBitstreamConverter();
499 buffer_queue_.Clear();
500 end_of_stream_ = false;
501 last_packet_timestamp_ = kNoTimestamp();
502 last_packet_duration_ = kNoTimestamp();
505 void FFmpegDemuxerStream::Stop() {
506 DCHECK(task_runner_->BelongsToCurrentThread());
507 buffer_queue_.Clear();
508 if (!read_cb_.is_null()) {
509 base::ResetAndReturn(&read_cb_).Run(
510 DemuxerStream::kOk, DecoderBuffer::CreateEOSBuffer());
512 demuxer_ = NULL;
513 stream_ = NULL;
514 end_of_stream_ = true;
517 DemuxerStream::Type FFmpegDemuxerStream::type() const {
518 DCHECK(task_runner_->BelongsToCurrentThread());
519 return type_;
522 DemuxerStream::Liveness FFmpegDemuxerStream::liveness() const {
523 DCHECK(task_runner_->BelongsToCurrentThread());
524 return liveness_;
527 void FFmpegDemuxerStream::Read(const ReadCB& read_cb) {
528 DCHECK(task_runner_->BelongsToCurrentThread());
529 CHECK(read_cb_.is_null()) << "Overlapping reads are not supported";
530 read_cb_ = BindToCurrentLoop(read_cb);
532 // Don't accept any additional reads if we've been told to stop.
533 // The |demuxer_| may have been destroyed in the pipeline thread.
535 // TODO(scherkus): it would be cleaner to reply with an error message.
536 if (!demuxer_) {
537 base::ResetAndReturn(&read_cb_).Run(
538 DemuxerStream::kOk, DecoderBuffer::CreateEOSBuffer());
539 return;
542 SatisfyPendingRead();
545 void FFmpegDemuxerStream::EnableBitstreamConverter() {
546 DCHECK(task_runner_->BelongsToCurrentThread());
548 #if defined(USE_PROPRIETARY_CODECS)
549 InitBitstreamConverter();
550 #else
551 NOTREACHED() << "Proprietary codecs not enabled.";
552 #endif
555 void FFmpegDemuxerStream::ResetBitstreamConverter() {
556 #if defined(USE_PROPRIETARY_CODECS)
557 if (bitstream_converter_)
558 InitBitstreamConverter();
559 #endif // defined(USE_PROPRIETARY_CODECS)
562 void FFmpegDemuxerStream::InitBitstreamConverter() {
563 #if defined(USE_PROPRIETARY_CODECS)
564 if (stream_->codec->codec_id == AV_CODEC_ID_H264) {
565 bitstream_converter_.reset(
566 new FFmpegH264ToAnnexBBitstreamConverter(stream_->codec));
567 #if defined(ENABLE_HEVC_DEMUXING)
568 } else if (stream_->codec->codec_id == AV_CODEC_ID_HEVC) {
569 bitstream_converter_.reset(
570 new FFmpegH265ToAnnexBBitstreamConverter(stream_->codec));
571 #endif
572 } else if (stream_->codec->codec_id == AV_CODEC_ID_AAC) {
573 bitstream_converter_.reset(
574 new FFmpegAACBitstreamConverter(stream_->codec));
576 #endif // defined(USE_PROPRIETARY_CODECS)
579 bool FFmpegDemuxerStream::SupportsConfigChanges() { return false; }
581 AudioDecoderConfig FFmpegDemuxerStream::audio_decoder_config() {
582 DCHECK(task_runner_->BelongsToCurrentThread());
583 CHECK_EQ(type_, AUDIO);
584 return audio_config_;
587 VideoDecoderConfig FFmpegDemuxerStream::video_decoder_config() {
588 DCHECK(task_runner_->BelongsToCurrentThread());
589 CHECK_EQ(type_, VIDEO);
590 return video_config_;
593 VideoRotation FFmpegDemuxerStream::video_rotation() {
594 return video_rotation_;
597 void FFmpegDemuxerStream::SetLiveness(Liveness liveness) {
598 DCHECK(task_runner_->BelongsToCurrentThread());
599 DCHECK_EQ(liveness_, LIVENESS_UNKNOWN);
600 liveness_ = liveness;
603 base::TimeDelta FFmpegDemuxerStream::GetElapsedTime() const {
604 return ConvertStreamTimestamp(stream_->time_base, stream_->cur_dts);
607 Ranges<base::TimeDelta> FFmpegDemuxerStream::GetBufferedRanges() const {
608 return buffered_ranges_;
611 void FFmpegDemuxerStream::SatisfyPendingRead() {
612 DCHECK(task_runner_->BelongsToCurrentThread());
613 if (!read_cb_.is_null()) {
614 if (!buffer_queue_.IsEmpty()) {
615 base::ResetAndReturn(&read_cb_).Run(
616 DemuxerStream::kOk, buffer_queue_.Pop());
617 } else if (end_of_stream_) {
618 base::ResetAndReturn(&read_cb_).Run(
619 DemuxerStream::kOk, DecoderBuffer::CreateEOSBuffer());
623 // Have capacity? Ask for more!
624 if (HasAvailableCapacity() && !end_of_stream_) {
625 demuxer_->NotifyCapacityAvailable();
629 bool FFmpegDemuxerStream::HasAvailableCapacity() {
630 // TODO(scherkus): Remove this return and reenable time-based capacity
631 // after our data sources support canceling/concurrent reads, see
632 // http://crbug.com/165762 for details.
633 #if 1
634 return !read_cb_.is_null();
635 #else
636 // Try to have one second's worth of encoded data per stream.
637 const base::TimeDelta kCapacity = base::TimeDelta::FromSeconds(1);
638 return buffer_queue_.IsEmpty() || buffer_queue_.Duration() < kCapacity;
639 #endif
642 size_t FFmpegDemuxerStream::MemoryUsage() const {
643 return buffer_queue_.data_size();
646 TextKind FFmpegDemuxerStream::GetTextKind() const {
647 DCHECK_EQ(type_, DemuxerStream::TEXT);
649 if (stream_->disposition & AV_DISPOSITION_CAPTIONS)
650 return kTextCaptions;
652 if (stream_->disposition & AV_DISPOSITION_DESCRIPTIONS)
653 return kTextDescriptions;
655 if (stream_->disposition & AV_DISPOSITION_METADATA)
656 return kTextMetadata;
658 return kTextSubtitles;
661 std::string FFmpegDemuxerStream::GetMetadata(const char* key) const {
662 const AVDictionaryEntry* entry =
663 av_dict_get(stream_->metadata, key, NULL, 0);
664 return (entry == NULL || entry->value == NULL) ? "" : entry->value;
667 // static
668 base::TimeDelta FFmpegDemuxerStream::ConvertStreamTimestamp(
669 const AVRational& time_base, int64 timestamp) {
670 if (timestamp == static_cast<int64>(AV_NOPTS_VALUE))
671 return kNoTimestamp();
673 return ConvertFromTimeBase(time_base, timestamp);
677 // FFmpegDemuxer
679 FFmpegDemuxer::FFmpegDemuxer(
680 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
681 DataSource* data_source,
682 const EncryptedMediaInitDataCB& encrypted_media_init_data_cb,
683 const scoped_refptr<MediaLog>& media_log)
684 : host_(NULL),
685 task_runner_(task_runner),
686 blocking_thread_("FFmpegDemuxer"),
687 pending_read_(false),
688 pending_seek_(false),
689 data_source_(data_source),
690 media_log_(media_log),
691 bitrate_(0),
692 start_time_(kNoTimestamp()),
693 preferred_stream_for_seeking_(-1, kNoTimestamp()),
694 fallback_stream_for_seeking_(-1, kNoTimestamp()),
695 text_enabled_(false),
696 duration_known_(false),
697 encrypted_media_init_data_cb_(encrypted_media_init_data_cb),
698 weak_factory_(this) {
699 DCHECK(task_runner_.get());
700 DCHECK(data_source_);
703 FFmpegDemuxer::~FFmpegDemuxer() {}
705 void FFmpegDemuxer::Stop() {
706 DCHECK(task_runner_->BelongsToCurrentThread());
708 // The order of Stop() and Abort() is important here. If Abort() is called
709 // first, control may pass into FFmpeg where it can destruct buffers that are
710 // in the process of being fulfilled by the DataSource.
711 data_source_->Stop();
712 url_protocol_->Abort();
714 // This will block until all tasks complete. Note that after this returns it's
715 // possible for reply tasks (e.g., OnReadFrameDone()) to be queued on this
716 // thread. Each of the reply task methods must check whether we've stopped the
717 // thread and drop their results on the floor.
718 blocking_thread_.Stop();
720 StreamVector::iterator iter;
721 for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
722 if (*iter)
723 (*iter)->Stop();
726 data_source_ = NULL;
729 void FFmpegDemuxer::Seek(base::TimeDelta time, const PipelineStatusCB& cb) {
730 DCHECK(task_runner_->BelongsToCurrentThread());
731 CHECK(!pending_seek_);
733 // TODO(scherkus): Inspect |pending_read_| and cancel IO via |blocking_url_|,
734 // otherwise we can end up waiting for a pre-seek read to complete even though
735 // we know we're going to drop it on the floor.
737 // FFmpeg requires seeks to be adjusted according to the lowest starting time.
738 // Since EnqueuePacket() rebased negative timestamps by the start time, we
739 // must correct the shift here.
741 // Additionally, to workaround limitations in how we expose seekable ranges to
742 // Blink (http://crbug.com/137275), we also want to clamp seeks before the
743 // start time to the start time.
744 base::TimeDelta seek_time = start_time_ < base::TimeDelta()
745 ? time + start_time_
746 : time < start_time_ ? start_time_ : time;
748 // When seeking in an opus stream we need to ensure we deliver enough data to
749 // satisfy the seek preroll; otherwise the audio at the actual seek time will
750 // not be entirely accurate.
751 FFmpegDemuxerStream* audio_stream = GetFFmpegStream(DemuxerStream::AUDIO);
752 if (audio_stream) {
753 const AudioDecoderConfig& config = audio_stream->audio_decoder_config();
754 if (config.codec() == kCodecOpus)
755 seek_time = std::max(start_time_, seek_time - config.seek_preroll());
758 // Choose the seeking stream based on whether it contains the seek time, if no
759 // match can be found prefer the preferred stream.
761 // TODO(dalecurtis): Currently FFmpeg does not ensure that all streams in a
762 // given container will demux all packets after the seek point. Instead it
763 // only guarantees that all packets after the file position of the seek will
764 // be demuxed. It's an open question whether FFmpeg should fix this:
765 // http://lists.ffmpeg.org/pipermail/ffmpeg-devel/2014-June/159212.html
766 // Tracked by http://crbug.com/387996.
767 DCHECK(preferred_stream_for_seeking_.second != kNoTimestamp());
768 const int stream_index =
769 seek_time < preferred_stream_for_seeking_.second &&
770 seek_time >= fallback_stream_for_seeking_.second
771 ? fallback_stream_for_seeking_.first
772 : preferred_stream_for_seeking_.first;
773 DCHECK_NE(stream_index, -1);
775 const AVStream* seeking_stream =
776 glue_->format_context()->streams[stream_index];
778 pending_seek_ = true;
779 base::PostTaskAndReplyWithResult(
780 blocking_thread_.task_runner().get(),
781 FROM_HERE,
782 base::Bind(&av_seek_frame,
783 glue_->format_context(),
784 seeking_stream->index,
785 ConvertToTimeBase(seeking_stream->time_base, seek_time),
786 // Always seek to a timestamp <= to the desired timestamp.
787 AVSEEK_FLAG_BACKWARD),
788 base::Bind(
789 &FFmpegDemuxer::OnSeekFrameDone, weak_factory_.GetWeakPtr(), cb));
792 std::string FFmpegDemuxer::GetDisplayName() const {
793 return "FFmpegDemuxer";
796 void FFmpegDemuxer::Initialize(DemuxerHost* host,
797 const PipelineStatusCB& status_cb,
798 bool enable_text_tracks) {
799 DCHECK(task_runner_->BelongsToCurrentThread());
800 host_ = host;
801 text_enabled_ = enable_text_tracks;
803 url_protocol_.reset(new BlockingUrlProtocol(data_source_, BindToCurrentLoop(
804 base::Bind(&FFmpegDemuxer::OnDataSourceError, base::Unretained(this)))));
805 glue_.reset(new FFmpegGlue(url_protocol_.get()));
806 AVFormatContext* format_context = glue_->format_context();
808 // Disable ID3v1 tag reading to avoid costly seeks to end of file for data we
809 // don't use. FFmpeg will only read ID3v1 tags if no other metadata is
810 // available, so add a metadata entry to ensure some is always present.
811 av_dict_set(&format_context->metadata, "skip_id3v1_tags", "", 0);
813 // Ensure ffmpeg doesn't give up too early while looking for stream params;
814 // this does not increase the amount of data downloaded. The default value
815 // is 5 AV_TIME_BASE units (1 second each), which prevents some oddly muxed
816 // streams from being detected properly; this value was chosen arbitrarily.
817 format_context->max_analyze_duration2 = 60 * AV_TIME_BASE;
819 // Open the AVFormatContext using our glue layer.
820 CHECK(blocking_thread_.Start());
821 base::PostTaskAndReplyWithResult(
822 blocking_thread_.task_runner().get(),
823 FROM_HERE,
824 base::Bind(&FFmpegGlue::OpenContext, base::Unretained(glue_.get())),
825 base::Bind(&FFmpegDemuxer::OnOpenContextDone,
826 weak_factory_.GetWeakPtr(),
827 status_cb));
830 base::Time FFmpegDemuxer::GetTimelineOffset() const {
831 return timeline_offset_;
834 DemuxerStream* FFmpegDemuxer::GetStream(DemuxerStream::Type type) {
835 DCHECK(task_runner_->BelongsToCurrentThread());
836 return GetFFmpegStream(type);
839 FFmpegDemuxerStream* FFmpegDemuxer::GetFFmpegStream(
840 DemuxerStream::Type type) const {
841 StreamVector::const_iterator iter;
842 for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
843 if (*iter && (*iter)->type() == type) {
844 return *iter;
847 return NULL;
850 base::TimeDelta FFmpegDemuxer::GetStartTime() const {
851 return std::max(start_time_, base::TimeDelta());
854 void FFmpegDemuxer::AddTextStreams() {
855 DCHECK(task_runner_->BelongsToCurrentThread());
857 for (StreamVector::size_type idx = 0; idx < streams_.size(); ++idx) {
858 FFmpegDemuxerStream* stream = streams_[idx];
859 if (stream == NULL || stream->type() != DemuxerStream::TEXT)
860 continue;
862 TextKind kind = stream->GetTextKind();
863 std::string title = stream->GetMetadata("title");
864 std::string language = stream->GetMetadata("language");
866 // TODO: Implement "id" metadata in FFMPEG.
867 // See: http://crbug.com/323183
868 host_->AddTextStream(stream, TextTrackConfig(kind, title, language,
869 std::string()));
873 // Helper for calculating the bitrate of the media based on information stored
874 // in |format_context| or failing that the size and duration of the media.
876 // Returns 0 if a bitrate could not be determined.
877 static int CalculateBitrate(
878 AVFormatContext* format_context,
879 const base::TimeDelta& duration,
880 int64 filesize_in_bytes) {
881 // If there is a bitrate set on the container, use it.
882 if (format_context->bit_rate > 0)
883 return format_context->bit_rate;
885 // Then try to sum the bitrates individually per stream.
886 int bitrate = 0;
887 for (size_t i = 0; i < format_context->nb_streams; ++i) {
888 AVCodecContext* codec_context = format_context->streams[i]->codec;
889 bitrate += codec_context->bit_rate;
891 if (bitrate > 0)
892 return bitrate;
894 // See if we can approximate the bitrate as long as we have a filesize and
895 // valid duration.
896 if (duration.InMicroseconds() <= 0 ||
897 duration == kInfiniteDuration() ||
898 filesize_in_bytes == 0) {
899 return 0;
902 // Do math in floating point as we'd overflow an int64 if the filesize was
903 // larger than ~1073GB.
904 double bytes = filesize_in_bytes;
905 double duration_us = duration.InMicroseconds();
906 return bytes * 8000000.0 / duration_us;
909 void FFmpegDemuxer::OnOpenContextDone(const PipelineStatusCB& status_cb,
910 bool result) {
911 DCHECK(task_runner_->BelongsToCurrentThread());
912 if (!blocking_thread_.IsRunning()) {
913 MEDIA_LOG(ERROR, media_log_) << GetDisplayName() << ": bad state";
914 status_cb.Run(PIPELINE_ERROR_ABORT);
915 return;
918 if (!result) {
919 MEDIA_LOG(ERROR, media_log_) << GetDisplayName() << ": open context failed";
920 status_cb.Run(DEMUXER_ERROR_COULD_NOT_OPEN);
921 return;
924 // Fully initialize AVFormatContext by parsing the stream a little.
925 base::PostTaskAndReplyWithResult(
926 blocking_thread_.task_runner().get(),
927 FROM_HERE,
928 base::Bind(&avformat_find_stream_info,
929 glue_->format_context(),
930 static_cast<AVDictionary**>(NULL)),
931 base::Bind(&FFmpegDemuxer::OnFindStreamInfoDone,
932 weak_factory_.GetWeakPtr(),
933 status_cb));
936 void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb,
937 int result) {
938 DCHECK(task_runner_->BelongsToCurrentThread());
939 if (!blocking_thread_.IsRunning() || !data_source_) {
940 MEDIA_LOG(ERROR, media_log_) << GetDisplayName() << ": bad state";
941 status_cb.Run(PIPELINE_ERROR_ABORT);
942 return;
945 if (result < 0) {
946 MEDIA_LOG(ERROR, media_log_) << GetDisplayName()
947 << ": find stream info failed";
948 status_cb.Run(DEMUXER_ERROR_COULD_NOT_PARSE);
949 return;
952 // Create demuxer stream entries for each possible AVStream. Each stream
953 // is examined to determine if it is supported or not (is the codec enabled
954 // for it in this release?). Unsupported streams are skipped, allowing for
955 // partial playback. At least one audio or video stream must be playable.
956 AVFormatContext* format_context = glue_->format_context();
957 streams_.resize(format_context->nb_streams);
959 // Estimate the start time for each stream by looking through the packets
960 // buffered during avformat_find_stream_info(). These values will be
961 // considered later when determining the actual stream start time.
963 // These packets haven't been completely processed yet, so only look through
964 // these values if the AVFormatContext has a valid start time.
966 // If no estimate is found, the stream entry will be kInfiniteDuration().
967 std::vector<base::TimeDelta> start_time_estimates(format_context->nb_streams,
968 kInfiniteDuration());
969 const AVFormatInternal* internal = format_context->internal;
970 if (internal && internal->packet_buffer &&
971 format_context->start_time != static_cast<int64>(AV_NOPTS_VALUE)) {
972 struct AVPacketList* packet_buffer = internal->packet_buffer;
973 while (packet_buffer != internal->packet_buffer_end) {
974 DCHECK_LT(static_cast<size_t>(packet_buffer->pkt.stream_index),
975 start_time_estimates.size());
976 const AVStream* stream =
977 format_context->streams[packet_buffer->pkt.stream_index];
978 if (packet_buffer->pkt.pts != static_cast<int64>(AV_NOPTS_VALUE)) {
979 const base::TimeDelta packet_pts =
980 ConvertFromTimeBase(stream->time_base, packet_buffer->pkt.pts);
981 if (packet_pts < start_time_estimates[stream->index])
982 start_time_estimates[stream->index] = packet_pts;
984 packet_buffer = packet_buffer->next;
988 AVStream* audio_stream = NULL;
989 AudioDecoderConfig audio_config;
991 AVStream* video_stream = NULL;
992 VideoDecoderConfig video_config;
994 // If available, |start_time_| will be set to the lowest stream start time.
995 start_time_ = kInfiniteDuration();
997 base::TimeDelta max_duration;
998 for (size_t i = 0; i < format_context->nb_streams; ++i) {
999 AVStream* stream = format_context->streams[i];
1000 const AVCodecContext* codec_context = stream->codec;
1001 const AVMediaType codec_type = codec_context->codec_type;
1003 if (codec_type == AVMEDIA_TYPE_AUDIO) {
1004 if (audio_stream)
1005 continue;
1007 // Log the codec detected, whether it is supported or not.
1008 UMA_HISTOGRAM_SPARSE_SLOWLY("Media.DetectedAudioCodecHash",
1009 GetCodecHash(codec_context));
1011 // Ensure the codec is supported. IsValidConfig() also checks that the
1012 // channel layout and sample format are valid.
1013 AVStreamToAudioDecoderConfig(stream, &audio_config);
1014 if (!audio_config.IsValidConfig())
1015 continue;
1016 audio_stream = stream;
1017 } else if (codec_type == AVMEDIA_TYPE_VIDEO) {
1018 if (video_stream)
1019 continue;
1021 #if defined(ENABLE_HEVC_DEMUXING)
1022 if (stream->codec->codec_id == AV_CODEC_ID_HEVC) {
1023 // If ffmpeg is built without HEVC parser/decoder support, it will be
1024 // able to demux HEVC based solely on container-provided information,
1025 // but unable to get some of the parameters without parsing the stream
1026 // (e.g. coded size needs to be read from SPS, pixel format is typically
1027 // deduced from decoder config in hvcC box). These are not really needed
1028 // when using external decoder (e.g. hardware decoder), so override them
1029 // here, to make sure this translates into a valid VideoDecoderConfig.
1030 if (stream->codec->coded_width == 0 &&
1031 stream->codec->coded_height == 0) {
1032 DCHECK(stream->codec->width > 0);
1033 DCHECK(stream->codec->height > 0);
1034 stream->codec->coded_width = stream->codec->width;
1035 stream->codec->coded_height = stream->codec->height;
1037 if (stream->codec->pix_fmt == AV_PIX_FMT_NONE) {
1038 stream->codec->pix_fmt = PIX_FMT_YUV420P;
1041 #endif
1042 // Log the codec detected, whether it is supported or not.
1043 UMA_HISTOGRAM_SPARSE_SLOWLY("Media.DetectedVideoCodecHash",
1044 GetCodecHash(codec_context));
1046 // Ensure the codec is supported. IsValidConfig() also checks that the
1047 // frame size and visible size are valid.
1048 AVStreamToVideoDecoderConfig(stream, &video_config);
1050 if (!video_config.IsValidConfig())
1051 continue;
1052 video_stream = stream;
1053 } else if (codec_type == AVMEDIA_TYPE_SUBTITLE) {
1054 if (codec_context->codec_id != AV_CODEC_ID_WEBVTT || !text_enabled_) {
1055 continue;
1057 } else {
1058 continue;
1061 streams_[i] = new FFmpegDemuxerStream(this, stream);
1063 // Record audio or video src= playback UMA stats for the stream's decoder
1064 // config.
1065 if (codec_type == AVMEDIA_TYPE_AUDIO) {
1066 RecordAudioCodecStats(streams_[i]->audio_decoder_config());
1067 } else if (codec_type == AVMEDIA_TYPE_VIDEO) {
1068 RecordVideoCodecStats(streams_[i]->video_decoder_config(),
1069 stream->codec->color_range);
1072 max_duration = std::max(max_duration, streams_[i]->duration());
1074 const base::TimeDelta start_time =
1075 ExtractStartTime(stream, start_time_estimates[i]);
1076 const bool has_start_time = start_time != kNoTimestamp();
1078 // Always prefer the video stream for seeking. If none exists, we'll swap
1079 // the fallback stream with the preferred stream below.
1080 if (codec_type == AVMEDIA_TYPE_VIDEO) {
1081 preferred_stream_for_seeking_ =
1082 StreamSeekInfo(i, has_start_time ? start_time : base::TimeDelta());
1085 if (!has_start_time)
1086 continue;
1088 if (start_time < start_time_) {
1089 start_time_ = start_time;
1091 // Choose the stream with the lowest starting time as the fallback stream
1092 // for seeking. Video should always be preferred.
1093 fallback_stream_for_seeking_ = StreamSeekInfo(i, start_time);
1097 if (!audio_stream && !video_stream) {
1098 MEDIA_LOG(ERROR, media_log_) << GetDisplayName()
1099 << ": no supported streams";
1100 status_cb.Run(DEMUXER_ERROR_NO_SUPPORTED_STREAMS);
1101 return;
1104 if (text_enabled_)
1105 AddTextStreams();
1107 if (format_context->duration != static_cast<int64_t>(AV_NOPTS_VALUE)) {
1108 // If there is a duration value in the container use that to find the
1109 // maximum between it and the duration from A/V streams.
1110 const AVRational av_time_base = {1, AV_TIME_BASE};
1111 max_duration =
1112 std::max(max_duration,
1113 ConvertFromTimeBase(av_time_base, format_context->duration));
1114 } else {
1115 // The duration is unknown, in which case this is likely a live stream.
1116 max_duration = kInfiniteDuration();
1119 // FFmpeg represents audio data marked as before the beginning of stream as
1120 // having negative timestamps. This data must be discarded after it has been
1121 // decoded, not before since it is used to warmup the decoder. There are
1122 // currently two known cases for this: vorbis in ogg and opus in ogg and webm.
1124 // For API clarity, it was decided that the rest of the media pipeline should
1125 // not be exposed to negative timestamps. Which means we need to rebase these
1126 // negative timestamps and mark them for discard post decoding.
1128 // Post-decode frame dropping for packets with negative timestamps is outlined
1129 // in section A.2 in the Ogg Vorbis spec:
1130 // http://xiph.org/vorbis/doc/Vorbis_I_spec.html
1132 // FFmpeg's use of negative timestamps for opus pre-skip is nonstandard, but
1133 // for more information on pre-skip see section 4.2 of the Ogg Opus spec:
1134 // https://tools.ietf.org/html/draft-ietf-codec-oggopus-08#section-4.2
1135 if (audio_stream && (audio_stream->codec->codec_id == AV_CODEC_ID_OPUS ||
1136 (strcmp(format_context->iformat->name, "ogg") == 0 &&
1137 audio_stream->codec->codec_id == AV_CODEC_ID_VORBIS))) {
1138 for (size_t i = 0; i < streams_.size(); ++i) {
1139 if (streams_[i])
1140 streams_[i]->enable_negative_timestamp_fixups();
1143 // Fixup the seeking information to avoid selecting the audio stream simply
1144 // because it has a lower starting time.
1145 if (fallback_stream_for_seeking_.first == audio_stream->index &&
1146 fallback_stream_for_seeking_.second < base::TimeDelta()) {
1147 fallback_stream_for_seeking_.second = base::TimeDelta();
1151 // If no start time could be determined, default to zero and prefer the video
1152 // stream over the audio stream for seeking. E.g., The WAV demuxer does not
1153 // put timestamps on its frames.
1154 if (start_time_ == kInfiniteDuration()) {
1155 start_time_ = base::TimeDelta();
1156 preferred_stream_for_seeking_ = StreamSeekInfo(
1157 video_stream ? video_stream->index : audio_stream->index, start_time_);
1158 } else if (!video_stream) {
1159 // If no video stream exists, use the audio or text stream found above.
1160 preferred_stream_for_seeking_ = fallback_stream_for_seeking_;
1163 // MPEG-4 B-frames cause grief for a simple container like AVI. Enable PTS
1164 // generation so we always get timestamps, see http://crbug.com/169570
1165 if (strcmp(format_context->iformat->name, "avi") == 0)
1166 format_context->flags |= AVFMT_FLAG_GENPTS;
1168 // For testing purposes, don't overwrite the timeline offset if set already.
1169 if (timeline_offset_.is_null())
1170 timeline_offset_ = ExtractTimelineOffset(format_context);
1172 // Since we're shifting the externally visible start time to zero, we need to
1173 // adjust the timeline offset to compensate.
1174 if (!timeline_offset_.is_null() && start_time_ < base::TimeDelta())
1175 timeline_offset_ += start_time_;
1177 if (max_duration == kInfiniteDuration() && !timeline_offset_.is_null()) {
1178 SetLiveness(DemuxerStream::LIVENESS_LIVE);
1179 } else if (max_duration != kInfiniteDuration()) {
1180 SetLiveness(DemuxerStream::LIVENESS_RECORDED);
1181 } else {
1182 SetLiveness(DemuxerStream::LIVENESS_UNKNOWN);
1185 // Good to go: set the duration and bitrate and notify we're done
1186 // initializing.
1187 host_->SetDuration(max_duration);
1188 duration_known_ = (max_duration != kInfiniteDuration());
1190 int64 filesize_in_bytes = 0;
1191 url_protocol_->GetSize(&filesize_in_bytes);
1192 bitrate_ = CalculateBitrate(format_context, max_duration, filesize_in_bytes);
1193 if (bitrate_ > 0)
1194 data_source_->SetBitrate(bitrate_);
1196 // Audio logging
1197 if (audio_stream) {
1198 AVCodecContext* audio_codec = audio_stream->codec;
1199 media_log_->SetBooleanProperty("found_audio_stream", true);
1201 SampleFormat sample_format = audio_config.sample_format();
1202 std::string sample_name = SampleFormatToString(sample_format);
1204 media_log_->SetStringProperty("audio_sample_format", sample_name);
1206 AVCodec* codec = avcodec_find_decoder(audio_codec->codec_id);
1207 if (codec) {
1208 media_log_->SetStringProperty("audio_codec_name", codec->name);
1211 media_log_->SetIntegerProperty("audio_channels_count",
1212 audio_codec->channels);
1213 media_log_->SetIntegerProperty("audio_samples_per_second",
1214 audio_config.samples_per_second());
1215 } else {
1216 media_log_->SetBooleanProperty("found_audio_stream", false);
1219 // Video logging
1220 if (video_stream) {
1221 AVCodecContext* video_codec = video_stream->codec;
1222 media_log_->SetBooleanProperty("found_video_stream", true);
1224 AVCodec* codec = avcodec_find_decoder(video_codec->codec_id);
1225 if (codec) {
1226 media_log_->SetStringProperty("video_codec_name", codec->name);
1227 } else if (video_codec->codec_id == AV_CODEC_ID_VP9) {
1228 // ffmpeg doesn't know about VP9 decoder. So we need to log it explicitly.
1229 media_log_->SetStringProperty("video_codec_name", "vp9");
1232 media_log_->SetIntegerProperty("width", video_codec->width);
1233 media_log_->SetIntegerProperty("height", video_codec->height);
1234 media_log_->SetIntegerProperty("coded_width",
1235 video_codec->coded_width);
1236 media_log_->SetIntegerProperty("coded_height",
1237 video_codec->coded_height);
1238 media_log_->SetStringProperty(
1239 "time_base",
1240 base::StringPrintf("%d/%d",
1241 video_codec->time_base.num,
1242 video_codec->time_base.den));
1243 media_log_->SetStringProperty(
1244 "video_format", VideoPixelFormatToString(video_config.format()));
1245 media_log_->SetBooleanProperty("video_is_encrypted",
1246 video_config.is_encrypted());
1247 } else {
1248 media_log_->SetBooleanProperty("found_video_stream", false);
1251 media_log_->SetTimeProperty("max_duration", max_duration);
1252 media_log_->SetTimeProperty("start_time", start_time_);
1253 media_log_->SetIntegerProperty("bitrate", bitrate_);
1255 status_cb.Run(PIPELINE_OK);
1258 void FFmpegDemuxer::OnSeekFrameDone(const PipelineStatusCB& cb, int result) {
1259 DCHECK(task_runner_->BelongsToCurrentThread());
1260 CHECK(pending_seek_);
1261 pending_seek_ = false;
1263 if (!blocking_thread_.IsRunning()) {
1264 MEDIA_LOG(ERROR, media_log_) << GetDisplayName() << ": bad state";
1265 cb.Run(PIPELINE_ERROR_ABORT);
1266 return;
1269 if (result < 0) {
1270 // Use VLOG(1) instead of NOTIMPLEMENTED() to prevent the message being
1271 // captured from stdout and contaminates testing.
1272 // TODO(scherkus): Implement this properly and signal error (BUG=23447).
1273 VLOG(1) << "Not implemented";
1276 // Tell streams to flush buffers due to seeking.
1277 StreamVector::iterator iter;
1278 for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
1279 if (*iter)
1280 (*iter)->FlushBuffers();
1283 // Resume reading until capacity.
1284 ReadFrameIfNeeded();
1286 // Notify we're finished seeking.
1287 cb.Run(PIPELINE_OK);
1290 void FFmpegDemuxer::ReadFrameIfNeeded() {
1291 DCHECK(task_runner_->BelongsToCurrentThread());
1293 // Make sure we have work to do before reading.
1294 if (!blocking_thread_.IsRunning() || !StreamsHaveAvailableCapacity() ||
1295 pending_read_ || pending_seek_) {
1296 return;
1299 // Allocate and read an AVPacket from the media. Save |packet_ptr| since
1300 // evaluation order of packet.get() and base::Passed(&packet) is
1301 // undefined.
1302 ScopedAVPacket packet(new AVPacket());
1303 AVPacket* packet_ptr = packet.get();
1305 pending_read_ = true;
1306 base::PostTaskAndReplyWithResult(
1307 blocking_thread_.task_runner().get(),
1308 FROM_HERE,
1309 base::Bind(&av_read_frame, glue_->format_context(), packet_ptr),
1310 base::Bind(&FFmpegDemuxer::OnReadFrameDone,
1311 weak_factory_.GetWeakPtr(),
1312 base::Passed(&packet)));
1315 void FFmpegDemuxer::OnReadFrameDone(ScopedAVPacket packet, int result) {
1316 DCHECK(task_runner_->BelongsToCurrentThread());
1317 DCHECK(pending_read_);
1318 pending_read_ = false;
1320 if (!blocking_thread_.IsRunning() || pending_seek_) {
1321 return;
1324 // Consider the stream as ended if:
1325 // - either underlying ffmpeg returned an error
1326 // - or FFMpegDemuxer reached the maximum allowed memory usage.
1327 if (result < 0 || IsMaxMemoryUsageReached()) {
1328 // Update the duration based on the highest elapsed time across all streams
1329 // if it was previously unknown.
1330 if (!duration_known_) {
1331 base::TimeDelta max_duration;
1333 for (StreamVector::iterator iter = streams_.begin();
1334 iter != streams_.end();
1335 ++iter) {
1336 if (!*iter)
1337 continue;
1339 base::TimeDelta duration = (*iter)->GetElapsedTime();
1340 if (duration != kNoTimestamp() && duration > max_duration)
1341 max_duration = duration;
1344 if (max_duration > base::TimeDelta()) {
1345 host_->SetDuration(max_duration);
1346 duration_known_ = true;
1349 // If we have reached the end of stream, tell the downstream filters about
1350 // the event.
1351 StreamHasEnded();
1352 return;
1355 // Queue the packet with the appropriate stream.
1356 DCHECK_GE(packet->stream_index, 0);
1357 DCHECK_LT(packet->stream_index, static_cast<int>(streams_.size()));
1359 // Defend against ffmpeg giving us a bad stream index.
1360 if (packet->stream_index >= 0 &&
1361 packet->stream_index < static_cast<int>(streams_.size()) &&
1362 streams_[packet->stream_index]) {
1363 // TODO(scherkus): Fix demuxing upstream to never return packets w/o data
1364 // when av_read_frame() returns success code. See bug comment for ideas:
1366 // https://code.google.com/p/chromium/issues/detail?id=169133#c10
1367 if (!packet->data) {
1368 ScopedAVPacket new_packet(new AVPacket());
1369 av_new_packet(new_packet.get(), 0);
1370 av_packet_copy_props(new_packet.get(), packet.get());
1371 packet.swap(new_packet);
1374 FFmpegDemuxerStream* demuxer_stream = streams_[packet->stream_index];
1375 demuxer_stream->EnqueuePacket(packet.Pass());
1378 // Keep reading until we've reached capacity.
1379 ReadFrameIfNeeded();
1382 bool FFmpegDemuxer::StreamsHaveAvailableCapacity() {
1383 DCHECK(task_runner_->BelongsToCurrentThread());
1384 StreamVector::iterator iter;
1385 for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
1386 if (*iter && (*iter)->HasAvailableCapacity()) {
1387 return true;
1390 return false;
1393 bool FFmpegDemuxer::IsMaxMemoryUsageReached() const {
1394 DCHECK(task_runner_->BelongsToCurrentThread());
1396 // Max allowed memory usage, all streams combined.
1397 const size_t kDemuxerMemoryLimit = 150 * 1024 * 1024;
1399 size_t memory_left = kDemuxerMemoryLimit;
1400 for (StreamVector::const_iterator iter = streams_.begin();
1401 iter != streams_.end(); ++iter) {
1402 if (!(*iter))
1403 continue;
1405 size_t stream_memory_usage = (*iter)->MemoryUsage();
1406 if (stream_memory_usage > memory_left)
1407 return true;
1408 memory_left -= stream_memory_usage;
1410 return false;
1413 void FFmpegDemuxer::StreamHasEnded() {
1414 DCHECK(task_runner_->BelongsToCurrentThread());
1415 StreamVector::iterator iter;
1416 for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
1417 if (!*iter)
1418 continue;
1419 (*iter)->SetEndOfStream();
1423 void FFmpegDemuxer::OnEncryptedMediaInitData(
1424 EmeInitDataType init_data_type,
1425 const std::string& encryption_key_id) {
1426 std::vector<uint8> key_id_local(encryption_key_id.begin(),
1427 encryption_key_id.end());
1428 encrypted_media_init_data_cb_.Run(init_data_type, key_id_local);
1431 void FFmpegDemuxer::NotifyCapacityAvailable() {
1432 DCHECK(task_runner_->BelongsToCurrentThread());
1433 ReadFrameIfNeeded();
1436 void FFmpegDemuxer::NotifyBufferingChanged() {
1437 DCHECK(task_runner_->BelongsToCurrentThread());
1438 Ranges<base::TimeDelta> buffered;
1439 FFmpegDemuxerStream* audio = GetFFmpegStream(DemuxerStream::AUDIO);
1440 FFmpegDemuxerStream* video = GetFFmpegStream(DemuxerStream::VIDEO);
1441 if (audio && video) {
1442 buffered = audio->GetBufferedRanges().IntersectionWith(
1443 video->GetBufferedRanges());
1444 } else if (audio) {
1445 buffered = audio->GetBufferedRanges();
1446 } else if (video) {
1447 buffered = video->GetBufferedRanges();
1449 for (size_t i = 0; i < buffered.size(); ++i)
1450 host_->AddBufferedTimeRange(buffered.start(i), buffered.end(i));
1453 void FFmpegDemuxer::OnDataSourceError() {
1454 MEDIA_LOG(ERROR, media_log_) << GetDisplayName() << ": data source error";
1455 host_->OnDemuxerError(PIPELINE_ERROR_READ);
1458 void FFmpegDemuxer::SetLiveness(DemuxerStream::Liveness liveness) {
1459 DCHECK(task_runner_->BelongsToCurrentThread());
1460 for (const auto& stream : streams_) { // |stream| is a ref to a pointer.
1461 if (stream)
1462 stream->SetLiveness(liveness);
1466 } // namespace media