Loading media/libmediaformatshaper/CodecProperties.cpp +62 −9 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <utils/Log.h> #include <string> #include <stdlib.h> #include <media/formatshaper/CodecProperties.h> Loading Loading @@ -63,17 +64,12 @@ void CodecProperties::setFeatureValue(std::string key, int32_t value) { ALOGD("setFeatureValue(%s,%d)", key.c_str(), value); mFeatures.insert({key, value}); if (!strcmp(key.c_str(), "vq-minimum-quality")) { setSupportedMinimumQuality(value); } else if (!strcmp(key.c_str(), "vq-supports-qp")) { // key from prototyping if (!strcmp(key.c_str(), "qp-bounds")) { // official key setSupportsQp(1); } else if (!strcmp(key.c_str(), "qp-bounds")) { // official key } else if (!strcmp(key.c_str(), "vq-supports-qp")) { // key from prototyping setSupportsQp(1); } else if (!strcmp(key.c_str(), "vq-target-qpmax")) { setTargetQpMax(value); } else if (!strcmp(key.c_str(), "vq-target-bppx100")) { double bpp = value / 100.0; setBpp(bpp); } else if (!strcmp(key.c_str(), "vq-minimum-quality")) { setSupportedMinimumQuality(1); } } Loading @@ -90,6 +86,63 @@ bool CodecProperties::getFeatureValue(std::string key, int32_t *valuep) { return false; } // Tuning values (which differ from Features) // this is where we set up things like target bitrates and QP ranges // NB the tuning values arrive as a string, allowing us to convert it into an appropriate // format (int, float, ranges, other combinations) // void CodecProperties::setTuningValue(std::string key, std::string value) { ALOGD("setTuningValue(%s,%s)", key.c_str(), value.c_str()); mTunings.insert({key, value}); bool legal = false; // NB: old school strtol() because std::stoi() throws exceptions if (!strcmp(key.c_str(), "vq-target-qpmax")) { const char *p = value.c_str(); char *q; int32_t iValue = strtol(p, &q, 0); if (q != p) { setTargetQpMax(iValue); legal = true; } } else if (!strcmp(key.c_str(), "vq-target-bpp")) { const char *p = value.c_str(); char *q; double bpp = strtod(p, &q); if (q != p) { setBpp(bpp); legal = true; } } else if (!strcmp(key.c_str(), "vq-target-bppx100")) { const char *p = value.c_str(); char *q; int32_t iValue = strtol(p, &q, 0); if (q != p) { double bpp = iValue / 100.0; setBpp(bpp); legal = true; } } else { legal = true; } if (!legal) { ALOGW("setTuningValue() unable to apply tuning '%s' with value '%s'", key.c_str(), value.c_str()); } return; } bool CodecProperties::getTuningValue(std::string key, std::string &value) { ALOGV("getTuningValue(%s)", key.c_str()); auto mapped = mFeatures.find(key); if (mapped != mFeatures.end()) { value = mapped->second; return true; } return false; } std::string CodecProperties::getMapping(std::string key, std::string kind) { ALOGV("getMapping(key %s, kind %s )", key.c_str(), kind.c_str()); Loading media/libmediaformatshaper/CodecSeeding.cpp +40 −25 Original line number Diff line number Diff line Loading @@ -26,56 +26,63 @@ namespace android { namespace mediaformatshaper { /* * a block of pre-loads; things the library seeds into the codecproperties based * a block of pre-loaded tunings for codecs. * * things the library seeds into the codecproperties based * on the mediaType. * XXX: parsing from a file is likely better than embedding in code. */ typedef struct { bool overrideable; const char *key; int32_t value; } preloadFeature_t; const char *value; } preloadTuning_t; typedef struct { const char *mediaType; preloadFeature_t *features; } preloadProperties_t; preloadTuning_t *features; } preloadTunings_t; /* * 240 = 2.4 bits per pixel-per-second == 5mbps@1080, 2.3mbps@720p, which is about where * we want our initial floor for now. */ static preloadFeature_t featuresAvc[] = { {"vq-target-bppx100", 240}, {nullptr, 0} static preloadTuning_t featuresAvc[] = { {true, "vq-target-bpp", "2.45"}, {true, "vq-target-qpmax", "41"}, {true, nullptr, 0} }; static preloadFeature_t featuresHevc[] = { {"vq-target-bppx100", 240}, {nullptr, 0} static preloadTuning_t featuresHevc[] = { {true, "vq-target-bpp", "2.30"}, {true, "vq-target-qpmax", "42"}, // nop, since hevc codecs don't declare qp support {true, nullptr, 0} }; static preloadFeature_t featuresGenericVideo[] = { {"vq-target-bppx100", 240}, {nullptr, 0} static preloadTuning_t featuresGenericVideo[] = { {true, "vq-target-bpp", "2.40"}, {true, nullptr, 0} }; static preloadProperties_t preloadProperties[] = { static preloadTunings_t preloadTunings[] = { { "video/avc", featuresAvc}, { "video/hevc", &featuresHevc[0]}, // wildcard for any video format not already captured { "video/*", &featuresGenericVideo[0]}, { nullptr, nullptr} }; void CodecProperties::Seed() { ALOGV("Seed: for codec %s, mediatype %s", mName.c_str(), mMediaType.c_str()); void CodecProperties::addMediaDefaults(bool overrideable) { ALOGD("Seed: codec %s, mediatype %s, overrideable %d", mName.c_str(), mMediaType.c_str(), overrideable); // load me up with initial configuration data int count = 0; for (int i = 0; ; i++) { preloadProperties_t *p = &preloadProperties[i]; preloadTunings_t *p = &preloadTunings[i]; if (p->mediaType == nullptr) { break; } Loading @@ -100,11 +107,14 @@ void CodecProperties::Seed() { // walk through, filling things if (p->features != nullptr) { for (int j=0;; j++) { preloadFeature_t *q = &p->features[j]; preloadTuning_t *q = &p->features[j]; if (q->key == nullptr) { break; } setFeatureValue(q->key, q->value); if (q->overrideable != overrideable) { continue; } setTuningValue(q->key, q->value); count++; } break; Loading @@ -113,13 +123,18 @@ void CodecProperties::Seed() { ALOGV("loaded %d preset values", count); } // a chance, as we register the codec and accept no further updates, to // override any poor configuration that arrived from the device's XML files. // a chance, as we create the codec to inject any default behaviors we want. // XXX: consider whether we need pre/post or just post. it affects what can be // overridden by way of the codec XML // void CodecProperties::Seed() { ALOGV("Seed: for codec %s, mediatype %s", mName.c_str(), mMediaType.c_str()); addMediaDefaults(true); } void CodecProperties::Finish() { ALOGV("Finish: for codec %s, mediatype %s", mName.c_str(), mMediaType.c_str()); // currently a no-op addMediaDefaults(false); } } // namespace mediaformatshaper Loading media/libmediaformatshaper/FormatShaper.cpp +19 −0 Original line number Diff line number Diff line Loading @@ -99,6 +99,23 @@ int setFeature(shaperHandle_t shaper, const char *feature, int value) { return 0; } int setTuning(shaperHandle_t shaper, const char *tuning, const char *value) { ALOGV("setTuning: tuning %s value %s", tuning, value); CodecProperties *codec = (CodecProperties*) shaper; if (codec == nullptr) { return -1; } // must not yet be registered if (codec->isRegistered()) { return -1; } // save a map of all features codec->setTuningValue(tuning, value); return 0; } /* * The routines that manage finding, creating, and registering the shapers. */ Loading Loading @@ -176,6 +193,8 @@ extern "C" FormatShaperOps_t shaper_ops = { .shapeFormat = shapeFormat, .getMappings = getMappings, .getReverseMappings = getReverseMappings, .setTuning = setTuning, }; } // namespace mediaformatshaper Loading media/libmediaformatshaper/include/media/formatshaper/CodecProperties.h +8 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,10 @@ class CodecProperties { void setFeatureValue(std::string key, int32_t value); bool getFeatureValue(std::string key, int32_t *valuep); // keep a map of all tunings and their parameters void setTuningValue(std::string key, std::string value); bool getTuningValue(std::string key, std::string &value); // does the codec support the Android S minimum quality rules void setSupportedMinimumQuality(int vmaf); int supportedMinimumQuality(); Loading Loading @@ -97,6 +101,10 @@ class CodecProperties { std::map<std::string, std::string> mMappings /*GUARDED_BY(mMappingLock)*/ ; std::map<std::string, int32_t> mFeatures /*GUARDED_BY(mMappingLock)*/ ; std::map<std::string, std::string> mTunings /*GUARDED_BY(mMappingLock)*/ ; // Seed() and Finish() use this as the underlying implementation void addMediaDefaults(bool overrideable); bool mIsRegistered = false; Loading media/libmediaformatshaper/include/media/formatshaper/FormatShaper.h +10 −0 Original line number Diff line number Diff line Loading @@ -83,6 +83,12 @@ typedef int (*setMap_t)(shaperHandle_t shaper, const char *kind, const char *fro */ typedef int (*setFeature_t)(shaperHandle_t shaper, const char *feature, int value); /* * establishes that codec "codecName" encoding for "mediaType" supports the indicated * tuning at the indicated value */ typedef int (*setTuning_t)(shaperHandle_t shaper, const char *feature, const char * value); /* * The expectation is that the client will implement a flow similar to the following when * setting up an encoding. Loading Loading @@ -118,6 +124,10 @@ typedef struct FormatShaperOps { shapeFormat_t shapeFormat; getMappings_t getMappings; getMappings_t getReverseMappings; setTuning_t setTuning; // additions happen at the end of the structure } FormatShaperOps_t; // versioninf information Loading Loading
media/libmediaformatshaper/CodecProperties.cpp +62 −9 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <utils/Log.h> #include <string> #include <stdlib.h> #include <media/formatshaper/CodecProperties.h> Loading Loading @@ -63,17 +64,12 @@ void CodecProperties::setFeatureValue(std::string key, int32_t value) { ALOGD("setFeatureValue(%s,%d)", key.c_str(), value); mFeatures.insert({key, value}); if (!strcmp(key.c_str(), "vq-minimum-quality")) { setSupportedMinimumQuality(value); } else if (!strcmp(key.c_str(), "vq-supports-qp")) { // key from prototyping if (!strcmp(key.c_str(), "qp-bounds")) { // official key setSupportsQp(1); } else if (!strcmp(key.c_str(), "qp-bounds")) { // official key } else if (!strcmp(key.c_str(), "vq-supports-qp")) { // key from prototyping setSupportsQp(1); } else if (!strcmp(key.c_str(), "vq-target-qpmax")) { setTargetQpMax(value); } else if (!strcmp(key.c_str(), "vq-target-bppx100")) { double bpp = value / 100.0; setBpp(bpp); } else if (!strcmp(key.c_str(), "vq-minimum-quality")) { setSupportedMinimumQuality(1); } } Loading @@ -90,6 +86,63 @@ bool CodecProperties::getFeatureValue(std::string key, int32_t *valuep) { return false; } // Tuning values (which differ from Features) // this is where we set up things like target bitrates and QP ranges // NB the tuning values arrive as a string, allowing us to convert it into an appropriate // format (int, float, ranges, other combinations) // void CodecProperties::setTuningValue(std::string key, std::string value) { ALOGD("setTuningValue(%s,%s)", key.c_str(), value.c_str()); mTunings.insert({key, value}); bool legal = false; // NB: old school strtol() because std::stoi() throws exceptions if (!strcmp(key.c_str(), "vq-target-qpmax")) { const char *p = value.c_str(); char *q; int32_t iValue = strtol(p, &q, 0); if (q != p) { setTargetQpMax(iValue); legal = true; } } else if (!strcmp(key.c_str(), "vq-target-bpp")) { const char *p = value.c_str(); char *q; double bpp = strtod(p, &q); if (q != p) { setBpp(bpp); legal = true; } } else if (!strcmp(key.c_str(), "vq-target-bppx100")) { const char *p = value.c_str(); char *q; int32_t iValue = strtol(p, &q, 0); if (q != p) { double bpp = iValue / 100.0; setBpp(bpp); legal = true; } } else { legal = true; } if (!legal) { ALOGW("setTuningValue() unable to apply tuning '%s' with value '%s'", key.c_str(), value.c_str()); } return; } bool CodecProperties::getTuningValue(std::string key, std::string &value) { ALOGV("getTuningValue(%s)", key.c_str()); auto mapped = mFeatures.find(key); if (mapped != mFeatures.end()) { value = mapped->second; return true; } return false; } std::string CodecProperties::getMapping(std::string key, std::string kind) { ALOGV("getMapping(key %s, kind %s )", key.c_str(), kind.c_str()); Loading
media/libmediaformatshaper/CodecSeeding.cpp +40 −25 Original line number Diff line number Diff line Loading @@ -26,56 +26,63 @@ namespace android { namespace mediaformatshaper { /* * a block of pre-loads; things the library seeds into the codecproperties based * a block of pre-loaded tunings for codecs. * * things the library seeds into the codecproperties based * on the mediaType. * XXX: parsing from a file is likely better than embedding in code. */ typedef struct { bool overrideable; const char *key; int32_t value; } preloadFeature_t; const char *value; } preloadTuning_t; typedef struct { const char *mediaType; preloadFeature_t *features; } preloadProperties_t; preloadTuning_t *features; } preloadTunings_t; /* * 240 = 2.4 bits per pixel-per-second == 5mbps@1080, 2.3mbps@720p, which is about where * we want our initial floor for now. */ static preloadFeature_t featuresAvc[] = { {"vq-target-bppx100", 240}, {nullptr, 0} static preloadTuning_t featuresAvc[] = { {true, "vq-target-bpp", "2.45"}, {true, "vq-target-qpmax", "41"}, {true, nullptr, 0} }; static preloadFeature_t featuresHevc[] = { {"vq-target-bppx100", 240}, {nullptr, 0} static preloadTuning_t featuresHevc[] = { {true, "vq-target-bpp", "2.30"}, {true, "vq-target-qpmax", "42"}, // nop, since hevc codecs don't declare qp support {true, nullptr, 0} }; static preloadFeature_t featuresGenericVideo[] = { {"vq-target-bppx100", 240}, {nullptr, 0} static preloadTuning_t featuresGenericVideo[] = { {true, "vq-target-bpp", "2.40"}, {true, nullptr, 0} }; static preloadProperties_t preloadProperties[] = { static preloadTunings_t preloadTunings[] = { { "video/avc", featuresAvc}, { "video/hevc", &featuresHevc[0]}, // wildcard for any video format not already captured { "video/*", &featuresGenericVideo[0]}, { nullptr, nullptr} }; void CodecProperties::Seed() { ALOGV("Seed: for codec %s, mediatype %s", mName.c_str(), mMediaType.c_str()); void CodecProperties::addMediaDefaults(bool overrideable) { ALOGD("Seed: codec %s, mediatype %s, overrideable %d", mName.c_str(), mMediaType.c_str(), overrideable); // load me up with initial configuration data int count = 0; for (int i = 0; ; i++) { preloadProperties_t *p = &preloadProperties[i]; preloadTunings_t *p = &preloadTunings[i]; if (p->mediaType == nullptr) { break; } Loading @@ -100,11 +107,14 @@ void CodecProperties::Seed() { // walk through, filling things if (p->features != nullptr) { for (int j=0;; j++) { preloadFeature_t *q = &p->features[j]; preloadTuning_t *q = &p->features[j]; if (q->key == nullptr) { break; } setFeatureValue(q->key, q->value); if (q->overrideable != overrideable) { continue; } setTuningValue(q->key, q->value); count++; } break; Loading @@ -113,13 +123,18 @@ void CodecProperties::Seed() { ALOGV("loaded %d preset values", count); } // a chance, as we register the codec and accept no further updates, to // override any poor configuration that arrived from the device's XML files. // a chance, as we create the codec to inject any default behaviors we want. // XXX: consider whether we need pre/post or just post. it affects what can be // overridden by way of the codec XML // void CodecProperties::Seed() { ALOGV("Seed: for codec %s, mediatype %s", mName.c_str(), mMediaType.c_str()); addMediaDefaults(true); } void CodecProperties::Finish() { ALOGV("Finish: for codec %s, mediatype %s", mName.c_str(), mMediaType.c_str()); // currently a no-op addMediaDefaults(false); } } // namespace mediaformatshaper Loading
media/libmediaformatshaper/FormatShaper.cpp +19 −0 Original line number Diff line number Diff line Loading @@ -99,6 +99,23 @@ int setFeature(shaperHandle_t shaper, const char *feature, int value) { return 0; } int setTuning(shaperHandle_t shaper, const char *tuning, const char *value) { ALOGV("setTuning: tuning %s value %s", tuning, value); CodecProperties *codec = (CodecProperties*) shaper; if (codec == nullptr) { return -1; } // must not yet be registered if (codec->isRegistered()) { return -1; } // save a map of all features codec->setTuningValue(tuning, value); return 0; } /* * The routines that manage finding, creating, and registering the shapers. */ Loading Loading @@ -176,6 +193,8 @@ extern "C" FormatShaperOps_t shaper_ops = { .shapeFormat = shapeFormat, .getMappings = getMappings, .getReverseMappings = getReverseMappings, .setTuning = setTuning, }; } // namespace mediaformatshaper Loading
media/libmediaformatshaper/include/media/formatshaper/CodecProperties.h +8 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,10 @@ class CodecProperties { void setFeatureValue(std::string key, int32_t value); bool getFeatureValue(std::string key, int32_t *valuep); // keep a map of all tunings and their parameters void setTuningValue(std::string key, std::string value); bool getTuningValue(std::string key, std::string &value); // does the codec support the Android S minimum quality rules void setSupportedMinimumQuality(int vmaf); int supportedMinimumQuality(); Loading Loading @@ -97,6 +101,10 @@ class CodecProperties { std::map<std::string, std::string> mMappings /*GUARDED_BY(mMappingLock)*/ ; std::map<std::string, int32_t> mFeatures /*GUARDED_BY(mMappingLock)*/ ; std::map<std::string, std::string> mTunings /*GUARDED_BY(mMappingLock)*/ ; // Seed() and Finish() use this as the underlying implementation void addMediaDefaults(bool overrideable); bool mIsRegistered = false; Loading
media/libmediaformatshaper/include/media/formatshaper/FormatShaper.h +10 −0 Original line number Diff line number Diff line Loading @@ -83,6 +83,12 @@ typedef int (*setMap_t)(shaperHandle_t shaper, const char *kind, const char *fro */ typedef int (*setFeature_t)(shaperHandle_t shaper, const char *feature, int value); /* * establishes that codec "codecName" encoding for "mediaType" supports the indicated * tuning at the indicated value */ typedef int (*setTuning_t)(shaperHandle_t shaper, const char *feature, const char * value); /* * The expectation is that the client will implement a flow similar to the following when * setting up an encoding. Loading Loading @@ -118,6 +124,10 @@ typedef struct FormatShaperOps { shapeFormat_t shapeFormat; getMappings_t getMappings; getMappings_t getReverseMappings; setTuning_t setTuning; // additions happen at the end of the structure } FormatShaperOps_t; // versioninf information Loading