Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(346)

Side by Side Diff: media/filters/ffmpeg_demuxer.cc

Issue 2497603003: Roll src/third_party/ffmpeg/ 3c7a09882..cdf4accee (3188 commits). (Closed)
Patch Set: Rebase (liberato@'s pipeline_integration_test_base conflicted; using liberato@'s now here) Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <memory> 8 #include <memory>
9 #include <set> 9 #include <set>
10 #include <utility> 10 #include <utility>
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 176
177 // Note the PRESUBMIT_IGNORE_UMA_MAX below, this silences the PRESUBMIT.py 177 // Note the PRESUBMIT_IGNORE_UMA_MAX below, this silences the PRESUBMIT.py
178 // check for uma enum max usage, since we're abusing 178 // check for uma enum max usage, since we're abusing
179 // UMA_HISTOGRAM_ENUMERATION to report a discrete value. 179 // UMA_HISTOGRAM_ENUMERATION to report a discrete value.
180 UMA_HISTOGRAM_ENUMERATION("Media.VideoColorRange", color_range, 180 UMA_HISTOGRAM_ENUMERATION("Media.VideoColorRange", color_range,
181 AVCOL_RANGE_NB); // PRESUBMIT_IGNORE_UMA_MAX 181 AVCOL_RANGE_NB); // PRESUBMIT_IGNORE_UMA_MAX
182 } 182 }
183 183
184 static const char kCodecNone[] = "none"; 184 static const char kCodecNone[] = "none";
185 185
186 static const char* GetCodecName(const AVCodecContext* context) { 186 static const char* GetCodecName(enum AVCodecID id) {
187 if (context->codec_descriptor) 187 const AVCodecDescriptor* codec_descriptor = avcodec_descriptor_get(id);
188 return context->codec_descriptor->name;
189 const AVCodecDescriptor* codec_descriptor =
190 avcodec_descriptor_get(context->codec_id);
191 // If the codec name can't be determined, return none for tracking. 188 // If the codec name can't be determined, return none for tracking.
192 return codec_descriptor ? codec_descriptor->name : kCodecNone; 189 return codec_descriptor ? codec_descriptor->name : kCodecNone;
193 } 190 }
194 191
195 static void SetTimeProperty(MediaLogEvent* event, 192 static void SetTimeProperty(MediaLogEvent* event,
196 const std::string& key, 193 const std::string& key,
197 base::TimeDelta value) { 194 base::TimeDelta value) {
198 if (value == kInfiniteDuration) 195 if (value == kInfiniteDuration)
199 event->params.SetString(key, "kInfiniteDuration"); 196 event->params.SetString(key, "kInfiniteDuration");
200 else if (value == kNoTimestamp) 197 else if (value == kNoTimestamp)
201 event->params.SetString(key, "kNoTimestamp"); 198 event->params.SetString(key, "kNoTimestamp");
202 else 199 else
203 event->params.SetDouble(key, value.InSecondsF()); 200 event->params.SetDouble(key, value.InSecondsF());
204 } 201 }
205 202
206 std::unique_ptr<FFmpegDemuxerStream> FFmpegDemuxerStream::Create( 203 std::unique_ptr<FFmpegDemuxerStream> FFmpegDemuxerStream::Create(
207 FFmpegDemuxer* demuxer, 204 FFmpegDemuxer* demuxer,
208 AVStream* stream, 205 AVStream* stream,
209 const scoped_refptr<MediaLog>& media_log) { 206 const scoped_refptr<MediaLog>& media_log) {
210 if (!demuxer || !stream) 207 if (!demuxer || !stream)
211 return nullptr; 208 return nullptr;
212 209
213 std::unique_ptr<FFmpegDemuxerStream> demuxer_stream; 210 std::unique_ptr<FFmpegDemuxerStream> demuxer_stream;
214 std::unique_ptr<AudioDecoderConfig> audio_config; 211 std::unique_ptr<AudioDecoderConfig> audio_config;
215 std::unique_ptr<VideoDecoderConfig> video_config; 212 std::unique_ptr<VideoDecoderConfig> video_config;
216 213
217 if (stream->codec->codec_type == AVMEDIA_TYPE_AUDIO) { 214 if (stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
218 audio_config.reset(new AudioDecoderConfig()); 215 audio_config.reset(new AudioDecoderConfig());
219 216
220 // IsValidConfig() checks that the codec is supported and that the channel 217 // IsValidConfig() checks that the codec is supported and that the channel
221 // layout and sample format are valid. 218 // layout and sample format are valid.
222 // 219 //
223 // TODO(chcunningham): Change AVStreamToAudioDecoderConfig to check 220 // TODO(chcunningham): Change AVStreamToAudioDecoderConfig to check
224 // IsValidConfig internally and return a null scoped_ptr if not valid. 221 // IsValidConfig internally and return a null scoped_ptr if not valid.
225 if (!AVStreamToAudioDecoderConfig(stream, audio_config.get()) || 222 if (!AVStreamToAudioDecoderConfig(stream, audio_config.get()) ||
226 !audio_config->IsValidConfig()) { 223 !audio_config->IsValidConfig()) {
227 MEDIA_LOG(ERROR, media_log) 224 MEDIA_LOG(ERROR, media_log)
228 << "FFmpegDemuxer: failed creating audio stream"; 225 << "FFmpegDemuxer: failed creating audio stream";
229 return nullptr; 226 return nullptr;
230 } 227 }
231 228
232 MEDIA_LOG(INFO, media_log) << "FFmpegDemuxer: created audio stream, config " 229 MEDIA_LOG(INFO, media_log) << "FFmpegDemuxer: created audio stream, config "
233 << audio_config->AsHumanReadableString(); 230 << audio_config->AsHumanReadableString();
234 } else if (stream->codec->codec_type == AVMEDIA_TYPE_VIDEO) { 231 } else if (stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
235 video_config.reset(new VideoDecoderConfig()); 232 video_config.reset(new VideoDecoderConfig());
236 233
237 // IsValidConfig() checks that the codec is supported and that the channel 234 // IsValidConfig() checks that the codec is supported and that the channel
238 // layout and sample format are valid. 235 // layout and sample format are valid.
239 // 236 //
240 // TODO(chcunningham): Change AVStreamToVideoDecoderConfig to check 237 // TODO(chcunningham): Change AVStreamToVideoDecoderConfig to check
241 // IsValidConfig internally and return a null scoped_ptr if not valid. 238 // IsValidConfig internally and return a null scoped_ptr if not valid.
242 if (!AVStreamToVideoDecoderConfig(stream, video_config.get()) || 239 if (!AVStreamToVideoDecoderConfig(stream, video_config.get()) ||
243 !video_config->IsValidConfig()) { 240 !video_config->IsValidConfig()) {
244 MEDIA_LOG(ERROR, media_log) 241 MEDIA_LOG(ERROR, media_log)
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 is_enabled_(true), 278 is_enabled_(true),
282 waiting_for_keyframe_(false), 279 waiting_for_keyframe_(false),
283 fixup_negative_timestamps_(false) { 280 fixup_negative_timestamps_(false) {
284 DCHECK(demuxer_); 281 DCHECK(demuxer_);
285 282
286 bool is_encrypted = false; 283 bool is_encrypted = false;
287 int rotation = 0; 284 int rotation = 0;
288 AVDictionaryEntry* rotation_entry = NULL; 285 AVDictionaryEntry* rotation_entry = NULL;
289 286
290 // Determine our media format. 287 // Determine our media format.
291 switch (stream->codec->codec_type) { 288 switch (stream->codecpar->codec_type) {
292 case AVMEDIA_TYPE_AUDIO: 289 case AVMEDIA_TYPE_AUDIO:
293 DCHECK(audio_config_.get() && !video_config_.get()); 290 DCHECK(audio_config_.get() && !video_config_.get());
294 type_ = AUDIO; 291 type_ = AUDIO;
295 is_encrypted = audio_config_->is_encrypted(); 292 is_encrypted = audio_config_->is_encrypted();
296 break; 293 break;
297 case AVMEDIA_TYPE_VIDEO: 294 case AVMEDIA_TYPE_VIDEO:
298 DCHECK(video_config_.get() && !audio_config_.get()); 295 DCHECK(video_config_.get() && !audio_config_.get());
299 type_ = VIDEO; 296 type_ = VIDEO;
300 is_encrypted = video_config_->is_encrypted(); 297 is_encrypted = video_config_->is_encrypted();
301 298
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 if (start_time > base::TimeDelta()) 493 if (start_time > base::TimeDelta())
497 start_time = base::TimeDelta(); 494 start_time = base::TimeDelta();
498 495
499 buffer->set_timestamp(stream_timestamp - start_time); 496 buffer->set_timestamp(stream_timestamp - start_time);
500 497
501 // If enabled, and no codec delay is present, mark audio packets with 498 // If enabled, and no codec delay is present, mark audio packets with
502 // negative timestamps for post-decode discard. 499 // negative timestamps for post-decode discard.
503 if (fixup_negative_timestamps_ && is_audio && 500 if (fixup_negative_timestamps_ && is_audio &&
504 stream_timestamp < base::TimeDelta() && 501 stream_timestamp < base::TimeDelta() &&
505 buffer->duration() != kNoTimestamp) { 502 buffer->duration() != kNoTimestamp) {
506 if (!stream_->codec->delay) { 503 if (!audio_decoder_config().codec_delay()) {
507 DCHECK_EQ(buffer->discard_padding().first, base::TimeDelta()); 504 DCHECK_EQ(buffer->discard_padding().first, base::TimeDelta());
508 505
509 if (stream_timestamp + buffer->duration() < base::TimeDelta()) { 506 if (stream_timestamp + buffer->duration() < base::TimeDelta()) {
510 DCHECK_EQ(buffer->discard_padding().second, base::TimeDelta()); 507 DCHECK_EQ(buffer->discard_padding().second, base::TimeDelta());
511 508
512 // Discard the entire packet if it's entirely before zero. 509 // Discard the entire packet if it's entirely before zero.
513 buffer->set_discard_padding( 510 buffer->set_discard_padding(
514 std::make_pair(kInfiniteDuration, base::TimeDelta())); 511 std::make_pair(kInfiniteDuration, base::TimeDelta()));
515 } else { 512 } else {
516 // Only discard part of the frame if it overlaps zero. 513 // Only discard part of the frame if it overlaps zero.
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 658
662 void FFmpegDemuxerStream::ResetBitstreamConverter() { 659 void FFmpegDemuxerStream::ResetBitstreamConverter() {
663 #if defined(USE_PROPRIETARY_CODECS) 660 #if defined(USE_PROPRIETARY_CODECS)
664 if (bitstream_converter_) 661 if (bitstream_converter_)
665 InitBitstreamConverter(); 662 InitBitstreamConverter();
666 #endif // defined(USE_PROPRIETARY_CODECS) 663 #endif // defined(USE_PROPRIETARY_CODECS)
667 } 664 }
668 665
669 void FFmpegDemuxerStream::InitBitstreamConverter() { 666 void FFmpegDemuxerStream::InitBitstreamConverter() {
670 #if defined(USE_PROPRIETARY_CODECS) 667 #if defined(USE_PROPRIETARY_CODECS)
671 switch (stream_->codec->codec_id) { 668 switch (stream_->codecpar->codec_id) {
672 case AV_CODEC_ID_H264: 669 case AV_CODEC_ID_H264:
673 // Clear |extra_data| so that future (fallback) decoders will know that 670 // Clear |extra_data| so that future (fallback) decoders will know that
674 // conversion is forcibly enabled on this stream. 671 // conversion is forcibly enabled on this stream.
675 // 672 //
676 // TODO(sandersd): Ideally we would convert |extra_data| to concatenated 673 // TODO(sandersd): Ideally we would convert |extra_data| to concatenated
677 // SPS/PPS data, but it's too late to be useful because Initialize() was 674 // SPS/PPS data, but it's too late to be useful because Initialize() was
678 // already called on GpuVideoDecoder, which is the only path that would 675 // already called on GpuVideoDecoder, which is the only path that would
679 // consume that data. 676 // consume that data.
680 if (video_config_) 677 if (video_config_)
681 video_config_->SetExtraData(std::vector<uint8_t>()); 678 video_config_->SetExtraData(std::vector<uint8_t>());
682 bitstream_converter_.reset( 679 bitstream_converter_.reset(
683 new FFmpegH264ToAnnexBBitstreamConverter(stream_->codec)); 680 new FFmpegH264ToAnnexBBitstreamConverter(stream_->codecpar));
684 break; 681 break;
685 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) 682 #if BUILDFLAG(ENABLE_HEVC_DEMUXING)
686 case AV_CODEC_ID_HEVC: 683 case AV_CODEC_ID_HEVC:
687 bitstream_converter_.reset( 684 bitstream_converter_.reset(
688 new FFmpegH265ToAnnexBBitstreamConverter(stream_->codec)); 685 new FFmpegH265ToAnnexBBitstreamConverter(stream_->codecpar));
689 break; 686 break;
690 #endif 687 #endif
691 case AV_CODEC_ID_AAC: 688 case AV_CODEC_ID_AAC:
692 bitstream_converter_.reset( 689 bitstream_converter_.reset(
693 new FFmpegAACBitstreamConverter(stream_->codec)); 690 new FFmpegAACBitstreamConverter(stream_->codecpar));
694 break; 691 break;
695 default: 692 default:
696 break; 693 break;
697 } 694 }
698 #endif // defined(USE_PROPRIETARY_CODECS) 695 #endif // defined(USE_PROPRIETARY_CODECS)
699 } 696 }
700 697
701 bool FFmpegDemuxerStream::SupportsConfigChanges() { return false; } 698 bool FFmpegDemuxerStream::SupportsConfigChanges() { return false; }
702 699
703 AudioDecoderConfig FFmpegDemuxerStream::audio_decoder_config() { 700 AudioDecoderConfig FFmpegDemuxerStream::audio_decoder_config() {
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
1108 static int CalculateBitrate(AVFormatContext* format_context, 1105 static int CalculateBitrate(AVFormatContext* format_context,
1109 const base::TimeDelta& duration, 1106 const base::TimeDelta& duration,
1110 int64_t filesize_in_bytes) { 1107 int64_t filesize_in_bytes) {
1111 // If there is a bitrate set on the container, use it. 1108 // If there is a bitrate set on the container, use it.
1112 if (format_context->bit_rate > 0) 1109 if (format_context->bit_rate > 0)
1113 return format_context->bit_rate; 1110 return format_context->bit_rate;
1114 1111
1115 // Then try to sum the bitrates individually per stream. 1112 // Then try to sum the bitrates individually per stream.
1116 int bitrate = 0; 1113 int bitrate = 0;
1117 for (size_t i = 0; i < format_context->nb_streams; ++i) { 1114 for (size_t i = 0; i < format_context->nb_streams; ++i) {
1118 AVCodecContext* codec_context = format_context->streams[i]->codec; 1115 AVCodecParameters* codec_parameters = format_context->streams[i]->codecpar;
1119 bitrate += codec_context->bit_rate; 1116 bitrate += codec_parameters->bit_rate;
1120 } 1117 }
1121 if (bitrate > 0) 1118 if (bitrate > 0)
1122 return bitrate; 1119 return bitrate;
1123 1120
1124 // See if we can approximate the bitrate as long as we have a filesize and 1121 // See if we can approximate the bitrate as long as we have a filesize and
1125 // valid duration. 1122 // valid duration.
1126 if (duration.InMicroseconds() <= 0 || duration == kInfiniteDuration || 1123 if (duration.InMicroseconds() <= 0 || duration == kInfiniteDuration ||
1127 filesize_in_bytes == 0) { 1124 filesize_in_bytes == 0) {
1128 return 0; 1125 return 0;
1129 } 1126 }
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1220 1217
1221 // If available, |start_time_| will be set to the lowest stream start time. 1218 // If available, |start_time_| will be set to the lowest stream start time.
1222 start_time_ = kInfiniteDuration; 1219 start_time_ = kInfiniteDuration;
1223 1220
1224 base::TimeDelta max_duration; 1221 base::TimeDelta max_duration;
1225 int detected_audio_track_count = 0; 1222 int detected_audio_track_count = 0;
1226 int detected_video_track_count = 0; 1223 int detected_video_track_count = 0;
1227 int detected_text_track_count = 0; 1224 int detected_text_track_count = 0;
1228 for (size_t i = 0; i < format_context->nb_streams; ++i) { 1225 for (size_t i = 0; i < format_context->nb_streams; ++i) {
1229 AVStream* stream = format_context->streams[i]; 1226 AVStream* stream = format_context->streams[i];
1230 const AVCodecContext* codec_context = stream->codec; 1227 const AVCodecParameters* codec_parameters = stream->codecpar;
1231 const AVMediaType codec_type = codec_context->codec_type; 1228 const AVMediaType codec_type = codec_parameters->codec_type;
1229 const AVCodecID codec_id = codec_parameters->codec_id;
1232 1230
1233 if (codec_type == AVMEDIA_TYPE_AUDIO) { 1231 if (codec_type == AVMEDIA_TYPE_AUDIO) {
1234 // Log the codec detected, whether it is supported or not, and whether or 1232 // Log the codec detected, whether it is supported or not, and whether or
1235 // not we have already detected a supported codec in another stream. 1233 // not we have already detected a supported codec in another stream.
1236 UMA_HISTOGRAM_SPARSE_SLOWLY("Media.DetectedAudioCodecHash", 1234 UMA_HISTOGRAM_SPARSE_SLOWLY("Media.DetectedAudioCodecHash",
1237 HashCodecName(GetCodecName(codec_context))); 1235 HashCodecName(GetCodecName(codec_id)));
1238 detected_audio_track_count++; 1236 detected_audio_track_count++;
1239 } else if (codec_type == AVMEDIA_TYPE_VIDEO) { 1237 } else if (codec_type == AVMEDIA_TYPE_VIDEO) {
1240 // Log the codec detected, whether it is supported or not, and whether or 1238 // Log the codec detected, whether it is supported or not, and whether or
1241 // not we have already detected a supported codec in another stream. 1239 // not we have already detected a supported codec in another stream.
1242 UMA_HISTOGRAM_SPARSE_SLOWLY("Media.DetectedVideoCodecHash", 1240 UMA_HISTOGRAM_SPARSE_SLOWLY("Media.DetectedVideoCodecHash",
1243 HashCodecName(GetCodecName(codec_context))); 1241 HashCodecName(GetCodecName(codec_id)));
1244 detected_video_track_count++; 1242 detected_video_track_count++;
1245 1243
1246 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) 1244 #if BUILDFLAG(ENABLE_HEVC_DEMUXING)
1247 if (stream->codec->codec_id == AV_CODEC_ID_HEVC) { 1245 if (codec_id == AV_CODEC_ID_HEVC) {
1248 // If ffmpeg is built without HEVC parser/decoder support, it will be 1246 // If ffmpeg is built without HEVC parser/decoder support, it will be
1249 // able to demux HEVC based solely on container-provided information, 1247 // able to demux HEVC based solely on container-provided information,
1250 // but unable to get some of the parameters without parsing the stream 1248 // but unable to get some of the parameters without parsing the stream
1251 // (e.g. coded size needs to be read from SPS, pixel format is typically 1249 // (e.g. coded size needs to be read from SPS, pixel format is typically
1252 // deduced from decoder config in hvcC box). These are not really needed 1250 // deduced from decoder config in hvcC box). These are not really needed
1253 // when using external decoder (e.g. hardware decoder), so override them 1251 // when using external decoder (e.g. hardware decoder), so override them
1254 // here, to make sure this translates into a valid VideoDecoderConfig. 1252 // to make sure this translates into a valid VideoDecoderConfig. Coded
1255 if (stream->codec->coded_width == 0 && 1253 // size is overridden in AVStreamToVideoDecoderConfig().
1256 stream->codec->coded_height == 0) { 1254 if (stream->codecpar->format == AV_PIX_FMT_NONE)
1257 DCHECK(stream->codec->width > 0); 1255 stream->codecpar->format = AV_PIX_FMT_YUV420P;
1258 DCHECK(stream->codec->height > 0);
1259 stream->codec->coded_width = stream->codec->width;
1260 stream->codec->coded_height = stream->codec->height;
1261 }
1262 if (stream->codec->pix_fmt == AV_PIX_FMT_NONE) {
1263 stream->codec->pix_fmt = AV_PIX_FMT_YUV420P;
1264 }
1265 } 1256 }
1266 #endif 1257 #endif
1267 } else if (codec_type == AVMEDIA_TYPE_SUBTITLE) { 1258 } else if (codec_type == AVMEDIA_TYPE_SUBTITLE) {
1268 detected_text_track_count++; 1259 detected_text_track_count++;
1269 if (codec_context->codec_id != AV_CODEC_ID_WEBVTT || !text_enabled_) { 1260 if (codec_id != AV_CODEC_ID_WEBVTT || !text_enabled_) {
1270 continue; 1261 continue;
1271 } 1262 }
1272 } else { 1263 } else {
1273 continue; 1264 continue;
1274 } 1265 }
1275 1266
1276 // Attempt to create a FFmpegDemuxerStream from the AVStream. This will 1267 // Attempt to create a FFmpegDemuxerStream from the AVStream. This will
1277 // return nullptr if the AVStream is invalid. Validity checks will verify 1268 // return nullptr if the AVStream is invalid. Validity checks will verify
1278 // things like: codec, channel layout, sample/pixel format, etc... 1269 // things like: codec, channel layout, sample/pixel format, etc...
1279 std::unique_ptr<FFmpegDemuxerStream> demuxer_stream = 1270 std::unique_ptr<FFmpegDemuxerStream> demuxer_stream =
1280 FFmpegDemuxerStream::Create(this, stream, media_log_); 1271 FFmpegDemuxerStream::Create(this, stream, media_log_);
1281 if (demuxer_stream.get()) { 1272 if (demuxer_stream.get()) {
1282 streams_[i] = std::move(demuxer_stream); 1273 streams_[i] = std::move(demuxer_stream);
1283 } else { 1274 } else {
1284 if (codec_type == AVMEDIA_TYPE_AUDIO) { 1275 if (codec_type == AVMEDIA_TYPE_AUDIO) {
1285 MEDIA_LOG(INFO, media_log_) 1276 MEDIA_LOG(INFO, media_log_)
1286 << GetDisplayName() 1277 << GetDisplayName()
1287 << ": skipping invalid or unsupported audio track"; 1278 << ": skipping invalid or unsupported audio track";
1288 } else if (codec_type == AVMEDIA_TYPE_VIDEO) { 1279 } else if (codec_type == AVMEDIA_TYPE_VIDEO) {
1289 MEDIA_LOG(INFO, media_log_) 1280 MEDIA_LOG(INFO, media_log_)
1290 << GetDisplayName() 1281 << GetDisplayName()
1291 << ": skipping invalid or unsupported video track"; 1282 << ": skipping invalid or unsupported video track";
1292 } 1283 }
1293 1284
1294 // This AVStream does not successfully convert. 1285 // This AVStream does not successfully convert.
1295 continue; 1286 continue;
1296 } 1287 }
1297 1288
1298 StreamParser::TrackId track_id = stream->id; 1289 StreamParser::TrackId track_id = stream->id;
1299
1300 if ((codec_type == AVMEDIA_TYPE_AUDIO &&
1301 media_tracks->getAudioConfig(track_id).IsValidConfig()) ||
1302 (codec_type == AVMEDIA_TYPE_VIDEO &&
1303 media_tracks->getVideoConfig(track_id).IsValidConfig())) {
1304 MEDIA_LOG(INFO, media_log_)
1305 << GetDisplayName()
1306 << ": skipping duplicate media stream id=" << track_id;
1307 continue;
1308 }
1309
1310 std::string track_label = streams_[i]->GetMetadata("handler_name"); 1290 std::string track_label = streams_[i]->GetMetadata("handler_name");
1311 std::string track_language = streams_[i]->GetMetadata("language"); 1291 std::string track_language = streams_[i]->GetMetadata("language");
1312 1292
1313 // Some metadata is named differently in FFmpeg for webm files. 1293 // Some metadata is named differently in FFmpeg for webm files.
1314 if (strstr(format_context->iformat->name, "webm") || 1294 if (strstr(format_context->iformat->name, "webm") ||
1315 strstr(format_context->iformat->name, "matroska")) { 1295 strstr(format_context->iformat->name, "matroska")) {
1316 // TODO(servolk): FFmpeg doesn't set stream->id correctly for webm files. 1296 // TODO(servolk): FFmpeg doesn't set stream->id correctly for webm files.
1317 // Need to fix that and use it as track id. crbug.com/323183 1297 // Need to fix that and use it as track id. crbug.com/323183
1318 track_id = 1298 track_id =
1319 static_cast<StreamParser::TrackId>(media_tracks->tracks().size() + 1); 1299 static_cast<StreamParser::TrackId>(media_tracks->tracks().size() + 1);
1320 track_label = streams_[i]->GetMetadata("title"); 1300 track_label = streams_[i]->GetMetadata("title");
1321 } 1301 }
1322 1302
1303 if ((codec_type == AVMEDIA_TYPE_AUDIO &&
1304 media_tracks->getAudioConfig(track_id).IsValidConfig()) ||
1305 (codec_type == AVMEDIA_TYPE_VIDEO &&
1306 media_tracks->getVideoConfig(track_id).IsValidConfig())) {
1307 MEDIA_LOG(INFO, media_log_)
1308 << GetDisplayName()
1309 << ": skipping duplicate media stream id=" << track_id;
1310 continue;
1311 }
1312
1323 // Note when we find our audio/video stream (we only want one of each) and 1313 // Note when we find our audio/video stream (we only want one of each) and
1324 // record src= playback UMA stats for the stream's decoder config. 1314 // record src= playback UMA stats for the stream's decoder config.
1325 MediaTrack* media_track = nullptr; 1315 MediaTrack* media_track = nullptr;
1326 if (codec_type == AVMEDIA_TYPE_AUDIO) { 1316 if (codec_type == AVMEDIA_TYPE_AUDIO) {
1327 AudioDecoderConfig audio_config = streams_[i]->audio_decoder_config(); 1317 AudioDecoderConfig audio_config = streams_[i]->audio_decoder_config();
1328 RecordAudioCodecStats(audio_config); 1318 RecordAudioCodecStats(audio_config);
1329 1319
1330 media_track = media_tracks->AddAudioTrack(audio_config, track_id, "main", 1320 media_track = media_tracks->AddAudioTrack(audio_config, track_id, "main",
1331 track_label, track_language); 1321 track_label, track_language);
1332 media_track->set_id(base::UintToString(track_id)); 1322 media_track->set_id(base::UintToString(track_id));
1333 DCHECK(track_id_to_demux_stream_map_.find(media_track->id()) == 1323 DCHECK(track_id_to_demux_stream_map_.find(media_track->id()) ==
1334 track_id_to_demux_stream_map_.end()); 1324 track_id_to_demux_stream_map_.end());
1335 track_id_to_demux_stream_map_[media_track->id()] = streams_[i].get(); 1325 track_id_to_demux_stream_map_[media_track->id()] = streams_[i].get();
1336 } else if (codec_type == AVMEDIA_TYPE_VIDEO) { 1326 } else if (codec_type == AVMEDIA_TYPE_VIDEO) {
1337 VideoDecoderConfig video_config = streams_[i]->video_decoder_config(); 1327 VideoDecoderConfig video_config = streams_[i]->video_decoder_config();
1338 1328
1339 RecordVideoCodecStats(video_config, stream->codec->color_range, 1329 RecordVideoCodecStats(video_config, stream->codecpar->color_range,
1340 media_log_.get()); 1330 media_log_.get());
1341 1331
1342 media_track = media_tracks->AddVideoTrack(video_config, track_id, "main", 1332 media_track = media_tracks->AddVideoTrack(video_config, track_id, "main",
1343 track_label, track_language); 1333 track_label, track_language);
1344 media_track->set_id(base::UintToString(track_id)); 1334 media_track->set_id(base::UintToString(track_id));
1345 DCHECK(track_id_to_demux_stream_map_.find(media_track->id()) == 1335 DCHECK(track_id_to_demux_stream_map_.find(media_track->id()) ==
1346 track_id_to_demux_stream_map_.end()); 1336 track_id_to_demux_stream_map_.end());
1347 track_id_to_demux_stream_map_[media_track->id()] = streams_[i].get(); 1337 track_id_to_demux_stream_map_[media_track->id()] = streams_[i].get();
1348 } 1338 }
1349 1339
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1402 // http://xiph.org/vorbis/doc/Vorbis_I_spec.html 1392 // http://xiph.org/vorbis/doc/Vorbis_I_spec.html
1403 // 1393 //
1404 // FFmpeg's use of negative timestamps for opus pre-skip is nonstandard, but 1394 // FFmpeg's use of negative timestamps for opus pre-skip is nonstandard, but
1405 // for more information on pre-skip see section 4.2 of the Ogg Opus spec: 1395 // for more information on pre-skip see section 4.2 of the Ogg Opus spec:
1406 // https://tools.ietf.org/html/draft-ietf-codec-oggopus-08#section-4.2 1396 // https://tools.ietf.org/html/draft-ietf-codec-oggopus-08#section-4.2
1407 for (const auto& stream : streams_) { 1397 for (const auto& stream : streams_) {
1408 if (!stream || stream->type() != DemuxerStream::AUDIO) 1398 if (!stream || stream->type() != DemuxerStream::AUDIO)
1409 continue; 1399 continue;
1410 const AVStream* audio_stream = stream->av_stream(); 1400 const AVStream* audio_stream = stream->av_stream();
1411 DCHECK(audio_stream); 1401 DCHECK(audio_stream);
1412 if (audio_stream->codec->codec_id == AV_CODEC_ID_OPUS || 1402 if (audio_stream->codecpar->codec_id == AV_CODEC_ID_OPUS ||
1413 (strcmp(format_context->iformat->name, "ogg") == 0 && 1403 (strcmp(format_context->iformat->name, "ogg") == 0 &&
1414 audio_stream->codec->codec_id == AV_CODEC_ID_VORBIS)) { 1404 audio_stream->codecpar->codec_id == AV_CODEC_ID_VORBIS)) {
1415 for (size_t i = 0; i < streams_.size(); ++i) { 1405 for (size_t i = 0; i < streams_.size(); ++i) {
1416 if (!streams_[i]) 1406 if (!streams_[i])
1417 continue; 1407 continue;
1418 streams_[i]->enable_negative_timestamp_fixups(); 1408 streams_[i]->enable_negative_timestamp_fixups();
1419 1409
1420 // Fixup the seeking information to avoid selecting the audio stream 1410 // Fixup the seeking information to avoid selecting the audio stream
1421 // simply because it has a lower starting time. 1411 // simply because it has a lower starting time.
1422 if (streams_[i]->av_stream() == audio_stream && 1412 if (streams_[i]->av_stream() == audio_stream &&
1423 streams_[i]->start_time() < base::TimeDelta()) { 1413 streams_[i]->start_time() < base::TimeDelta()) {
1424 streams_[i]->set_start_time(base::TimeDelta()); 1414 streams_[i]->set_start_time(base::TimeDelta());
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1484 int video_track_count = 0; 1474 int video_track_count = 0;
1485 for (size_t i = 0; i < streams_.size(); ++i) { 1475 for (size_t i = 0; i < streams_.size(); ++i) {
1486 FFmpegDemuxerStream* stream = streams_[i].get(); 1476 FFmpegDemuxerStream* stream = streams_[i].get();
1487 if (!stream) 1477 if (!stream)
1488 continue; 1478 continue;
1489 if (stream->type() == DemuxerStream::AUDIO) { 1479 if (stream->type() == DemuxerStream::AUDIO) {
1490 ++audio_track_count; 1480 ++audio_track_count;
1491 std::string suffix = ""; 1481 std::string suffix = "";
1492 if (audio_track_count > 1) 1482 if (audio_track_count > 1)
1493 suffix = "_track" + base::IntToString(audio_track_count); 1483 suffix = "_track" + base::IntToString(audio_track_count);
1494 const AVCodecContext* audio_codec = avctx->streams[i]->codec; 1484 const AVCodecParameters* audio_parameters = avctx->streams[i]->codecpar;
1495 const AudioDecoderConfig& audio_config = stream->audio_decoder_config(); 1485 const AudioDecoderConfig& audio_config = stream->audio_decoder_config();
1496 params.SetString("audio_codec_name" + suffix, GetCodecName(audio_codec)); 1486 params.SetString("audio_codec_name" + suffix,
1497 params.SetInteger("audio_channels_count" + suffix, audio_codec->channels); 1487 GetCodecName(audio_parameters->codec_id));
1488 params.SetInteger("audio_channels_count" + suffix,
1489 audio_parameters->channels);
1498 params.SetString("audio_sample_format" + suffix, 1490 params.SetString("audio_sample_format" + suffix,
1499 SampleFormatToString(audio_config.sample_format())); 1491 SampleFormatToString(audio_config.sample_format()));
1500 params.SetInteger("audio_samples_per_second" + suffix, 1492 params.SetInteger("audio_samples_per_second" + suffix,
1501 audio_config.samples_per_second()); 1493 audio_config.samples_per_second());
1502 } else if (stream->type() == DemuxerStream::VIDEO) { 1494 } else if (stream->type() == DemuxerStream::VIDEO) {
1503 ++video_track_count; 1495 ++video_track_count;
1504 std::string suffix = ""; 1496 std::string suffix = "";
1505 if (video_track_count > 1) 1497 if (video_track_count > 1)
1506 suffix = "_track" + base::IntToString(video_track_count); 1498 suffix = "_track" + base::IntToString(video_track_count);
1507 const AVCodecContext* video_codec = avctx->streams[i]->codec; 1499 const AVStream* video_av_stream = avctx->streams[i];
1500 const AVCodecParameters* video_parameters = video_av_stream->codecpar;
1508 const VideoDecoderConfig& video_config = stream->video_decoder_config(); 1501 const VideoDecoderConfig& video_config = stream->video_decoder_config();
1509 params.SetString("video_codec_name" + suffix, GetCodecName(video_codec)); 1502 params.SetString("video_codec_name" + suffix,
1510 params.SetInteger("width" + suffix, video_codec->width); 1503 GetCodecName(video_parameters->codec_id));
1511 params.SetInteger("height" + suffix, video_codec->height); 1504 params.SetInteger("width" + suffix, video_parameters->width);
1512 params.SetInteger("coded_width" + suffix, video_codec->coded_width); 1505 params.SetInteger("height" + suffix, video_parameters->height);
1513 params.SetInteger("coded_height" + suffix, video_codec->coded_height); 1506
1514 params.SetString("time_base" + suffix, 1507 // AVCodecParameters has no coded size fields. We gather this information
1515 base::StringPrintf("%d/%d", video_codec->time_base.num, 1508 // during video FFmpegDemuxerStream's VideoDecoderConfig setup.
1516 video_codec->time_base.den)); 1509 params.SetInteger("coded_width" + suffix,
1510 video_config.coded_size().width());
1511 params.SetInteger("coded_height" + suffix,
1512 video_config.coded_size().height());
1513
1514 // AVCodecParameters has no time_base field. We use the one from AVStream
1515 // here.
1516 params.SetString(
1517 "time_base" + suffix,
1518 base::StringPrintf("%d/%d", video_av_stream->time_base.num,
1519 video_av_stream->time_base.den));
1520
1517 params.SetString("video_format" + suffix, 1521 params.SetString("video_format" + suffix,
1518 VideoPixelFormatToString(video_config.format())); 1522 VideoPixelFormatToString(video_config.format()));
1519 params.SetBoolean("video_is_encrypted" + suffix, 1523 params.SetBoolean("video_is_encrypted" + suffix,
1520 video_config.is_encrypted()); 1524 video_config.is_encrypted());
1521 } 1525 }
1522 } 1526 }
1523 params.SetBoolean("found_audio_stream", (audio_track_count > 0)); 1527 params.SetBoolean("found_audio_stream", (audio_track_count > 0));
1524 params.SetBoolean("found_video_stream", (video_track_count > 0)); 1528 params.SetBoolean("found_video_stream", (video_track_count > 0));
1525 SetTimeProperty(metadata_event.get(), "max_duration", max_duration); 1529 SetTimeProperty(metadata_event.get(), "max_duration", max_duration);
1526 SetTimeProperty(metadata_event.get(), "start_time", start_time_); 1530 SetTimeProperty(metadata_event.get(), "start_time", start_time_);
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
1788 1792
1789 void FFmpegDemuxer::SetLiveness(DemuxerStream::Liveness liveness) { 1793 void FFmpegDemuxer::SetLiveness(DemuxerStream::Liveness liveness) {
1790 DCHECK(task_runner_->BelongsToCurrentThread()); 1794 DCHECK(task_runner_->BelongsToCurrentThread());
1791 for (const auto& stream : streams_) { 1795 for (const auto& stream : streams_) {
1792 if (stream) 1796 if (stream)
1793 stream->SetLiveness(liveness); 1797 stream->SetLiveness(liveness);
1794 } 1798 }
1795 } 1799 }
1796 1800
1797 } // namespace media 1801 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698