0dec8b8822229cadc076436b04304c0209a1fbfb
[platform/framework/web/crosswalk.git] / src / media / filters / ffmpeg_demuxer.cc
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.
4
5 #include "media/filters/ffmpeg_demuxer.h"
6
7 #include <algorithm>
8 #include <string>
9
10 #include "base/base64.h"
11 #include "base/bind.h"
12 #include "base/callback.h"
13 #include "base/callback_helpers.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/message_loop/message_loop_proxy.h"
16 #include "base/metrics/sparse_histogram.h"
17 #include "base/strings/string_util.h"
18 #include "base/strings/stringprintf.h"
19 #include "base/sys_byteorder.h"
20 #include "base/task_runner_util.h"
21 #include "base/time/time.h"
22 #include "media/base/audio_decoder_config.h"
23 #include "media/base/bind_to_current_loop.h"
24 #include "media/base/decoder_buffer.h"
25 #include "media/base/decrypt_config.h"
26 #include "media/base/limits.h"
27 #include "media/base/media_log.h"
28 #include "media/base/video_decoder_config.h"
29 #include "media/ffmpeg/ffmpeg_common.h"
30 #include "media/filters/ffmpeg_glue.h"
31 #include "media/filters/ffmpeg_h264_to_annex_b_bitstream_converter.h"
32 #include "media/filters/webvtt_util.h"
33 #include "media/formats/webm/webm_crypto_helpers.h"
34
35 namespace media {
36
37 //
38 // FFmpegDemuxerStream
39 //
40 FFmpegDemuxerStream::FFmpegDemuxerStream(
41     FFmpegDemuxer* demuxer,
42     AVStream* stream)
43     : demuxer_(demuxer),
44       task_runner_(base::MessageLoopProxy::current()),
45       stream_(stream),
46       type_(UNKNOWN),
47       end_of_stream_(false),
48       last_packet_timestamp_(kNoTimestamp()),
49       bitstream_converter_enabled_(false) {
50   DCHECK(demuxer_);
51
52   bool is_encrypted = false;
53
54   // Determine our media format.
55   switch (stream->codec->codec_type) {
56     case AVMEDIA_TYPE_AUDIO:
57       type_ = AUDIO;
58       AVStreamToAudioDecoderConfig(stream, &audio_config_, true);
59       is_encrypted = audio_config_.is_encrypted();
60       break;
61     case AVMEDIA_TYPE_VIDEO:
62       type_ = VIDEO;
63       AVStreamToVideoDecoderConfig(stream, &video_config_, true);
64       is_encrypted = video_config_.is_encrypted();
65       break;
66     case AVMEDIA_TYPE_SUBTITLE:
67       type_ = TEXT;
68       break;
69     default:
70       NOTREACHED();
71       break;
72   }
73
74   // Calculate the duration.
75   duration_ = ConvertStreamTimestamp(stream->time_base, stream->duration);
76
77   if (stream_->codec->codec_id == AV_CODEC_ID_H264) {
78     bitstream_converter_.reset(
79         new FFmpegH264ToAnnexBBitstreamConverter(stream_->codec));
80   }
81
82   if (is_encrypted) {
83     AVDictionaryEntry* key = av_dict_get(stream->metadata, "enc_key_id", NULL,
84                                          0);
85     DCHECK(key);
86     DCHECK(key->value);
87     if (!key || !key->value)
88       return;
89     base::StringPiece base64_key_id(key->value);
90     std::string enc_key_id;
91     base::Base64Decode(base64_key_id, &enc_key_id);
92     DCHECK(!enc_key_id.empty());
93     if (enc_key_id.empty())
94       return;
95
96     encryption_key_id_.assign(enc_key_id);
97     demuxer_->FireNeedKey(kWebMEncryptInitDataType, enc_key_id);
98   }
99 }
100
101 void FFmpegDemuxerStream::EnqueuePacket(ScopedAVPacket packet) {
102   DCHECK(task_runner_->BelongsToCurrentThread());
103
104   if (!demuxer_ || end_of_stream_) {
105     NOTREACHED() << "Attempted to enqueue packet on a stopped stream";
106     return;
107   }
108
109   // Convert the packet if there is a bitstream filter.
110   if (packet->data && bitstream_converter_enabled_ &&
111       !bitstream_converter_->ConvertPacket(packet.get())) {
112     LOG(ERROR) << "Format conversion failed.";
113   }
114
115   // Get side data if any. For now, the only type of side_data is VP8 Alpha. We
116   // keep this generic so that other side_data types in the future can be
117   // handled the same way as well.
118   av_packet_split_side_data(packet.get());
119
120   scoped_refptr<DecoderBuffer> buffer;
121
122   if (type() == DemuxerStream::TEXT) {
123     int id_size = 0;
124     uint8* id_data = av_packet_get_side_data(
125         packet.get(),
126         AV_PKT_DATA_WEBVTT_IDENTIFIER,
127         &id_size);
128
129     int settings_size = 0;
130     uint8* settings_data = av_packet_get_side_data(
131         packet.get(),
132         AV_PKT_DATA_WEBVTT_SETTINGS,
133         &settings_size);
134
135     std::vector<uint8> side_data;
136     MakeSideData(id_data, id_data + id_size,
137                  settings_data, settings_data + settings_size,
138                  &side_data);
139
140     buffer = DecoderBuffer::CopyFrom(packet.get()->data, packet.get()->size,
141                                      side_data.data(), side_data.size());
142   } else {
143     int side_data_size = 0;
144     uint8* side_data = av_packet_get_side_data(
145         packet.get(),
146         AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL,
147         &side_data_size);
148
149     scoped_ptr<DecryptConfig> decrypt_config;
150     int data_offset = 0;
151     if ((type() == DemuxerStream::AUDIO && audio_config_.is_encrypted()) ||
152         (type() == DemuxerStream::VIDEO && video_config_.is_encrypted())) {
153       if (!WebMCreateDecryptConfig(
154           packet->data, packet->size,
155           reinterpret_cast<const uint8*>(encryption_key_id_.data()),
156           encryption_key_id_.size(),
157           &decrypt_config,
158           &data_offset)) {
159         LOG(ERROR) << "Creation of DecryptConfig failed.";
160       }
161     }
162
163     // If a packet is returned by FFmpeg's av_parser_parse2() the packet will
164     // reference inner memory of FFmpeg.  As such we should transfer the packet
165     // into memory we control.
166     if (side_data_size > 0) {
167       buffer = DecoderBuffer::CopyFrom(packet.get()->data + data_offset,
168                                        packet.get()->size - data_offset,
169                                        side_data, side_data_size);
170     } else {
171       buffer = DecoderBuffer::CopyFrom(packet.get()->data + data_offset,
172                                        packet.get()->size - data_offset);
173     }
174
175     int skip_samples_size = 0;
176     uint8* skip_samples = av_packet_get_side_data(packet.get(),
177                                                   AV_PKT_DATA_SKIP_SAMPLES,
178                                                   &skip_samples_size);
179     const int kSkipSamplesValidSize = 10;
180     const int kSkipSamplesOffset = 4;
181     if (skip_samples_size >= kSkipSamplesValidSize) {
182       int discard_padding_samples = base::ByteSwapToLE32(
183           *(reinterpret_cast<const uint32*>(skip_samples +
184                                             kSkipSamplesOffset)));
185       // TODO(vigneshv): Change decoder buffer to use number of samples so that
186       // this conversion can be avoided.
187       buffer->set_discard_padding(base::TimeDelta::FromMicroseconds(
188           discard_padding_samples * 1000000.0 /
189           audio_decoder_config().samples_per_second()));
190     }
191
192     if (decrypt_config)
193       buffer->set_decrypt_config(decrypt_config.Pass());
194   }
195
196   buffer->set_timestamp(ConvertStreamTimestamp(
197       stream_->time_base, packet->pts));
198   buffer->set_duration(ConvertStreamTimestamp(
199       stream_->time_base, packet->duration));
200   if (buffer->timestamp() != kNoTimestamp() &&
201       last_packet_timestamp_ != kNoTimestamp() &&
202       last_packet_timestamp_ < buffer->timestamp()) {
203     buffered_ranges_.Add(last_packet_timestamp_, buffer->timestamp());
204     demuxer_->NotifyBufferingChanged();
205   }
206   last_packet_timestamp_ = buffer->timestamp();
207
208   buffer_queue_.Push(buffer);
209   SatisfyPendingRead();
210 }
211
212 void FFmpegDemuxerStream::SetEndOfStream() {
213   DCHECK(task_runner_->BelongsToCurrentThread());
214   end_of_stream_ = true;
215   SatisfyPendingRead();
216 }
217
218 void FFmpegDemuxerStream::FlushBuffers() {
219   DCHECK(task_runner_->BelongsToCurrentThread());
220   DCHECK(read_cb_.is_null()) << "There should be no pending read";
221   buffer_queue_.Clear();
222   end_of_stream_ = false;
223   last_packet_timestamp_ = kNoTimestamp();
224 }
225
226 void FFmpegDemuxerStream::Stop() {
227   DCHECK(task_runner_->BelongsToCurrentThread());
228   buffer_queue_.Clear();
229   if (!read_cb_.is_null()) {
230     base::ResetAndReturn(&read_cb_).Run(
231         DemuxerStream::kOk, DecoderBuffer::CreateEOSBuffer());
232   }
233   demuxer_ = NULL;
234   stream_ = NULL;
235   end_of_stream_ = true;
236 }
237
238 base::TimeDelta FFmpegDemuxerStream::duration() {
239   return duration_;
240 }
241
242 DemuxerStream::Type FFmpegDemuxerStream::type() {
243   DCHECK(task_runner_->BelongsToCurrentThread());
244   return type_;
245 }
246
247 void FFmpegDemuxerStream::Read(const ReadCB& read_cb) {
248   DCHECK(task_runner_->BelongsToCurrentThread());
249   CHECK(read_cb_.is_null()) << "Overlapping reads are not supported";
250   read_cb_ = BindToCurrentLoop(read_cb);
251
252   // Don't accept any additional reads if we've been told to stop.
253   // The |demuxer_| may have been destroyed in the pipeline thread.
254   //
255   // TODO(scherkus): it would be cleaner to reply with an error message.
256   if (!demuxer_) {
257     base::ResetAndReturn(&read_cb_).Run(
258         DemuxerStream::kOk, DecoderBuffer::CreateEOSBuffer());
259     return;
260   }
261
262   SatisfyPendingRead();
263 }
264
265 void FFmpegDemuxerStream::EnableBitstreamConverter() {
266   DCHECK(task_runner_->BelongsToCurrentThread());
267   CHECK(bitstream_converter_.get());
268   bitstream_converter_enabled_ = true;
269 }
270
271 AudioDecoderConfig FFmpegDemuxerStream::audio_decoder_config() {
272   DCHECK(task_runner_->BelongsToCurrentThread());
273   CHECK_EQ(type_, AUDIO);
274   return audio_config_;
275 }
276
277 VideoDecoderConfig FFmpegDemuxerStream::video_decoder_config() {
278   DCHECK(task_runner_->BelongsToCurrentThread());
279   CHECK_EQ(type_, VIDEO);
280   return video_config_;
281 }
282
283 FFmpegDemuxerStream::~FFmpegDemuxerStream() {
284   DCHECK(!demuxer_);
285   DCHECK(read_cb_.is_null());
286   DCHECK(buffer_queue_.IsEmpty());
287 }
288
289 base::TimeDelta FFmpegDemuxerStream::GetElapsedTime() const {
290   return ConvertStreamTimestamp(stream_->time_base, stream_->cur_dts);
291 }
292
293 Ranges<base::TimeDelta> FFmpegDemuxerStream::GetBufferedRanges() const {
294   return buffered_ranges_;
295 }
296
297 void FFmpegDemuxerStream::SatisfyPendingRead() {
298   DCHECK(task_runner_->BelongsToCurrentThread());
299   if (!read_cb_.is_null()) {
300     if (!buffer_queue_.IsEmpty()) {
301       base::ResetAndReturn(&read_cb_).Run(
302           DemuxerStream::kOk, buffer_queue_.Pop());
303     } else if (end_of_stream_) {
304       base::ResetAndReturn(&read_cb_).Run(
305           DemuxerStream::kOk, DecoderBuffer::CreateEOSBuffer());
306     }
307   }
308
309   // Have capacity? Ask for more!
310   if (HasAvailableCapacity() && !end_of_stream_) {
311     demuxer_->NotifyCapacityAvailable();
312   }
313 }
314
315 bool FFmpegDemuxerStream::HasAvailableCapacity() {
316   // TODO(scherkus): Remove early return and reenable time-based capacity
317   // after our data sources support canceling/concurrent reads, see
318   // http://crbug.com/165762 for details.
319   return !read_cb_.is_null();
320
321   // Try to have one second's worth of encoded data per stream.
322   const base::TimeDelta kCapacity = base::TimeDelta::FromSeconds(1);
323   return buffer_queue_.IsEmpty() || buffer_queue_.Duration() < kCapacity;
324 }
325
326 TextKind FFmpegDemuxerStream::GetTextKind() const {
327   DCHECK_EQ(type_, DemuxerStream::TEXT);
328
329   if (stream_->disposition & AV_DISPOSITION_CAPTIONS)
330     return kTextCaptions;
331
332   if (stream_->disposition & AV_DISPOSITION_DESCRIPTIONS)
333     return kTextDescriptions;
334
335   if (stream_->disposition & AV_DISPOSITION_METADATA)
336     return kTextMetadata;
337
338   return kTextSubtitles;
339 }
340
341 std::string FFmpegDemuxerStream::GetMetadata(const char* key) const {
342   const AVDictionaryEntry* entry =
343       av_dict_get(stream_->metadata, key, NULL, 0);
344   return (entry == NULL || entry->value == NULL) ? "" : entry->value;
345 }
346
347 // static
348 base::TimeDelta FFmpegDemuxerStream::ConvertStreamTimestamp(
349     const AVRational& time_base, int64 timestamp) {
350   if (timestamp == static_cast<int64>(AV_NOPTS_VALUE))
351     return kNoTimestamp();
352
353   return ConvertFromTimeBase(time_base, timestamp);
354 }
355
356 //
357 // FFmpegDemuxer
358 //
359 FFmpegDemuxer::FFmpegDemuxer(
360     const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
361     DataSource* data_source,
362     const NeedKeyCB& need_key_cb,
363     const scoped_refptr<MediaLog>& media_log)
364     : host_(NULL),
365       task_runner_(task_runner),
366       weak_factory_(this),
367       blocking_thread_("FFmpegDemuxer"),
368       pending_read_(false),
369       pending_seek_(false),
370       data_source_(data_source),
371       media_log_(media_log),
372       bitrate_(0),
373       start_time_(kNoTimestamp()),
374       audio_disabled_(false),
375       text_enabled_(false),
376       duration_known_(false),
377       need_key_cb_(need_key_cb) {
378   DCHECK(task_runner_.get());
379   DCHECK(data_source_);
380 }
381
382 FFmpegDemuxer::~FFmpegDemuxer() {}
383
384 void FFmpegDemuxer::Stop(const base::Closure& callback) {
385   DCHECK(task_runner_->BelongsToCurrentThread());
386   url_protocol_->Abort();
387   data_source_->Stop(BindToCurrentLoop(base::Bind(
388       &FFmpegDemuxer::OnDataSourceStopped, weak_this_,
389       BindToCurrentLoop(callback))));
390   data_source_ = NULL;
391 }
392
393 void FFmpegDemuxer::Seek(base::TimeDelta time, const PipelineStatusCB& cb) {
394   DCHECK(task_runner_->BelongsToCurrentThread());
395   CHECK(!pending_seek_);
396
397   // TODO(scherkus): Inspect |pending_read_| and cancel IO via |blocking_url_|,
398   // otherwise we can end up waiting for a pre-seek read to complete even though
399   // we know we're going to drop it on the floor.
400
401   // Always seek to a timestamp less than or equal to the desired timestamp.
402   int flags = AVSEEK_FLAG_BACKWARD;
403
404   // Passing -1 as our stream index lets FFmpeg pick a default stream.  FFmpeg
405   // will attempt to use the lowest-index video stream, if present, followed by
406   // the lowest-index audio stream.
407   pending_seek_ = true;
408   base::PostTaskAndReplyWithResult(
409       blocking_thread_.message_loop_proxy().get(),
410       FROM_HERE,
411       base::Bind(&av_seek_frame,
412                  glue_->format_context(),
413                  -1,
414                  time.InMicroseconds(),
415                  flags),
416       base::Bind(&FFmpegDemuxer::OnSeekFrameDone, weak_this_, cb));
417 }
418
419 void FFmpegDemuxer::OnAudioRendererDisabled() {
420   DCHECK(task_runner_->BelongsToCurrentThread());
421   audio_disabled_ = true;
422   StreamVector::iterator iter;
423   for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
424     if (*iter && (*iter)->type() == DemuxerStream::AUDIO) {
425       (*iter)->Stop();
426     }
427   }
428 }
429
430 void FFmpegDemuxer::Initialize(DemuxerHost* host,
431                                const PipelineStatusCB& status_cb,
432                                bool enable_text_tracks) {
433   DCHECK(task_runner_->BelongsToCurrentThread());
434   host_ = host;
435   weak_this_ = weak_factory_.GetWeakPtr();
436   text_enabled_ = enable_text_tracks;
437
438   // TODO(scherkus): DataSource should have a host by this point,
439   // see http://crbug.com/122071
440   data_source_->set_host(host);
441
442   url_protocol_.reset(new BlockingUrlProtocol(data_source_, BindToCurrentLoop(
443       base::Bind(&FFmpegDemuxer::OnDataSourceError, base::Unretained(this)))));
444   glue_.reset(new FFmpegGlue(url_protocol_.get()));
445   AVFormatContext* format_context = glue_->format_context();
446
447   // Disable ID3v1 tag reading to avoid costly seeks to end of file for data we
448   // don't use.  FFmpeg will only read ID3v1 tags if no other metadata is
449   // available, so add a metadata entry to ensure some is always present.
450   av_dict_set(&format_context->metadata, "skip_id3v1_tags", "", 0);
451
452   // Open the AVFormatContext using our glue layer.
453   CHECK(blocking_thread_.Start());
454   base::PostTaskAndReplyWithResult(
455       blocking_thread_.message_loop_proxy().get(),
456       FROM_HERE,
457       base::Bind(&FFmpegGlue::OpenContext, base::Unretained(glue_.get())),
458       base::Bind(&FFmpegDemuxer::OnOpenContextDone, weak_this_, status_cb));
459 }
460
461 DemuxerStream* FFmpegDemuxer::GetStream(DemuxerStream::Type type) {
462   DCHECK(task_runner_->BelongsToCurrentThread());
463   return GetFFmpegStream(type);
464 }
465
466 FFmpegDemuxerStream* FFmpegDemuxer::GetFFmpegStream(
467     DemuxerStream::Type type) const {
468   StreamVector::const_iterator iter;
469   for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
470     if (*iter && (*iter)->type() == type) {
471       return *iter;
472     }
473   }
474   return NULL;
475 }
476
477 base::TimeDelta FFmpegDemuxer::GetStartTime() const {
478   DCHECK(task_runner_->BelongsToCurrentThread());
479   return start_time_;
480 }
481
482 void FFmpegDemuxer::AddTextStreams() {
483   DCHECK(task_runner_->BelongsToCurrentThread());
484
485   for (StreamVector::size_type idx = 0; idx < streams_.size(); ++idx) {
486     FFmpegDemuxerStream* stream = streams_[idx];
487     if (stream == NULL || stream->type() != DemuxerStream::TEXT)
488       continue;
489
490     TextKind kind = stream->GetTextKind();
491     std::string title = stream->GetMetadata("title");
492     std::string language = stream->GetMetadata("language");
493
494     // TODO: Implement "id" metadata in FFMPEG.
495     // See: http://crbug.com/323183
496     host_->AddTextStream(stream, TextTrackConfig(kind, title, language,
497         std::string()));
498   }
499 }
500
501 // Helper for calculating the bitrate of the media based on information stored
502 // in |format_context| or failing that the size and duration of the media.
503 //
504 // Returns 0 if a bitrate could not be determined.
505 static int CalculateBitrate(
506     AVFormatContext* format_context,
507     const base::TimeDelta& duration,
508     int64 filesize_in_bytes) {
509   // If there is a bitrate set on the container, use it.
510   if (format_context->bit_rate > 0)
511     return format_context->bit_rate;
512
513   // Then try to sum the bitrates individually per stream.
514   int bitrate = 0;
515   for (size_t i = 0; i < format_context->nb_streams; ++i) {
516     AVCodecContext* codec_context = format_context->streams[i]->codec;
517     bitrate += codec_context->bit_rate;
518   }
519   if (bitrate > 0)
520     return bitrate;
521
522   // See if we can approximate the bitrate as long as we have a filesize and
523   // valid duration.
524   if (duration.InMicroseconds() <= 0 ||
525       duration == kInfiniteDuration() ||
526       filesize_in_bytes == 0) {
527     return 0;
528   }
529
530   // Do math in floating point as we'd overflow an int64 if the filesize was
531   // larger than ~1073GB.
532   double bytes = filesize_in_bytes;
533   double duration_us = duration.InMicroseconds();
534   return bytes * 8000000.0 / duration_us;
535 }
536
537 void FFmpegDemuxer::OnOpenContextDone(const PipelineStatusCB& status_cb,
538                                       bool result) {
539   DCHECK(task_runner_->BelongsToCurrentThread());
540   if (!blocking_thread_.IsRunning()) {
541     status_cb.Run(PIPELINE_ERROR_ABORT);
542     return;
543   }
544
545   if (!result) {
546     status_cb.Run(DEMUXER_ERROR_COULD_NOT_OPEN);
547     return;
548   }
549
550   // Fully initialize AVFormatContext by parsing the stream a little.
551   base::PostTaskAndReplyWithResult(
552       blocking_thread_.message_loop_proxy().get(),
553       FROM_HERE,
554       base::Bind(&avformat_find_stream_info,
555                  glue_->format_context(),
556                  static_cast<AVDictionary**>(NULL)),
557       base::Bind(&FFmpegDemuxer::OnFindStreamInfoDone, weak_this_, status_cb));
558 }
559
560 void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb,
561                                          int result) {
562   DCHECK(task_runner_->BelongsToCurrentThread());
563   if (!blocking_thread_.IsRunning() || !data_source_) {
564     status_cb.Run(PIPELINE_ERROR_ABORT);
565     return;
566   }
567
568   if (result < 0) {
569     status_cb.Run(DEMUXER_ERROR_COULD_NOT_PARSE);
570     return;
571   }
572
573   // Create demuxer stream entries for each possible AVStream. Each stream
574   // is examined to determine if it is supported or not (is the codec enabled
575   // for it in this release?). Unsupported streams are skipped, allowing for
576   // partial playback. At least one audio or video stream must be playable.
577   AVFormatContext* format_context = glue_->format_context();
578   streams_.resize(format_context->nb_streams);
579
580   AVStream* audio_stream = NULL;
581   AudioDecoderConfig audio_config;
582
583   AVStream* video_stream = NULL;
584   VideoDecoderConfig video_config;
585
586   base::TimeDelta max_duration;
587   for (size_t i = 0; i < format_context->nb_streams; ++i) {
588     AVStream* stream = format_context->streams[i];
589     AVCodecContext* codec_context = stream->codec;
590     AVMediaType codec_type = codec_context->codec_type;
591
592     if (codec_type == AVMEDIA_TYPE_AUDIO) {
593       if (audio_stream)
594         continue;
595
596       // Log the codec detected, whether it is supported or not.
597       UMA_HISTOGRAM_SPARSE_SLOWLY("Media.DetectedAudioCodec",
598                                   codec_context->codec_id);
599       // Ensure the codec is supported. IsValidConfig() also checks that the
600       // channel layout and sample format are valid.
601       AVStreamToAudioDecoderConfig(stream, &audio_config, false);
602       if (!audio_config.IsValidConfig())
603         continue;
604       audio_stream = stream;
605     } else if (codec_type == AVMEDIA_TYPE_VIDEO) {
606       if (video_stream)
607         continue;
608
609       // Log the codec detected, whether it is supported or not.
610       UMA_HISTOGRAM_SPARSE_SLOWLY("Media.DetectedVideoCodec",
611                                   codec_context->codec_id);
612       // Ensure the codec is supported. IsValidConfig() also checks that the
613       // frame size and visible size are valid.
614       AVStreamToVideoDecoderConfig(stream, &video_config, false);
615
616       if (!video_config.IsValidConfig())
617         continue;
618       video_stream = stream;
619     } else if (codec_type == AVMEDIA_TYPE_SUBTITLE) {
620       if (codec_context->codec_id != AV_CODEC_ID_WEBVTT || !text_enabled_) {
621         continue;
622       }
623     } else {
624       continue;
625     }
626
627     streams_[i] = new FFmpegDemuxerStream(this, stream);
628     max_duration = std::max(max_duration, streams_[i]->duration());
629
630     if (stream->first_dts != static_cast<int64_t>(AV_NOPTS_VALUE)) {
631       const base::TimeDelta first_dts = ConvertFromTimeBase(
632           stream->time_base, stream->first_dts);
633       if (start_time_ == kNoTimestamp() || first_dts < start_time_)
634         start_time_ = first_dts;
635     }
636   }
637
638   if (!audio_stream && !video_stream) {
639     status_cb.Run(DEMUXER_ERROR_NO_SUPPORTED_STREAMS);
640     return;
641   }
642
643   if (text_enabled_)
644     AddTextStreams();
645
646   if (format_context->duration != static_cast<int64_t>(AV_NOPTS_VALUE)) {
647     // If there is a duration value in the container use that to find the
648     // maximum between it and the duration from A/V streams.
649     const AVRational av_time_base = {1, AV_TIME_BASE};
650     max_duration =
651         std::max(max_duration,
652                  ConvertFromTimeBase(av_time_base, format_context->duration));
653   } else {
654     // The duration is unknown, in which case this is likely a live stream.
655     max_duration = kInfiniteDuration();
656   }
657
658   // Some demuxers, like WAV, do not put timestamps on their frames. We
659   // assume the the start time is 0.
660   if (start_time_ == kNoTimestamp())
661     start_time_ = base::TimeDelta();
662
663   // MPEG-4 B-frames cause grief for a simple container like AVI. Enable PTS
664   // generation so we always get timestamps, see http://crbug.com/169570
665   if (strcmp(format_context->iformat->name, "avi") == 0)
666     format_context->flags |= AVFMT_FLAG_GENPTS;
667
668   // Good to go: set the duration and bitrate and notify we're done
669   // initializing.
670   host_->SetDuration(max_duration);
671   duration_known_ = (max_duration != kInfiniteDuration());
672
673   int64 filesize_in_bytes = 0;
674   url_protocol_->GetSize(&filesize_in_bytes);
675   bitrate_ = CalculateBitrate(format_context, max_duration, filesize_in_bytes);
676   if (bitrate_ > 0)
677     data_source_->SetBitrate(bitrate_);
678
679   // Audio logging
680   if (audio_stream) {
681     AVCodecContext* audio_codec = audio_stream->codec;
682     media_log_->SetBooleanProperty("found_audio_stream", true);
683
684     SampleFormat sample_format = audio_config.sample_format();
685     std::string sample_name = SampleFormatToString(sample_format);
686
687     media_log_->SetStringProperty("audio_sample_format", sample_name);
688
689     AVCodec* codec = avcodec_find_decoder(audio_codec->codec_id);
690     if (codec) {
691       media_log_->SetStringProperty("audio_codec_name", codec->name);
692     }
693
694     media_log_->SetIntegerProperty("audio_channels_count",
695                                    audio_codec->channels);
696     media_log_->SetIntegerProperty("audio_samples_per_second",
697                                    audio_config.samples_per_second());
698   } else {
699     media_log_->SetBooleanProperty("found_audio_stream", false);
700   }
701
702   // Video logging
703   if (video_stream) {
704     AVCodecContext* video_codec = video_stream->codec;
705     media_log_->SetBooleanProperty("found_video_stream", true);
706
707     AVCodec* codec = avcodec_find_decoder(video_codec->codec_id);
708     if (codec) {
709       media_log_->SetStringProperty("video_codec_name", codec->name);
710     }
711
712     media_log_->SetIntegerProperty("width", video_codec->width);
713     media_log_->SetIntegerProperty("height", video_codec->height);
714     media_log_->SetIntegerProperty("coded_width",
715                                    video_codec->coded_width);
716     media_log_->SetIntegerProperty("coded_height",
717                                    video_codec->coded_height);
718     media_log_->SetStringProperty(
719         "time_base",
720         base::StringPrintf("%d/%d",
721                            video_codec->time_base.num,
722                            video_codec->time_base.den));
723     media_log_->SetStringProperty(
724         "video_format", VideoFrame::FormatToString(video_config.format()));
725     media_log_->SetBooleanProperty("video_is_encrypted",
726                                    video_config.is_encrypted());
727   } else {
728     media_log_->SetBooleanProperty("found_video_stream", false);
729   }
730
731
732   media_log_->SetDoubleProperty("max_duration", max_duration.InSecondsF());
733   media_log_->SetDoubleProperty("start_time", start_time_.InSecondsF());
734   media_log_->SetIntegerProperty("bitrate", bitrate_);
735
736   status_cb.Run(PIPELINE_OK);
737 }
738
739 void FFmpegDemuxer::OnSeekFrameDone(const PipelineStatusCB& cb, int result) {
740   DCHECK(task_runner_->BelongsToCurrentThread());
741   CHECK(pending_seek_);
742   pending_seek_ = false;
743
744   if (!blocking_thread_.IsRunning()) {
745     cb.Run(PIPELINE_ERROR_ABORT);
746     return;
747   }
748
749   if (result < 0) {
750     // Use VLOG(1) instead of NOTIMPLEMENTED() to prevent the message being
751     // captured from stdout and contaminates testing.
752     // TODO(scherkus): Implement this properly and signal error (BUG=23447).
753     VLOG(1) << "Not implemented";
754   }
755
756   // Tell streams to flush buffers due to seeking.
757   StreamVector::iterator iter;
758   for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
759     if (*iter)
760       (*iter)->FlushBuffers();
761   }
762
763   // Resume reading until capacity.
764   ReadFrameIfNeeded();
765
766   // Notify we're finished seeking.
767   cb.Run(PIPELINE_OK);
768 }
769
770 void FFmpegDemuxer::ReadFrameIfNeeded() {
771   DCHECK(task_runner_->BelongsToCurrentThread());
772
773   // Make sure we have work to do before reading.
774   if (!blocking_thread_.IsRunning() || !StreamsHaveAvailableCapacity() ||
775       pending_read_ || pending_seek_) {
776     return;
777   }
778
779   // Allocate and read an AVPacket from the media. Save |packet_ptr| since
780   // evaluation order of packet.get() and base::Passed(&packet) is
781   // undefined.
782   ScopedAVPacket packet(new AVPacket());
783   AVPacket* packet_ptr = packet.get();
784
785   pending_read_ = true;
786   base::PostTaskAndReplyWithResult(
787       blocking_thread_.message_loop_proxy().get(),
788       FROM_HERE,
789       base::Bind(&av_read_frame, glue_->format_context(), packet_ptr),
790       base::Bind(
791           &FFmpegDemuxer::OnReadFrameDone, weak_this_, base::Passed(&packet)));
792 }
793
794 void FFmpegDemuxer::OnReadFrameDone(ScopedAVPacket packet, int result) {
795   DCHECK(task_runner_->BelongsToCurrentThread());
796   DCHECK(pending_read_);
797   pending_read_ = false;
798
799   if (!blocking_thread_.IsRunning() || pending_seek_) {
800     return;
801   }
802
803   if (result < 0) {
804     // Update the duration based on the highest elapsed time across all streams
805     // if it was previously unknown.
806     if (!duration_known_) {
807       base::TimeDelta max_duration;
808
809       for (StreamVector::iterator iter = streams_.begin();
810            iter != streams_.end();
811            ++iter) {
812         if (!*iter)
813           continue;
814
815         base::TimeDelta duration = (*iter)->GetElapsedTime();
816         if (duration != kNoTimestamp() && duration > max_duration)
817           max_duration = duration;
818       }
819
820       if (max_duration > base::TimeDelta()) {
821         host_->SetDuration(max_duration);
822         duration_known_ = true;
823       }
824     }
825     // If we have reached the end of stream, tell the downstream filters about
826     // the event.
827     StreamHasEnded();
828     return;
829   }
830
831   // Queue the packet with the appropriate stream.
832   DCHECK_GE(packet->stream_index, 0);
833   DCHECK_LT(packet->stream_index, static_cast<int>(streams_.size()));
834
835   // Defend against ffmpeg giving us a bad stream index.
836   if (packet->stream_index >= 0 &&
837       packet->stream_index < static_cast<int>(streams_.size()) &&
838       streams_[packet->stream_index] &&
839       (!audio_disabled_ ||
840        streams_[packet->stream_index]->type() != DemuxerStream::AUDIO)) {
841
842     // TODO(scherkus): Fix demuxing upstream to never return packets w/o data
843     // when av_read_frame() returns success code. See bug comment for ideas:
844     //
845     // https://code.google.com/p/chromium/issues/detail?id=169133#c10
846     if (!packet->data) {
847       ScopedAVPacket new_packet(new AVPacket());
848       av_new_packet(new_packet.get(), 0);
849
850       new_packet->pts = packet->pts;
851       new_packet->dts = packet->dts;
852       new_packet->pos = packet->pos;
853       new_packet->duration = packet->duration;
854       new_packet->convergence_duration = packet->convergence_duration;
855       new_packet->flags = packet->flags;
856       new_packet->stream_index = packet->stream_index;
857
858       packet.swap(new_packet);
859     }
860
861     // Special case for opus in ogg.  FFmpeg is pre-trimming the codec delay
862     // from the packet timestamp.  Chrome expects to handle this itself inside
863     // the decoder, so shift timestamps by the delay in this case.
864     // TODO(dalecurtis): Try to get fixed upstream.  See http://crbug.com/328207
865     if (strcmp(glue_->format_context()->iformat->name, "ogg") == 0) {
866       const AVCodecContext* codec_context =
867           glue_->format_context()->streams[packet->stream_index]->codec;
868       if (codec_context->codec_id == AV_CODEC_ID_OPUS &&
869           codec_context->delay > 0) {
870         packet->pts += codec_context->delay;
871       }
872     }
873
874     FFmpegDemuxerStream* demuxer_stream = streams_[packet->stream_index];
875     demuxer_stream->EnqueuePacket(packet.Pass());
876   }
877
878   // Keep reading until we've reached capacity.
879   ReadFrameIfNeeded();
880 }
881
882 void FFmpegDemuxer::OnDataSourceStopped(const base::Closure& callback) {
883   // This will block until all tasks complete. Note that after this returns it's
884   // possible for reply tasks (e.g., OnReadFrameDone()) to be queued on this
885   // thread. Each of the reply task methods must check whether we've stopped the
886   // thread and drop their results on the floor.
887   DCHECK(task_runner_->BelongsToCurrentThread());
888   blocking_thread_.Stop();
889
890   StreamVector::iterator iter;
891   for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
892     if (*iter)
893       (*iter)->Stop();
894   }
895
896   callback.Run();
897 }
898
899 bool FFmpegDemuxer::StreamsHaveAvailableCapacity() {
900   DCHECK(task_runner_->BelongsToCurrentThread());
901   StreamVector::iterator iter;
902   for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
903     if (*iter && (*iter)->HasAvailableCapacity()) {
904       return true;
905     }
906   }
907   return false;
908 }
909
910 void FFmpegDemuxer::StreamHasEnded() {
911   DCHECK(task_runner_->BelongsToCurrentThread());
912   StreamVector::iterator iter;
913   for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
914     if (!*iter ||
915         (audio_disabled_ && (*iter)->type() == DemuxerStream::AUDIO)) {
916       continue;
917     }
918     (*iter)->SetEndOfStream();
919   }
920 }
921
922 void FFmpegDemuxer::FireNeedKey(const std::string& init_data_type,
923                                 const std::string& encryption_key_id) {
924   std::vector<uint8> key_id_local(encryption_key_id.begin(),
925                                   encryption_key_id.end());
926   need_key_cb_.Run(init_data_type, key_id_local);
927 }
928
929 void FFmpegDemuxer::NotifyCapacityAvailable() {
930   DCHECK(task_runner_->BelongsToCurrentThread());
931   ReadFrameIfNeeded();
932 }
933
934 void FFmpegDemuxer::NotifyBufferingChanged() {
935   DCHECK(task_runner_->BelongsToCurrentThread());
936   Ranges<base::TimeDelta> buffered;
937   FFmpegDemuxerStream* audio =
938       audio_disabled_ ? NULL : GetFFmpegStream(DemuxerStream::AUDIO);
939   FFmpegDemuxerStream* video = GetFFmpegStream(DemuxerStream::VIDEO);
940   if (audio && video) {
941     buffered = audio->GetBufferedRanges().IntersectionWith(
942         video->GetBufferedRanges());
943   } else if (audio) {
944     buffered = audio->GetBufferedRanges();
945   } else if (video) {
946     buffered = video->GetBufferedRanges();
947   }
948   for (size_t i = 0; i < buffered.size(); ++i)
949     host_->AddBufferedTimeRange(buffered.start(i), buffered.end(i));
950 }
951
952 void FFmpegDemuxer::OnDataSourceError() {
953   host_->OnDemuxerError(PIPELINE_ERROR_READ);
954 }
955
956 }  // namespace media