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

Unified Diff: media/filters/stream_parser_factory.cc

Issue 12713004: Add Chromium-side changes for MediaSource::isTypeSupported() (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Relax DEPS strictness to media/filters & rebased. Created 7 years, 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/filters/stream_parser_factory.h ('k') | media/media.gyp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/filters/stream_parser_factory.cc
diff --git a/media/filters/stream_parser_factory.cc b/media/filters/stream_parser_factory.cc
new file mode 100644
index 0000000000000000000000000000000000000000..0cd8b9a0b435ba1fecc4ddb07cc2d8ee848ea2cc
--- /dev/null
+++ b/media/filters/stream_parser_factory.cc
@@ -0,0 +1,256 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "media/filters/stream_parser_factory.h"
+
+#include "base/string_number_conversions.h"
+#include "base/string_util.h"
+#include "media/base/media_log.h"
+#include "media/webm/webm_stream_parser.h"
+
+#if defined(GOOGLE_CHROME_BUILD) || defined(USE_PROPRIETARY_CODECS)
+#include "media/mp4/es_descriptor.h"
+#include "media/mp4/mp4_stream_parser.h"
+#endif
+
+namespace media {
+
+typedef bool (*CodecIDValidatorFunction)(
+ const std::string& codecs_id, const media::LogCB& log_cb);
+
+struct CodecInfo {
+ enum Type {
+ UNKNOWN,
+ AUDIO,
+ VIDEO
+ };
+
+ const char* pattern;
+ Type type;
+ CodecIDValidatorFunction validator;
+};
+
+typedef media::StreamParser* (*ParserFactoryFunction)(
+ const std::vector<std::string>& codecs,
+ const media::LogCB& log_cb);
+
+struct SupportedTypeInfo {
+ const char* type;
+ const ParserFactoryFunction factory_function;
+ const CodecInfo** codecs;
+};
+
+static const CodecInfo kVP8CodecInfo = { "vp8", CodecInfo::VIDEO, NULL };
+static const CodecInfo kVorbisCodecInfo = { "vorbis", CodecInfo::AUDIO, NULL };
+
+static const CodecInfo* kVideoWebMCodecs[] = {
+ &kVP8CodecInfo,
+ &kVorbisCodecInfo,
+ NULL
+};
+
+static const CodecInfo* kAudioWebMCodecs[] = {
+ &kVorbisCodecInfo,
+ NULL
+};
+
+static media::StreamParser* BuildWebMParser(
+ const std::vector<std::string>& codecs,
+ const media::LogCB& log_cb) {
+#if defined(OS_ANDROID)
+ return NULL;
+#else
+ return new media::WebMStreamParser();
+#endif
+}
+
+#if defined(GOOGLE_CHROME_BUILD) || defined(USE_PROPRIETARY_CODECS)
+// AAC Object Type IDs that Chrome supports.
+static const int kAACLCObjectType = 2;
+static const int kAACSBRObjectType = 5;
+
+static int GetMP4AudioObjectType(const std::string& codec_id,
+ const media::LogCB& log_cb) {
+ int audio_object_type;
+ std::vector<std::string> tokens;
+ if (Tokenize(codec_id, ".", &tokens) != 3 ||
+ tokens[0] != "mp4a" || tokens[1] != "40" ||
+ !base::HexStringToInt(tokens[2], &audio_object_type)) {
+ MEDIA_LOG(log_cb) << "Malformed mimetype codec '" << codec_id << "'";
+ return -1;
+ }
+
+
+ return audio_object_type;
+}
+
+bool ValidateMP4ACodecID(const std::string& codec_id,
+ const media::LogCB& log_cb) {
+ int audio_object_type = GetMP4AudioObjectType(codec_id, log_cb);
+ if (audio_object_type == kAACLCObjectType ||
+ audio_object_type == kAACSBRObjectType) {
+ return true;
+ }
+
+ MEDIA_LOG(log_cb) << "Unsupported audio object type "
+ << "0x" << std::hex << audio_object_type
+ << " in codec '" << codec_id << "'";
+ return false;
+}
+
+static const CodecInfo kH264CodecInfo = { "avc1.*", CodecInfo::VIDEO, NULL };
+static const CodecInfo kMPEG4AACCodecInfo = {
+ "mp4a.40.*", CodecInfo::AUDIO, &ValidateMP4ACodecID
+};
+
+static const CodecInfo kMPEG2AACLCCodecInfo = {
+ "mp4a.67", CodecInfo::AUDIO, NULL
+};
+
+static const CodecInfo* kVideoMP4Codecs[] = {
+ &kH264CodecInfo,
+ &kMPEG4AACCodecInfo,
+ &kMPEG2AACLCCodecInfo,
+ NULL
+};
+
+static const CodecInfo* kAudioMP4Codecs[] = {
+ &kMPEG4AACCodecInfo,
+ &kMPEG2AACLCCodecInfo,
+ NULL
+};
+
+static media::StreamParser* BuildMP4Parser(
+ const std::vector<std::string>& codecs, const media::LogCB& log_cb) {
+#if defined(OS_ANDROID)
+ return NULL;
+#else
+ std::set<int> audio_object_types;
+ bool has_sbr = false;
+ for (size_t i = 0; i < codecs.size(); ++i) {
+ std::string codec_id = codecs[i];
+ if (MatchPattern(codec_id, kMPEG2AACLCCodecInfo.pattern)) {
+ audio_object_types.insert(media::mp4::kISO_13818_7_AAC_LC);
+ } else if (MatchPattern(codec_id, kMPEG4AACCodecInfo.pattern)) {
+ int audio_object_type = GetMP4AudioObjectType(codec_id, log_cb);
+ DCHECK_GT(audio_object_type, 0);
+
+ audio_object_types.insert(media::mp4::kISO_14496_3);
+
+ if (audio_object_type == kAACSBRObjectType) {
+ has_sbr = true;
+ break;
+ }
+ }
+ }
+
+ return new media::mp4::MP4StreamParser(audio_object_types, has_sbr);
+#endif
+}
+#endif
+
+static const SupportedTypeInfo kSupportedTypeInfo[] = {
+ { "video/webm", &BuildWebMParser, kVideoWebMCodecs },
+ { "audio/webm", &BuildWebMParser, kAudioWebMCodecs },
+#if defined(GOOGLE_CHROME_BUILD) || defined(USE_PROPRIETARY_CODECS)
+ { "video/mp4", &BuildMP4Parser, kVideoMP4Codecs },
+ { "audio/mp4", &BuildMP4Parser, kAudioMP4Codecs },
+#endif
+};
+
+// Checks to see if the specified |type| and |codecs| list are supported.
+// Returns true if |type| and all codecs listed in |codecs| are supported.
+// |factory_function| contains a function that can build a StreamParser
+// for this type.
+// |has_audio| is true if an audio codec was specified.
+// |has_video| is true if a video codec was specified.
+// Returns false otherwise. The values of |factory_function|, |has_audio|,
+// and |has_video| are undefined.
+static bool IsSupported(const std::string& type,
+ const std::vector<std::string>& codecs,
+ const media::LogCB& log_cb,
+ ParserFactoryFunction* factory_function,
+ bool* has_audio,
+ bool* has_video) {
+ DCHECK_GT(codecs.size(), 0u);
+ *factory_function = NULL;
+ *has_audio = false;
+ *has_video = false;
+
+ // Search for the SupportedTypeInfo for |type|.
+ for (size_t i = 0; i < arraysize(kSupportedTypeInfo); ++i) {
+ const SupportedTypeInfo& type_info = kSupportedTypeInfo[i];
+ if (type == type_info.type) {
+ // Make sure all the codecs specified in |codecs| are
+ // in the supported type info.
+ for (size_t j = 0; j < codecs.size(); ++j) {
+ // Search the type info for a match.
+ bool found_codec = false;
+ CodecInfo::Type codec_type = CodecInfo::UNKNOWN;
+ std::string codec_id = codecs[j];
+ for (int k = 0; type_info.codecs[k]; ++k) {
+ if (MatchPattern(codec_id, type_info.codecs[k]->pattern) &&
+ (!type_info.codecs[k]->validator ||
+ type_info.codecs[k]->validator(codec_id, log_cb))) {
+ found_codec = true;
+ codec_type = type_info.codecs[k]->type;
+ break;
+ }
+ }
+
+ if (!found_codec) {
+ MEDIA_LOG(log_cb) << "Codec '" << codec_id
+ <<"' is not supported for '" << type << "'";
+ return false;
+ }
+
+ switch (codec_type) {
+ case CodecInfo::AUDIO:
+ *has_audio = true;
+ break;
+ case CodecInfo::VIDEO:
+ *has_video = true;
+ break;
+ default:
+ MEDIA_LOG(log_cb) << "Unsupported codec type '"<< codec_type
+ << "' for " << codec_id;
+ return false;
+ }
+ }
+
+ *factory_function = type_info.factory_function;
+
+ // All codecs were supported by this |type|.
+ return true;
+ }
+ }
+
+ // |type| didn't match any of the supported types.
+ return false;
+}
+
+bool StreamParserFactory::IsTypeSupported(
+ const std::string& type, const std::vector<std::string>& codecs) {
+ bool has_audio;
+ bool has_video;
+ ParserFactoryFunction factory_function;
+ return IsSupported(type, codecs, media::LogCB(), &factory_function,
+ &has_audio, &has_video);
+}
+
+scoped_ptr<media::StreamParser> StreamParserFactory::Create(
+ const std::string& type, const std::vector<std::string>& codecs,
+ const media::LogCB& log_cb, bool* has_audio, bool* has_video) {
+ scoped_ptr<media::StreamParser> stream_parser;
+ ParserFactoryFunction factory_function;
+ if (IsSupported(type, codecs, log_cb, &factory_function,
+ has_audio, has_video)) {
+ stream_parser.reset(factory_function(codecs, log_cb));
+ }
+
+ return stream_parser.Pass();
+}
+
+
+} // namespace media
« no previous file with comments | « media/filters/stream_parser_factory.h ('k') | media/media.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698