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

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: Changing mp4a.40 to mp4a.40.2 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(
Ryan Sleevi 2014/06/10 19:15:43 Document.
amogh.bihani 2014/06/11 11:32:41 Done.
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_;
Ryan Sleevi 2014/06/10 19:15:43 Document
amogh.bihani 2014/06/11 11:32:41 Done.
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 // Following is the list of RFC compliant codecs:
477 // mp4a.6B - MPEG-1 audio
478 // mp4a.69 - MPEG-2 extension to MPEG-1
479 // mp4a.67 - MPEG-2 AAC
480 // mp4a.40.2 - MPEG-4 AAC
481 // mp4a.40.5 - MPEG-4 HE-AAC
482 //
483 // avc1.42E0xx - H.264 Baseline
484 // avc1.4D40xx - H.264 Main
485 // avc1.6400xx - H.264 High
486 //
487 // However some non-RFC compliant codecs are allowed so as to not break some
ddorwin 2014/06/11 00:46:10 Why is mp4a not one of those? What other non-compl
488 // websites.
Ryan Sleevi 2014/06/10 19:15:43 Document a bit about what non-compliant codecs you
489 static const char kProprietaryAudioCodecsExpression[] =
490 "mp4a.6?,mp4a.40,mp4a.40.?";
491 static const char kProprietaryCodecsExpression[] =
492 "avc1,avc3,avc1.??????,avc3.??????,mp4a.6?,mp4a.40,mp4a.40.?";
493
494 static const MediaFormatStrict format_mp4_codec_mappings[] = {
495 { "audio/mp4", kProprietaryAudioCodecsExpression },
496 { "audio/x-m4a", kProprietaryAudioCodecsExpression },
497 { "video/mp4", kProprietaryCodecsExpression },
498 { "video/x-m4v", kProprietaryCodecsExpression },
499 { "application/x-mpegurl", kProprietaryCodecsExpression },
500 { "application/vnd.apple.mpegurl", kProprietaryCodecsExpression }
501 };
502
468 MimeUtil::MimeUtil() { 503 MimeUtil::MimeUtil() {
469 InitializeMimeTypeMaps(); 504 InitializeMimeTypeMaps();
470 } 505 }
471 506
472 // static 507 // static
473 bool MimeUtil::AreSupportedCodecs(const MimeMappings& supported_codecs, 508 bool MimeUtil::AreSupportedCodecs(const MimeMappings& supported_codecs,
474 const std::vector<std::string>& codecs) { 509 const std::vector<std::string>& codecs) {
475 if (supported_codecs.empty()) 510 if (supported_codecs.empty())
476 return codecs.empty(); 511 return codecs.empty();
477 512
478 for (size_t i = 0; i < codecs.size(); ++i) { 513 for (size_t i = 0; i < codecs.size(); ++i) {
479 if (supported_codecs.find(codecs[i]) == supported_codecs.end()) 514 if (supported_codecs.find(codecs[i]) == supported_codecs.end())
480 return false; 515 return false;
481 } 516 }
482 return !codecs.empty(); 517 return !codecs.empty();
483 } 518 }
484 519
520 bool MimeUtil::AreSupportedCodecsWithProfile(
521 const MimeExpressionMappings& supported_codecs,
522 const std::vector<std::string>& codecs) {
523 DCHECK(!supported_codecs.empty());
524 for (size_t i = 0; i < codecs.size(); ++i) {
525 bool codec_matched = false;
526 for (size_t j = 0; j < supported_codecs.size(); ++j) {
527 if (!MatchPattern(base::StringPiece(codecs[i]),
528 base::StringPiece(supported_codecs[j]))) {
529 continue;
530 }
531 // If suffix exists, check whether it is hexadecimal.
532 for (size_t wildcard_pos = supported_codecs[j].find('?');
533 wildcard_pos < supported_codecs[j].length();
534 wildcard_pos = supported_codecs[j].find('?', wildcard_pos + 1)) {
535 // Don't enforce case sensitivity, even though it's called for, as it
536 // would break some websites.
537 if (wildcard_pos >= codecs[i].length() ||
538 !IsHexDigit(codecs[i].at(wildcard_pos))) {
539 return false;
540 }
541 }
542 codec_matched = true;
543 break;
544 }
545 if (!codec_matched)
546 return false;
Ryan Sleevi 2014/06/10 19:15:43 This suggests that only one codec has to match, wh
amogh.bihani 2014/06/11 11:32:41 This returns false as soon as it finds a non-match
547 }
548 return !codecs.empty();
549 }
550
485 void MimeUtil::InitializeMimeTypeMaps() { 551 void MimeUtil::InitializeMimeTypeMaps() {
486 for (size_t i = 0; i < arraysize(supported_image_types); ++i) 552 for (size_t i = 0; i < arraysize(supported_image_types); ++i)
487 image_map_.insert(supported_image_types[i]); 553 image_map_.insert(supported_image_types[i]);
488 554
489 // Initialize the supported non-image types. 555 // Initialize the supported non-image types.
490 for (size_t i = 0; i < arraysize(supported_non_image_types); ++i) 556 for (size_t i = 0; i < arraysize(supported_non_image_types); ++i)
491 non_image_map_.insert(supported_non_image_types[i]); 557 non_image_map_.insert(supported_non_image_types[i]);
492 for (size_t i = 0; i < arraysize(supported_certificate_types); ++i) 558 for (size_t i = 0; i < arraysize(supported_certificate_types); ++i)
493 non_image_map_.insert(supported_certificate_types[i].mime_type); 559 non_image_map_.insert(supported_certificate_types[i].mime_type);
494 for (size_t i = 0; i < arraysize(unsupported_text_types); ++i) 560 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; 611 MimeMappings codecs;
546 for (size_t j = 0; j < mime_type_codecs.size(); ++j) { 612 for (size_t j = 0; j < mime_type_codecs.size(); ++j) {
547 #if defined(OS_ANDROID) 613 #if defined(OS_ANDROID)
548 if (!IsCodecSupportedOnAndroid(mime_type_codecs[j])) 614 if (!IsCodecSupportedOnAndroid(mime_type_codecs[j]))
549 continue; 615 continue;
550 #endif 616 #endif
551 codecs.insert(mime_type_codecs[j]); 617 codecs.insert(mime_type_codecs[j]);
552 } 618 }
553 strict_format_map_[format_codec_mappings[i].mime_type] = codecs; 619 strict_format_map_[format_codec_mappings[i].mime_type] = codecs;
554 } 620 }
621 for (size_t i = 0; i < arraysize(format_mp4_codec_mappings); ++i) {
622 std::vector<std::string> mime_type_codecs;
623 ParseCodecString(
624 format_mp4_codec_mappings[i].codecs_list, &mime_type_codecs, false);
625
626 MimeExpressionMappings codecs;
627 for (size_t j = 0; j < mime_type_codecs.size(); ++j)
628 codecs.push_back(mime_type_codecs[j]);
629 strict_mp4_format_map_[format_mp4_codec_mappings[i].mime_type] = codecs;
630 }
555 } 631 }
556 632
557 bool MimeUtil::IsSupportedImageMimeType(const std::string& mime_type) const { 633 bool MimeUtil::IsSupportedImageMimeType(const std::string& mime_type) const {
558 return image_map_.find(mime_type) != image_map_.end(); 634 return image_map_.find(mime_type) != image_map_.end();
559 } 635 }
560 636
561 bool MimeUtil::IsSupportedMediaMimeType(const std::string& mime_type) const { 637 bool MimeUtil::IsSupportedMediaMimeType(const std::string& mime_type) const {
562 return media_map_.find(mime_type) != media_map_.end(); 638 return media_map_.find(mime_type) != media_map_.end();
563 } 639 }
564 640
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
725 for (std::vector<std::string>::iterator it = codecs_out->begin(); 801 for (std::vector<std::string>::iterator it = codecs_out->begin();
726 it != codecs_out->end(); 802 it != codecs_out->end();
727 ++it) { 803 ++it) {
728 size_t found = it->find_first_of('.'); 804 size_t found = it->find_first_of('.');
729 if (found != std::string::npos) 805 if (found != std::string::npos)
730 it->resize(found); 806 it->resize(found);
731 } 807 }
732 } 808 }
733 809
734 bool MimeUtil::IsStrictMediaMimeType(const std::string& mime_type) const { 810 bool MimeUtil::IsStrictMediaMimeType(const std::string& mime_type) const {
735 if (strict_format_map_.find(mime_type) == strict_format_map_.end()) 811 if (strict_format_map_.find(mime_type) == strict_format_map_.end() &&
812 strict_mp4_format_map_.find(mime_type) == strict_mp4_format_map_.end())
736 return false; 813 return false;
737 return true; 814 return true;
738 } 815 }
739 816
740 bool MimeUtil::IsSupportedStrictMediaMimeType( 817 SupportsType MimeUtil::IsSupportedStrictMediaMimeType(
741 const std::string& mime_type, 818 const std::string& mime_type,
742 const std::vector<std::string>& codecs) const { 819 const std::vector<std::string>& codecs) const {
743 StrictMappings::const_iterator it = strict_format_map_.find(mime_type); 820 StrictMappings::const_iterator it_strict_map =
744 return (it != strict_format_map_.end()) && 821 strict_format_map_.find(mime_type);
745 AreSupportedCodecs(it->second, codecs); 822 if ((it_strict_map != strict_format_map_.end()) &&
823 AreSupportedCodecs(it_strict_map->second, codecs)) {
824 return IsSupported;
825 }
826
827 StrictExpressionMappings::const_iterator it_expression_map =
828 strict_mp4_format_map_.find(mime_type);
829 if ((it_expression_map != strict_mp4_format_map_.end()) &&
830 AreSupportedCodecsWithProfile(it_expression_map->second, codecs)) {
831 return MayBeSupported;
832 }
833
834 if (codecs.empty())
835 return MayBeSupported;
836
837 return IsNotSupported;
746 } 838 }
747 839
748 void MimeUtil::RemoveProprietaryMediaTypesAndCodecsForTests() { 840 void MimeUtil::RemoveProprietaryMediaTypesAndCodecsForTests() {
749 for (size_t i = 0; i < arraysize(proprietary_media_types); ++i) { 841 for (size_t i = 0; i < arraysize(proprietary_media_types); ++i) {
750 non_image_map_.erase(proprietary_media_types[i]); 842 non_image_map_.erase(proprietary_media_types[i]);
751 media_map_.erase(proprietary_media_types[i]); 843 media_map_.erase(proprietary_media_types[i]);
752 } 844 }
753 for (size_t i = 0; i < arraysize(proprietary_media_codecs); ++i) 845 for (size_t i = 0; i < arraysize(proprietary_media_codecs); ++i)
754 codecs_map_.erase(proprietary_media_codecs[i]); 846 codecs_map_.erase(proprietary_media_codecs[i]);
755 } 847 }
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
820 } 912 }
821 913
822 bool AreSupportedMediaCodecs(const std::vector<std::string>& codecs) { 914 bool AreSupportedMediaCodecs(const std::vector<std::string>& codecs) {
823 return g_mime_util.Get().AreSupportedMediaCodecs(codecs); 915 return g_mime_util.Get().AreSupportedMediaCodecs(codecs);
824 } 916 }
825 917
826 bool IsStrictMediaMimeType(const std::string& mime_type) { 918 bool IsStrictMediaMimeType(const std::string& mime_type) {
827 return g_mime_util.Get().IsStrictMediaMimeType(mime_type); 919 return g_mime_util.Get().IsStrictMediaMimeType(mime_type);
828 } 920 }
829 921
830 bool IsSupportedStrictMediaMimeType(const std::string& mime_type, 922 SupportsType IsSupportedStrictMediaMimeType(
831 const std::vector<std::string>& codecs) { 923 const std::string& mime_type,
924 const std::vector<std::string>& codecs) {
832 return g_mime_util.Get().IsSupportedStrictMediaMimeType(mime_type, codecs); 925 return g_mime_util.Get().IsSupportedStrictMediaMimeType(mime_type, codecs);
833 } 926 }
834 927
835 void ParseCodecString(const std::string& codecs, 928 void ParseCodecString(const std::string& codecs,
836 std::vector<std::string>* codecs_out, 929 std::vector<std::string>* codecs_out,
837 const bool strip) { 930 const bool strip) {
838 g_mime_util.Get().ParseCodecString(codecs, codecs_out, strip); 931 g_mime_util.Get().ParseCodecString(codecs, codecs_out, strip);
839 } 932 }
840 933
841 namespace { 934 namespace {
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
1069 post_data->append("\r\n" + value + "\r\n"); 1162 post_data->append("\r\n" + value + "\r\n");
1070 } 1163 }
1071 1164
1072 void AddMultipartFinalDelimiterForUpload(const std::string& mime_boundary, 1165 void AddMultipartFinalDelimiterForUpload(const std::string& mime_boundary,
1073 std::string* post_data) { 1166 std::string* post_data) {
1074 DCHECK(post_data); 1167 DCHECK(post_data);
1075 post_data->append("--" + mime_boundary + "--\r\n"); 1168 post_data->append("--" + mime_boundary + "--\r\n");
1076 } 1169 }
1077 1170
1078 } // namespace net 1171 } // 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