Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d8e0c1f8 authored by Ray Essick's avatar Ray Essick Committed by Android (Google) Code Review
Browse files

Merge "Better tuning hooks for mediaformatshaper" into sc-dev

parents df59bc90 a727ef99
Loading
Loading
Loading
Loading
+62 −9
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include <utils/Log.h>

#include <string>
#include <stdlib.h>

#include <media/formatshaper/CodecProperties.h>

@@ -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);
    }
}

@@ -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());
+40 −25
Original line number Diff line number Diff line
@@ -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;
        }
@@ -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;
@@ -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
+19 −0
Original line number Diff line number Diff line
@@ -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.
 */
@@ -176,6 +193,8 @@ extern "C" FormatShaperOps_t shaper_ops = {
    .shapeFormat = shapeFormat,
    .getMappings = getMappings,
    .getReverseMappings = getReverseMappings,

    .setTuning = setTuning,
};

}  // namespace mediaformatshaper
+8 −0
Original line number Diff line number Diff line
@@ -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();
@@ -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;

+10 −0
Original line number Diff line number Diff line
@@ -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.
@@ -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