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

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: removing nit 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 // Returns true is |codecs| is nonempty and all the items in it match with the
109 // codecs expression in |supported_codecs|.
110 static bool AreSupportedCodecsWithProfile(
111 const MimeExpressionMappings& supported_codecs,
112 const std::vector<std::string>& codecs);
104 113
105 // For faster lookup, keep hash sets. 114 // For faster lookup, keep hash sets.
106 void InitializeMimeTypeMaps(); 115 void InitializeMimeTypeMaps();
107 116
108 bool GetMimeTypeFromExtensionHelper(const base::FilePath::StringType& ext, 117 bool GetMimeTypeFromExtensionHelper(const base::FilePath::StringType& ext,
109 bool include_platform_types, 118 bool include_platform_types,
110 std::string* mime_type) const; 119 std::string* mime_type) const;
111 120
112 MimeMappings image_map_; 121 MimeMappings image_map_;
113 MimeMappings media_map_; 122 MimeMappings media_map_;
114 MimeMappings non_image_map_; 123 MimeMappings non_image_map_;
115 MimeMappings unsupported_text_map_; 124 MimeMappings unsupported_text_map_;
116 MimeMappings javascript_map_; 125 MimeMappings javascript_map_;
117 MimeMappings codecs_map_; 126 MimeMappings codecs_map_;
118 127
128 // A map of mime_types and hash map of the supported codecs for the mime_type.
119 StrictMappings strict_format_map_; 129 StrictMappings strict_format_map_;
130 // A map of MP4 mime_types which expect codecs with profile parameter and
131 // vector of supported codecs expressions for the mime_type.
132 StrictExpressionMappings strict_mp4_format_map_;
120 }; // class MimeUtil 133 }; // class MimeUtil
121 134
122 // This variable is Leaky because we need to access it from WorkerPool threads. 135 // This variable is Leaky because we need to access it from WorkerPool threads.
123 static base::LazyInstance<MimeUtil>::Leaky g_mime_util = 136 static base::LazyInstance<MimeUtil>::Leaky g_mime_util =
124 LAZY_INSTANCE_INITIALIZER; 137 LAZY_INSTANCE_INITIALIZER;
125 138
126 struct MimeInfo { 139 struct MimeInfo {
127 const char* mime_type; 140 const char* mime_type;
128 const char* extensions; // comma separated list 141 const char* extensions; // comma separated list
129 }; 142 };
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 { "audio/wav", "1" }, 471 { "audio/wav", "1" },
459 { "audio/x-wav", "1" }, 472 { "audio/x-wav", "1" },
460 { "video/ogg", "opus,theora,vorbis" }, 473 { "video/ogg", "opus,theora,vorbis" },
461 { "audio/ogg", "opus,vorbis" }, 474 { "audio/ogg", "opus,vorbis" },
462 { "application/ogg", "opus,theora,vorbis" }, 475 { "application/ogg", "opus,theora,vorbis" },
463 { "audio/mpeg", "" }, 476 { "audio/mpeg", "" },
464 { "audio/mp3", "" }, 477 { "audio/mp3", "" },
465 { "audio/x-mp3", "" } 478 { "audio/x-mp3", "" }
466 }; 479 };
467 480
481 // Following is the list of RFC compliant codecs:
Ryan Sleevi 2014/06/12 19:03:53 Which RFC(s)? Important to document in case it's u
482 // mp4a.6B - MPEG-1 audio
483 // mp4a.69 - MPEG-2 extension to MPEG-1
484 // mp4a.67 - MPEG-2 AAC
485 // mp4a.40.2 - MPEG-4 AAC
486 // mp4a.40.5 - MPEG-4 HE-AAC
487 //
488 // avc1.42E0xx - H.264 Baseline
489 // avc1.4D40xx - H.264 Main
490 // avc1.6400xx - H.264 High
491 //
492 // However some non-RFC compliant codecs are allowed so as to not break some
493 // websites. Eg. mp4a.40 or avc1.123456.
Ryan Sleevi 2014/06/12 19:03:53 This comment - whiel helpful, doesn't help me unde
amogh.bihani 2014/06/13 03:16:47 we are allowing 6? because some websites might me
494 static const char kProprietaryAudioCodecsExpression[] =
495 "mp4a.6?,mp4a.40,mp4a.40.?";
496 static const char kProprietaryCodecsExpression[] =
497 "avc1,avc3,avc1.??????,avc3.??????,mp4a.6?,mp4a.40,mp4a.40.?";
498
499 static const MediaFormatStrict format_mp4_codec_mappings[] = {
500 { "audio/mp4", kProprietaryAudioCodecsExpression },
501 { "audio/x-m4a", kProprietaryAudioCodecsExpression },
502 { "video/mp4", kProprietaryCodecsExpression },
503 { "video/x-m4v", kProprietaryCodecsExpression },
504 { "application/x-mpegurl", kProprietaryCodecsExpression },
505 { "application/vnd.apple.mpegurl", kProprietaryCodecsExpression }
506 };
507
468 MimeUtil::MimeUtil() { 508 MimeUtil::MimeUtil() {
469 InitializeMimeTypeMaps(); 509 InitializeMimeTypeMaps();
470 } 510 }
471 511
472 // static 512 // static
473 bool MimeUtil::AreSupportedCodecs(const MimeMappings& supported_codecs, 513 bool MimeUtil::AreSupportedCodecs(const MimeMappings& supported_codecs,
474 const std::vector<std::string>& codecs) { 514 const std::vector<std::string>& codecs) {
475 if (supported_codecs.empty()) 515 if (supported_codecs.empty())
476 return codecs.empty(); 516 return codecs.empty();
477 517
478 for (size_t i = 0; i < codecs.size(); ++i) { 518 for (size_t i = 0; i < codecs.size(); ++i) {
479 if (supported_codecs.find(codecs[i]) == supported_codecs.end()) 519 if (supported_codecs.find(codecs[i]) == supported_codecs.end())
480 return false; 520 return false;
481 } 521 }
482 return !codecs.empty(); 522 return !codecs.empty();
483 } 523 }
484 524
525 // Checks all the codecs present in the |codecs| against the entries in
526 // |supported_codecs|. Returns true only if |codecs| is non-empty and all the
527 // codecs match |supported_codecs| expressions.
528 bool MimeUtil::AreSupportedCodecsWithProfile(
529 const MimeExpressionMappings& supported_codecs,
530 const std::vector<std::string>& codecs) {
531 DCHECK(!supported_codecs.empty());
532 for (size_t i = 0; i < codecs.size(); ++i) {
533 bool codec_matched = false;
534 for (size_t j = 0; j < supported_codecs.size(); ++j) {
535 if (!MatchPattern(base::StringPiece(codecs[i]),
536 base::StringPiece(supported_codecs[j]))) {
537 continue;
538 }
539 // If suffix exists, check whether it is hexadecimal.
540 for (size_t wildcard_pos = supported_codecs[j].find('?');
541 wildcard_pos < supported_codecs[j].length();
542 wildcard_pos = supported_codecs[j].find('?', wildcard_pos + 1)) {
543 // Don't enforce case sensitivity, even though it's called for, as it
544 // would break some websites.
545 if (wildcard_pos >= codecs[i].length() ||
546 !IsHexDigit(codecs[i].at(wildcard_pos))) {
547 return false;
548 }
549 }
550 codec_matched = true;
551 break;
552 }
553 if (!codec_matched)
554 return false;
555 }
556 return !codecs.empty();
557 }
558
485 void MimeUtil::InitializeMimeTypeMaps() { 559 void MimeUtil::InitializeMimeTypeMaps() {
486 for (size_t i = 0; i < arraysize(supported_image_types); ++i) 560 for (size_t i = 0; i < arraysize(supported_image_types); ++i)
487 image_map_.insert(supported_image_types[i]); 561 image_map_.insert(supported_image_types[i]);
488 562
489 // Initialize the supported non-image types. 563 // Initialize the supported non-image types.
490 for (size_t i = 0; i < arraysize(supported_non_image_types); ++i) 564 for (size_t i = 0; i < arraysize(supported_non_image_types); ++i)
491 non_image_map_.insert(supported_non_image_types[i]); 565 non_image_map_.insert(supported_non_image_types[i]);
492 for (size_t i = 0; i < arraysize(supported_certificate_types); ++i) 566 for (size_t i = 0; i < arraysize(supported_certificate_types); ++i)
493 non_image_map_.insert(supported_certificate_types[i].mime_type); 567 non_image_map_.insert(supported_certificate_types[i].mime_type);
494 for (size_t i = 0; i < arraysize(unsupported_text_types); ++i) 568 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; 619 MimeMappings codecs;
546 for (size_t j = 0; j < mime_type_codecs.size(); ++j) { 620 for (size_t j = 0; j < mime_type_codecs.size(); ++j) {
547 #if defined(OS_ANDROID) 621 #if defined(OS_ANDROID)
548 if (!IsCodecSupportedOnAndroid(mime_type_codecs[j])) 622 if (!IsCodecSupportedOnAndroid(mime_type_codecs[j]))
549 continue; 623 continue;
550 #endif 624 #endif
551 codecs.insert(mime_type_codecs[j]); 625 codecs.insert(mime_type_codecs[j]);
552 } 626 }
553 strict_format_map_[format_codec_mappings[i].mime_type] = codecs; 627 strict_format_map_[format_codec_mappings[i].mime_type] = codecs;
554 } 628 }
629 for (size_t i = 0; i < arraysize(format_mp4_codec_mappings); ++i) {
630 std::vector<std::string> mime_type_codecs;
631 ParseCodecString(
632 format_mp4_codec_mappings[i].codecs_list, &mime_type_codecs, false);
633
634 MimeExpressionMappings codecs;
635 for (size_t j = 0; j < mime_type_codecs.size(); ++j)
636 codecs.push_back(mime_type_codecs[j]);
637 strict_mp4_format_map_[format_mp4_codec_mappings[i].mime_type] = codecs;
638 }
555 } 639 }
556 640
557 bool MimeUtil::IsSupportedImageMimeType(const std::string& mime_type) const { 641 bool MimeUtil::IsSupportedImageMimeType(const std::string& mime_type) const {
558 return image_map_.find(mime_type) != image_map_.end(); 642 return image_map_.find(mime_type) != image_map_.end();
559 } 643 }
560 644
561 bool MimeUtil::IsSupportedMediaMimeType(const std::string& mime_type) const { 645 bool MimeUtil::IsSupportedMediaMimeType(const std::string& mime_type) const {
562 return media_map_.find(mime_type) != media_map_.end(); 646 return media_map_.find(mime_type) != media_map_.end();
563 } 647 }
564 648
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
725 for (std::vector<std::string>::iterator it = codecs_out->begin(); 809 for (std::vector<std::string>::iterator it = codecs_out->begin();
726 it != codecs_out->end(); 810 it != codecs_out->end();
727 ++it) { 811 ++it) {
728 size_t found = it->find_first_of('.'); 812 size_t found = it->find_first_of('.');
729 if (found != std::string::npos) 813 if (found != std::string::npos)
730 it->resize(found); 814 it->resize(found);
731 } 815 }
732 } 816 }
733 817
734 bool MimeUtil::IsStrictMediaMimeType(const std::string& mime_type) const { 818 bool MimeUtil::IsStrictMediaMimeType(const std::string& mime_type) const {
735 if (strict_format_map_.find(mime_type) == strict_format_map_.end()) 819 if (strict_format_map_.find(mime_type) == strict_format_map_.end() &&
820 strict_mp4_format_map_.find(mime_type) == strict_mp4_format_map_.end())
736 return false; 821 return false;
737 return true; 822 return true;
738 } 823 }
739 824
740 bool MimeUtil::IsSupportedStrictMediaMimeType( 825 SupportsType MimeUtil::IsSupportedStrictMediaMimeType(
741 const std::string& mime_type, 826 const std::string& mime_type,
742 const std::vector<std::string>& codecs) const { 827 const std::vector<std::string>& codecs) const {
743 StrictMappings::const_iterator it = strict_format_map_.find(mime_type); 828 StrictMappings::const_iterator it_strict_map =
744 return (it != strict_format_map_.end()) && 829 strict_format_map_.find(mime_type);
745 AreSupportedCodecs(it->second, codecs); 830 if ((it_strict_map != strict_format_map_.end()) &&
831 AreSupportedCodecs(it_strict_map->second, codecs)) {
832 return IsSupported;
833 }
834
835 StrictExpressionMappings::const_iterator it_expression_map =
836 strict_mp4_format_map_.find(mime_type);
837 if ((it_expression_map != strict_mp4_format_map_.end()) &&
838 AreSupportedCodecsWithProfile(it_expression_map->second, codecs)) {
839 return MayBeSupported;
840 }
841
842 if (codecs.empty())
843 return MayBeSupported;
844
845 return IsNotSupported;
746 } 846 }
747 847
748 void MimeUtil::RemoveProprietaryMediaTypesAndCodecsForTests() { 848 void MimeUtil::RemoveProprietaryMediaTypesAndCodecsForTests() {
749 for (size_t i = 0; i < arraysize(proprietary_media_types); ++i) { 849 for (size_t i = 0; i < arraysize(proprietary_media_types); ++i) {
750 non_image_map_.erase(proprietary_media_types[i]); 850 non_image_map_.erase(proprietary_media_types[i]);
751 media_map_.erase(proprietary_media_types[i]); 851 media_map_.erase(proprietary_media_types[i]);
752 } 852 }
753 for (size_t i = 0; i < arraysize(proprietary_media_codecs); ++i) 853 for (size_t i = 0; i < arraysize(proprietary_media_codecs); ++i)
754 codecs_map_.erase(proprietary_media_codecs[i]); 854 codecs_map_.erase(proprietary_media_codecs[i]);
755 } 855 }
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
820 } 920 }
821 921
822 bool AreSupportedMediaCodecs(const std::vector<std::string>& codecs) { 922 bool AreSupportedMediaCodecs(const std::vector<std::string>& codecs) {
823 return g_mime_util.Get().AreSupportedMediaCodecs(codecs); 923 return g_mime_util.Get().AreSupportedMediaCodecs(codecs);
824 } 924 }
825 925
826 bool IsStrictMediaMimeType(const std::string& mime_type) { 926 bool IsStrictMediaMimeType(const std::string& mime_type) {
827 return g_mime_util.Get().IsStrictMediaMimeType(mime_type); 927 return g_mime_util.Get().IsStrictMediaMimeType(mime_type);
828 } 928 }
829 929
830 bool IsSupportedStrictMediaMimeType(const std::string& mime_type, 930 SupportsType IsSupportedStrictMediaMimeType(
831 const std::vector<std::string>& codecs) { 931 const std::string& mime_type,
932 const std::vector<std::string>& codecs) {
832 return g_mime_util.Get().IsSupportedStrictMediaMimeType(mime_type, codecs); 933 return g_mime_util.Get().IsSupportedStrictMediaMimeType(mime_type, codecs);
833 } 934 }
834 935
835 void ParseCodecString(const std::string& codecs, 936 void ParseCodecString(const std::string& codecs,
836 std::vector<std::string>* codecs_out, 937 std::vector<std::string>* codecs_out,
837 const bool strip) { 938 const bool strip) {
838 g_mime_util.Get().ParseCodecString(codecs, codecs_out, strip); 939 g_mime_util.Get().ParseCodecString(codecs, codecs_out, strip);
839 } 940 }
840 941
841 namespace { 942 namespace {
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
1069 post_data->append("\r\n" + value + "\r\n"); 1170 post_data->append("\r\n" + value + "\r\n");
1070 } 1171 }
1071 1172
1072 void AddMultipartFinalDelimiterForUpload(const std::string& mime_boundary, 1173 void AddMultipartFinalDelimiterForUpload(const std::string& mime_boundary,
1073 std::string* post_data) { 1174 std::string* post_data) {
1074 DCHECK(post_data); 1175 DCHECK(post_data);
1075 post_data->append("--" + mime_boundary + "--\r\n"); 1176 post_data->append("--" + mime_boundary + "--\r\n");
1076 } 1177 }
1077 1178
1078 } // namespace net 1179 } // namespace net
OLDNEW
« net/base/mime_util.h ('K') | « net/base/mime_util.h ('k') | net/base/mime_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698