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

Commit 352d72ba authored by Ray Essick's avatar Ray Essick Committed by Automerger Merge Worker
Browse files

Merge "Tuning mediaformatshaper" into sc-dev am: 318dbdf2

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/av/+/14411812

Change-Id: I71dbf3ca768ca26e79d13fc9c11edcb2958ff481
parents f480f4ad 318dbdf2
Loading
Loading
Loading
Loading
+130 −7
Original line number Diff line number Diff line
@@ -53,13 +53,6 @@ void CodecProperties::setSupportedMinimumQuality(int vmaf) {
    mMinimumQuality = vmaf;
}

int CodecProperties::targetQpMax() {
    return mTargetQpMax;
}
void CodecProperties::setTargetQpMax(int qpMax) {
    mTargetQpMax = qpMax;
}

void CodecProperties::setMissingQpBoost(double boost) {
    mMissingQpBoost = boost;
}
@@ -118,6 +111,11 @@ void CodecProperties::setTuningValue(std::string key, std::string value) {
            setTargetQpMax(iValue);
            legal = true;
        }
    } else if (!strncmp(key.c_str(), "vq-target-qpmax-", strlen("vq-target-qpmax-"))) {
            std::string resolution = key.substr(strlen("vq-target-qpmax-"));
            if (qpMaxPoint(resolution, value)) {
                legal = true;
            }
    } else if (!strcmp(key.c_str(), "vq-target-bpp")) {
        const char *p = value.c_str();
        char *q;
@@ -292,6 +290,131 @@ double CodecProperties::getBpp(int32_t width, int32_t height) {
    return mBpp;
}

bool CodecProperties::qpMaxPoint(std::string resolution, std::string value) {

    int32_t width = 0;
    int32_t height = 0;
    int qpMax = INT32_MAX;

    // resolution is "WxH", "W*H" or a standard name like "720p"
    if (resolution == "1080p") {
        width = 1080; height = 1920;
    } else if (resolution == "720p") {
        width = 720; height = 1280;
    } else if (resolution == "540p") {
        width = 540; height = 960;
    } else if (resolution == "480p") {
        width = 480; height = 854;
    } else {
        size_t sep = resolution.find('x');
        if (sep == std::string::npos) {
            sep = resolution.find('*');
        }
        if (sep == std::string::npos) {
            ALOGW("unable to parse resolution: '%s'", resolution.c_str());
            return false;
        }
        std::string w = resolution.substr(0, sep);
        std::string h = resolution.substr(sep+1);

        char *q;
        const char *p = w.c_str();
        width = strtol(p, &q, 0);
        if (q == p) {
                width = -1;
        }
        p = h.c_str();
        height = strtol(p, &q, 0);
        if (q == p) {
                height = -1;
        }
        if (width <= 0 || height <= 0 || width > DIMENSION_LIMIT || height > DIMENSION_LIMIT) {
            ALOGW("unparseable: width, height '%s'", resolution.c_str());
            return false;
        }
    }

    const char *p = value.c_str();
    char *q;
    qpMax = strtol(p, &q, 0);
    if (q == p) {
        ALOGW("unparseable qpmax '%s'", value.c_str());
        return false;
    }

    // convert to our internal 'unspecified' notation
    if (qpMax == -1)
        qpMax = INT32_MAX;

    struct qpmax_point *point = (struct qpmax_point*) malloc(sizeof(*point));
    if (point == nullptr) {
        ALOGW("unable to allocate memory for qpmax point");
        return false;
    }

    point->pixels = width * height;
    point->width = width;
    point->height = height;
    point->qpMax = qpMax;

    if (mQpMaxPoints == nullptr) {
        point->next = nullptr;
        mQpMaxPoints = point;
    } else if (point->pixels < mQpMaxPoints->pixels) {
        // at the front
        point->next = mQpMaxPoints;
        mQpMaxPoints = point;
    } else {
        struct qpmax_point *after = mQpMaxPoints;
        while (after->next) {
            if (point->pixels > after->next->pixels) {
                after = after->next;
                continue;
            }

            // insert before after->next
            point->next = after->next;
            after->next = point;
            break;
        }
        if (after->next == nullptr) {
            // hasn't gone in yet
            point->next = nullptr;
            after->next = point;
        }
    }

    return true;
}

int CodecProperties::targetQpMax(int32_t width, int32_t height) {
    // look in the per-resolution list

    int32_t pixels = width * height;

    if (mQpMaxPoints) {
        struct qpmax_point *point = mQpMaxPoints;
        while (point && point->pixels < pixels) {
            point = point->next;
        }
        if (point) {
            ALOGV("targetQpMax(w=%d,h=%d) returns %d from qpmax_point w=%d h=%d",
                width, height, point->qpMax, point->width, point->height);
            return point->qpMax;
        }
    }

    ALOGV("defaulting to %d qpmax", mTargetQpMax);
    return mTargetQpMax;
}

void CodecProperties::setTargetQpMax(int qpMax) {
    // convert to our internal 'unspecified' notation
    if (qpMax == -1)
        qpMax = INT32_MAX;
    mTargetQpMax = qpMax;
}

std::string CodecProperties::getMapping(std::string key, std::string kind) {
    ALOGV("getMapping(key %s, kind %s )", key.c_str(), kind.c_str());
    //play with mMappings
+14 −1
Original line number Diff line number Diff line
@@ -69,7 +69,7 @@ class CodecProperties {
    // qp max bound used to compensate when SupportedMinimumQuality == 0
    // 0 == let a system default handle it
    void setTargetQpMax(int qpmax);
    int targetQpMax();
    int targetQpMax(int32_t width, int32_t height);

    // target bits-per-pixel (per second) for encoding operations.
    // This is used to calculate a minimum bitrate for any particular resolution.
@@ -123,6 +123,19 @@ class CodecProperties {
    struct bpp_point *mBppPoints = nullptr;
    bool bppPoint(std::string resolution, std::string value);

    // same thing for qpmax -- allow different ones based on resolution
    // allow different target bits-per-pixel based on resolution
    // similar to codec 'performance points'
    // uses 'next largest' (by pixel count) point as minimum bpp
    struct qpmax_point {
        struct qpmax_point *next;
        int32_t pixels;
        int32_t width, height;
        int qpMax;
    };
    struct qpmax_point *mQpMaxPoints = nullptr;
    bool qpMaxPoint(std::string resolution, std::string value);

    std::mutex mMappingLock;
    // XXX figure out why I'm having problems getting compiler to like GUARDED_BY
    std::map<std::string, std::string> mMappings /*GUARDED_BY(mMappingLock)*/ ;
+14 −3
Original line number Diff line number Diff line
@@ -49,28 +49,39 @@ typedef struct {
 */

static preloadTuning_t featuresAvc[] = {
      {true, "vq-target-bpp", "0"},
      {true, "vq-target-bpp-1080p", "1.90"},
      {true, "vq-target-bpp-720p", "2.25"},
      {true, "vq-target-bpp-540p", "2.65"},
      {true, "vq-target-bpp-480p", "3.00"},
      {true, "vq-target-qpmax", "40"},
      {true, "vq-target-qpmax", "-1"},
      {true, "vq-target-qpmax-1080p", "45"},
      {true, "vq-target-qpmax-720p", "43"},
      {true, "vq-target-qpmax-540p", "42"},
      {true, "vq-target-qpmax-480p", "38"},
      {true, "vq-bitrate-phaseout", "1.75"},
      {true, "vq-boost-missing-qp", "0.20"},
      {true, nullptr, 0}
};

static preloadTuning_t featuresHevc[] = {
      {true, "vq-target-bpp", "0"},
      {true, "vq-target-bpp-1080p", "1.50"},
      {true, "vq-target-bpp-720p", "1.80"},
      {true, "vq-target-bpp-540p", "2.10"},
      {true, "vq-target-qpmax", "40"},
      {true, "vq-target-qpmax", "-1"},
      {true, "vq-target-qpmax-1080p", "45"},
      {true, "vq-target-qpmax-720p", "43"},
      {true, "vq-target-qpmax-540p", "42"},
      {true, "vq-target-qpmax-480p", "39"},
      {true, "vq-bitrate-phaseout", "1.75"},
      {true, "vq-boost-missing-qp", "0.20"},
      {true, nullptr, 0}
};

static preloadTuning_t featuresGenericVideo[] = {
      {true, "vq-target-bpp", "2.00"},
        // 0 == off
      {true, "vq-target-bpp", "0"},
      {true, nullptr, 0}
};

+1 −1
Original line number Diff line number Diff line
@@ -115,7 +115,7 @@ int VQApply(CodecProperties *codec, vqOps_t *info, AMediaFormat* inFormat, int f
    bool qpPresent = hasQpMax(inFormat);

    // calculate a target QP value
    int32_t qpmax = codec->targetQpMax();
    int32_t qpmax = codec->targetQpMax(width, height);
    if (!qpPresent) {
        // user didn't, so shaper wins
        if (qpmax != INT32_MAX) {