Video Quality extensions to Codec XML parser
add <Mapping name="" kind="" value="" /> for video quality work.
Updated unit tests to validate new fields
Bug: 182498739
Test: atest XMLParserTest
Test: videoquality testing
Change-Id: Ifa261cb2ae4730db75ef8c6c1cabc4d6ace42bfb
diff --git a/media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp b/media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp
index dbdb43c..5a9760d 100644
--- a/media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp
+++ b/media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp
@@ -346,6 +346,7 @@
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);
@@ -428,7 +429,7 @@
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);
}
@@ -741,13 +742,16 @@
{
// 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);
@@ -981,7 +985,9 @@
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;
@@ -994,19 +1000,25 @@
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 };
}
}
}
@@ -1386,6 +1398,53 @@
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;
diff --git a/media/libstagefright/xmlparser/api/current.txt b/media/libstagefright/xmlparser/api/current.txt
index 16c8af8..6f55dc0 100644
--- a/media/libstagefright/xmlparser/api/current.txt
+++ b/media/libstagefright/xmlparser/api/current.txt
@@ -65,6 +65,16 @@
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();
@@ -73,6 +83,7 @@
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();
diff --git a/media/libstagefright/xmlparser/media_codecs.xsd b/media/libstagefright/xmlparser/media_codecs.xsd
index 3b5681f..30974f6 100644
--- a/media/libstagefright/xmlparser/media_codecs.xsd
+++ b/media/libstagefright/xmlparser/media_codecs.xsd
@@ -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"/>
@@ -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>
diff --git a/media/libstagefright/xmlparser/test/XMLParserTest.cpp b/media/libstagefright/xmlparser/test/XMLParserTest.cpp
index 9ddd374..c411c8d 100644
--- a/media/libstagefright/xmlparser/test/XMLParserTest.cpp
+++ b/media/libstagefright/xmlparser/test/XMLParserTest.cpp
@@ -127,6 +127,18 @@
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")});
@@ -162,6 +174,12 @@
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")});
diff --git a/media/libstagefright/xmlparser/test/testdata/media_codecs_unit_test.xml b/media/libstagefright/xmlparser/test/testdata/media_codecs_unit_test.xml
index a7299d3..c8913e5 100644
--- a/media/libstagefright/xmlparser/test/testdata/media_codecs_unit_test.xml
+++ b/media/libstagefright/xmlparser/test/testdata/media_codecs_unit_test.xml
@@ -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>