Loading media/libmediaformatshaper/VQApply.cpp +23 −0 Original line number Diff line number Diff line Loading @@ -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 Loading media/libstagefright/MediaCodec.cpp +84 −0 Original line number Diff line number Diff line Loading @@ -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> Loading @@ -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> Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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) { Loading Loading @@ -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, Loading Loading
media/libmediaformatshaper/VQApply.cpp +23 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
media/libstagefright/MediaCodec.cpp +84 −0 Original line number Diff line number Diff line Loading @@ -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> Loading @@ -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> Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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) { Loading Loading @@ -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, Loading