Loading media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp +65 −6 Original line number Diff line number Diff line Loading @@ -346,6 +346,7 @@ struct MediaCodecsXmlParser::Impl { status_t addAlias(const char **attrs); status_t addFeature(const char **attrs); status_t addLimit(const char **attrs); status_t addMapping(const char **attrs); status_t addQuirk(const char **attrs, const char *prefix = nullptr); status_t addSetting(const char **attrs, const char *prefix = nullptr); status_t enterMediaCodec(const char **attrs, bool encoder); Loading Loading @@ -428,7 +429,7 @@ status_t MediaCodecsXmlParser::Impl::parseXmlFilesInSearchDirs( if (findFileInDirs(searchDirs, fileName, &path)) { err = parseXmlPath(path); } else { ALOGD("Cannot find %s", path.c_str()); ALOGD("Cannot find %s in search path", fileName.c_str()); } res = combineStatus(res, err); } Loading Loading @@ -741,13 +742,16 @@ void MediaCodecsXmlParser::Impl::Parser::startElementHandler( { // ignore limits and features specified outside of type if (!mState->inType() && (strEq(name, "Limit") || strEq(name, "Feature") || strEq(name, "Variant"))) { && (strEq(name, "Limit") || strEq(name, "Feature") || strEq(name, "Variant") || strEq(name, "Mapping"))) { PLOGD("ignoring %s specified outside of a Type", name); return; } else if (strEq(name, "Limit")) { err = addLimit(attrs); } else if (strEq(name, "Feature")) { err = addFeature(attrs); } else if (strEq(name, "Mapping")) { err = addMapping(attrs); } else if (strEq(name, "Variant") && section != SECTION_VARIANT) { err = limitVariants(attrs); mState->enterSection(err == OK ? SECTION_VARIANT : SECTION_UNKNOWN); Loading Loading @@ -981,7 +985,9 @@ MediaCodecsXmlParser::Impl::State::enterMediaCodec( TypeMap::iterator typeIt; if (codecIt == mData->mCodecMap.end()) { // New codec name if (updating) { return { NAME_NOT_FOUND, "MediaCodec: cannot update non-existing codec" }; std::string msg = "MediaCodec: cannot update non-existing codec: "; msg = msg + name; return { NAME_NOT_FOUND, msg }; } // Create a new codec in mCodecMap codecIt = mData->mCodecMap.insert(Codec(name, CodecProperties())).first; Loading @@ -994,19 +1000,25 @@ MediaCodecsXmlParser::Impl::State::enterMediaCodec( codecIt->second.order = mData->mCodecMap.size(); } else { // Existing codec name if (!updating) { return { ALREADY_EXISTS, "MediaCodec: cannot add existing codec" }; std::string msg = "MediaCodec: cannot add existing codec: "; msg = msg + name; return { ALREADY_EXISTS, msg }; } if (type != nullptr) { typeIt = codecIt->second.typeMap.find(type); if (typeIt == codecIt->second.typeMap.end()) { return { NAME_NOT_FOUND, "MediaCodec: cannot update non-existing type for codec" }; std::string msg = "MediaCodec: cannot update non-existing type for codec: "; msg = msg + name; return { NAME_NOT_FOUND, msg }; } } else { // This should happen only when the codec has at most one type. typeIt = codecIt->second.typeMap.begin(); if (typeIt == codecIt->second.typeMap.end() || codecIt->second.typeMap.size() != 1) { return { BAD_VALUE, "MediaCodec: cannot update codec without type specified" }; std::string msg = "MediaCodec: cannot update codec without type specified: "; msg = msg + name; return { BAD_VALUE, msg }; } } } Loading Loading @@ -1386,6 +1398,53 @@ status_t MediaCodecsXmlParser::Impl::Parser::addFeature(const char **attrs) { return OK; } status_t MediaCodecsXmlParser::Impl::Parser::addMapping(const char **attrs) { CHECK(mState->inType()); size_t i = 0; const char *a_name = nullptr; const char *a_value = nullptr; const char *a_kind = nullptr; while (attrs[i] != nullptr) { CHECK((i & 1) == 0); if (attrs[i + 1] == nullptr) { PLOGD("Mapping: attribute '%s' is null", attrs[i]); return BAD_VALUE; } if (strEq(attrs[i], "name")) { a_name = attrs[++i]; } else if (strEq(attrs[i], "kind")) { a_kind = attrs[++i]; } else if (strEq(attrs[i], "value")) { a_value = attrs[++i]; } else { PLOGD("Mapping: ignoring unrecognized attribute '%s'", attrs[i]); ++i; } ++i; } // Every mapping must have all 3 fields if (a_name == nullptr) { PLOGD("Mapping with no 'name' attribute"); return BAD_VALUE; } if (a_kind == nullptr) { PLOGD("Mapping with no 'kind' attribute"); return BAD_VALUE; } if (a_value == nullptr) { PLOGD("Mapping with no 'value' attribute"); return BAD_VALUE; } mState->addDetail(std::string("mapping-") + a_kind + "-" + a_name, a_value); return OK; } status_t MediaCodecsXmlParser::Impl::Parser::addAlias(const char **attrs) { CHECK(mState->inCodec()); size_t i = 0; Loading media/libstagefright/xmlparser/api/current.txt +11 −0 Original line number Diff line number Diff line Loading @@ -65,6 +65,16 @@ package media.codecs { method public void set_default(String); } public class Mapping { ctor public Mapping(); method public String getKind(); method public String getName(); method public String getValue(); method public void setKind(String); method public void setName(String); method public void setValue(String); } public class MediaCodec { ctor public MediaCodec(); method public java.util.List<media.codecs.Alias> getAlias_optional(); Loading @@ -73,6 +83,7 @@ package media.codecs { method public String getEnabled(); method public java.util.List<media.codecs.Feature> getFeature_optional(); method public java.util.List<media.codecs.Limit> getLimit_optional(); method public java.util.List<media.codecs.Mapping> getMapping_optional(); method public String getName(); method public java.util.List<media.codecs.Quirk> getQuirk_optional(); method public String getRank(); Loading media/libstagefright/xmlparser/media_codecs.xsd +6 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,7 @@ <xs:element name="Alias" type="Alias" minOccurs="0" maxOccurs="unbounded"/> <xs:element name="Limit" type="Limit" minOccurs="0" maxOccurs="unbounded"/> <xs:element name="Feature" type="Feature" minOccurs="0" maxOccurs="unbounded"/> <xs:element name="Mapping" type="Mapping" minOccurs="0" maxOccurs="unbounded"/> <xs:element name="Variant" type="Variant" minOccurs="0" maxOccurs="unbounded"/> </xs:choice> <xs:attribute name="name" type="xs:string"/> Loading Loading @@ -122,6 +123,11 @@ <xs:attribute name="enabled" type="xs:string"/> <xs:attribute name="update" type="xs:string"/> </xs:complexType> <xs:complexType name="Mapping"> <xs:attribute name="name" type="xs:string"/> <xs:attribute name="kind" type="xs:string"/> <xs:attribute name="value" type="xs:string"/> </xs:complexType> <xs:complexType name="Include"> <xs:attribute name="href" type="xs:string"/> </xs:complexType> Loading media/libstagefright/xmlparser/test/XMLParserTest.cpp +18 −0 Original line number Diff line number Diff line Loading @@ -127,6 +127,18 @@ void XMLParseTest::setUpDatabase() { setCodecProperties("test8.encoder", true, 8, {}, {}, {}, "audio/opus", {pair<string, string>("max-limit1", "limit1Max")}, {}, ""); setCodecProperties("test9.encoder", true, 9, {}, {}, {}, "video/avc", { pair<string, string>("mapping-sure-before", "after"), }, {}, ""); setCodecProperties("test10.encoder", true, 10, {}, {}, {}, "video/hevc", { pair<string, string>("mapping-fire-from", "to"), }, {}, ""); setRoleProperties("audio_decoder.mp3", false, 1, "audio/mpeg", "test1.decoder", {pair<string, string>("attribute::disabled", "present"), pair<string, string>("rank", "4")}); Loading Loading @@ -162,6 +174,12 @@ void XMLParseTest::setUpDatabase() { setRoleProperties("audio_encoder.opus", true, 8, "audio/opus", "test8.encoder", {pair<string, string>("max-limit1", "limit1Max")}); setRoleProperties("video_encoder.avc", true, 9, "video/avc", "test9.encoder", {pair<string, string>("mapping-sure-before", "after")}); setRoleProperties("video_encoder.hevc", true, 10, "video/hevc", "test10.encoder", { pair<string, string>("mapping-fire-from", "to")}); setServiceAttribute( {pair<string, string>("domain-telephony", "0"), pair<string, string>("domain-tv", "0"), pair<string, string>("setting2", "0"), pair<string, string>("variant-variant1", "0")}); Loading media/libstagefright/xmlparser/test/testdata/media_codecs_unit_test.xml +7 −0 Original line number Diff line number Diff line Loading @@ -76,5 +76,12 @@ <MediaCodec name="test8.encoder" type="audio/opus"> <Limit name="limit1" max="limit1Max" /> </MediaCodec> <!-- entry for testing Mapping --> <MediaCodec name="test9.encoder" type="video/avc" > <Mapping kind="sure" name="before" value="after"/> </MediaCodec> <MediaCodec name="test10.encoder" type="video/hevc" > <Mapping kind="fire" name="from" value="to"/> </MediaCodec> </Encoders> </Included> Loading
media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp +65 −6 Original line number Diff line number Diff line Loading @@ -346,6 +346,7 @@ struct MediaCodecsXmlParser::Impl { status_t addAlias(const char **attrs); status_t addFeature(const char **attrs); status_t addLimit(const char **attrs); status_t addMapping(const char **attrs); status_t addQuirk(const char **attrs, const char *prefix = nullptr); status_t addSetting(const char **attrs, const char *prefix = nullptr); status_t enterMediaCodec(const char **attrs, bool encoder); Loading Loading @@ -428,7 +429,7 @@ status_t MediaCodecsXmlParser::Impl::parseXmlFilesInSearchDirs( if (findFileInDirs(searchDirs, fileName, &path)) { err = parseXmlPath(path); } else { ALOGD("Cannot find %s", path.c_str()); ALOGD("Cannot find %s in search path", fileName.c_str()); } res = combineStatus(res, err); } Loading Loading @@ -741,13 +742,16 @@ void MediaCodecsXmlParser::Impl::Parser::startElementHandler( { // ignore limits and features specified outside of type if (!mState->inType() && (strEq(name, "Limit") || strEq(name, "Feature") || strEq(name, "Variant"))) { && (strEq(name, "Limit") || strEq(name, "Feature") || strEq(name, "Variant") || strEq(name, "Mapping"))) { PLOGD("ignoring %s specified outside of a Type", name); return; } else if (strEq(name, "Limit")) { err = addLimit(attrs); } else if (strEq(name, "Feature")) { err = addFeature(attrs); } else if (strEq(name, "Mapping")) { err = addMapping(attrs); } else if (strEq(name, "Variant") && section != SECTION_VARIANT) { err = limitVariants(attrs); mState->enterSection(err == OK ? SECTION_VARIANT : SECTION_UNKNOWN); Loading Loading @@ -981,7 +985,9 @@ MediaCodecsXmlParser::Impl::State::enterMediaCodec( TypeMap::iterator typeIt; if (codecIt == mData->mCodecMap.end()) { // New codec name if (updating) { return { NAME_NOT_FOUND, "MediaCodec: cannot update non-existing codec" }; std::string msg = "MediaCodec: cannot update non-existing codec: "; msg = msg + name; return { NAME_NOT_FOUND, msg }; } // Create a new codec in mCodecMap codecIt = mData->mCodecMap.insert(Codec(name, CodecProperties())).first; Loading @@ -994,19 +1000,25 @@ MediaCodecsXmlParser::Impl::State::enterMediaCodec( codecIt->second.order = mData->mCodecMap.size(); } else { // Existing codec name if (!updating) { return { ALREADY_EXISTS, "MediaCodec: cannot add existing codec" }; std::string msg = "MediaCodec: cannot add existing codec: "; msg = msg + name; return { ALREADY_EXISTS, msg }; } if (type != nullptr) { typeIt = codecIt->second.typeMap.find(type); if (typeIt == codecIt->second.typeMap.end()) { return { NAME_NOT_FOUND, "MediaCodec: cannot update non-existing type for codec" }; std::string msg = "MediaCodec: cannot update non-existing type for codec: "; msg = msg + name; return { NAME_NOT_FOUND, msg }; } } else { // This should happen only when the codec has at most one type. typeIt = codecIt->second.typeMap.begin(); if (typeIt == codecIt->second.typeMap.end() || codecIt->second.typeMap.size() != 1) { return { BAD_VALUE, "MediaCodec: cannot update codec without type specified" }; std::string msg = "MediaCodec: cannot update codec without type specified: "; msg = msg + name; return { BAD_VALUE, msg }; } } } Loading Loading @@ -1386,6 +1398,53 @@ status_t MediaCodecsXmlParser::Impl::Parser::addFeature(const char **attrs) { return OK; } status_t MediaCodecsXmlParser::Impl::Parser::addMapping(const char **attrs) { CHECK(mState->inType()); size_t i = 0; const char *a_name = nullptr; const char *a_value = nullptr; const char *a_kind = nullptr; while (attrs[i] != nullptr) { CHECK((i & 1) == 0); if (attrs[i + 1] == nullptr) { PLOGD("Mapping: attribute '%s' is null", attrs[i]); return BAD_VALUE; } if (strEq(attrs[i], "name")) { a_name = attrs[++i]; } else if (strEq(attrs[i], "kind")) { a_kind = attrs[++i]; } else if (strEq(attrs[i], "value")) { a_value = attrs[++i]; } else { PLOGD("Mapping: ignoring unrecognized attribute '%s'", attrs[i]); ++i; } ++i; } // Every mapping must have all 3 fields if (a_name == nullptr) { PLOGD("Mapping with no 'name' attribute"); return BAD_VALUE; } if (a_kind == nullptr) { PLOGD("Mapping with no 'kind' attribute"); return BAD_VALUE; } if (a_value == nullptr) { PLOGD("Mapping with no 'value' attribute"); return BAD_VALUE; } mState->addDetail(std::string("mapping-") + a_kind + "-" + a_name, a_value); return OK; } status_t MediaCodecsXmlParser::Impl::Parser::addAlias(const char **attrs) { CHECK(mState->inCodec()); size_t i = 0; Loading
media/libstagefright/xmlparser/api/current.txt +11 −0 Original line number Diff line number Diff line Loading @@ -65,6 +65,16 @@ package media.codecs { method public void set_default(String); } public class Mapping { ctor public Mapping(); method public String getKind(); method public String getName(); method public String getValue(); method public void setKind(String); method public void setName(String); method public void setValue(String); } public class MediaCodec { ctor public MediaCodec(); method public java.util.List<media.codecs.Alias> getAlias_optional(); Loading @@ -73,6 +83,7 @@ package media.codecs { method public String getEnabled(); method public java.util.List<media.codecs.Feature> getFeature_optional(); method public java.util.List<media.codecs.Limit> getLimit_optional(); method public java.util.List<media.codecs.Mapping> getMapping_optional(); method public String getName(); method public java.util.List<media.codecs.Quirk> getQuirk_optional(); method public String getRank(); Loading
media/libstagefright/xmlparser/media_codecs.xsd +6 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,7 @@ <xs:element name="Alias" type="Alias" minOccurs="0" maxOccurs="unbounded"/> <xs:element name="Limit" type="Limit" minOccurs="0" maxOccurs="unbounded"/> <xs:element name="Feature" type="Feature" minOccurs="0" maxOccurs="unbounded"/> <xs:element name="Mapping" type="Mapping" minOccurs="0" maxOccurs="unbounded"/> <xs:element name="Variant" type="Variant" minOccurs="0" maxOccurs="unbounded"/> </xs:choice> <xs:attribute name="name" type="xs:string"/> Loading Loading @@ -122,6 +123,11 @@ <xs:attribute name="enabled" type="xs:string"/> <xs:attribute name="update" type="xs:string"/> </xs:complexType> <xs:complexType name="Mapping"> <xs:attribute name="name" type="xs:string"/> <xs:attribute name="kind" type="xs:string"/> <xs:attribute name="value" type="xs:string"/> </xs:complexType> <xs:complexType name="Include"> <xs:attribute name="href" type="xs:string"/> </xs:complexType> Loading
media/libstagefright/xmlparser/test/XMLParserTest.cpp +18 −0 Original line number Diff line number Diff line Loading @@ -127,6 +127,18 @@ void XMLParseTest::setUpDatabase() { setCodecProperties("test8.encoder", true, 8, {}, {}, {}, "audio/opus", {pair<string, string>("max-limit1", "limit1Max")}, {}, ""); setCodecProperties("test9.encoder", true, 9, {}, {}, {}, "video/avc", { pair<string, string>("mapping-sure-before", "after"), }, {}, ""); setCodecProperties("test10.encoder", true, 10, {}, {}, {}, "video/hevc", { pair<string, string>("mapping-fire-from", "to"), }, {}, ""); setRoleProperties("audio_decoder.mp3", false, 1, "audio/mpeg", "test1.decoder", {pair<string, string>("attribute::disabled", "present"), pair<string, string>("rank", "4")}); Loading Loading @@ -162,6 +174,12 @@ void XMLParseTest::setUpDatabase() { setRoleProperties("audio_encoder.opus", true, 8, "audio/opus", "test8.encoder", {pair<string, string>("max-limit1", "limit1Max")}); setRoleProperties("video_encoder.avc", true, 9, "video/avc", "test9.encoder", {pair<string, string>("mapping-sure-before", "after")}); setRoleProperties("video_encoder.hevc", true, 10, "video/hevc", "test10.encoder", { pair<string, string>("mapping-fire-from", "to")}); setServiceAttribute( {pair<string, string>("domain-telephony", "0"), pair<string, string>("domain-tv", "0"), pair<string, string>("setting2", "0"), pair<string, string>("variant-variant1", "0")}); Loading
media/libstagefright/xmlparser/test/testdata/media_codecs_unit_test.xml +7 −0 Original line number Diff line number Diff line Loading @@ -76,5 +76,12 @@ <MediaCodec name="test8.encoder" type="audio/opus"> <Limit name="limit1" max="limit1Max" /> </MediaCodec> <!-- entry for testing Mapping --> <MediaCodec name="test9.encoder" type="video/avc" > <Mapping kind="sure" name="before" value="after"/> </MediaCodec> <MediaCodec name="test10.encoder" type="video/hevc" > <Mapping kind="fire" name="from" value="to"/> </MediaCodec> </Encoders> </Included>