OLD | NEW |
---|---|
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
ddorwin
2016/02/17 19:31:20
This is going to conflict with Dale's CL to move m
| |
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 <stddef.h> | 5 #include <stddef.h> |
6 #include <stdint.h> | 6 #include <stdint.h> |
7 | 7 |
8 #include <map> | 8 #include <map> |
9 | 9 |
10 #include "base/containers/hash_tables.h" | 10 #include "base/containers/hash_tables.h" |
11 #include "base/lazy_instance.h" | 11 #include "base/lazy_instance.h" |
12 #include "base/macros.h" | 12 #include "base/macros.h" |
13 #include "base/strings/string_number_conversions.h" | 13 #include "base/strings/string_number_conversions.h" |
14 #include "base/strings/string_split.h" | 14 #include "base/strings/string_split.h" |
15 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
16 #include "build/build_config.h" | 16 #include "build/build_config.h" |
17 #include "media/base/mime_util.h" | 17 #include "media/base/mime_util.h" |
18 #include "media/base/video_codecs.h" | |
18 #include "media/media_features.h" | 19 #include "media/media_features.h" |
19 | 20 |
20 #if defined(OS_ANDROID) | 21 #if defined(OS_ANDROID) |
21 #include "base/android/build_info.h" | 22 #include "base/android/build_info.h" |
22 #endif | 23 #endif |
23 | 24 |
24 namespace media { | 25 namespace media { |
25 | 26 |
26 // Singleton utility class for mime types. | 27 // Singleton utility class for mime types. |
27 class MimeUtil { | 28 class MimeUtil { |
28 public: | 29 public: |
29 enum Codec { | 30 enum Codec { |
30 INVALID_CODEC, | 31 INVALID_CODEC, |
31 PCM, | 32 PCM, |
32 MP3, | 33 MP3, |
33 AC3, | 34 AC3, |
34 EAC3, | 35 EAC3, |
35 MPEG2_AAC_LC, | 36 MPEG2_AAC_LC, |
36 MPEG2_AAC_MAIN, | 37 MPEG2_AAC_MAIN, |
37 MPEG2_AAC_SSR, | 38 MPEG2_AAC_SSR, |
38 MPEG4_AAC_LC, | 39 MPEG4_AAC_LC, |
39 MPEG4_AAC_SBR_v1, | 40 MPEG4_AAC_SBR_v1, |
40 MPEG4_AAC_SBR_PS_v2, | 41 MPEG4_AAC_SBR_PS_v2, |
41 VORBIS, | 42 VORBIS, |
42 OPUS, | 43 OPUS, |
43 H264_BASELINE, | 44 H264, |
44 H264_MAIN, | |
45 H264_HIGH, | |
46 HEVC_MAIN, | 45 HEVC_MAIN, |
ddorwin
2016/02/17 19:31:20
Should we remove _MAIN here too?
servolk
2016/02/17 19:49:54
Yes, I'm planning to do that in a separate CL whic
| |
47 VP8, | 46 VP8, |
48 VP9, | 47 VP9, |
49 THEORA | 48 THEORA |
50 }; | 49 }; |
51 | 50 |
52 bool IsSupportedMediaMimeType(const std::string& mime_type) const; | 51 bool IsSupportedMediaMimeType(const std::string& mime_type) const; |
53 | 52 |
54 void ParseCodecString(const std::string& codecs, | 53 void ParseCodecString(const std::string& codecs, |
55 std::vector<std::string>* codecs_out, | 54 std::vector<std::string>* codecs_out, |
56 bool strip); | 55 bool strip); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
141 switch (codec) { | 140 switch (codec) { |
142 case MimeUtil::INVALID_CODEC: | 141 case MimeUtil::INVALID_CODEC: |
143 return false; | 142 return false; |
144 | 143 |
145 case MimeUtil::PCM: | 144 case MimeUtil::PCM: |
146 case MimeUtil::MP3: | 145 case MimeUtil::MP3: |
147 case MimeUtil::MPEG4_AAC_LC: | 146 case MimeUtil::MPEG4_AAC_LC: |
148 case MimeUtil::MPEG4_AAC_SBR_v1: | 147 case MimeUtil::MPEG4_AAC_SBR_v1: |
149 case MimeUtil::MPEG4_AAC_SBR_PS_v2: | 148 case MimeUtil::MPEG4_AAC_SBR_PS_v2: |
150 case MimeUtil::VORBIS: | 149 case MimeUtil::VORBIS: |
151 case MimeUtil::H264_BASELINE: | 150 case MimeUtil::H264: |
152 case MimeUtil::H264_MAIN: | |
153 case MimeUtil::H264_HIGH: | |
154 case MimeUtil::VP8: | 151 case MimeUtil::VP8: |
155 return true; | 152 return true; |
156 | 153 |
157 case MimeUtil::AC3: | 154 case MimeUtil::AC3: |
158 case MimeUtil::EAC3: | 155 case MimeUtil::EAC3: |
159 // TODO(servolk): Revisit this for AC3/EAC3 support on AndroidTV | 156 // TODO(servolk): Revisit this for AC3/EAC3 support on AndroidTV |
160 return false; | 157 return false; |
161 | 158 |
162 case MimeUtil::MPEG2_AAC_LC: | 159 case MimeUtil::MPEG2_AAC_LC: |
163 case MimeUtil::MPEG2_AAC_MAIN: | 160 case MimeUtil::MPEG2_AAC_MAIN: |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
288 const char* const codec_id; | 285 const char* const codec_id; |
289 MimeUtil::Codec codec; | 286 MimeUtil::Codec codec; |
290 }; | 287 }; |
291 | 288 |
292 // List of codec IDs that provide enough information to determine the | 289 // List of codec IDs that provide enough information to determine the |
293 // codec and profile being requested. | 290 // codec and profile being requested. |
294 // | 291 // |
295 // The "mp4a" strings come from RFC 6381. | 292 // The "mp4a" strings come from RFC 6381. |
296 static const CodecIDMappings kUnambiguousCodecStringMap[] = { | 293 static const CodecIDMappings kUnambiguousCodecStringMap[] = { |
297 {"1", MimeUtil::PCM}, // We only allow this for WAV so it isn't ambiguous. | 294 {"1", MimeUtil::PCM}, // We only allow this for WAV so it isn't ambiguous. |
298 // avc1/avc3.XXXXXX may be unambiguous; handled by ParseH264CodecID(). | 295 // avc1/avc3.XXXXXX may be unambiguous; handled by ParseAVCCodecId(). |
299 // hev1/hvc1.XXXXXX may be unambiguous; handled by ParseHEVCCodecID(). | 296 // hev1/hvc1.XXXXXX may be unambiguous; handled by ParseHEVCCodecID(). |
300 {"mp3", MimeUtil::MP3}, | 297 {"mp3", MimeUtil::MP3}, |
301 {"mp4a.66", MimeUtil::MPEG2_AAC_MAIN}, | 298 {"mp4a.66", MimeUtil::MPEG2_AAC_MAIN}, |
302 {"mp4a.67", MimeUtil::MPEG2_AAC_LC}, | 299 {"mp4a.67", MimeUtil::MPEG2_AAC_LC}, |
303 {"mp4a.68", MimeUtil::MPEG2_AAC_SSR}, | 300 {"mp4a.68", MimeUtil::MPEG2_AAC_SSR}, |
304 {"mp4a.69", MimeUtil::MP3}, | 301 {"mp4a.69", MimeUtil::MP3}, |
305 {"mp4a.6B", MimeUtil::MP3}, | 302 {"mp4a.6B", MimeUtil::MP3}, |
306 {"mp4a.40.2", MimeUtil::MPEG4_AAC_LC}, | 303 {"mp4a.40.2", MimeUtil::MPEG4_AAC_LC}, |
307 {"mp4a.40.02", MimeUtil::MPEG4_AAC_LC}, | 304 {"mp4a.40.02", MimeUtil::MPEG4_AAC_LC}, |
308 {"mp4a.40.5", MimeUtil::MPEG4_AAC_SBR_v1}, | 305 {"mp4a.40.5", MimeUtil::MPEG4_AAC_SBR_v1}, |
(...skipping 20 matching lines...) Expand all Loading... | |
329 {"vp9", MimeUtil::VP9}, | 326 {"vp9", MimeUtil::VP9}, |
330 {"vp9.0", MimeUtil::VP9}, | 327 {"vp9.0", MimeUtil::VP9}, |
331 {"theora", MimeUtil::THEORA}}; | 328 {"theora", MimeUtil::THEORA}}; |
332 | 329 |
333 // List of codec IDs that are ambiguous and don't provide | 330 // List of codec IDs that are ambiguous and don't provide |
334 // enough information to determine the codec and profile. | 331 // enough information to determine the codec and profile. |
335 // The codec in these entries indicate the codec and profile | 332 // The codec in these entries indicate the codec and profile |
336 // we assume the user is trying to indicate. | 333 // we assume the user is trying to indicate. |
337 static const CodecIDMappings kAmbiguousCodecStringMap[] = { | 334 static const CodecIDMappings kAmbiguousCodecStringMap[] = { |
338 {"mp4a.40", MimeUtil::MPEG4_AAC_LC}, | 335 {"mp4a.40", MimeUtil::MPEG4_AAC_LC}, |
339 {"avc1", MimeUtil::H264_BASELINE}, | 336 {"avc1", MimeUtil::H264}, |
340 {"avc3", MimeUtil::H264_BASELINE}, | 337 {"avc3", MimeUtil::H264}, |
341 // avc1/avc3.XXXXXX may be ambiguous; handled by ParseH264CodecID(). | 338 // avc1/avc3.XXXXXX may be ambiguous; handled by ParseAVCCodecId(). |
342 }; | 339 }; |
343 | 340 |
344 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER) | 341 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER) |
345 static const char kHexString[] = "0123456789ABCDEF"; | 342 static const char kHexString[] = "0123456789ABCDEF"; |
346 static char IntToHex(int i) { | 343 static char IntToHex(int i) { |
347 DCHECK_GE(i, 0) << i << " not a hex value"; | 344 DCHECK_GE(i, 0) << i << " not a hex value"; |
348 DCHECK_LE(i, 15) << i << " not a hex value"; | 345 DCHECK_LE(i, 15) << i << " not a hex value"; |
349 return kHexString[i]; | 346 return kHexString[i]; |
350 } | 347 } |
351 | 348 |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
525 return AreSupportedCodecs(it_media_format_map->second, codecs); | 522 return AreSupportedCodecs(it_media_format_map->second, codecs); |
526 } | 523 } |
527 | 524 |
528 void MimeUtil::RemoveProprietaryMediaTypesAndCodecsForTests() { | 525 void MimeUtil::RemoveProprietaryMediaTypesAndCodecsForTests() { |
529 for (size_t i = 0; i < arraysize(kFormatCodecMappings); ++i) | 526 for (size_t i = 0; i < arraysize(kFormatCodecMappings); ++i) |
530 if (kFormatCodecMappings[i].format_type == PROPRIETARY) | 527 if (kFormatCodecMappings[i].format_type == PROPRIETARY) |
531 media_format_map_.erase(kFormatCodecMappings[i].mime_type); | 528 media_format_map_.erase(kFormatCodecMappings[i].mime_type); |
532 allow_proprietary_codecs_ = false; | 529 allow_proprietary_codecs_ = false; |
533 } | 530 } |
534 | 531 |
535 static bool IsValidH264Level(const std::string& level_str) { | 532 static bool IsValidH264Level(uint8_t level_idc) { |
536 uint32_t level; | 533 // Valid levels taken from Table A-1 in ISO/IEC 14496-10. |
537 if (level_str.size() != 2 || !base::HexStringToUInt(level_str, &level)) | 534 // Level_idc represents the standard level represented as decimal number |
538 return false; | 535 // multiplied by ten, e.g. level_idc==32 corresponds to level==3.2 |
539 | 536 return ((level_idc >= 10 && level_idc <= 13) || |
540 // Valid levels taken from Table A-1 in ISO-14496-10. | 537 (level_idc >= 20 && level_idc <= 22) || |
541 // Essentially |level_str| is toHex(10 * level). | 538 (level_idc >= 30 && level_idc <= 32) || |
542 return ((level >= 10 && level <= 13) || | 539 (level_idc >= 40 && level_idc <= 42) || |
543 (level >= 20 && level <= 22) || | 540 (level_idc >= 50 && level_idc <= 51)); |
544 (level >= 30 && level <= 32) || | |
545 (level >= 40 && level <= 42) || | |
546 (level >= 50 && level <= 51)); | |
547 } | |
548 | |
549 // Handle parsing H.264 codec IDs as outlined in RFC 6381 and ISO-14496-10. | |
550 // avc1.42x0yy - H.264 Baseline | |
551 // avc1.4Dx0yy - H.264 Main | |
552 // avc1.64x0yy - H.264 High | |
553 // | |
554 // avc1.xxxxxx & avc3.xxxxxx are considered ambiguous forms that are trying to | |
555 // signal H.264 Baseline. For example, the idc_level, profile_idc and | |
556 // constraint_set3_flag pieces may explicitly require decoder to conform to | |
557 // baseline profile at the specified level (see Annex A and constraint_set0 in | |
558 // ISO-14496-10). | |
559 static bool ParseH264CodecID(const std::string& codec_id, | |
560 MimeUtil::Codec* codec, | |
561 bool* is_ambiguous) { | |
562 // Make sure we have avc1.xxxxxx or avc3.xxxxxx , where xxxxxx are hex digits | |
563 if (!base::StartsWith(codec_id, "avc1.", base::CompareCase::SENSITIVE) && | |
564 !base::StartsWith(codec_id, "avc3.", base::CompareCase::SENSITIVE)) { | |
565 return false; | |
566 } | |
567 if (codec_id.size() != 11 || | |
568 !base::IsHexDigit(codec_id[5]) || !base::IsHexDigit(codec_id[6]) || | |
569 !base::IsHexDigit(codec_id[7]) || !base::IsHexDigit(codec_id[8]) || | |
570 !base::IsHexDigit(codec_id[9]) || !base::IsHexDigit(codec_id[10])) { | |
571 return false; | |
572 } | |
573 | |
574 // Validate constraint flags and reserved bits. | |
575 if (!base::IsHexDigit(codec_id[7]) || codec_id[8] != '0') { | |
576 *codec = MimeUtil::H264_BASELINE; | |
577 *is_ambiguous = true; | |
578 return true; | |
579 } | |
580 | |
581 // Extract the profile. | |
582 std::string profile = base::ToUpperASCII(codec_id.substr(5, 2)); | |
583 if (profile == "42") { | |
584 *codec = MimeUtil::H264_BASELINE; | |
585 } else if (profile == "4D") { | |
586 *codec = MimeUtil::H264_MAIN; | |
587 } else if (profile == "64") { | |
588 *codec = MimeUtil::H264_HIGH; | |
589 } else { | |
590 *codec = MimeUtil::H264_BASELINE; | |
591 *is_ambiguous = true; | |
592 return true; | |
593 } | |
594 | |
595 // Validate level. | |
596 *is_ambiguous = !IsValidH264Level(codec_id.substr(9)); | |
597 return true; | |
598 } | 541 } |
599 | 542 |
600 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) | 543 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) |
601 // ISO/IEC FDIS 14496-15 standard section E.3 describes the syntax of codec ids | 544 // ISO/IEC FDIS 14496-15 standard section E.3 describes the syntax of codec ids |
602 // reserved for HEVC. According to that spec HEVC codec id must start with | 545 // reserved for HEVC. According to that spec HEVC codec id must start with |
603 // either "hev1." or "hvc1.". We don't yet support full parsing of HEVC codec | 546 // either "hev1." or "hvc1.". We don't yet support full parsing of HEVC codec |
604 // ids, but since no other codec id starts with those string we'll just treat | 547 // ids, but since no other codec id starts with those string we'll just treat |
605 // any string starting with "hev1." or "hvc1." as valid HEVC codec ids. | 548 // any string starting with "hev1." or "hvc1." as valid HEVC codec ids. |
606 // crbug.com/482761 | 549 // crbug.com/482761 |
607 static bool ParseHEVCCodecID(const std::string& codec_id, | 550 static bool ParseHEVCCodecID(const std::string& codec_id, |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
645 } | 588 } |
646 | 589 |
647 // If |codec_id| is not in |string_to_codec_map_|, then we assume that it is | 590 // If |codec_id| is not in |string_to_codec_map_|, then we assume that it is |
648 // either H.264 or HEVC/H.265 codec ID because currently those are the only | 591 // either H.264 or HEVC/H.265 codec ID because currently those are the only |
649 // ones that are not added to the |string_to_codec_map_| and require parsing. | 592 // ones that are not added to the |string_to_codec_map_| and require parsing. |
650 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) | 593 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) |
651 if (ParseHEVCCodecID(codec_id, codec, is_ambiguous)) { | 594 if (ParseHEVCCodecID(codec_id, codec, is_ambiguous)) { |
652 return true; | 595 return true; |
653 } | 596 } |
654 #endif | 597 #endif |
655 return ParseH264CodecID(codec_id, codec, is_ambiguous); | 598 |
599 VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN; | |
600 uint8_t level_idc = 0; | |
601 if (ParseAVCCodecId(codec_id, &profile, &level_idc)) { | |
602 *codec = MimeUtil::H264; | |
603 *is_ambiguous = | |
604 (profile != H264PROFILE_BASELINE && profile != H264PROFILE_MAIN && | |
605 profile != H264PROFILE_HIGH) || | |
606 !IsValidH264Level(level_idc); | |
607 return true; | |
608 } | |
609 | |
610 DVLOG(4) << __FUNCTION__ << ": Unrecognized codec id " << codec_id; | |
611 return false; | |
656 } | 612 } |
657 | 613 |
658 bool MimeUtil::IsCodecSupported(Codec codec) const { | 614 bool MimeUtil::IsCodecSupported(Codec codec) const { |
659 DCHECK_NE(codec, INVALID_CODEC); | 615 DCHECK_NE(codec, INVALID_CODEC); |
660 | 616 |
661 #if defined(OS_ANDROID) | 617 #if defined(OS_ANDROID) |
662 if (!IsCodecSupportedOnAndroid(codec)) | 618 if (!IsCodecSupportedOnAndroid(codec)) |
663 return false; | 619 return false; |
664 #endif | 620 #endif |
665 | 621 |
666 return allow_proprietary_codecs_ || !IsCodecProprietary(codec); | 622 return allow_proprietary_codecs_ || !IsCodecProprietary(codec); |
667 } | 623 } |
668 | 624 |
669 bool MimeUtil::IsCodecProprietary(Codec codec) const { | 625 bool MimeUtil::IsCodecProprietary(Codec codec) const { |
670 switch (codec) { | 626 switch (codec) { |
671 case INVALID_CODEC: | 627 case INVALID_CODEC: |
672 case AC3: | 628 case AC3: |
673 case EAC3: | 629 case EAC3: |
674 case MP3: | 630 case MP3: |
675 case MPEG2_AAC_LC: | 631 case MPEG2_AAC_LC: |
676 case MPEG2_AAC_MAIN: | 632 case MPEG2_AAC_MAIN: |
677 case MPEG2_AAC_SSR: | 633 case MPEG2_AAC_SSR: |
678 case MPEG4_AAC_LC: | 634 case MPEG4_AAC_LC: |
679 case MPEG4_AAC_SBR_v1: | 635 case MPEG4_AAC_SBR_v1: |
680 case MPEG4_AAC_SBR_PS_v2: | 636 case MPEG4_AAC_SBR_PS_v2: |
681 case H264_BASELINE: | 637 case H264: |
682 case H264_MAIN: | |
683 case H264_HIGH: | |
684 case HEVC_MAIN: | 638 case HEVC_MAIN: |
685 return true; | 639 return true; |
686 | 640 |
687 case PCM: | 641 case PCM: |
688 case VORBIS: | 642 case VORBIS: |
689 case OPUS: | 643 case OPUS: |
690 case VP8: | 644 case VP8: |
691 case VP9: | 645 case VP9: |
692 case THEORA: | 646 case THEORA: |
693 return false; | 647 return false; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
734 std::vector<std::string>* codecs_out, | 688 std::vector<std::string>* codecs_out, |
735 const bool strip) { | 689 const bool strip) { |
736 g_media_mime_util.Get().ParseCodecString(codecs, codecs_out, strip); | 690 g_media_mime_util.Get().ParseCodecString(codecs, codecs_out, strip); |
737 } | 691 } |
738 | 692 |
739 void RemoveProprietaryMediaTypesAndCodecsForTests() { | 693 void RemoveProprietaryMediaTypesAndCodecsForTests() { |
740 g_media_mime_util.Get().RemoveProprietaryMediaTypesAndCodecsForTests(); | 694 g_media_mime_util.Get().RemoveProprietaryMediaTypesAndCodecsForTests(); |
741 } | 695 } |
742 | 696 |
743 } // namespace media | 697 } // namespace media |
OLD | NEW |