OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/filters/ffmpeg_demuxer.h" | 5 #include "media/filters/ffmpeg_demuxer.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/base64.h" | 10 #include "base/base64.h" |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/callback_helpers.h" | 12 #include "base/callback_helpers.h" |
13 #include "base/macros.h" | 13 #include "base/macros.h" |
14 #include "base/memory/scoped_ptr.h" | 14 #include "base/memory/scoped_ptr.h" |
15 #include "base/metrics/histogram_macros.h" | 15 #include "base/metrics/histogram_macros.h" |
16 #include "base/metrics/sparse_histogram.h" | 16 #include "base/metrics/sparse_histogram.h" |
17 #include "base/single_thread_task_runner.h" | 17 #include "base/single_thread_task_runner.h" |
18 #include "base/strings/string_number_conversions.h" | 18 #include "base/strings/string_number_conversions.h" |
19 #include "base/strings/string_util.h" | 19 #include "base/strings/string_util.h" |
20 #include "base/strings/stringprintf.h" | 20 #include "base/strings/stringprintf.h" |
21 #include "base/sys_byteorder.h" | 21 #include "base/sys_byteorder.h" |
22 #include "base/task_runner_util.h" | 22 #include "base/task_runner_util.h" |
23 #include "base/thread_task_runner_handle.h" | 23 #include "base/thread_task_runner_handle.h" |
24 #include "base/time/time.h" | 24 #include "base/time/time.h" |
25 #include "media/audio/sample_rates.h" | 25 #include "media/audio/sample_rates.h" |
26 #include "media/base/bind_to_current_loop.h" | 26 #include "media/base/bind_to_current_loop.h" |
27 #include "media/base/decrypt_config.h" | 27 #include "media/base/decrypt_config.h" |
28 #include "media/base/limits.h" | 28 #include "media/base/limits.h" |
29 #include "media/base/media_log.h" | 29 #include "media/base/media_log.h" |
| 30 #include "media/base/media_tracks.h" |
30 #include "media/base/timestamp_constants.h" | 31 #include "media/base/timestamp_constants.h" |
31 #include "media/ffmpeg/ffmpeg_common.h" | 32 #include "media/ffmpeg/ffmpeg_common.h" |
32 #include "media/filters/ffmpeg_aac_bitstream_converter.h" | 33 #include "media/filters/ffmpeg_aac_bitstream_converter.h" |
33 #include "media/filters/ffmpeg_bitstream_converter.h" | 34 #include "media/filters/ffmpeg_bitstream_converter.h" |
34 #include "media/filters/ffmpeg_glue.h" | 35 #include "media/filters/ffmpeg_glue.h" |
35 #include "media/filters/ffmpeg_h264_to_annex_b_bitstream_converter.h" | 36 #include "media/filters/ffmpeg_h264_to_annex_b_bitstream_converter.h" |
36 #include "media/filters/webvtt_util.h" | 37 #include "media/filters/webvtt_util.h" |
37 #include "media/formats/webm/webm_crypto_helpers.h" | 38 #include "media/formats/webm/webm_crypto_helpers.h" |
38 #include "media/media_features.h" | 39 #include "media/media_features.h" |
39 | 40 |
(...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
734 return ConvertFromTimeBase(time_base, timestamp); | 735 return ConvertFromTimeBase(time_base, timestamp); |
735 } | 736 } |
736 | 737 |
737 // | 738 // |
738 // FFmpegDemuxer | 739 // FFmpegDemuxer |
739 // | 740 // |
740 FFmpegDemuxer::FFmpegDemuxer( | 741 FFmpegDemuxer::FFmpegDemuxer( |
741 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, | 742 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, |
742 DataSource* data_source, | 743 DataSource* data_source, |
743 const EncryptedMediaInitDataCB& encrypted_media_init_data_cb, | 744 const EncryptedMediaInitDataCB& encrypted_media_init_data_cb, |
| 745 const MediaTracksUpdatedCB& media_tracks_updated_cb, |
744 const scoped_refptr<MediaLog>& media_log) | 746 const scoped_refptr<MediaLog>& media_log) |
745 : host_(NULL), | 747 : host_(NULL), |
746 task_runner_(task_runner), | 748 task_runner_(task_runner), |
747 blocking_thread_("FFmpegDemuxer"), | 749 blocking_thread_("FFmpegDemuxer"), |
748 pending_read_(false), | 750 pending_read_(false), |
749 pending_seek_(false), | 751 pending_seek_(false), |
750 data_source_(data_source), | 752 data_source_(data_source), |
751 media_log_(media_log), | 753 media_log_(media_log), |
752 bitrate_(0), | 754 bitrate_(0), |
753 start_time_(kNoTimestamp()), | 755 start_time_(kNoTimestamp()), |
754 preferred_stream_for_seeking_(-1, kNoTimestamp()), | 756 preferred_stream_for_seeking_(-1, kNoTimestamp()), |
755 fallback_stream_for_seeking_(-1, kNoTimestamp()), | 757 fallback_stream_for_seeking_(-1, kNoTimestamp()), |
756 text_enabled_(false), | 758 text_enabled_(false), |
757 duration_known_(false), | 759 duration_known_(false), |
758 encrypted_media_init_data_cb_(encrypted_media_init_data_cb), | 760 encrypted_media_init_data_cb_(encrypted_media_init_data_cb), |
| 761 media_tracks_updated_cb_(media_tracks_updated_cb), |
759 weak_factory_(this) { | 762 weak_factory_(this) { |
760 DCHECK(task_runner_.get()); | 763 DCHECK(task_runner_.get()); |
761 DCHECK(data_source_); | 764 DCHECK(data_source_); |
| 765 DCHECK(!media_tracks_updated_cb_.is_null()); |
762 } | 766 } |
763 | 767 |
764 FFmpegDemuxer::~FFmpegDemuxer() {} | 768 FFmpegDemuxer::~FFmpegDemuxer() {} |
765 | 769 |
766 void FFmpegDemuxer::Stop() { | 770 void FFmpegDemuxer::Stop() { |
767 DCHECK(task_runner_->BelongsToCurrentThread()); | 771 DCHECK(task_runner_->BelongsToCurrentThread()); |
768 | 772 |
769 // The order of Stop() and Abort() is important here. If Abort() is called | 773 // The order of Stop() and Abort() is important here. If Abort() is called |
770 // first, control may pass into FFmpeg where it can destruct buffers that are | 774 // first, control may pass into FFmpeg where it can destruct buffers that are |
771 // in the process of being fulfilled by the DataSource. | 775 // in the process of being fulfilled by the DataSource. |
(...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1313 media_log_->SetBooleanProperty("video_is_encrypted", | 1317 media_log_->SetBooleanProperty("video_is_encrypted", |
1314 video_config.is_encrypted()); | 1318 video_config.is_encrypted()); |
1315 } else { | 1319 } else { |
1316 media_log_->SetBooleanProperty("found_video_stream", false); | 1320 media_log_->SetBooleanProperty("found_video_stream", false); |
1317 } | 1321 } |
1318 | 1322 |
1319 media_log_->SetTimeProperty("max_duration", max_duration); | 1323 media_log_->SetTimeProperty("max_duration", max_duration); |
1320 media_log_->SetTimeProperty("start_time", start_time_); | 1324 media_log_->SetTimeProperty("start_time", start_time_); |
1321 media_log_->SetIntegerProperty("bitrate", bitrate_); | 1325 media_log_->SetIntegerProperty("bitrate", bitrate_); |
1322 | 1326 |
| 1327 { |
| 1328 scoped_ptr<MediaTracks> media_tracks(new MediaTracks()); |
| 1329 |
| 1330 if (audio_stream) { |
| 1331 AVDictionaryEntry* lang_tag = |
| 1332 av_dict_get(audio_stream->metadata, "language", NULL, 0); |
| 1333 std::string track_language = "und"; |
| 1334 if (lang_tag && lang_tag->value) |
| 1335 track_language = lang_tag->value; |
| 1336 |
| 1337 media_tracks->AddAudioTrack(audio_config, "audio", "main", "", |
| 1338 track_language); |
| 1339 } |
| 1340 if (video_stream) { |
| 1341 AVDictionaryEntry* lang_tag = |
| 1342 av_dict_get(video_stream->metadata, "language", NULL, 0); |
| 1343 std::string track_language = "und"; |
| 1344 if (lang_tag && lang_tag->value) |
| 1345 track_language = lang_tag->value; |
| 1346 |
| 1347 media_tracks->AddVideoTrack(video_config, "video", "main", "", |
| 1348 track_language); |
| 1349 } |
| 1350 media_tracks_updated_cb_.Run(std::move(media_tracks)); |
| 1351 } |
| 1352 |
1323 status_cb.Run(PIPELINE_OK); | 1353 status_cb.Run(PIPELINE_OK); |
1324 } | 1354 } |
1325 | 1355 |
1326 void FFmpegDemuxer::OnSeekFrameDone(const PipelineStatusCB& cb, int result) { | 1356 void FFmpegDemuxer::OnSeekFrameDone(const PipelineStatusCB& cb, int result) { |
1327 DCHECK(task_runner_->BelongsToCurrentThread()); | 1357 DCHECK(task_runner_->BelongsToCurrentThread()); |
1328 CHECK(pending_seek_); | 1358 CHECK(pending_seek_); |
1329 pending_seek_ = false; | 1359 pending_seek_ = false; |
1330 | 1360 |
1331 if (!blocking_thread_.IsRunning()) { | 1361 if (!blocking_thread_.IsRunning()) { |
1332 MEDIA_LOG(ERROR, media_log_) << GetDisplayName() << ": bad state"; | 1362 MEDIA_LOG(ERROR, media_log_) << GetDisplayName() << ": bad state"; |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1524 | 1554 |
1525 void FFmpegDemuxer::SetLiveness(DemuxerStream::Liveness liveness) { | 1555 void FFmpegDemuxer::SetLiveness(DemuxerStream::Liveness liveness) { |
1526 DCHECK(task_runner_->BelongsToCurrentThread()); | 1556 DCHECK(task_runner_->BelongsToCurrentThread()); |
1527 for (const auto& stream : streams_) { // |stream| is a ref to a pointer. | 1557 for (const auto& stream : streams_) { // |stream| is a ref to a pointer. |
1528 if (stream) | 1558 if (stream) |
1529 stream->SetLiveness(liveness); | 1559 stream->SetLiveness(liveness); |
1530 } | 1560 } |
1531 } | 1561 } |
1532 | 1562 |
1533 } // namespace media | 1563 } // namespace media |
OLD | NEW |