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

Commit 96939a5e authored by Girish's avatar Girish
Browse files

MediaCodec: convert per frame resources into static count

Bug: 393365529
Test: ccodec_unit_test
      atest CtsMediaMiscTestCases:android.media.misc.cts.ResourceManagerTest
Flag: EXEMPT bugfix
Change-Id: I20b0ee37e8b37c2c744999f7742b0cfe79bacf0e
parent 31d9a1ab
Loading
Loading
Loading
Loading
+114 −0
Original line number Diff line number Diff line
@@ -1220,6 +1220,95 @@ inline MediaResourceType getResourceType(const std::string& resourceName) {
    return MediaResourceType::kUnspecified;
}

/**
 * Get the float/integer value associated with the given key.
 *
 * If no such key is found, it will return false without updating
 * the value.
 */
static bool getValueFor(const sp<AMessage>& msg,
                        const char* key,
                        float* value) {
    if (msg->findFloat(key, value)) {
        return true;
    }

    int32_t intValue = 0;
    if (msg->findInt32(key, &intValue)) {
        *value = (float)intValue;
        return true;
    }

    return false;
}

/*
 * Use operating frame rate for per frame resource calculation as below:
 * - Check if operating-rate is available. If so, use it.
 * - If its encoder and if we have capture-rate, use that as frame rate.
 * - Else, check if frame-rate is available. If so, use it.
 * - Else, use the default value.
 *
 * NOTE: This function is called with format that could be:
 *   - format used to configure the codec
 *   - codec's input format
 *   - codec's output format
 *
 * Some of the key's may not be present in either input or output format or
 * both.
 * For example, "capture-rate", this is currently only used in configure format.
 *
 * For encoders, in rare cases, we would expect "operating-rate" to be set
 * for high-speed capture and it's only used during configuration.
 */
static float getOperatingFrameRate(const sp<AMessage>& format,
                                   float defaultFrameRate,
                                   bool isEncoder) {
    float operatingRate = 0;
    if (getValueFor(format, "operating-rate", &operatingRate)) {
        // Use operating rate to convert per-frame resources into a whole.
        return operatingRate;
    }

    float captureRate = 0;
    if (isEncoder && getValueFor(format, "capture-rate", &captureRate)) {
        // Use capture rate to convert per-frame resources into a whole.
        return captureRate;
    }

    // Otherwise use frame-rate (or fallback to the default framerate passed)
    float frameRate = defaultFrameRate;
    getValueFor(format, "frame-rate", &frameRate);
    return frameRate;
}

/**
 * Convert per frame/input/output resources into static_count
 *
 * TODO: (girishshetty): In the future, change InstanceResourceInfo to hold:
 * - resource type (const, per frame, per input/output)
 * - resource count
 */
std::vector<InstanceResourceInfo> MediaCodec::computeDynamicResources(
        const std::vector<InstanceResourceInfo>& inResources) {
    std::vector<InstanceResourceInfo> dynamicResources;
    for (const InstanceResourceInfo& resource : inResources) {
        // If mStaticCount isn't 0, nothing to be changed because effectively this is a union.
        if (resource.mStaticCount != 0) {
            dynamicResources.push_back(resource);
            continue;
        }
        if (resource.mPerFrameCount != 0) {
            uint64_t staticCount = resource.mPerFrameCount * mFrameRate;
            // We are tracking everything as static count here. So set per frame count to 0.
            dynamicResources.emplace_back(resource.mName, staticCount, 0);
        }
        // TODO: (girishshetty): Add per input/output resource conversion here.
    }

    return dynamicResources;
}

//static
status_t MediaCodec::getGloballyAvailableResources(std::vector<GlobalResourceInfo>& resources) {
    resources.clear();
@@ -2597,6 +2686,14 @@ status_t MediaCodec::configure(

    sp<AMessage> callback = mCallback;

    if (mDomain == DOMAIN_VIDEO) {
        // Use format to compute initial operating frame rate.
        // After the successful configuration (and also possibly when output
        // format change notification), this value will be recalculated.
        bool isEncoder = (flags & CONFIGURE_FLAG_ENCODE);
        mFrameRate = getOperatingFrameRate(format, mFrameRate, isEncoder);
    }

    std::vector<MediaResourceParcel> resources;
    resources.push_back(MediaResource::CodecResource(mFlags & kFlagIsSecure,
            toMediaResourceSubType(mIsHardware, mDomain)));
@@ -4432,6 +4529,12 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
                        Mutexed<std::vector<InstanceResourceInfo>>::Locked resourcesLocked(
                                mRequiredResourceInfo);
                        *resourcesLocked = mCodec->getRequiredSystemResources();
                        // Use input and output formats to get operating frame-rate.
                        bool isEncoder = mFlags & kFlagIsEncoder;
                        mFrameRate = getOperatingFrameRate(mInputFormat, mFrameRate, isEncoder);
                        mFrameRate = getOperatingFrameRate(mOutputFormat, mFrameRate, isEncoder);
                        // Update the dynamic resource usage with the current operating frame-rate.
                        *resourcesLocked = computeDynamicResources(*resourcesLocked);
                    }

                    setState(CONFIGURED);
@@ -6183,6 +6286,15 @@ void MediaCodec::handleOutputFormatChangeIfNeeded(const sp<MediaCodecBuffer> &bu
    }

    updateHdrMetrics(false /* isConfig */);

    if (mDomain == DOMAIN_VIDEO) {
        bool isEncoder = mFlags & kFlagIsEncoder;
        // Since the output format has changed, see if we need to update
        // operating frame-rate.
        mFrameRate = getOperatingFrameRate(mOutputFormat, mFrameRate, isEncoder);
        // TODO: (girishshetty): See if the change in operating frame-rate calls for
        // onRequiredResourcesChanged callback.
    }
}

// always called from the looper thread (and therefore not mutexed)
@@ -7227,6 +7339,8 @@ void MediaCodec::onRequiredResourcesChanged(
        android::media::codec::codec_availability_support()) {
        Mutexed<std::vector<InstanceResourceInfo>>::Locked resourcesLocked(mRequiredResourceInfo);
        *resourcesLocked = resourceInfo;
        // Convert per frame/input/output resources into static_count
        *resourcesLocked = computeDynamicResources(*resourcesLocked);
        canIssueCallback = true;
    }
    // Make sure codec availability feature is on.
+8 −0
Original line number Diff line number Diff line
@@ -381,6 +381,11 @@ private:
                                             uint32_t flags,
                                             status_t* err);

    // Convert all dynamic (non-constant) resource types into
    // constant resource counts.
    std::vector<InstanceResourceInfo> computeDynamicResources(
            const std::vector<InstanceResourceInfo>& resources);

private:
    enum State {
        UNINITIALIZED,
@@ -820,6 +825,9 @@ private:
    // Required resource info for this codec.
    Mutexed<std::vector<InstanceResourceInfo>> mRequiredResourceInfo;

    // Default frame-rate.
    float mFrameRate = 30.0;

    DISALLOW_EVIL_CONSTRUCTORS(MediaCodec);
};