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 1042 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1082 if (packet_buffer->pkt.pts != static_cast<int64_t>(AV_NOPTS_VALUE)) { | 1083 if (packet_buffer->pkt.pts != static_cast<int64_t>(AV_NOPTS_VALUE)) { |
1083 const base::TimeDelta packet_pts = | 1084 const base::TimeDelta packet_pts = |
1084 ConvertFromTimeBase(stream->time_base, packet_buffer->pkt.pts); | 1085 ConvertFromTimeBase(stream->time_base, packet_buffer->pkt.pts); |
1085 if (packet_pts < start_time_estimates[stream->index]) | 1086 if (packet_pts < start_time_estimates[stream->index]) |
1086 start_time_estimates[stream->index] = packet_pts; | 1087 start_time_estimates[stream->index] = packet_pts; |
1087 } | 1088 } |
1088 packet_buffer = packet_buffer->next; | 1089 packet_buffer = packet_buffer->next; |
1089 } | 1090 } |
1090 } | 1091 } |
1091 | 1092 |
| 1093 scoped_ptr<MediaTracks> media_tracks(new MediaTracks()); |
1092 AVStream* audio_stream = NULL; | 1094 AVStream* audio_stream = NULL; |
1093 AudioDecoderConfig audio_config; | 1095 AudioDecoderConfig audio_config; |
1094 AVStream* video_stream = NULL; | 1096 AVStream* video_stream = NULL; |
1095 VideoDecoderConfig video_config; | 1097 VideoDecoderConfig video_config; |
1096 | 1098 |
1097 // If available, |start_time_| will be set to the lowest stream start time. | 1099 // If available, |start_time_| will be set to the lowest stream start time. |
1098 start_time_ = kInfiniteDuration(); | 1100 start_time_ = kInfiniteDuration(); |
1099 | 1101 |
1100 base::TimeDelta max_duration; | 1102 base::TimeDelta max_duration; |
1101 for (size_t i = 0; i < format_context->nb_streams; ++i) { | 1103 for (size_t i = 0; i < format_context->nb_streams; ++i) { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1151 // things like: codec, channel layout, sample/pixel format, etc... | 1153 // things like: codec, channel layout, sample/pixel format, etc... |
1152 scoped_ptr<FFmpegDemuxerStream> demuxer_stream = | 1154 scoped_ptr<FFmpegDemuxerStream> demuxer_stream = |
1153 FFmpegDemuxerStream::Create(this, stream, media_log_); | 1155 FFmpegDemuxerStream::Create(this, stream, media_log_); |
1154 if (demuxer_stream.get()) { | 1156 if (demuxer_stream.get()) { |
1155 streams_[i] = demuxer_stream.release(); | 1157 streams_[i] = demuxer_stream.release(); |
1156 } else { | 1158 } else { |
1157 // This AVStream does not successfully convert. | 1159 // This AVStream does not successfully convert. |
1158 continue; | 1160 continue; |
1159 } | 1161 } |
1160 | 1162 |
| 1163 std::string track_id = base::IntToString(stream->id); |
| 1164 std::string track_label = streams_[i]->GetMetadata("handler_name"); |
| 1165 std::string track_language = streams_[i]->GetMetadata("language"); |
| 1166 |
| 1167 // Some metadata is named differently in FFmpeg for webm files. |
| 1168 if (strstr(format_context->iformat->name, "webm") || |
| 1169 strstr(format_context->iformat->name, "matroska")) { |
| 1170 // TODO(servolk): FFmpeg doesn't set stream->id correctly for webm files. |
| 1171 // Need to fix that and use it as track id. crbug.com/323183 |
| 1172 track_id = base::UintToString(media_tracks->tracks().size() + 1); |
| 1173 track_label = streams_[i]->GetMetadata("title"); |
| 1174 } |
| 1175 |
1161 // Note when we find our audio/video stream (we only want one of each) and | 1176 // Note when we find our audio/video stream (we only want one of each) and |
1162 // record src= playback UMA stats for the stream's decoder config. | 1177 // record src= playback UMA stats for the stream's decoder config. |
1163 if (codec_type == AVMEDIA_TYPE_AUDIO) { | 1178 if (codec_type == AVMEDIA_TYPE_AUDIO) { |
1164 CHECK(!audio_stream); | 1179 CHECK(!audio_stream); |
1165 audio_stream = stream; | 1180 audio_stream = stream; |
1166 audio_config = streams_[i]->audio_decoder_config(); | 1181 audio_config = streams_[i]->audio_decoder_config(); |
1167 RecordAudioCodecStats(audio_config); | 1182 RecordAudioCodecStats(audio_config); |
| 1183 |
| 1184 media_tracks->AddAudioTrack(audio_config, track_id, "main", track_label, |
| 1185 track_language); |
1168 } else if (codec_type == AVMEDIA_TYPE_VIDEO) { | 1186 } else if (codec_type == AVMEDIA_TYPE_VIDEO) { |
1169 CHECK(!video_stream); | 1187 CHECK(!video_stream); |
1170 video_stream = stream; | 1188 video_stream = stream; |
1171 video_config = streams_[i]->video_decoder_config(); | 1189 video_config = streams_[i]->video_decoder_config(); |
1172 RecordVideoCodecStats(video_config, stream->codec->color_range); | 1190 RecordVideoCodecStats(video_config, stream->codec->color_range); |
| 1191 |
| 1192 media_tracks->AddVideoTrack(video_config, track_id, "main", track_label, |
| 1193 track_language); |
1173 } | 1194 } |
1174 | 1195 |
1175 max_duration = std::max(max_duration, streams_[i]->duration()); | 1196 max_duration = std::max(max_duration, streams_[i]->duration()); |
1176 | 1197 |
1177 const base::TimeDelta start_time = | 1198 const base::TimeDelta start_time = |
1178 ExtractStartTime(stream, start_time_estimates[i]); | 1199 ExtractStartTime(stream, start_time_estimates[i]); |
1179 const bool has_start_time = start_time != kNoTimestamp(); | 1200 const bool has_start_time = start_time != kNoTimestamp(); |
1180 | 1201 |
1181 // Always prefer the video stream for seeking. If none exists, we'll swap | 1202 // Always prefer the video stream for seeking. If none exists, we'll swap |
1182 // the fallback stream with the preferred stream below. | 1203 // the fallback stream with the preferred stream below. |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1333 media_log_->SetBooleanProperty("video_is_encrypted", | 1354 media_log_->SetBooleanProperty("video_is_encrypted", |
1334 video_config.is_encrypted()); | 1355 video_config.is_encrypted()); |
1335 } else { | 1356 } else { |
1336 media_log_->SetBooleanProperty("found_video_stream", false); | 1357 media_log_->SetBooleanProperty("found_video_stream", false); |
1337 } | 1358 } |
1338 | 1359 |
1339 media_log_->SetTimeProperty("max_duration", max_duration); | 1360 media_log_->SetTimeProperty("max_duration", max_duration); |
1340 media_log_->SetTimeProperty("start_time", start_time_); | 1361 media_log_->SetTimeProperty("start_time", start_time_); |
1341 media_log_->SetIntegerProperty("bitrate", bitrate_); | 1362 media_log_->SetIntegerProperty("bitrate", bitrate_); |
1342 | 1363 |
| 1364 media_tracks_updated_cb_.Run(std::move(media_tracks)); |
| 1365 |
1343 status_cb.Run(PIPELINE_OK); | 1366 status_cb.Run(PIPELINE_OK); |
1344 } | 1367 } |
1345 | 1368 |
1346 void FFmpegDemuxer::OnSeekFrameDone(const PipelineStatusCB& cb, int result) { | 1369 void FFmpegDemuxer::OnSeekFrameDone(const PipelineStatusCB& cb, int result) { |
1347 DCHECK(task_runner_->BelongsToCurrentThread()); | 1370 DCHECK(task_runner_->BelongsToCurrentThread()); |
1348 CHECK(pending_seek_); | 1371 CHECK(pending_seek_); |
1349 pending_seek_ = false; | 1372 pending_seek_ = false; |
1350 | 1373 |
1351 if (!blocking_thread_.IsRunning()) { | 1374 if (!blocking_thread_.IsRunning()) { |
1352 MEDIA_LOG(ERROR, media_log_) << GetDisplayName() << ": bad state"; | 1375 MEDIA_LOG(ERROR, media_log_) << GetDisplayName() << ": bad state"; |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1515 | 1538 |
1516 void FFmpegDemuxer::SetLiveness(DemuxerStream::Liveness liveness) { | 1539 void FFmpegDemuxer::SetLiveness(DemuxerStream::Liveness liveness) { |
1517 DCHECK(task_runner_->BelongsToCurrentThread()); | 1540 DCHECK(task_runner_->BelongsToCurrentThread()); |
1518 for (const auto& stream : streams_) { // |stream| is a ref to a pointer. | 1541 for (const auto& stream : streams_) { // |stream| is a ref to a pointer. |
1519 if (stream) | 1542 if (stream) |
1520 stream->SetLiveness(liveness); | 1543 stream->SetLiveness(liveness); |
1521 } | 1544 } |
1522 } | 1545 } |
1523 | 1546 |
1524 } // namespace media | 1547 } // namespace media |
OLD | NEW |