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