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

Side by Side Diff: net/base/mime_util.cc

Issue 254983006: Fix: Adding list of supported codecs for MP4 containers (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: adding compile_assert, correcting mpeg audio codec values Created 6 years, 6 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
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 <algorithm> 5 #include <algorithm>
6 #include <iterator> 6 #include <iterator>
7 #include <map> 7 #include <map>
8 #include <string> 8 #include <string>
9 9
10 #include "base/containers/hash_tables.h" 10 #include "base/containers/hash_tables.h"
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 76
77 bool IsValidTopLevelMimeType(const std::string& type_string) const; 77 bool IsValidTopLevelMimeType(const std::string& type_string) const;
78 78
79 bool AreSupportedMediaCodecs(const std::vector<std::string>& codecs) const; 79 bool AreSupportedMediaCodecs(const std::vector<std::string>& codecs) const;
80 80
81 void ParseCodecString(const std::string& codecs, 81 void ParseCodecString(const std::string& codecs,
82 std::vector<std::string>* codecs_out, 82 std::vector<std::string>* codecs_out,
83 bool strip); 83 bool strip);
84 84
85 bool IsStrictMediaMimeType(const std::string& mime_type) const; 85 bool IsStrictMediaMimeType(const std::string& mime_type) const;
86 bool IsSupportedStrictMediaMimeType( 86 SupportsType IsSupportedStrictMediaMimeType(
87 const std::string& mime_type, 87 const std::string& mime_type,
88 const std::vector<std::string>& codecs) const; 88 const std::vector<std::string>& codecs) const;
89 89
90 void RemoveProprietaryMediaTypesAndCodecsForTests(); 90 void RemoveProprietaryMediaTypesAndCodecsForTests();
91 91
92 private: 92 private:
93 friend struct base::DefaultLazyInstanceTraits<MimeUtil>; 93 friend struct base::DefaultLazyInstanceTraits<MimeUtil>;
94 94
95 typedef base::hash_set<std::string> MimeMappings; 95 typedef base::hash_set<std::string> MimeMappings;
96 typedef std::map<std::string, MimeMappings> StrictMappings; 96 typedef std::map<std::string, MimeMappings> StrictMappings;
97 97
98 typedef std::vector<std::string> MimeExpressionMappings;
99 typedef std::map<std::string, MimeExpressionMappings>
100 StrictExpressionMappings;
101
98 MimeUtil(); 102 MimeUtil();
99 103
100 // Returns true if |codecs| is nonempty and all the items in it are present in 104 // Returns true if |codecs| is nonempty and all the items in it are present in
101 // |supported_codecs|. 105 // |supported_codecs|.
102 static bool AreSupportedCodecs(const MimeMappings& supported_codecs, 106 static bool AreSupportedCodecs(const MimeMappings& supported_codecs,
103 const std::vector<std::string>& codecs); 107 const std::vector<std::string>& codecs);
108 static bool AreSupportedCodecsWithProfile(
109 const MimeExpressionMappings& supported_codecs,
110 const std::vector<std::string>& codecs);
104 111
105 // For faster lookup, keep hash sets. 112 // For faster lookup, keep hash sets.
106 void InitializeMimeTypeMaps(); 113 void InitializeMimeTypeMaps();
107 114
108 bool GetMimeTypeFromExtensionHelper(const base::FilePath::StringType& ext, 115 bool GetMimeTypeFromExtensionHelper(const base::FilePath::StringType& ext,
109 bool include_platform_types, 116 bool include_platform_types,
110 std::string* mime_type) const; 117 std::string* mime_type) const;
111 118
112 MimeMappings image_map_; 119 MimeMappings image_map_;
113 MimeMappings media_map_; 120 MimeMappings media_map_;
114 MimeMappings non_image_map_; 121 MimeMappings non_image_map_;
115 MimeMappings unsupported_text_map_; 122 MimeMappings unsupported_text_map_;
116 MimeMappings javascript_map_; 123 MimeMappings javascript_map_;
117 MimeMappings codecs_map_; 124 MimeMappings codecs_map_;
118 125
119 StrictMappings strict_format_map_; 126 StrictMappings strict_format_map_;
127 StrictExpressionMappings strict_mp4_format_map_;
120 }; // class MimeUtil 128 }; // class MimeUtil
121 129
122 // This variable is Leaky because we need to access it from WorkerPool threads. 130 // This variable is Leaky because we need to access it from WorkerPool threads.
123 static base::LazyInstance<MimeUtil>::Leaky g_mime_util = 131 static base::LazyInstance<MimeUtil>::Leaky g_mime_util =
124 LAZY_INSTANCE_INITIALIZER; 132 LAZY_INSTANCE_INITIALIZER;
125 133
126 struct MimeInfo { 134 struct MimeInfo {
127 const char* mime_type; 135 const char* mime_type;
128 const char* extensions; // comma separated list 136 const char* extensions; // comma separated list
129 }; 137 };
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 { "audio/wav", "1" }, 466 { "audio/wav", "1" },
459 { "audio/x-wav", "1" }, 467 { "audio/x-wav", "1" },
460 { "video/ogg", "opus,theora,vorbis" }, 468 { "video/ogg", "opus,theora,vorbis" },
461 { "audio/ogg", "opus,vorbis" }, 469 { "audio/ogg", "opus,vorbis" },
462 { "application/ogg", "opus,theora,vorbis" }, 470 { "application/ogg", "opus,theora,vorbis" },
463 { "audio/mpeg", "" }, 471 { "audio/mpeg", "" },
464 { "audio/mp3", "" }, 472 { "audio/mp3", "" },
465 { "audio/x-mp3", "" } 473 { "audio/x-mp3", "" }
466 }; 474 };
467 475
476 /**
477 * Following is the list of RFC compliant codecs:
478 * mp4a.6B - MPEG-1 audio
479 * mp4a.69 - MPEG-2 extension to MPEG-1
480 * mp4a.67 - MPEG-2 AAC
481 * mp4a.40.2 - MPEG-4 AAC
482 * mp4a.40.5 - MPEG-4 HE-AAC
483 *
484 * avc1.42E0xx - H.264 Baseline
485 * avc1.4D40xx - H.264 Main
486 * avc1.6400xx - H.264 High
487 *
488 * However some non-RFC compliant codecs are allowed so as to not break some
489 * websites.
490 **/
Ryan Sleevi 2014/06/03 20:36:51 Format this comment like the rest of the file - us
491 static const char* kProprietaryAudioCodecsExpression =
Ryan Sleevi 2014/06/03 20:36:51 Use "static const char kProprietary...[]" rather t
492 "mp4a.6?,mp4a.40,mp4a.40.?";
493 static const char* kProprietaryCodecsExpression =
494 "avc1,avc3,avc1.??????,avc3.??????,mp4a.6?,mp4a.40,mp4a.40.?";
495
496 static const MediaFormatStrict format_mp4_codec_mappings[] = {
497 { "audio/mp4", kProprietaryAudioCodecsExpression },
498 { "audio/x-m4a", kProprietaryAudioCodecsExpression },
499 { "video/mp4", kProprietaryCodecsExpression },
500 { "video/x-m4v", kProprietaryCodecsExpression },
501 { "application/x-mpegurl", kProprietaryCodecsExpression },
502 { "application/vnd.apple.mpegurl", kProprietaryCodecsExpression }
503 };
504
468 MimeUtil::MimeUtil() { 505 MimeUtil::MimeUtil() {
469 InitializeMimeTypeMaps(); 506 InitializeMimeTypeMaps();
470 } 507 }
471 508
472 // static 509 // static
473 bool MimeUtil::AreSupportedCodecs(const MimeMappings& supported_codecs, 510 bool MimeUtil::AreSupportedCodecs(const MimeMappings& supported_codecs,
474 const std::vector<std::string>& codecs) { 511 const std::vector<std::string>& codecs) {
475 if (supported_codecs.empty()) 512 if (supported_codecs.empty())
476 return codecs.empty(); 513 return codecs.empty();
477 514
478 for (size_t i = 0; i < codecs.size(); ++i) { 515 for (size_t i = 0; i < codecs.size(); ++i) {
479 if (supported_codecs.find(codecs[i]) == supported_codecs.end()) 516 if (supported_codecs.find(codecs[i]) == supported_codecs.end())
480 return false; 517 return false;
481 } 518 }
482 return !codecs.empty(); 519 return !codecs.empty();
483 } 520 }
484 521
522 bool MimeUtil::AreSupportedCodecsWithProfile(
523 const MimeExpressionMappings& supported_codecs,
524 const std::vector<std::string>& codecs) {
525 DCHECK(!supported_codecs.empty());
526 for (size_t i = 0; i < codecs.size(); ++i) {
527 bool codec_matched = false;
528 for (size_t j = 0; j < supported_codecs.size(); ++j) {
529 if (!MatchPattern(base::StringPiece(codecs[i]),
530 base::StringPiece(supported_codecs[j]))) {
531 continue;
532 }
533 // If suffix exists, check whether it is hexadecimal.
534 for (size_t wildcard_pos = supported_codecs[j].find('?');
535 wildcard_pos < supported_codecs[j].length();
536 wildcard_pos = supported_codecs[j].find('?', wildcard_pos + 1)) {
537 // Don't enforce case sensitivity, even though it's called for, as it
538 // would break some websites.
539 if (wildcard_pos >= codecs[i].length() ||
540 !IsHexDigit(codecs[i].at(wildcard_pos))) {
541 return false;
542 }
543 }
544 codec_matched = true;
545 break;
546 }
547 if (!codec_matched)
548 return false;
549 }
550 return !codecs.empty();
551 }
552
485 void MimeUtil::InitializeMimeTypeMaps() { 553 void MimeUtil::InitializeMimeTypeMaps() {
486 for (size_t i = 0; i < arraysize(supported_image_types); ++i) 554 for (size_t i = 0; i < arraysize(supported_image_types); ++i)
487 image_map_.insert(supported_image_types[i]); 555 image_map_.insert(supported_image_types[i]);
488 556
489 // Initialize the supported non-image types. 557 // Initialize the supported non-image types.
490 for (size_t i = 0; i < arraysize(supported_non_image_types); ++i) 558 for (size_t i = 0; i < arraysize(supported_non_image_types); ++i)
491 non_image_map_.insert(supported_non_image_types[i]); 559 non_image_map_.insert(supported_non_image_types[i]);
492 for (size_t i = 0; i < arraysize(supported_certificate_types); ++i) 560 for (size_t i = 0; i < arraysize(supported_certificate_types); ++i)
493 non_image_map_.insert(supported_certificate_types[i].mime_type); 561 non_image_map_.insert(supported_certificate_types[i].mime_type);
494 for (size_t i = 0; i < arraysize(unsupported_text_types); ++i) 562 for (size_t i = 0; i < arraysize(unsupported_text_types); ++i)
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 MimeMappings codecs; 613 MimeMappings codecs;
546 for (size_t j = 0; j < mime_type_codecs.size(); ++j) { 614 for (size_t j = 0; j < mime_type_codecs.size(); ++j) {
547 #if defined(OS_ANDROID) 615 #if defined(OS_ANDROID)
548 if (!IsCodecSupportedOnAndroid(mime_type_codecs[j])) 616 if (!IsCodecSupportedOnAndroid(mime_type_codecs[j]))
549 continue; 617 continue;
550 #endif 618 #endif
551 codecs.insert(mime_type_codecs[j]); 619 codecs.insert(mime_type_codecs[j]);
552 } 620 }
553 strict_format_map_[format_codec_mappings[i].mime_type] = codecs; 621 strict_format_map_[format_codec_mappings[i].mime_type] = codecs;
554 } 622 }
623 for (size_t i = 0; i < arraysize(format_mp4_codec_mappings); ++i) {
624 std::vector<std::string> mime_type_codecs;
625 ParseCodecString(
626 format_mp4_codec_mappings[i].codecs_list, &mime_type_codecs, false);
627
628 MimeExpressionMappings codecs;
629 for (size_t j = 0; j < mime_type_codecs.size(); ++j) {
630 codecs.push_back(mime_type_codecs[j]);
631 }
Ryan Sleevi 2014/06/03 20:36:51 No braces here, like the rest of the file.
632 strict_mp4_format_map_[format_mp4_codec_mappings[i].mime_type] = codecs;
633 }
555 } 634 }
556 635
557 bool MimeUtil::IsSupportedImageMimeType(const std::string& mime_type) const { 636 bool MimeUtil::IsSupportedImageMimeType(const std::string& mime_type) const {
558 return image_map_.find(mime_type) != image_map_.end(); 637 return image_map_.find(mime_type) != image_map_.end();
559 } 638 }
560 639
561 bool MimeUtil::IsSupportedMediaMimeType(const std::string& mime_type) const { 640 bool MimeUtil::IsSupportedMediaMimeType(const std::string& mime_type) const {
562 return media_map_.find(mime_type) != media_map_.end(); 641 return media_map_.find(mime_type) != media_map_.end();
563 } 642 }
564 643
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
725 for (std::vector<std::string>::iterator it = codecs_out->begin(); 804 for (std::vector<std::string>::iterator it = codecs_out->begin();
726 it != codecs_out->end(); 805 it != codecs_out->end();
727 ++it) { 806 ++it) {
728 size_t found = it->find_first_of('.'); 807 size_t found = it->find_first_of('.');
729 if (found != std::string::npos) 808 if (found != std::string::npos)
730 it->resize(found); 809 it->resize(found);
731 } 810 }
732 } 811 }
733 812
734 bool MimeUtil::IsStrictMediaMimeType(const std::string& mime_type) const { 813 bool MimeUtil::IsStrictMediaMimeType(const std::string& mime_type) const {
735 if (strict_format_map_.find(mime_type) == strict_format_map_.end()) 814 if (strict_format_map_.find(mime_type) == strict_format_map_.end() &&
815 strict_mp4_format_map_.find(mime_type) == strict_mp4_format_map_.end())
736 return false; 816 return false;
737 return true; 817 return true;
738 } 818 }
739 819
740 bool MimeUtil::IsSupportedStrictMediaMimeType( 820 SupportsType MimeUtil::IsSupportedStrictMediaMimeType(
741 const std::string& mime_type, 821 const std::string& mime_type,
742 const std::vector<std::string>& codecs) const { 822 const std::vector<std::string>& codecs) const {
743 StrictMappings::const_iterator it = strict_format_map_.find(mime_type); 823 StrictMappings::const_iterator it_strict_map =
744 return (it != strict_format_map_.end()) && 824 strict_format_map_.find(mime_type);
745 AreSupportedCodecs(it->second, codecs); 825 if ((it_strict_map != strict_format_map_.end()) &&
826 AreSupportedCodecs(it_strict_map->second, codecs)) {
827 return IsSupported;
828 }
829
830 StrictExpressionMappings::const_iterator it_expression_map =
831 strict_mp4_format_map_.find(mime_type);
832 if ((it_expression_map != strict_mp4_format_map_.end()) &&
833 AreSupportedCodecsWithProfile(it_expression_map->second, codecs)) {
834 return MayBeSupported;
835 }
836
837 if (codecs.empty())
838 return MayBeSupported;
839
840 return IsNotSupported;
746 } 841 }
747 842
748 void MimeUtil::RemoveProprietaryMediaTypesAndCodecsForTests() { 843 void MimeUtil::RemoveProprietaryMediaTypesAndCodecsForTests() {
749 for (size_t i = 0; i < arraysize(proprietary_media_types); ++i) { 844 for (size_t i = 0; i < arraysize(proprietary_media_types); ++i) {
750 non_image_map_.erase(proprietary_media_types[i]); 845 non_image_map_.erase(proprietary_media_types[i]);
751 media_map_.erase(proprietary_media_types[i]); 846 media_map_.erase(proprietary_media_types[i]);
752 } 847 }
753 for (size_t i = 0; i < arraysize(proprietary_media_codecs); ++i) 848 for (size_t i = 0; i < arraysize(proprietary_media_codecs); ++i)
754 codecs_map_.erase(proprietary_media_codecs[i]); 849 codecs_map_.erase(proprietary_media_codecs[i]);
755 } 850 }
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
820 } 915 }
821 916
822 bool AreSupportedMediaCodecs(const std::vector<std::string>& codecs) { 917 bool AreSupportedMediaCodecs(const std::vector<std::string>& codecs) {
823 return g_mime_util.Get().AreSupportedMediaCodecs(codecs); 918 return g_mime_util.Get().AreSupportedMediaCodecs(codecs);
824 } 919 }
825 920
826 bool IsStrictMediaMimeType(const std::string& mime_type) { 921 bool IsStrictMediaMimeType(const std::string& mime_type) {
827 return g_mime_util.Get().IsStrictMediaMimeType(mime_type); 922 return g_mime_util.Get().IsStrictMediaMimeType(mime_type);
828 } 923 }
829 924
830 bool IsSupportedStrictMediaMimeType(const std::string& mime_type, 925 SupportsType IsSupportedStrictMediaMimeType(
831 const std::vector<std::string>& codecs) { 926 const std::string& mime_type,
927 const std::vector<std::string>& codecs) {
832 return g_mime_util.Get().IsSupportedStrictMediaMimeType(mime_type, codecs); 928 return g_mime_util.Get().IsSupportedStrictMediaMimeType(mime_type, codecs);
833 } 929 }
834 930
835 void ParseCodecString(const std::string& codecs, 931 void ParseCodecString(const std::string& codecs,
836 std::vector<std::string>* codecs_out, 932 std::vector<std::string>* codecs_out,
837 const bool strip) { 933 const bool strip) {
838 g_mime_util.Get().ParseCodecString(codecs, codecs_out, strip); 934 g_mime_util.Get().ParseCodecString(codecs, codecs_out, strip);
839 } 935 }
840 936
841 namespace { 937 namespace {
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
1069 post_data->append("\r\n" + value + "\r\n"); 1165 post_data->append("\r\n" + value + "\r\n");
1070 } 1166 }
1071 1167
1072 void AddMultipartFinalDelimiterForUpload(const std::string& mime_boundary, 1168 void AddMultipartFinalDelimiterForUpload(const std::string& mime_boundary,
1073 std::string* post_data) { 1169 std::string* post_data) {
1074 DCHECK(post_data); 1170 DCHECK(post_data);
1075 post_data->append("--" + mime_boundary + "--\r\n"); 1171 post_data->append("--" + mime_boundary + "--\r\n");
1076 } 1172 }
1077 1173
1078 } // namespace net 1174 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698