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

Commit a5a2d67d authored by Girish's avatar Girish
Browse files

resourcemanager: subclassify codecs into HW or SW

As part of refactoring the resource manager and the resources,
this change does the subclassification of codecs into
hardware of software.
Since, there is no change in the functionality or addition
or modifications of ResourceManagerService binder APIs,
this change is unflagged.

Bug: 289097671
Test: atest android.media.misc.cts.ResourceManagerTest
      atest android.media.misc.cts.ResourceManagerMultiTest
      /data/nativetest64/ResourceManagerService_test/ResourceManagerService_test
      /data/nativetest64/ResourceObserverService_test/ResourceObserverService_test
Change-Id: Ia5e2607a541ee687b1b8bc0b9e3aeba7edb2a2c8
parent 80ad54f6
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -61,8 +61,9 @@ MediaResource MediaResource::CpuBoostResource() {
}

//static
MediaResource MediaResource::VideoBatteryResource() {
    return MediaResource(Type::kBattery, SubType::kVideoCodec, 1);
MediaResource MediaResource::VideoBatteryResource(bool isHardware) {
    SubType subType = isHardware ? SubType::kHwVideoCodec : SubType::kSwVideoCodec;
    return MediaResource(Type::kBattery, subType, 1);
}

//static
+8 −5
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@ public:
            int64_t instanceCount = 1);
    static MediaResource GraphicMemoryResource(int64_t value);
    static MediaResource CpuBoostResource();
    static MediaResource VideoBatteryResource();
    static MediaResource VideoBatteryResource(bool isHardware = true);
    static MediaResource DrmSessionResource(const std::vector<uint8_t> &id, int64_t value);
};

@@ -61,9 +61,12 @@ inline static const char *asString(MediaResource::Type i, const char *def = "??"
inline static const char *asString(MediaResource::SubType i, const char *def = "??") {
    switch (i) {
        case MediaResource::SubType::kUnspecifiedSubType: return "unspecified";
        case MediaResource::SubType::kAudioCodec:         return "audio-codec";
        case MediaResource::SubType::kVideoCodec:         return "video-codec";
        case MediaResource::SubType::kImageCodec:         return "image-codec";
        case MediaResource::SubType::kHwAudioCodec:       return "hw-audio-codec";
        case MediaResource::SubType::kSwAudioCodec:       return "sw-audio-codec";
        case MediaResource::SubType::kHwVideoCodec:       return "hw-video-codec";
        case MediaResource::SubType::kSwVideoCodec:       return "sw-video-codec";
        case MediaResource::SubType::kHwImageCodec:       return "hw-image-codec";
        case MediaResource::SubType::kSwImageCodec:       return "sw-image-codec";
        default:                                          return def;
    }
}
+26 −16
Original line number Diff line number Diff line
@@ -1017,12 +1017,19 @@ void CodecCallback::onMetricsUpdated(const sp<AMessage> &updatedMetrics) {
    notify->post();
}

static MediaResourceSubType toMediaResourceSubType(MediaCodec::Domain domain) {
static MediaResourceSubType toMediaResourceSubType(bool isHardware, MediaCodec::Domain domain) {
    switch (domain) {
        case MediaCodec::DOMAIN_VIDEO: return MediaResourceSubType::kVideoCodec;
        case MediaCodec::DOMAIN_AUDIO: return MediaResourceSubType::kAudioCodec;
        case MediaCodec::DOMAIN_IMAGE: return MediaResourceSubType::kImageCodec;
        default:                       return MediaResourceSubType::kUnspecifiedSubType;
    case MediaCodec::DOMAIN_VIDEO:
        return isHardware? MediaResourceSubType::kHwVideoCodec :
                           MediaResourceSubType::kSwVideoCodec;
    case MediaCodec::DOMAIN_AUDIO:
        return isHardware? MediaResourceSubType::kHwAudioCodec :
                           MediaResourceSubType::kSwAudioCodec;
    case MediaCodec::DOMAIN_IMAGE:
        return isHardware? MediaResourceSubType::kHwImageCodec :
                           MediaResourceSubType::kSwImageCodec;
    default:
        return MediaResourceSubType::kUnspecifiedSubType;
    }
}

@@ -1791,7 +1798,7 @@ void MediaCodec::statsBufferSent(int64_t presentationUs, const sp<MediaCodecBuff

    if (mBatteryChecker != nullptr) {
        mBatteryChecker->onCodecActivity([this] () {
            mResourceManagerProxy->addResource(MediaResource::VideoBatteryResource());
            mResourceManagerProxy->addResource(MediaResource::VideoBatteryResource(mIsHardware));
        });
    }

@@ -1863,7 +1870,7 @@ void MediaCodec::statsBufferReceived(int64_t presentationUs, const sp<MediaCodec

    if (mBatteryChecker != nullptr) {
        mBatteryChecker->onCodecActivity([this] () {
            mResourceManagerProxy->addResource(MediaResource::VideoBatteryResource());
            mResourceManagerProxy->addResource(MediaResource::VideoBatteryResource(mIsHardware));
        });
    }

@@ -2118,13 +2125,16 @@ status_t MediaCodec::init(const AString &name) {
        mBatteryChecker = new BatteryChecker(new AMessage(kWhatCheckBatteryStats, this));
    }

    std::vector<MediaResourceParcel> resources;
    resources.push_back(MediaResource::CodecResource(secureCodec, toMediaResourceSubType(mDomain)));

    // If the ComponentName is not set yet, use the name passed by the user.
    if (mComponentName.empty()) {
        mIsHardware = !MediaCodecList::isSoftwareCodec(name);
        mResourceManagerProxy->setCodecName(name.c_str());
    }

    std::vector<MediaResourceParcel> resources;
    resources.push_back(MediaResource::CodecResource(secureCodec,
                                                     toMediaResourceSubType(mIsHardware, mDomain)));

    for (int i = 0; i <= kMaxRetry; ++i) {
        if (i > 0) {
            // Don't try to reclaim resource for the first time.
@@ -2368,7 +2378,7 @@ status_t MediaCodec::configure(
    status_t err;
    std::vector<MediaResourceParcel> resources;
    resources.push_back(MediaResource::CodecResource(mFlags & kFlagIsSecure,
            toMediaResourceSubType(mDomain)));
            toMediaResourceSubType(mIsHardware, mDomain)));
    if (mDomain == DOMAIN_VIDEO || mDomain == DOMAIN_IMAGE) {
        // Don't know the buffer size at this point, but it's fine to use 1 because
        // the reclaimResource call doesn't consider the requester's buffer size for now.
@@ -2973,7 +2983,7 @@ status_t MediaCodec::start() {
    status_t err;
    std::vector<MediaResourceParcel> resources;
    resources.push_back(MediaResource::CodecResource(mFlags & kFlagIsSecure,
            toMediaResourceSubType(mDomain)));
            toMediaResourceSubType(mIsHardware, mDomain)));
    if (mDomain == DOMAIN_VIDEO || mDomain == DOMAIN_IMAGE) {
        // Don't know the buffer size at this point, but it's fine to use 1 because
        // the reclaimResource call doesn't consider the requester's buffer size for now.
@@ -3729,9 +3739,8 @@ MediaCodec::DequeueOutputResult MediaCodec::handleDequeueOutputBuffer(


inline void MediaCodec::initClientConfigParcel(ClientConfigParcel& clientConfig) {
    clientConfig.codecType = toMediaResourceSubType(mDomain);
    clientConfig.codecType = toMediaResourceSubType(mIsHardware, mDomain);
    clientConfig.isEncoder = mFlags & kFlagIsEncoder;
    clientConfig.isHardware = !MediaCodecList::isSoftwareCodec(mComponentName);
    clientConfig.width = mWidth;
    clientConfig.height = mHeight;
    clientConfig.timeStamp = systemTime(SYSTEM_TIME_MONOTONIC) / 1000LL;
@@ -3960,6 +3969,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
                    CHECK(msg->findString("componentName", &mComponentName));

                    if (mComponentName.c_str()) {
                        mIsHardware = !MediaCodecList::isSoftwareCodec(mComponentName);
                        mediametrics_setCString(mMetricsHandle, kCodecCodec,
                                                mComponentName.c_str());
                        // Update the codec name.
@@ -3987,7 +3997,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
                                          MediaCodecList::isSoftwareCodec(mComponentName) ? 0 : 1);

                    mResourceManagerProxy->addResource(MediaResource::CodecResource(
                            mFlags & kFlagIsSecure, toMediaResourceSubType(mDomain)));
                            mFlags & kFlagIsSecure, toMediaResourceSubType(mIsHardware, mDomain)));

                    postPendingRepliesAndDeferredMessages("kWhatComponentAllocated");
                    break;
@@ -5506,7 +5516,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
            if (mBatteryChecker != nullptr) {
                mBatteryChecker->onCheckBatteryTimer(msg, [this] () {
                    mResourceManagerProxy->removeResource(
                            MediaResource::VideoBatteryResource());
                            MediaResource::VideoBatteryResource(mIsHardware));
                });
            }
            break;
+1 −0
Original line number Diff line number Diff line
@@ -720,6 +720,7 @@ private:

    // An unique ID for the codec - Used by the metrics.
    uint64_t mCodecId = 0;
    bool     mIsHardware = false;

    std::function<sp<CodecBase>(const AString &, const char *)> mGetCodecBase;
    std::function<status_t(const AString &, sp<MediaCodecInfo> *)> mGetCodecInfo;
+47 −54
Original line number Diff line number Diff line
@@ -46,9 +46,12 @@ using stats::media_metrics::\

inline const char* getCodecType(MediaResourceSubType codecType) {
    switch (codecType) {
        case MediaResourceSubType::kAudioCodec:         return "Audio";
        case MediaResourceSubType::kVideoCodec:         return "Video";
        case MediaResourceSubType::kImageCodec:         return "Image";
        case MediaResourceSubType::kHwAudioCodec:       return "Hw Audio";
        case MediaResourceSubType::kSwAudioCodec:       return "Sw Audio";
        case MediaResourceSubType::kHwVideoCodec:       return "Hw Video";
        case MediaResourceSubType::kSwVideoCodec:       return "Sw Video";
        case MediaResourceSubType::kHwImageCodec:       return "Hw Image";
        case MediaResourceSubType::kSwImageCodec:       return "Sw Image";
        case MediaResourceSubType::kUnspecifiedSubType:
        default:
                                                        return "Unspecified";
@@ -56,40 +59,30 @@ inline const char* getCodecType(MediaResourceSubType codecType) {
    return "Unspecified";
}

static CodecBucket getCodecBucket(bool isHardware,
                                  bool isEncoder,
                                  MediaResourceSubType codecType) {
    if (isHardware) {
        switch (codecType) {
            case MediaResourceSubType::kAudioCodec:
                if (isEncoder) return HwAudioEncoder;
                return HwAudioDecoder;
            case MediaResourceSubType::kVideoCodec:
                if (isEncoder) return HwVideoEncoder;
                return HwVideoDecoder;
            case MediaResourceSubType::kImageCodec:
                if (isEncoder) return HwImageEncoder;
                return HwImageDecoder;
            case MediaResourceSubType::kUnspecifiedSubType:
            default:
                return CodecBucketUnspecified;
inline bool isHardwareCodec(MediaResourceSubType codecType) {
    return (codecType == MediaResourceSubType::kHwAudioCodec ||
            codecType == MediaResourceSubType::kHwVideoCodec ||
            codecType == MediaResourceSubType::kHwImageCodec);
}
    } else {

static CodecBucket getCodecBucket(bool isEncoder, MediaResourceSubType codecType) {
    switch (codecType) {
            case MediaResourceSubType::kAudioCodec:
                if (isEncoder) return SwAudioEncoder;
                return SwAudioDecoder;
            case MediaResourceSubType::kVideoCodec:
                if (isEncoder) return SwVideoEncoder;
                return SwVideoDecoder;
            case MediaResourceSubType::kImageCodec:
                if (isEncoder) return SwImageEncoder;
                return SwImageDecoder;
    case MediaResourceSubType::kHwAudioCodec:
        return isEncoder? HwAudioEncoder : HwAudioDecoder;
    case MediaResourceSubType::kSwAudioCodec:
        return isEncoder? SwAudioEncoder : SwAudioDecoder;
    case MediaResourceSubType::kHwVideoCodec:
        return isEncoder? HwVideoEncoder : HwVideoDecoder;
    case MediaResourceSubType::kSwVideoCodec:
        return isEncoder? SwVideoEncoder : SwVideoDecoder;
    case MediaResourceSubType::kHwImageCodec:
        return isEncoder? HwImageEncoder : HwImageDecoder;
    case MediaResourceSubType::kSwImageCodec:
        return isEncoder? SwImageEncoder : SwImageDecoder;
    case MediaResourceSubType::kUnspecifiedSubType:
    default:
        return CodecBucketUnspecified;
    }
    }

    return CodecBucketUnspecified;
}
@@ -179,8 +172,10 @@ void ResourceManagerMetrics::notifyClientConfigChanged(const ClientConfigParcel&
    std::scoped_lock lock(mLock);
    ClientConfigMap::iterator entry = mClientConfigMap.find(clientConfig.clientInfo.id);
    if (entry != mClientConfigMap.end() &&
        (clientConfig.codecType == MediaResourceSubType::kVideoCodec ||
        clientConfig.codecType == MediaResourceSubType::kImageCodec)) {
        (clientConfig.codecType == MediaResourceSubType::kHwVideoCodec ||
         clientConfig.codecType == MediaResourceSubType::kSwVideoCodec ||
         clientConfig.codecType == MediaResourceSubType::kHwImageCodec ||
         clientConfig.codecType == MediaResourceSubType::kSwImageCodec)) {
        int pid = clientConfig.clientInfo.pid;
        // Update the pixel count for this process
        updatePixelCount(pid, clientConfig.width * (long)clientConfig.height,
@@ -201,13 +196,13 @@ void ResourceManagerMetrics::notifyClientStarted(const ClientConfigParcel& clien
    mClientConfigMap[clientConfig.clientInfo.id] = clientConfig;

    // Update the concurrent codec count for this process.
    CodecBucket codecBucket = getCodecBucket(clientConfig.isHardware,
                                             clientConfig.isEncoder,
                                             clientConfig.codecType);
    CodecBucket codecBucket = getCodecBucket(clientConfig.isEncoder, clientConfig.codecType);
    increaseConcurrentCodecs(pid, codecBucket);

    if (clientConfig.codecType == MediaResourceSubType::kVideoCodec ||
        clientConfig.codecType == MediaResourceSubType::kImageCodec) {
    if (clientConfig.codecType == MediaResourceSubType::kHwVideoCodec ||
        clientConfig.codecType == MediaResourceSubType::kSwVideoCodec ||
        clientConfig.codecType == MediaResourceSubType::kHwImageCodec ||
        clientConfig.codecType == MediaResourceSubType::kSwImageCodec) {
        // Update the pixel count for this process
        increasePixelCount(pid, clientConfig.width * (long)clientConfig.height);
    }
@@ -236,7 +231,7 @@ void ResourceManagerMetrics::notifyClientStarted(const ClientConfigParcel& clien
         clientConfig.clientInfo.name.c_str(),
         static_cast<int32_t>(clientConfig.codecType),
         clientConfig.isEncoder,
         clientConfig.isHardware,
         isHardwareCodec(clientConfig.codecType),
         clientConfig.width, clientConfig.height,
         systemConcurrentCodecs,
         appConcurrentCodecs,
@@ -249,7 +244,7 @@ void ResourceManagerMetrics::notifyClientStarted(const ClientConfigParcel& clien

    ALOGV("%s: Pushed MEDIA_CODEC_STARTED atom: "
          "Process[pid(%d): uid(%d)] "
          "Codec: [%s: %ju] is %s %s %s "
          "Codec: [%s: %ju] is %s %s "
          "Timestamp: %jd "
          "Resolution: %d x %d "
          "ConcurrentCodec[%d]={System: %d App: %d} "
@@ -259,7 +254,6 @@ void ResourceManagerMetrics::notifyClientStarted(const ClientConfigParcel& clien
          pid, clientConfig.clientInfo.uid,
          clientConfig.clientInfo.name.c_str(),
          clientConfig.id,
          clientConfig.isHardware? "hardware" : "software",
          getCodecType(clientConfig.codecType),
          clientConfig.isEncoder? "encoder" : "decoder",
          clientConfig.timeStamp,
@@ -273,13 +267,13 @@ void ResourceManagerMetrics::notifyClientStopped(const ClientConfigParcel& clien
    std::scoped_lock lock(mLock);
    int pid = clientConfig.clientInfo.pid;
    // Update the concurrent codec count for this process.
    CodecBucket codecBucket = getCodecBucket(clientConfig.isHardware,
                                             clientConfig.isEncoder,
                                             clientConfig.codecType);
    CodecBucket codecBucket = getCodecBucket(clientConfig.isEncoder, clientConfig.codecType);
    decreaseConcurrentCodecs(pid, codecBucket);

    if (clientConfig.codecType == MediaResourceSubType::kVideoCodec ||
        clientConfig.codecType == MediaResourceSubType::kImageCodec) {
    if (clientConfig.codecType == MediaResourceSubType::kHwVideoCodec ||
        clientConfig.codecType == MediaResourceSubType::kSwVideoCodec ||
        clientConfig.codecType == MediaResourceSubType::kHwImageCodec ||
        clientConfig.codecType == MediaResourceSubType::kSwImageCodec) {
        // Update the pixel count for this process
        decreasePixelCount(pid, clientConfig.width * (long)clientConfig.height);
    }
@@ -319,7 +313,7 @@ void ResourceManagerMetrics::notifyClientStopped(const ClientConfigParcel& clien
         clientConfig.clientInfo.name.c_str(),
         static_cast<int32_t>(clientConfig.codecType),
         clientConfig.isEncoder,
         clientConfig.isHardware,
         isHardwareCodec(clientConfig.codecType),
         clientConfig.width, clientConfig.height,
         systemConcurrentCodecs,
         appConcurrentCodecs,
@@ -327,7 +321,7 @@ void ResourceManagerMetrics::notifyClientStopped(const ClientConfigParcel& clien
         usageTime);
    ALOGV("%s: Pushed MEDIA_CODEC_STOPPED atom: "
          "Process[pid(%d): uid(%d)] "
          "Codec: [%s: %ju] is %s %s %s "
          "Codec: [%s: %ju] is %s %s "
          "Timestamp: %jd Usage time: %jd "
          "Resolution: %d x %d "
          "ConcurrentCodec[%d]={System: %d App: %d} "
@@ -336,7 +330,6 @@ void ResourceManagerMetrics::notifyClientStopped(const ClientConfigParcel& clien
          pid, clientConfig.clientInfo.uid,
          clientConfig.clientInfo.name.c_str(),
          clientConfig.id,
          clientConfig.isHardware? "hardware" : "software",
          getCodecType(clientConfig.codecType),
          clientConfig.isEncoder? "encoder" : "decoder",
          clientConfig.timeStamp, usageTime,
Loading