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

Commit aab76fc0 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Pass the minimum quality enablement across C2 interface" into sc-dev...

Merge "Pass the minimum quality enablement across C2 interface" into sc-dev am: 2779f525 am: 8c30961e

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

Change-Id: I0768d77f2f2105977e8d0e646ad20f3e649d7f66
parents bb4c71e4 8c30961e
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -63,13 +63,36 @@ int VQApply(CodecProperties *codec, vqOps_t *info, AMediaFormat* inFormat, int f
        return 0;
    }

    // only proceed if we're in the handheld category.
    // We embed this information within the codec record when we build up features
    // and pass them in from MediaCodec; it's the easiest place to store it
    //
    // TODO: make a #define for ' _vq_eligible.device' here and in MediaCodec.cpp
    //
    int32_t isVQEligible = 0;
    (void) codec->getFeatureValue("_vq_eligible.device", &isVQEligible);
    ALOGD("minquality:  are we eligible: %d", isVQEligible);
    if (!isVQEligible) {
        ALOGD("minquality: not an eligible device class");
        return 0;
    }

    if (codec->supportedMinimumQuality() > 0) {
        // allow the codec provided minimum quality behavior to work at it
        ALOGD("minquality: codec claims to implement minquality=%d",
              codec->supportedMinimumQuality());

        // tell the underlying codec to do its thing; we won't try to second guess.
        // default to 1, aka S_HANDHELD;
        int32_t qualityTarget = 1;
        (void) codec->getFeatureValue("_quality.target", &qualityTarget);
        AMediaFormat_setInt32(inFormat, "android._encoding-quality-level", qualityTarget);
        return 0;
    }

    // let the codec know that we'll be enforcing the minimum quality standards
    AMediaFormat_setInt32(inFormat, "android._encoding-quality-level", 0);

    //
    // consider any and all tools available
    // -- qp
+84 −0
Original line number Diff line number Diff line
@@ -31,6 +31,8 @@
#include "include/SoftwareRenderer.h"
#include "PlaybackDurationAccumulator.h"

#include <android/binder_manager.h>
#include <android/content/pm/IPackageManagerNative.h>
#include <android/hardware/cas/native/1.0/IDescrambler.h>
#include <android/hardware/media/omx/1.0/IGraphicBufferSource.h>

@@ -40,6 +42,7 @@
#include <android/binder_manager.h>
#include <android/dlext.h>
#include <binder/IMemory.h>
#include <binder/IServiceManager.h>
#include <binder/MemoryDealer.h>
#include <cutils/properties.h>
#include <gui/BufferQueue.h>
@@ -1697,6 +1700,7 @@ status_t MediaCodec::configure(
//

static android::mediaformatshaper::FormatShaperOps_t *sShaperOps = NULL;
static bool sIsHandheld = true;

static bool connectFormatShaper() {
    static std::once_flag sCheckOnce;
@@ -1770,6 +1774,64 @@ static bool connectFormatShaper() {
        ALOGV("connectFormatShaper: loaded libraries: %" PRId64 " us",
              (loading_finished - loading_started)/1000);


        // we also want to know whether this is a handheld device
        // start with assumption that the device is handheld.
        sIsHandheld = true;
        sp<IServiceManager> serviceMgr = defaultServiceManager();
        sp<content::pm::IPackageManagerNative> packageMgr;
        if (serviceMgr.get() != nullptr) {
            sp<IBinder> binder = serviceMgr->waitForService(String16("package_native"));
            packageMgr = interface_cast<content::pm::IPackageManagerNative>(binder);
        }
        // if we didn't get serviceMgr, we'll leave packageMgr as default null
        if (packageMgr != nullptr) {

            // MUST have these
            static const String16 featuresNeeded[] = {
                String16("android.hardware.touchscreen")
            };
            // these must be present to be a handheld
            for (::android::String16 required : featuresNeeded) {
                bool hasFeature = false;
                binder::Status status = packageMgr->hasSystemFeature(required, 0, &hasFeature);
                if (!status.isOk()) {
                    ALOGE("%s: hasSystemFeature failed: %s",
                        __func__, status.exceptionMessage().c_str());
                    continue;
                }
                ALOGV("feature %s says %d", String8(required).c_str(), hasFeature);
                if (!hasFeature) {
                    ALOGV("... which means we are not handheld");
                    sIsHandheld = false;
                    break;
                }
            }

            // MUST NOT have these
            static const String16 featuresDisallowed[] = {
                String16("android.hardware.type.automotive"),
                String16("android.hardware.type.television"),
                String16("android.hardware.type.watch")
            };
            // any of these present -- we aren't a handheld
            for (::android::String16 forbidden : featuresDisallowed) {
                bool hasFeature = false;
                binder::Status status = packageMgr->hasSystemFeature(forbidden, 0, &hasFeature);
                if (!status.isOk()) {
                    ALOGE("%s: hasSystemFeature failed: %s",
                        __func__, status.exceptionMessage().c_str());
                    continue;
                }
                ALOGV("feature %s says %d", String8(forbidden).c_str(), hasFeature);
                if (hasFeature) {
                    ALOGV("... which means we are not handheld");
                    sIsHandheld = false;
                    break;
                }
            }
        }

    });

    return true;
@@ -1848,6 +1910,18 @@ static void loadCodecProperties(mediaformatshaper::shaperHandle_t shaperHandle,
            }
        }
    }

    // we also carry in the codec description whether we are on a handheld device.
    // this info is eventually used by both the Codec and the C2 machinery to inform
    // the underlying codec whether to do any shaping.
    //
    if (sIsHandheld) {
        // set if we are indeed a handheld device (or in future 'any eligible device'
        // missing on devices that aren't eligible for minimum quality enforcement.
        (void)(sShaperOps->setFeature)(shaperHandle, "_vq_eligible.device", 1);
        // strictly speaking, it's a tuning, but those are strings and feature stores int
        (void)(sShaperOps->setFeature)(shaperHandle, "_quality.target", 1 /* S_HANDHELD */);
    }
}

status_t MediaCodec::setupFormatShaper(AString mediaType) {
@@ -1888,6 +1962,16 @@ status_t MediaCodec::setupFormatShaper(AString mediaType) {
// Format Shaping
//      Mapping and Manipulation of encoding parameters
//
//      All of these decisions are pushed into the shaper instead of here within MediaCodec.
//      this includes decisions based on whether the codec implements minimum quality bars
//      itself or needs to be shaped outside of the codec.
//      This keeps all those decisions in one place.
//      It also means that we push some extra decision information (is this a handheld device
//      or one that is otherwise eligible for minimum quality manipulation, which generational
//      quality target is in force, etc).  This allows those values to be cached in the
//      per-codec structures that are done 1 time within a process instead of for each
//      codec instantiation.
//

status_t MediaCodec::shapeMediaFormat(
            const sp<AMessage> &format,