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

Side by Side Diff: media/base/mime_util_internal.cc

Issue 1677563003: Implemented parsing for H.264/AVC codec ids (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase + resolve conflicts Created 4 years, 10 months 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
« no previous file with comments | « media/base/mime_util_internal.h ('k') | media/base/video_codecs.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 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/base/mime_util_internal.h" 5 #include "media/base/mime_util_internal.h"
6 6
7 #include "base/strings/string_number_conversions.h" 7 #include "base/strings/string_number_conversions.h"
8 #include "base/strings/string_split.h" 8 #include "base/strings/string_split.h"
9 #include "base/strings/string_util.h" 9 #include "base/strings/string_util.h"
10 #include "build/build_config.h" 10 #include "build/build_config.h"
11 #include "media/base/video_codecs.h"
11 #include "media/media_features.h" 12 #include "media/media_features.h"
12 13
13 #if defined(OS_ANDROID) 14 #if defined(OS_ANDROID)
14 #include "base/android/build_info.h" 15 #include "base/android/build_info.h"
15 #endif 16 #endif
16 17
17 namespace media { 18 namespace media {
18 namespace internal { 19 namespace internal {
19 20
20 enum MediaFormatType { COMMON, PROPRIETARY }; 21 enum MediaFormatType { COMMON, PROPRIETARY };
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 const char* const codec_id; 116 const char* const codec_id;
116 MimeUtil::Codec codec; 117 MimeUtil::Codec codec;
117 }; 118 };
118 119
119 // List of codec IDs that provide enough information to determine the 120 // List of codec IDs that provide enough information to determine the
120 // codec and profile being requested. 121 // codec and profile being requested.
121 // 122 //
122 // The "mp4a" strings come from RFC 6381. 123 // The "mp4a" strings come from RFC 6381.
123 static const CodecIDMappings kUnambiguousCodecStringMap[] = { 124 static const CodecIDMappings kUnambiguousCodecStringMap[] = {
124 {"1", MimeUtil::PCM}, // We only allow this for WAV so it isn't ambiguous. 125 {"1", MimeUtil::PCM}, // We only allow this for WAV so it isn't ambiguous.
125 // avc1/avc3.XXXXXX may be unambiguous; handled by ParseH264CodecID(). 126 // avc1/avc3.XXXXXX may be unambiguous; handled by ParseAVCCodecId().
126 // hev1/hvc1.XXXXXX may be unambiguous; handled by ParseHEVCCodecID(). 127 // hev1/hvc1.XXXXXX may be unambiguous; handled by ParseHEVCCodecID().
127 {"mp3", MimeUtil::MP3}, 128 {"mp3", MimeUtil::MP3},
128 {"mp4a.66", MimeUtil::MPEG2_AAC_MAIN}, 129 {"mp4a.66", MimeUtil::MPEG2_AAC_MAIN},
129 {"mp4a.67", MimeUtil::MPEG2_AAC_LC}, 130 {"mp4a.67", MimeUtil::MPEG2_AAC_LC},
130 {"mp4a.68", MimeUtil::MPEG2_AAC_SSR}, 131 {"mp4a.68", MimeUtil::MPEG2_AAC_SSR},
131 {"mp4a.69", MimeUtil::MP3}, 132 {"mp4a.69", MimeUtil::MP3},
132 {"mp4a.6B", MimeUtil::MP3}, 133 {"mp4a.6B", MimeUtil::MP3},
133 {"mp4a.40.2", MimeUtil::MPEG4_AAC_LC}, 134 {"mp4a.40.2", MimeUtil::MPEG4_AAC_LC},
134 {"mp4a.40.02", MimeUtil::MPEG4_AAC_LC}, 135 {"mp4a.40.02", MimeUtil::MPEG4_AAC_LC},
135 {"mp4a.40.5", MimeUtil::MPEG4_AAC_SBR_v1}, 136 {"mp4a.40.5", MimeUtil::MPEG4_AAC_SBR_v1},
(...skipping 20 matching lines...) Expand all
156 {"vp9", MimeUtil::VP9}, 157 {"vp9", MimeUtil::VP9},
157 {"vp9.0", MimeUtil::VP9}, 158 {"vp9.0", MimeUtil::VP9},
158 {"theora", MimeUtil::THEORA}}; 159 {"theora", MimeUtil::THEORA}};
159 160
160 // List of codec IDs that are ambiguous and don't provide 161 // List of codec IDs that are ambiguous and don't provide
161 // enough information to determine the codec and profile. 162 // enough information to determine the codec and profile.
162 // The codec in these entries indicate the codec and profile 163 // The codec in these entries indicate the codec and profile
163 // we assume the user is trying to indicate. 164 // we assume the user is trying to indicate.
164 static const CodecIDMappings kAmbiguousCodecStringMap[] = { 165 static const CodecIDMappings kAmbiguousCodecStringMap[] = {
165 {"mp4a.40", MimeUtil::MPEG4_AAC_LC}, 166 {"mp4a.40", MimeUtil::MPEG4_AAC_LC},
166 {"avc1", MimeUtil::H264_BASELINE}, 167 {"avc1", MimeUtil::H264},
167 {"avc3", MimeUtil::H264_BASELINE}, 168 {"avc3", MimeUtil::H264},
168 // avc1/avc3.XXXXXX may be ambiguous; handled by ParseH264CodecID(). 169 // avc1/avc3.XXXXXX may be ambiguous; handled by ParseAVCCodecId().
169 }; 170 };
170 171
171 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER) 172 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER)
172 static const char kHexString[] = "0123456789ABCDEF"; 173 static const char kHexString[] = "0123456789ABCDEF";
173 static char IntToHex(int i) { 174 static char IntToHex(int i) {
174 DCHECK_GE(i, 0) << i << " not a hex value"; 175 DCHECK_GE(i, 0) << i << " not a hex value";
175 DCHECK_LE(i, 15) << i << " not a hex value"; 176 DCHECK_LE(i, 15) << i << " not a hex value";
176 return kHexString[i]; 177 return kHexString[i];
177 } 178 }
178 179
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 result.push_back(IntToHex(level >> 4)); 211 result.push_back(IntToHex(level >> 4));
211 result.push_back(IntToHex(level & 0xf)); 212 result.push_back(IntToHex(level & 0xf));
212 return result; 213 return result;
213 } 214 }
214 215
215 // This is not a valid legacy avc1 codec id - return the original codec id. 216 // This is not a valid legacy avc1 codec id - return the original codec id.
216 return codec_id; 217 return codec_id;
217 } 218 }
218 #endif 219 #endif
219 220
220 static bool IsValidH264Level(const std::string& level_str) { 221 static bool IsValidH264Level(uint8_t level_idc) {
221 uint32_t level; 222 // Valid levels taken from Table A-1 in ISO/IEC 14496-10.
222 if (level_str.size() != 2 || !base::HexStringToUInt(level_str, &level)) 223 // Level_idc represents the standard level represented as decimal number
223 return false; 224 // multiplied by ten, e.g. level_idc==32 corresponds to level==3.2
224 225 return ((level_idc >= 10 && level_idc <= 13) ||
225 // Valid levels taken from Table A-1 in ISO-14496-10. 226 (level_idc >= 20 && level_idc <= 22) ||
226 // Essentially |level_str| is toHex(10 * level). 227 (level_idc >= 30 && level_idc <= 32) ||
227 return ((level >= 10 && level <= 13) || (level >= 20 && level <= 22) || 228 (level_idc >= 40 && level_idc <= 42) ||
228 (level >= 30 && level <= 32) || (level >= 40 && level <= 42) || 229 (level_idc >= 50 && level_idc <= 51));
229 (level >= 50 && level <= 51));
230 }
231
232 // Handle parsing H.264 codec IDs as outlined in RFC 6381 and ISO-14496-10.
233 // avc1.42x0yy - H.264 Baseline
234 // avc1.4Dx0yy - H.264 Main
235 // avc1.64x0yy - H.264 High
236 //
237 // avc1.xxxxxx & avc3.xxxxxx are considered ambiguous forms that are trying to
238 // signal H.264 Baseline. For example, the idc_level, profile_idc and
239 // constraint_set3_flag pieces may explicitly require decoder to conform to
240 // baseline profile at the specified level (see Annex A and constraint_set0 in
241 // ISO-14496-10).
242 static bool ParseH264CodecID(const std::string& codec_id,
243 MimeUtil::Codec* codec,
244 bool* is_ambiguous) {
245 // Make sure we have avc1.xxxxxx or avc3.xxxxxx , where xxxxxx are hex digits
246 if (!base::StartsWith(codec_id, "avc1.", base::CompareCase::SENSITIVE) &&
247 !base::StartsWith(codec_id, "avc3.", base::CompareCase::SENSITIVE)) {
248 return false;
249 }
250 if (codec_id.size() != 11 || !base::IsHexDigit(codec_id[5]) ||
251 !base::IsHexDigit(codec_id[6]) || !base::IsHexDigit(codec_id[7]) ||
252 !base::IsHexDigit(codec_id[8]) || !base::IsHexDigit(codec_id[9]) ||
253 !base::IsHexDigit(codec_id[10])) {
254 return false;
255 }
256
257 // Validate constraint flags and reserved bits.
258 if (!base::IsHexDigit(codec_id[7]) || codec_id[8] != '0') {
259 *codec = MimeUtil::H264_BASELINE;
260 *is_ambiguous = true;
261 return true;
262 }
263
264 // Extract the profile.
265 std::string profile = base::ToUpperASCII(codec_id.substr(5, 2));
266 if (profile == "42") {
267 *codec = MimeUtil::H264_BASELINE;
268 } else if (profile == "4D") {
269 *codec = MimeUtil::H264_MAIN;
270 } else if (profile == "64") {
271 *codec = MimeUtil::H264_HIGH;
272 } else {
273 *codec = MimeUtil::H264_BASELINE;
274 *is_ambiguous = true;
275 return true;
276 }
277
278 // Validate level.
279 *is_ambiguous = !IsValidH264Level(codec_id.substr(9));
280 return true;
281 } 230 }
282 231
283 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) 232 #if BUILDFLAG(ENABLE_HEVC_DEMUXING)
284 // ISO/IEC FDIS 14496-15 standard section E.3 describes the syntax of codec ids 233 // ISO/IEC FDIS 14496-15 standard section E.3 describes the syntax of codec ids
285 // reserved for HEVC. According to that spec HEVC codec id must start with 234 // reserved for HEVC. According to that spec HEVC codec id must start with
286 // either "hev1." or "hvc1.". We don't yet support full parsing of HEVC codec 235 // either "hev1." or "hvc1.". We don't yet support full parsing of HEVC codec
287 // ids, but since no other codec id starts with those string we'll just treat 236 // ids, but since no other codec id starts with those string we'll just treat
288 // any string starting with "hev1." or "hvc1." as valid HEVC codec ids. 237 // any string starting with "hev1." or "hvc1." as valid HEVC codec ids.
289 // crbug.com/482761 238 // crbug.com/482761
290 static bool ParseHEVCCodecID(const std::string& codec_id, 239 static bool ParseHEVCCodecID(const std::string& codec_id,
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 // If |codec_id| is not in |string_to_codec_map_|, then we assume that it is 422 // If |codec_id| is not in |string_to_codec_map_|, then we assume that it is
474 // either H.264 or HEVC/H.265 codec ID because currently those are the only 423 // either H.264 or HEVC/H.265 codec ID because currently those are the only
475 // ones that are not added to the |string_to_codec_map_| and require parsing. 424 // ones that are not added to the |string_to_codec_map_| and require parsing.
476 425
477 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) 426 #if BUILDFLAG(ENABLE_HEVC_DEMUXING)
478 if (ParseHEVCCodecID(codec_id, codec, is_ambiguous)) { 427 if (ParseHEVCCodecID(codec_id, codec, is_ambiguous)) {
479 return true; 428 return true;
480 } 429 }
481 #endif 430 #endif
482 431
483 return ParseH264CodecID(codec_id, codec, is_ambiguous); 432 VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN;
433 uint8_t level_idc = 0;
434 if (ParseAVCCodecId(codec_id, &profile, &level_idc)) {
435 *codec = MimeUtil::H264;
436 *is_ambiguous =
437 (profile != H264PROFILE_BASELINE && profile != H264PROFILE_MAIN &&
438 profile != H264PROFILE_HIGH) ||
439 !IsValidH264Level(level_idc);
440 return true;
441 }
442
443 DVLOG(4) << __FUNCTION__ << ": Unrecognized codec id " << codec_id;
444 return false;
484 } 445 }
485 446
486 bool MimeUtil::IsCodecSupported(Codec codec) const { 447 bool MimeUtil::IsCodecSupported(Codec codec) const {
487 DCHECK_NE(codec, INVALID_CODEC); 448 DCHECK_NE(codec, INVALID_CODEC);
488 449
489 #if defined(OS_ANDROID) 450 #if defined(OS_ANDROID)
490 if (!IsCodecSupportedOnAndroid(codec)) 451 if (!IsCodecSupportedOnAndroid(codec))
491 return false; 452 return false;
492 #endif 453 #endif
493 454
494 return allow_proprietary_codecs_ || !IsCodecProprietary(codec); 455 return allow_proprietary_codecs_ || !IsCodecProprietary(codec);
495 } 456 }
496 457
497 bool MimeUtil::IsCodecProprietary(Codec codec) const { 458 bool MimeUtil::IsCodecProprietary(Codec codec) const {
498 switch (codec) { 459 switch (codec) {
499 case INVALID_CODEC: 460 case INVALID_CODEC:
500 case AC3: 461 case AC3:
501 case EAC3: 462 case EAC3:
502 case MP3: 463 case MP3:
503 case MPEG2_AAC_LC: 464 case MPEG2_AAC_LC:
504 case MPEG2_AAC_MAIN: 465 case MPEG2_AAC_MAIN:
505 case MPEG2_AAC_SSR: 466 case MPEG2_AAC_SSR:
506 case MPEG4_AAC_LC: 467 case MPEG4_AAC_LC:
507 case MPEG4_AAC_SBR_v1: 468 case MPEG4_AAC_SBR_v1:
508 case MPEG4_AAC_SBR_PS_v2: 469 case MPEG4_AAC_SBR_PS_v2:
509 case H264_BASELINE: 470 case H264:
510 case H264_MAIN:
511 case H264_HIGH:
512 case HEVC_MAIN: 471 case HEVC_MAIN:
513 return true; 472 return true;
514 473
515 case PCM: 474 case PCM:
516 case VORBIS: 475 case VORBIS:
517 case OPUS: 476 case OPUS:
518 case VP8: 477 case VP8:
519 case VP9: 478 case VP9:
520 case THEORA: 479 case THEORA:
521 return false; 480 return false;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 switch (codec) { 513 switch (codec) {
555 case INVALID_CODEC: 514 case INVALID_CODEC:
556 return false; 515 return false;
557 516
558 case PCM: 517 case PCM:
559 case MP3: 518 case MP3:
560 case MPEG4_AAC_LC: 519 case MPEG4_AAC_LC:
561 case MPEG4_AAC_SBR_v1: 520 case MPEG4_AAC_SBR_v1:
562 case MPEG4_AAC_SBR_PS_v2: 521 case MPEG4_AAC_SBR_PS_v2:
563 case VORBIS: 522 case VORBIS:
564 case H264_BASELINE: 523 case H264:
565 case H264_MAIN:
566 case H264_HIGH:
567 case VP8: 524 case VP8:
568 return true; 525 return true;
569 526
570 case AC3: 527 case AC3:
571 case EAC3: 528 case EAC3:
572 // TODO(servolk): Revisit this for AC3/EAC3 support on AndroidTV 529 // TODO(servolk): Revisit this for AC3/EAC3 support on AndroidTV
573 return false; 530 return false;
574 531
575 case MPEG2_AAC_LC: 532 case MPEG2_AAC_LC:
576 case MPEG2_AAC_MAIN: 533 case MPEG2_AAC_MAIN:
(...skipping 21 matching lines...) Expand all
598 case THEORA: 555 case THEORA:
599 return false; 556 return false;
600 } 557 }
601 558
602 return false; 559 return false;
603 } 560 }
604 #endif 561 #endif
605 562
606 } // namespace internal 563 } // namespace internal
607 } // namespace media 564 } // namespace media
OLDNEW
« no previous file with comments | « media/base/mime_util_internal.h ('k') | media/base/video_codecs.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698