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"
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.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"
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
;
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
),
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.
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(
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(),
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);
123 if (ToAudioSampleRate(audio_config
.samples_per_second(), &asr
)) {
124 UMA_HISTOGRAM_ENUMERATION("Media.AudioSamplesPerSecond", asr
,
125 kAudioSampleRateMax
+ 1);
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(),
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
164 // FFmpegDemuxerStream
166 FFmpegDemuxerStream::FFmpegDemuxerStream(FFmpegDemuxer
* demuxer
,
169 task_runner_(base::ThreadTaskRunnerHandle::Get()),
172 liveness_(LIVENESS_UNKNOWN
),
173 end_of_stream_(false),
174 last_packet_timestamp_(kNoTimestamp()),
175 last_packet_duration_(kNoTimestamp()),
176 video_rotation_(VIDEO_ROTATION_0
),
177 fixup_negative_timestamps_(false) {
180 bool is_encrypted
= false;
182 AVDictionaryEntry
* rotation_entry
= NULL
;
184 // Determine our media format.
185 switch (stream
->codec
->codec_type
) {
186 case AVMEDIA_TYPE_AUDIO
:
188 AVStreamToAudioDecoderConfig(stream
, &audio_config_
);
189 is_encrypted
= audio_config_
.is_encrypted();
191 case AVMEDIA_TYPE_VIDEO
:
193 AVStreamToVideoDecoderConfig(stream
, &video_config_
);
194 is_encrypted
= video_config_
.is_encrypted();
196 rotation_entry
= av_dict_get(stream
->metadata
, "rotate", NULL
, 0);
197 if (rotation_entry
&& rotation_entry
->value
&& rotation_entry
->value
[0])
198 base::StringToInt(rotation_entry
->value
, &rotation
);
204 video_rotation_
= VIDEO_ROTATION_90
;
207 video_rotation_
= VIDEO_ROTATION_180
;
210 video_rotation_
= VIDEO_ROTATION_270
;
213 LOG(ERROR
) << "Unsupported video rotation metadata: " << rotation
;
218 case AVMEDIA_TYPE_SUBTITLE
:
226 // Calculate the duration.
227 duration_
= ConvertStreamTimestamp(stream
->time_base
, stream
->duration
);
230 AVDictionaryEntry
* key
= av_dict_get(stream
->metadata
, "enc_key_id", NULL
,
234 if (!key
|| !key
->value
)
236 base::StringPiece
base64_key_id(key
->value
);
237 std::string enc_key_id
;
238 base::Base64Decode(base64_key_id
, &enc_key_id
);
239 DCHECK(!enc_key_id
.empty());
240 if (enc_key_id
.empty())
243 encryption_key_id_
.assign(enc_key_id
);
244 demuxer_
->OnEncryptedMediaInitData(EmeInitDataType::WEBM
, enc_key_id
);
248 FFmpegDemuxerStream::~FFmpegDemuxerStream() {
250 DCHECK(read_cb_
.is_null());
251 DCHECK(buffer_queue_
.IsEmpty());
254 void FFmpegDemuxerStream::EnqueuePacket(ScopedAVPacket packet
) {
255 DCHECK(task_runner_
->BelongsToCurrentThread());
257 if (!demuxer_
|| end_of_stream_
) {
258 NOTREACHED() << "Attempted to enqueue packet on a stopped stream";
262 #if defined(USE_PROPRIETARY_CODECS)
263 // Convert the packet if there is a bitstream filter.
264 if (packet
->data
&& bitstream_converter_
&&
265 !bitstream_converter_
->ConvertPacket(packet
.get())) {
266 LOG(ERROR
) << "Format conversion failed.";
270 // Get side data if any. For now, the only type of side_data is VP8 Alpha. We
271 // keep this generic so that other side_data types in the future can be
272 // handled the same way as well.
273 av_packet_split_side_data(packet
.get());
275 scoped_refptr
<DecoderBuffer
> buffer
;
277 if (type() == DemuxerStream::TEXT
) {
279 uint8
* id_data
= av_packet_get_side_data(
281 AV_PKT_DATA_WEBVTT_IDENTIFIER
,
284 int settings_size
= 0;
285 uint8
* settings_data
= av_packet_get_side_data(
287 AV_PKT_DATA_WEBVTT_SETTINGS
,
290 std::vector
<uint8
> side_data
;
291 MakeSideData(id_data
, id_data
+ id_size
,
292 settings_data
, settings_data
+ settings_size
,
295 buffer
= DecoderBuffer::CopyFrom(packet
.get()->data
, packet
.get()->size
,
296 side_data
.data(), side_data
.size());
298 int side_data_size
= 0;
299 uint8
* side_data
= av_packet_get_side_data(
301 AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL
,
304 scoped_ptr
<DecryptConfig
> decrypt_config
;
306 if ((type() == DemuxerStream::AUDIO
&& audio_config_
.is_encrypted()) ||
307 (type() == DemuxerStream::VIDEO
&& video_config_
.is_encrypted())) {
308 if (!WebMCreateDecryptConfig(
309 packet
->data
, packet
->size
,
310 reinterpret_cast<const uint8
*>(encryption_key_id_
.data()),
311 encryption_key_id_
.size(),
314 LOG(ERROR
) << "Creation of DecryptConfig failed.";
318 // If a packet is returned by FFmpeg's av_parser_parse2() the packet will
319 // reference inner memory of FFmpeg. As such we should transfer the packet
320 // into memory we control.
321 if (side_data_size
> 0) {
322 buffer
= DecoderBuffer::CopyFrom(packet
.get()->data
+ data_offset
,
323 packet
.get()->size
- data_offset
,
324 side_data
, side_data_size
);
326 buffer
= DecoderBuffer::CopyFrom(packet
.get()->data
+ data_offset
,
327 packet
.get()->size
- data_offset
);
330 int skip_samples_size
= 0;
331 const uint32
* skip_samples_ptr
=
332 reinterpret_cast<const uint32
*>(av_packet_get_side_data(
333 packet
.get(), AV_PKT_DATA_SKIP_SAMPLES
, &skip_samples_size
));
334 const int kSkipSamplesValidSize
= 10;
335 const int kSkipEndSamplesOffset
= 1;
336 if (skip_samples_size
>= kSkipSamplesValidSize
) {
337 // Because FFmpeg rolls codec delay and skip samples into one we can only
338 // allow front discard padding on the first buffer. Otherwise the discard
339 // helper can't figure out which data to discard. See AudioDiscardHelper.
340 int discard_front_samples
= base::ByteSwapToLE32(*skip_samples_ptr
);
341 if (last_packet_timestamp_
!= kNoTimestamp() && discard_front_samples
) {
342 DLOG(ERROR
) << "Skip samples are only allowed for the first packet.";
343 discard_front_samples
= 0;
346 const int discard_end_samples
=
347 base::ByteSwapToLE32(*(skip_samples_ptr
+ kSkipEndSamplesOffset
));
348 const int samples_per_second
=
349 audio_decoder_config().samples_per_second();
350 buffer
->set_discard_padding(std::make_pair(
351 FramesToTimeDelta(discard_front_samples
, samples_per_second
),
352 FramesToTimeDelta(discard_end_samples
, samples_per_second
)));
356 buffer
->set_decrypt_config(decrypt_config
.Pass());
359 if (packet
->duration
>= 0) {
360 buffer
->set_duration(
361 ConvertStreamTimestamp(stream_
->time_base
, packet
->duration
));
363 // TODO(wolenetz): Remove when FFmpeg stops returning negative durations.
364 // https://crbug.com/394418
365 DVLOG(1) << "FFmpeg returned a buffer with a negative duration! "
367 buffer
->set_duration(kNoTimestamp());
370 // Note: If pts is AV_NOPTS_VALUE, stream_timestamp will be kNoTimestamp().
371 const base::TimeDelta stream_timestamp
=
372 ConvertStreamTimestamp(stream_
->time_base
, packet
->pts
);
374 if (stream_timestamp
!= kNoTimestamp()) {
375 const bool is_audio
= type() == AUDIO
;
377 // If this file has negative timestamps don't rebase any other stream types
378 // against the negative starting time.
379 base::TimeDelta start_time
= demuxer_
->start_time();
380 if (fixup_negative_timestamps_
&& !is_audio
&&
381 start_time
< base::TimeDelta()) {
382 start_time
= base::TimeDelta();
385 // Don't rebase timestamps for positive start times, the HTML Media Spec
386 // details this in section "4.8.10.6 Offsets into the media resource." We
387 // will still need to rebase timestamps before seeking with FFmpeg though.
388 if (start_time
> base::TimeDelta())
389 start_time
= base::TimeDelta();
391 buffer
->set_timestamp(stream_timestamp
- start_time
);
393 // If enabled, and no codec delay is present, mark audio packets with
394 // negative timestamps for post-decode discard.
395 if (fixup_negative_timestamps_
&& is_audio
&&
396 stream_timestamp
< base::TimeDelta() &&
397 buffer
->duration() != kNoTimestamp()) {
398 if (!stream_
->codec
->delay
) {
399 DCHECK_EQ(buffer
->discard_padding().first
, base::TimeDelta());
401 if (stream_timestamp
+ buffer
->duration() < base::TimeDelta()) {
402 DCHECK_EQ(buffer
->discard_padding().second
, base::TimeDelta());
404 // Discard the entire packet if it's entirely before zero.
405 buffer
->set_discard_padding(
406 std::make_pair(kInfiniteDuration(), base::TimeDelta()));
408 // Only discard part of the frame if it overlaps zero.
409 buffer
->set_discard_padding(std::make_pair(
410 -stream_timestamp
, buffer
->discard_padding().second
));
413 // Verify that codec delay would cover discard and that we don't need to
414 // mark the packet for post decode discard. Since timestamps may be in
415 // milliseconds and codec delay in nanosecond precision, round up to the
416 // nearest millisecond. See enable_negative_timestamp_fixups().
417 DCHECK_LE(-std::ceil(FramesToTimeDelta(
418 audio_decoder_config().codec_delay(),
419 audio_decoder_config().samples_per_second())
421 stream_timestamp
.InMillisecondsF());
425 // If this happens on the first packet, decoders will throw an error.
426 buffer
->set_timestamp(kNoTimestamp());
429 if (last_packet_timestamp_
!= kNoTimestamp()) {
430 // FFmpeg doesn't support chained ogg correctly. Instead of guaranteeing
431 // continuity across links in the chain it uses the timestamp information
432 // from each link directly. Doing so can lead to timestamps which appear to
433 // go backwards in time.
435 // If the new link starts with a negative timestamp or a timestamp less than
436 // the original (positive) |start_time|, we will get a negative timestamp
437 // here. It's also possible FFmpeg returns kNoTimestamp() here if it's not
438 // able to work out a timestamp using the previous link and the next.
440 // Fixing chained ogg is non-trivial, so for now just reuse the last good
441 // timestamp. The decoder will rewrite the timestamps to be sample accurate
442 // later. See http://crbug.com/396864.
443 if (fixup_negative_timestamps_
&&
444 (buffer
->timestamp() == kNoTimestamp() ||
445 buffer
->timestamp() < last_packet_timestamp_
)) {
446 buffer
->set_timestamp(last_packet_timestamp_
+
447 (last_packet_duration_
!= kNoTimestamp()
448 ? last_packet_duration_
449 : base::TimeDelta::FromMicroseconds(1)));
452 // The demuxer should always output positive timestamps.
453 DCHECK(buffer
->timestamp() >= base::TimeDelta());
454 DCHECK(buffer
->timestamp() != kNoTimestamp());
456 if (last_packet_timestamp_
< buffer
->timestamp()) {
457 buffered_ranges_
.Add(last_packet_timestamp_
, buffer
->timestamp());
458 demuxer_
->NotifyBufferingChanged();
462 if (packet
.get()->flags
& AV_PKT_FLAG_KEY
)
463 buffer
->set_is_key_frame(true);
465 last_packet_timestamp_
= buffer
->timestamp();
466 last_packet_duration_
= buffer
->duration();
468 buffer_queue_
.Push(buffer
);
469 SatisfyPendingRead();
472 void FFmpegDemuxerStream::SetEndOfStream() {
473 DCHECK(task_runner_
->BelongsToCurrentThread());
474 end_of_stream_
= true;
475 SatisfyPendingRead();
478 void FFmpegDemuxerStream::FlushBuffers() {
479 DCHECK(task_runner_
->BelongsToCurrentThread());
480 DCHECK(read_cb_
.is_null()) << "There should be no pending read";
482 // H264 and AAC require that we resend the header after flush.
483 // Reset bitstream for converter to do so.
484 // This is related to chromium issue 140371 (http://crbug.com/140371).
485 ResetBitstreamConverter();
487 buffer_queue_
.Clear();
488 end_of_stream_
= false;
489 last_packet_timestamp_
= kNoTimestamp();
490 last_packet_duration_
= kNoTimestamp();
493 void FFmpegDemuxerStream::Stop() {
494 DCHECK(task_runner_
->BelongsToCurrentThread());
495 buffer_queue_
.Clear();
496 if (!read_cb_
.is_null()) {
497 base::ResetAndReturn(&read_cb_
).Run(
498 DemuxerStream::kOk
, DecoderBuffer::CreateEOSBuffer());
502 end_of_stream_
= true;
505 DemuxerStream::Type
FFmpegDemuxerStream::type() const {
506 DCHECK(task_runner_
->BelongsToCurrentThread());
510 DemuxerStream::Liveness
FFmpegDemuxerStream::liveness() const {
511 DCHECK(task_runner_
->BelongsToCurrentThread());
515 void FFmpegDemuxerStream::Read(const ReadCB
& read_cb
) {
516 DCHECK(task_runner_
->BelongsToCurrentThread());
517 CHECK(read_cb_
.is_null()) << "Overlapping reads are not supported";
518 read_cb_
= BindToCurrentLoop(read_cb
);
520 // Don't accept any additional reads if we've been told to stop.
521 // The |demuxer_| may have been destroyed in the pipeline thread.
523 // TODO(scherkus): it would be cleaner to reply with an error message.
525 base::ResetAndReturn(&read_cb_
).Run(
526 DemuxerStream::kOk
, DecoderBuffer::CreateEOSBuffer());
530 SatisfyPendingRead();
533 void FFmpegDemuxerStream::EnableBitstreamConverter() {
534 DCHECK(task_runner_
->BelongsToCurrentThread());
536 #if defined(USE_PROPRIETARY_CODECS)
537 InitBitstreamConverter();
539 NOTREACHED() << "Proprietary codecs not enabled.";
543 void FFmpegDemuxerStream::ResetBitstreamConverter() {
544 #if defined(USE_PROPRIETARY_CODECS)
545 if (bitstream_converter_
)
546 InitBitstreamConverter();
547 #endif // defined(USE_PROPRIETARY_CODECS)
550 void FFmpegDemuxerStream::InitBitstreamConverter() {
551 #if defined(USE_PROPRIETARY_CODECS)
552 if (stream_
->codec
->codec_id
== AV_CODEC_ID_H264
) {
553 bitstream_converter_
.reset(
554 new FFmpegH264ToAnnexBBitstreamConverter(stream_
->codec
));
555 #if defined(ENABLE_HEVC_DEMUXING)
556 } else if (stream_
->codec
->codec_id
== AV_CODEC_ID_HEVC
) {
557 bitstream_converter_
.reset(
558 new FFmpegH265ToAnnexBBitstreamConverter(stream_
->codec
));
560 } else if (stream_
->codec
->codec_id
== AV_CODEC_ID_AAC
) {
561 bitstream_converter_
.reset(
562 new FFmpegAACBitstreamConverter(stream_
->codec
));
564 #endif // defined(USE_PROPRIETARY_CODECS)
567 bool FFmpegDemuxerStream::SupportsConfigChanges() { return false; }
569 AudioDecoderConfig
FFmpegDemuxerStream::audio_decoder_config() {
570 DCHECK(task_runner_
->BelongsToCurrentThread());
571 CHECK_EQ(type_
, AUDIO
);
572 return audio_config_
;
575 VideoDecoderConfig
FFmpegDemuxerStream::video_decoder_config() {
576 DCHECK(task_runner_
->BelongsToCurrentThread());
577 CHECK_EQ(type_
, VIDEO
);
578 return video_config_
;
581 VideoRotation
FFmpegDemuxerStream::video_rotation() {
582 return video_rotation_
;
585 void FFmpegDemuxerStream::SetLiveness(Liveness liveness
) {
586 DCHECK(task_runner_
->BelongsToCurrentThread());
587 DCHECK_EQ(liveness_
, LIVENESS_UNKNOWN
);
588 liveness_
= liveness
;
591 base::TimeDelta
FFmpegDemuxerStream::GetElapsedTime() const {
592 return ConvertStreamTimestamp(stream_
->time_base
, stream_
->cur_dts
);
595 Ranges
<base::TimeDelta
> FFmpegDemuxerStream::GetBufferedRanges() const {
596 return buffered_ranges_
;
599 void FFmpegDemuxerStream::SatisfyPendingRead() {
600 DCHECK(task_runner_
->BelongsToCurrentThread());
601 if (!read_cb_
.is_null()) {
602 if (!buffer_queue_
.IsEmpty()) {
603 base::ResetAndReturn(&read_cb_
).Run(
604 DemuxerStream::kOk
, buffer_queue_
.Pop());
605 } else if (end_of_stream_
) {
606 base::ResetAndReturn(&read_cb_
).Run(
607 DemuxerStream::kOk
, DecoderBuffer::CreateEOSBuffer());
611 // Have capacity? Ask for more!
612 if (HasAvailableCapacity() && !end_of_stream_
) {
613 demuxer_
->NotifyCapacityAvailable();
617 bool FFmpegDemuxerStream::HasAvailableCapacity() {
618 // TODO(scherkus): Remove this return and reenable time-based capacity
619 // after our data sources support canceling/concurrent reads, see
620 // http://crbug.com/165762 for details.
622 return !read_cb_
.is_null();
624 // Try to have one second's worth of encoded data per stream.
625 const base::TimeDelta kCapacity
= base::TimeDelta::FromSeconds(1);
626 return buffer_queue_
.IsEmpty() || buffer_queue_
.Duration() < kCapacity
;
630 size_t FFmpegDemuxerStream::MemoryUsage() const {
631 return buffer_queue_
.data_size();
634 TextKind
FFmpegDemuxerStream::GetTextKind() const {
635 DCHECK_EQ(type_
, DemuxerStream::TEXT
);
637 if (stream_
->disposition
& AV_DISPOSITION_CAPTIONS
)
638 return kTextCaptions
;
640 if (stream_
->disposition
& AV_DISPOSITION_DESCRIPTIONS
)
641 return kTextDescriptions
;
643 if (stream_
->disposition
& AV_DISPOSITION_METADATA
)
644 return kTextMetadata
;
646 return kTextSubtitles
;
649 std::string
FFmpegDemuxerStream::GetMetadata(const char* key
) const {
650 const AVDictionaryEntry
* entry
=
651 av_dict_get(stream_
->metadata
, key
, NULL
, 0);
652 return (entry
== NULL
|| entry
->value
== NULL
) ? "" : entry
->value
;
656 base::TimeDelta
FFmpegDemuxerStream::ConvertStreamTimestamp(
657 const AVRational
& time_base
, int64 timestamp
) {
658 if (timestamp
== static_cast<int64
>(AV_NOPTS_VALUE
))
659 return kNoTimestamp();
661 return ConvertFromTimeBase(time_base
, timestamp
);
667 FFmpegDemuxer::FFmpegDemuxer(
668 const scoped_refptr
<base::SingleThreadTaskRunner
>& task_runner
,
669 DataSource
* data_source
,
670 const EncryptedMediaInitDataCB
& encrypted_media_init_data_cb
,
671 const scoped_refptr
<MediaLog
>& media_log
)
673 task_runner_(task_runner
),
674 blocking_thread_("FFmpegDemuxer"),
675 pending_read_(false),
676 pending_seek_(false),
677 data_source_(data_source
),
678 media_log_(media_log
),
680 start_time_(kNoTimestamp()),
681 preferred_stream_for_seeking_(-1, kNoTimestamp()),
682 fallback_stream_for_seeking_(-1, kNoTimestamp()),
683 text_enabled_(false),
684 duration_known_(false),
685 encrypted_media_init_data_cb_(encrypted_media_init_data_cb
),
686 weak_factory_(this) {
687 DCHECK(task_runner_
.get());
688 DCHECK(data_source_
);
691 FFmpegDemuxer::~FFmpegDemuxer() {}
693 void FFmpegDemuxer::Stop() {
694 DCHECK(task_runner_
->BelongsToCurrentThread());
696 // The order of Stop() and Abort() is important here. If Abort() is called
697 // first, control may pass into FFmpeg where it can destruct buffers that are
698 // in the process of being fulfilled by the DataSource.
699 data_source_
->Stop();
700 url_protocol_
->Abort();
702 // This will block until all tasks complete. Note that after this returns it's
703 // possible for reply tasks (e.g., OnReadFrameDone()) to be queued on this
704 // thread. Each of the reply task methods must check whether we've stopped the
705 // thread and drop their results on the floor.
706 blocking_thread_
.Stop();
708 StreamVector::iterator iter
;
709 for (iter
= streams_
.begin(); iter
!= streams_
.end(); ++iter
) {
717 void FFmpegDemuxer::Seek(base::TimeDelta time
, const PipelineStatusCB
& cb
) {
718 DCHECK(task_runner_
->BelongsToCurrentThread());
719 CHECK(!pending_seek_
);
721 // TODO(scherkus): Inspect |pending_read_| and cancel IO via |blocking_url_|,
722 // otherwise we can end up waiting for a pre-seek read to complete even though
723 // we know we're going to drop it on the floor.
725 // FFmpeg requires seeks to be adjusted according to the lowest starting time.
726 // Since EnqueuePacket() rebased negative timestamps by the start time, we
727 // must correct the shift here.
729 // Additionally, to workaround limitations in how we expose seekable ranges to
730 // Blink (http://crbug.com/137275), we also want to clamp seeks before the
731 // start time to the start time.
732 base::TimeDelta seek_time
= start_time_
< base::TimeDelta()
734 : time
< start_time_
? start_time_
: time
;
736 // When seeking in an opus stream we need to ensure we deliver enough data to
737 // satisfy the seek preroll; otherwise the audio at the actual seek time will
738 // not be entirely accurate.
739 FFmpegDemuxerStream
* audio_stream
= GetFFmpegStream(DemuxerStream::AUDIO
);
741 const AudioDecoderConfig
& config
= audio_stream
->audio_decoder_config();
742 if (config
.codec() == kCodecOpus
)
743 seek_time
= std::max(start_time_
, seek_time
- config
.seek_preroll());
746 // Choose the seeking stream based on whether it contains the seek time, if no
747 // match can be found prefer the preferred stream.
749 // TODO(dalecurtis): Currently FFmpeg does not ensure that all streams in a
750 // given container will demux all packets after the seek point. Instead it
751 // only guarantees that all packets after the file position of the seek will
752 // be demuxed. It's an open question whether FFmpeg should fix this:
753 // http://lists.ffmpeg.org/pipermail/ffmpeg-devel/2014-June/159212.html
754 // Tracked by http://crbug.com/387996.
755 DCHECK(preferred_stream_for_seeking_
.second
!= kNoTimestamp());
756 const int stream_index
=
757 seek_time
< preferred_stream_for_seeking_
.second
&&
758 seek_time
>= fallback_stream_for_seeking_
.second
759 ? fallback_stream_for_seeking_
.first
760 : preferred_stream_for_seeking_
.first
;
761 DCHECK_NE(stream_index
, -1);
763 const AVStream
* seeking_stream
=
764 glue_
->format_context()->streams
[stream_index
];
766 pending_seek_
= true;
767 base::PostTaskAndReplyWithResult(
768 blocking_thread_
.task_runner().get(),
770 base::Bind(&av_seek_frame
,
771 glue_
->format_context(),
772 seeking_stream
->index
,
773 ConvertToTimeBase(seeking_stream
->time_base
, seek_time
),
774 // Always seek to a timestamp <= to the desired timestamp.
775 AVSEEK_FLAG_BACKWARD
),
777 &FFmpegDemuxer::OnSeekFrameDone
, weak_factory_
.GetWeakPtr(), cb
));
780 std::string
FFmpegDemuxer::GetDisplayName() const {
781 return "FFmpegDemuxer";
784 void FFmpegDemuxer::Initialize(DemuxerHost
* host
,
785 const PipelineStatusCB
& status_cb
,
786 bool enable_text_tracks
) {
787 DCHECK(task_runner_
->BelongsToCurrentThread());
789 text_enabled_
= enable_text_tracks
;
791 url_protocol_
.reset(new BlockingUrlProtocol(data_source_
, BindToCurrentLoop(
792 base::Bind(&FFmpegDemuxer::OnDataSourceError
, base::Unretained(this)))));
793 glue_
.reset(new FFmpegGlue(url_protocol_
.get()));
794 AVFormatContext
* format_context
= glue_
->format_context();
796 // Disable ID3v1 tag reading to avoid costly seeks to end of file for data we
797 // don't use. FFmpeg will only read ID3v1 tags if no other metadata is
798 // available, so add a metadata entry to ensure some is always present.
799 av_dict_set(&format_context
->metadata
, "skip_id3v1_tags", "", 0);
801 // Ensure ffmpeg doesn't give up too early while looking for stream params;
802 // this does not increase the amount of data downloaded. The default value
803 // is 5 AV_TIME_BASE units (1 second each), which prevents some oddly muxed
804 // streams from being detected properly; this value was chosen arbitrarily.
805 format_context
->max_analyze_duration2
= 60 * AV_TIME_BASE
;
807 // Open the AVFormatContext using our glue layer.
808 CHECK(blocking_thread_
.Start());
809 base::PostTaskAndReplyWithResult(
810 blocking_thread_
.task_runner().get(),
812 base::Bind(&FFmpegGlue::OpenContext
, base::Unretained(glue_
.get())),
813 base::Bind(&FFmpegDemuxer::OnOpenContextDone
,
814 weak_factory_
.GetWeakPtr(),
818 base::Time
FFmpegDemuxer::GetTimelineOffset() const {
819 return timeline_offset_
;
822 DemuxerStream
* FFmpegDemuxer::GetStream(DemuxerStream::Type type
) {
823 DCHECK(task_runner_
->BelongsToCurrentThread());
824 return GetFFmpegStream(type
);
827 FFmpegDemuxerStream
* FFmpegDemuxer::GetFFmpegStream(
828 DemuxerStream::Type type
) const {
829 StreamVector::const_iterator iter
;
830 for (iter
= streams_
.begin(); iter
!= streams_
.end(); ++iter
) {
831 if (*iter
&& (*iter
)->type() == type
) {
838 base::TimeDelta
FFmpegDemuxer::GetStartTime() const {
839 return std::max(start_time_
, base::TimeDelta());
842 void FFmpegDemuxer::AddTextStreams() {
843 DCHECK(task_runner_
->BelongsToCurrentThread());
845 for (StreamVector::size_type idx
= 0; idx
< streams_
.size(); ++idx
) {
846 FFmpegDemuxerStream
* stream
= streams_
[idx
];
847 if (stream
== NULL
|| stream
->type() != DemuxerStream::TEXT
)
850 TextKind kind
= stream
->GetTextKind();
851 std::string title
= stream
->GetMetadata("title");
852 std::string language
= stream
->GetMetadata("language");
854 // TODO: Implement "id" metadata in FFMPEG.
855 // See: http://crbug.com/323183
856 host_
->AddTextStream(stream
, TextTrackConfig(kind
, title
, language
,
861 // Helper for calculating the bitrate of the media based on information stored
862 // in |format_context| or failing that the size and duration of the media.
864 // Returns 0 if a bitrate could not be determined.
865 static int CalculateBitrate(
866 AVFormatContext
* format_context
,
867 const base::TimeDelta
& duration
,
868 int64 filesize_in_bytes
) {
869 // If there is a bitrate set on the container, use it.
870 if (format_context
->bit_rate
> 0)
871 return format_context
->bit_rate
;
873 // Then try to sum the bitrates individually per stream.
875 for (size_t i
= 0; i
< format_context
->nb_streams
; ++i
) {
876 AVCodecContext
* codec_context
= format_context
->streams
[i
]->codec
;
877 bitrate
+= codec_context
->bit_rate
;
882 // See if we can approximate the bitrate as long as we have a filesize and
884 if (duration
.InMicroseconds() <= 0 ||
885 duration
== kInfiniteDuration() ||
886 filesize_in_bytes
== 0) {
890 // Do math in floating point as we'd overflow an int64 if the filesize was
891 // larger than ~1073GB.
892 double bytes
= filesize_in_bytes
;
893 double duration_us
= duration
.InMicroseconds();
894 return bytes
* 8000000.0 / duration_us
;
897 void FFmpegDemuxer::OnOpenContextDone(const PipelineStatusCB
& status_cb
,
899 DCHECK(task_runner_
->BelongsToCurrentThread());
900 if (!blocking_thread_
.IsRunning()) {
901 MEDIA_LOG(ERROR
, media_log_
) << GetDisplayName() << ": bad state";
902 status_cb
.Run(PIPELINE_ERROR_ABORT
);
907 MEDIA_LOG(ERROR
, media_log_
) << GetDisplayName() << ": open context failed";
908 status_cb
.Run(DEMUXER_ERROR_COULD_NOT_OPEN
);
912 // Fully initialize AVFormatContext by parsing the stream a little.
913 base::PostTaskAndReplyWithResult(
914 blocking_thread_
.task_runner().get(),
916 base::Bind(&avformat_find_stream_info
,
917 glue_
->format_context(),
918 static_cast<AVDictionary
**>(NULL
)),
919 base::Bind(&FFmpegDemuxer::OnFindStreamInfoDone
,
920 weak_factory_
.GetWeakPtr(),
924 void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB
& status_cb
,
926 DCHECK(task_runner_
->BelongsToCurrentThread());
927 if (!blocking_thread_
.IsRunning() || !data_source_
) {
928 MEDIA_LOG(ERROR
, media_log_
) << GetDisplayName() << ": bad state";
929 status_cb
.Run(PIPELINE_ERROR_ABORT
);
934 MEDIA_LOG(ERROR
, media_log_
) << GetDisplayName()
935 << ": find stream info failed";
936 status_cb
.Run(DEMUXER_ERROR_COULD_NOT_PARSE
);
940 // Create demuxer stream entries for each possible AVStream. Each stream
941 // is examined to determine if it is supported or not (is the codec enabled
942 // for it in this release?). Unsupported streams are skipped, allowing for
943 // partial playback. At least one audio or video stream must be playable.
944 AVFormatContext
* format_context
= glue_
->format_context();
945 streams_
.resize(format_context
->nb_streams
);
947 // Estimate the start time for each stream by looking through the packets
948 // buffered during avformat_find_stream_info(). These values will be
949 // considered later when determining the actual stream start time.
951 // These packets haven't been completely processed yet, so only look through
952 // these values if the AVFormatContext has a valid start time.
954 // If no estimate is found, the stream entry will be kInfiniteDuration().
955 std::vector
<base::TimeDelta
> start_time_estimates(format_context
->nb_streams
,
956 kInfiniteDuration());
957 const AVFormatInternal
* internal
= format_context
->internal
;
958 if (internal
&& internal
->packet_buffer
&&
959 format_context
->start_time
!= static_cast<int64
>(AV_NOPTS_VALUE
)) {
960 struct AVPacketList
* packet_buffer
= internal
->packet_buffer
;
961 while (packet_buffer
!= internal
->packet_buffer_end
) {
962 DCHECK_LT(static_cast<size_t>(packet_buffer
->pkt
.stream_index
),
963 start_time_estimates
.size());
964 const AVStream
* stream
=
965 format_context
->streams
[packet_buffer
->pkt
.stream_index
];
966 if (packet_buffer
->pkt
.pts
!= static_cast<int64
>(AV_NOPTS_VALUE
)) {
967 const base::TimeDelta packet_pts
=
968 ConvertFromTimeBase(stream
->time_base
, packet_buffer
->pkt
.pts
);
969 if (packet_pts
< start_time_estimates
[stream
->index
])
970 start_time_estimates
[stream
->index
] = packet_pts
;
972 packet_buffer
= packet_buffer
->next
;
976 AVStream
* audio_stream
= NULL
;
977 AudioDecoderConfig audio_config
;
979 AVStream
* video_stream
= NULL
;
980 VideoDecoderConfig video_config
;
982 // If available, |start_time_| will be set to the lowest stream start time.
983 start_time_
= kInfiniteDuration();
985 base::TimeDelta max_duration
;
986 for (size_t i
= 0; i
< format_context
->nb_streams
; ++i
) {
987 AVStream
* stream
= format_context
->streams
[i
];
988 const AVCodecContext
* codec_context
= stream
->codec
;
989 const AVMediaType codec_type
= codec_context
->codec_type
;
991 if (codec_type
== AVMEDIA_TYPE_AUDIO
) {
995 // Log the codec detected, whether it is supported or not.
996 UMA_HISTOGRAM_SPARSE_SLOWLY("Media.DetectedAudioCodec",
997 codec_context
->codec_id
);
998 // Ensure the codec is supported. IsValidConfig() also checks that the
999 // channel layout and sample format are valid.
1000 AVStreamToAudioDecoderConfig(stream
, &audio_config
);
1001 if (!audio_config
.IsValidConfig())
1003 audio_stream
= stream
;
1004 } else if (codec_type
== AVMEDIA_TYPE_VIDEO
) {
1009 #if defined(ENABLE_HEVC_DEMUXING)
1010 if (stream
->codec
->codec_id
== AV_CODEC_ID_HEVC
) {
1011 // If ffmpeg is built without HEVC parser/decoder support, it will be
1012 // able to demux HEVC based solely on container-provided information,
1013 // but unable to get some of the parameters without parsing the stream
1014 // (e.g. coded size needs to be read from SPS, pixel format is typically
1015 // deduced from decoder config in hvcC box). These are not really needed
1016 // when using external decoder (e.g. hardware decoder), so override them
1017 // here, to make sure this translates into a valid VideoDecoderConfig.
1018 if (stream
->codec
->coded_width
== 0 &&
1019 stream
->codec
->coded_height
== 0) {
1020 DCHECK(stream
->codec
->width
> 0);
1021 DCHECK(stream
->codec
->height
> 0);
1022 stream
->codec
->coded_width
= stream
->codec
->width
;
1023 stream
->codec
->coded_height
= stream
->codec
->height
;
1025 if (stream
->codec
->pix_fmt
== AV_PIX_FMT_NONE
) {
1026 stream
->codec
->pix_fmt
= PIX_FMT_YUV420P
;
1030 // Log the codec detected, whether it is supported or not.
1031 UMA_HISTOGRAM_SPARSE_SLOWLY("Media.DetectedVideoCodec",
1032 codec_context
->codec_id
);
1033 // Ensure the codec is supported. IsValidConfig() also checks that the
1034 // frame size and visible size are valid.
1035 AVStreamToVideoDecoderConfig(stream
, &video_config
);
1037 if (!video_config
.IsValidConfig())
1039 video_stream
= stream
;
1040 } else if (codec_type
== AVMEDIA_TYPE_SUBTITLE
) {
1041 if (codec_context
->codec_id
!= AV_CODEC_ID_WEBVTT
|| !text_enabled_
) {
1048 streams_
[i
] = new FFmpegDemuxerStream(this, stream
);
1050 // Record audio or video src= playback UMA stats for the stream's decoder
1052 if (codec_type
== AVMEDIA_TYPE_AUDIO
) {
1053 RecordAudioCodecStats(streams_
[i
]->audio_decoder_config());
1054 } else if (codec_type
== AVMEDIA_TYPE_VIDEO
) {
1055 RecordVideoCodecStats(streams_
[i
]->video_decoder_config(),
1056 stream
->codec
->color_range
);
1059 max_duration
= std::max(max_duration
, streams_
[i
]->duration());
1061 const base::TimeDelta start_time
=
1062 ExtractStartTime(stream
, start_time_estimates
[i
]);
1063 const bool has_start_time
= start_time
!= kNoTimestamp();
1065 // Always prefer the video stream for seeking. If none exists, we'll swap
1066 // the fallback stream with the preferred stream below.
1067 if (codec_type
== AVMEDIA_TYPE_VIDEO
) {
1068 preferred_stream_for_seeking_
=
1069 StreamSeekInfo(i
, has_start_time
? start_time
: base::TimeDelta());
1072 if (!has_start_time
)
1075 if (start_time
< start_time_
) {
1076 start_time_
= start_time
;
1078 // Choose the stream with the lowest starting time as the fallback stream
1079 // for seeking. Video should always be preferred.
1080 fallback_stream_for_seeking_
= StreamSeekInfo(i
, start_time
);
1084 if (!audio_stream
&& !video_stream
) {
1085 MEDIA_LOG(ERROR
, media_log_
) << GetDisplayName()
1086 << ": no supported streams";
1087 status_cb
.Run(DEMUXER_ERROR_NO_SUPPORTED_STREAMS
);
1094 if (format_context
->duration
!= static_cast<int64_t>(AV_NOPTS_VALUE
)) {
1095 // If there is a duration value in the container use that to find the
1096 // maximum between it and the duration from A/V streams.
1097 const AVRational av_time_base
= {1, AV_TIME_BASE
};
1099 std::max(max_duration
,
1100 ConvertFromTimeBase(av_time_base
, format_context
->duration
));
1102 // The duration is unknown, in which case this is likely a live stream.
1103 max_duration
= kInfiniteDuration();
1106 // FFmpeg represents audio data marked as before the beginning of stream as
1107 // having negative timestamps. This data must be discarded after it has been
1108 // decoded, not before since it is used to warmup the decoder. There are
1109 // currently two known cases for this: vorbis in ogg and opus in ogg and webm.
1111 // For API clarity, it was decided that the rest of the media pipeline should
1112 // not be exposed to negative timestamps. Which means we need to rebase these
1113 // negative timestamps and mark them for discard post decoding.
1115 // Post-decode frame dropping for packets with negative timestamps is outlined
1116 // in section A.2 in the Ogg Vorbis spec:
1117 // http://xiph.org/vorbis/doc/Vorbis_I_spec.html
1119 // FFmpeg's use of negative timestamps for opus pre-skip is nonstandard, but
1120 // for more information on pre-skip see section 4.2 of the Ogg Opus spec:
1121 // https://tools.ietf.org/html/draft-ietf-codec-oggopus-08#section-4.2
1122 if (audio_stream
&& (audio_stream
->codec
->codec_id
== AV_CODEC_ID_OPUS
||
1123 (strcmp(format_context
->iformat
->name
, "ogg") == 0 &&
1124 audio_stream
->codec
->codec_id
== AV_CODEC_ID_VORBIS
))) {
1125 for (size_t i
= 0; i
< streams_
.size(); ++i
) {
1127 streams_
[i
]->enable_negative_timestamp_fixups();
1130 // Fixup the seeking information to avoid selecting the audio stream simply
1131 // because it has a lower starting time.
1132 if (fallback_stream_for_seeking_
.first
== audio_stream
->index
&&
1133 fallback_stream_for_seeking_
.second
< base::TimeDelta()) {
1134 fallback_stream_for_seeking_
.second
= base::TimeDelta();
1138 // If no start time could be determined, default to zero and prefer the video
1139 // stream over the audio stream for seeking. E.g., The WAV demuxer does not
1140 // put timestamps on its frames.
1141 if (start_time_
== kInfiniteDuration()) {
1142 start_time_
= base::TimeDelta();
1143 preferred_stream_for_seeking_
= StreamSeekInfo(
1144 video_stream
? video_stream
->index
: audio_stream
->index
, start_time_
);
1145 } else if (!video_stream
) {
1146 // If no video stream exists, use the audio or text stream found above.
1147 preferred_stream_for_seeking_
= fallback_stream_for_seeking_
;
1150 // MPEG-4 B-frames cause grief for a simple container like AVI. Enable PTS
1151 // generation so we always get timestamps, see http://crbug.com/169570
1152 if (strcmp(format_context
->iformat
->name
, "avi") == 0)
1153 format_context
->flags
|= AVFMT_FLAG_GENPTS
;
1155 // For testing purposes, don't overwrite the timeline offset if set already.
1156 if (timeline_offset_
.is_null())
1157 timeline_offset_
= ExtractTimelineOffset(format_context
);
1159 // Since we're shifting the externally visible start time to zero, we need to
1160 // adjust the timeline offset to compensate.
1161 if (!timeline_offset_
.is_null() && start_time_
< base::TimeDelta())
1162 timeline_offset_
+= start_time_
;
1164 if (max_duration
== kInfiniteDuration() && !timeline_offset_
.is_null()) {
1165 SetLiveness(DemuxerStream::LIVENESS_LIVE
);
1166 } else if (max_duration
!= kInfiniteDuration()) {
1167 SetLiveness(DemuxerStream::LIVENESS_RECORDED
);
1169 SetLiveness(DemuxerStream::LIVENESS_UNKNOWN
);
1172 // Good to go: set the duration and bitrate and notify we're done
1174 host_
->SetDuration(max_duration
);
1175 duration_known_
= (max_duration
!= kInfiniteDuration());
1177 int64 filesize_in_bytes
= 0;
1178 url_protocol_
->GetSize(&filesize_in_bytes
);
1179 bitrate_
= CalculateBitrate(format_context
, max_duration
, filesize_in_bytes
);
1181 data_source_
->SetBitrate(bitrate_
);
1185 AVCodecContext
* audio_codec
= audio_stream
->codec
;
1186 media_log_
->SetBooleanProperty("found_audio_stream", true);
1188 SampleFormat sample_format
= audio_config
.sample_format();
1189 std::string sample_name
= SampleFormatToString(sample_format
);
1191 media_log_
->SetStringProperty("audio_sample_format", sample_name
);
1193 AVCodec
* codec
= avcodec_find_decoder(audio_codec
->codec_id
);
1195 media_log_
->SetStringProperty("audio_codec_name", codec
->name
);
1198 media_log_
->SetIntegerProperty("audio_channels_count",
1199 audio_codec
->channels
);
1200 media_log_
->SetIntegerProperty("audio_samples_per_second",
1201 audio_config
.samples_per_second());
1203 media_log_
->SetBooleanProperty("found_audio_stream", false);
1208 AVCodecContext
* video_codec
= video_stream
->codec
;
1209 media_log_
->SetBooleanProperty("found_video_stream", true);
1211 AVCodec
* codec
= avcodec_find_decoder(video_codec
->codec_id
);
1213 media_log_
->SetStringProperty("video_codec_name", codec
->name
);
1214 } else if (video_codec
->codec_id
== AV_CODEC_ID_VP9
) {
1215 // ffmpeg doesn't know about VP9 decoder. So we need to log it explicitly.
1216 media_log_
->SetStringProperty("video_codec_name", "vp9");
1219 media_log_
->SetIntegerProperty("width", video_codec
->width
);
1220 media_log_
->SetIntegerProperty("height", video_codec
->height
);
1221 media_log_
->SetIntegerProperty("coded_width",
1222 video_codec
->coded_width
);
1223 media_log_
->SetIntegerProperty("coded_height",
1224 video_codec
->coded_height
);
1225 media_log_
->SetStringProperty(
1227 base::StringPrintf("%d/%d",
1228 video_codec
->time_base
.num
,
1229 video_codec
->time_base
.den
));
1230 media_log_
->SetStringProperty(
1231 "video_format", VideoPixelFormatToString(video_config
.format()));
1232 media_log_
->SetBooleanProperty("video_is_encrypted",
1233 video_config
.is_encrypted());
1235 media_log_
->SetBooleanProperty("found_video_stream", false);
1238 media_log_
->SetTimeProperty("max_duration", max_duration
);
1239 media_log_
->SetTimeProperty("start_time", start_time_
);
1240 media_log_
->SetIntegerProperty("bitrate", bitrate_
);
1242 status_cb
.Run(PIPELINE_OK
);
1245 void FFmpegDemuxer::OnSeekFrameDone(const PipelineStatusCB
& cb
, int result
) {
1246 DCHECK(task_runner_
->BelongsToCurrentThread());
1247 CHECK(pending_seek_
);
1248 pending_seek_
= false;
1250 if (!blocking_thread_
.IsRunning()) {
1251 MEDIA_LOG(ERROR
, media_log_
) << GetDisplayName() << ": bad state";
1252 cb
.Run(PIPELINE_ERROR_ABORT
);
1257 // Use VLOG(1) instead of NOTIMPLEMENTED() to prevent the message being
1258 // captured from stdout and contaminates testing.
1259 // TODO(scherkus): Implement this properly and signal error (BUG=23447).
1260 VLOG(1) << "Not implemented";
1263 // Tell streams to flush buffers due to seeking.
1264 StreamVector::iterator iter
;
1265 for (iter
= streams_
.begin(); iter
!= streams_
.end(); ++iter
) {
1267 (*iter
)->FlushBuffers();
1270 // Resume reading until capacity.
1271 ReadFrameIfNeeded();
1273 // Notify we're finished seeking.
1274 cb
.Run(PIPELINE_OK
);
1277 void FFmpegDemuxer::ReadFrameIfNeeded() {
1278 DCHECK(task_runner_
->BelongsToCurrentThread());
1280 // Make sure we have work to do before reading.
1281 if (!blocking_thread_
.IsRunning() || !StreamsHaveAvailableCapacity() ||
1282 pending_read_
|| pending_seek_
) {
1286 // Allocate and read an AVPacket from the media. Save |packet_ptr| since
1287 // evaluation order of packet.get() and base::Passed(&packet) is
1289 ScopedAVPacket
packet(new AVPacket());
1290 AVPacket
* packet_ptr
= packet
.get();
1292 pending_read_
= true;
1293 base::PostTaskAndReplyWithResult(
1294 blocking_thread_
.task_runner().get(),
1296 base::Bind(&av_read_frame
, glue_
->format_context(), packet_ptr
),
1297 base::Bind(&FFmpegDemuxer::OnReadFrameDone
,
1298 weak_factory_
.GetWeakPtr(),
1299 base::Passed(&packet
)));
1302 void FFmpegDemuxer::OnReadFrameDone(ScopedAVPacket packet
, int result
) {
1303 DCHECK(task_runner_
->BelongsToCurrentThread());
1304 DCHECK(pending_read_
);
1305 pending_read_
= false;
1307 if (!blocking_thread_
.IsRunning() || pending_seek_
) {
1311 // Consider the stream as ended if:
1312 // - either underlying ffmpeg returned an error
1313 // - or FFMpegDemuxer reached the maximum allowed memory usage.
1314 if (result
< 0 || IsMaxMemoryUsageReached()) {
1315 // Update the duration based on the highest elapsed time across all streams
1316 // if it was previously unknown.
1317 if (!duration_known_
) {
1318 base::TimeDelta max_duration
;
1320 for (StreamVector::iterator iter
= streams_
.begin();
1321 iter
!= streams_
.end();
1326 base::TimeDelta duration
= (*iter
)->GetElapsedTime();
1327 if (duration
!= kNoTimestamp() && duration
> max_duration
)
1328 max_duration
= duration
;
1331 if (max_duration
> base::TimeDelta()) {
1332 host_
->SetDuration(max_duration
);
1333 duration_known_
= true;
1336 // If we have reached the end of stream, tell the downstream filters about
1342 // Queue the packet with the appropriate stream.
1343 DCHECK_GE(packet
->stream_index
, 0);
1344 DCHECK_LT(packet
->stream_index
, static_cast<int>(streams_
.size()));
1346 // Defend against ffmpeg giving us a bad stream index.
1347 if (packet
->stream_index
>= 0 &&
1348 packet
->stream_index
< static_cast<int>(streams_
.size()) &&
1349 streams_
[packet
->stream_index
]) {
1350 // TODO(scherkus): Fix demuxing upstream to never return packets w/o data
1351 // when av_read_frame() returns success code. See bug comment for ideas:
1353 // https://code.google.com/p/chromium/issues/detail?id=169133#c10
1354 if (!packet
->data
) {
1355 ScopedAVPacket
new_packet(new AVPacket());
1356 av_new_packet(new_packet
.get(), 0);
1357 av_packet_copy_props(new_packet
.get(), packet
.get());
1358 packet
.swap(new_packet
);
1361 FFmpegDemuxerStream
* demuxer_stream
= streams_
[packet
->stream_index
];
1362 demuxer_stream
->EnqueuePacket(packet
.Pass());
1365 // Keep reading until we've reached capacity.
1366 ReadFrameIfNeeded();
1369 bool FFmpegDemuxer::StreamsHaveAvailableCapacity() {
1370 DCHECK(task_runner_
->BelongsToCurrentThread());
1371 StreamVector::iterator iter
;
1372 for (iter
= streams_
.begin(); iter
!= streams_
.end(); ++iter
) {
1373 if (*iter
&& (*iter
)->HasAvailableCapacity()) {
1380 bool FFmpegDemuxer::IsMaxMemoryUsageReached() const {
1381 DCHECK(task_runner_
->BelongsToCurrentThread());
1383 // Max allowed memory usage, all streams combined.
1384 const size_t kDemuxerMemoryLimit
= 150 * 1024 * 1024;
1386 size_t memory_left
= kDemuxerMemoryLimit
;
1387 for (StreamVector::const_iterator iter
= streams_
.begin();
1388 iter
!= streams_
.end(); ++iter
) {
1392 size_t stream_memory_usage
= (*iter
)->MemoryUsage();
1393 if (stream_memory_usage
> memory_left
)
1395 memory_left
-= stream_memory_usage
;
1400 void FFmpegDemuxer::StreamHasEnded() {
1401 DCHECK(task_runner_
->BelongsToCurrentThread());
1402 StreamVector::iterator iter
;
1403 for (iter
= streams_
.begin(); iter
!= streams_
.end(); ++iter
) {
1406 (*iter
)->SetEndOfStream();
1410 void FFmpegDemuxer::OnEncryptedMediaInitData(
1411 EmeInitDataType init_data_type
,
1412 const std::string
& encryption_key_id
) {
1413 std::vector
<uint8
> key_id_local(encryption_key_id
.begin(),
1414 encryption_key_id
.end());
1415 encrypted_media_init_data_cb_
.Run(init_data_type
, key_id_local
);
1418 void FFmpegDemuxer::NotifyCapacityAvailable() {
1419 DCHECK(task_runner_
->BelongsToCurrentThread());
1420 ReadFrameIfNeeded();
1423 void FFmpegDemuxer::NotifyBufferingChanged() {
1424 DCHECK(task_runner_
->BelongsToCurrentThread());
1425 Ranges
<base::TimeDelta
> buffered
;
1426 FFmpegDemuxerStream
* audio
= GetFFmpegStream(DemuxerStream::AUDIO
);
1427 FFmpegDemuxerStream
* video
= GetFFmpegStream(DemuxerStream::VIDEO
);
1428 if (audio
&& video
) {
1429 buffered
= audio
->GetBufferedRanges().IntersectionWith(
1430 video
->GetBufferedRanges());
1432 buffered
= audio
->GetBufferedRanges();
1434 buffered
= video
->GetBufferedRanges();
1436 for (size_t i
= 0; i
< buffered
.size(); ++i
)
1437 host_
->AddBufferedTimeRange(buffered
.start(i
), buffered
.end(i
));
1440 void FFmpegDemuxer::OnDataSourceError() {
1441 MEDIA_LOG(ERROR
, media_log_
) << GetDisplayName() << ": data source error";
1442 host_
->OnDemuxerError(PIPELINE_ERROR_READ
);
1445 void FFmpegDemuxer::SetLiveness(DemuxerStream::Liveness liveness
) {
1446 DCHECK(task_runner_
->BelongsToCurrentThread());
1447 for (const auto& stream
: streams_
) { // |stream| is a ref to a pointer.
1449 stream
->SetLiveness(liveness
);
1453 } // namespace media