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

Commit 0ccdce19 authored by Ray Essick's avatar Ray Essick
Browse files

move MediaCodec metrics processing to looper thread

consolidate to avoid concurrency/mutex problems.

Bug: 256087846
Bug: 245860753
Test: atest CtsMediaV2TestCases
Test: atest CtsMediaCodecTestCases
Merged-In: Ie77f0028cab8091edd97d3a60ad4c80da3092cfe
Merged-In: I56eceb6b12ce14348d3f9f2944968e70c6086aa8
Merged-In: I94b0a2ac029dc0b90a93e9ed844768e9da5259b9
Merged-In: I739248436a4801a4b9a96395f481640f2956cedf
Change-Id: If5269d3efcd7c262020e580fe84fe89261a1af60
parent dab37c25
Loading
Loading
Loading
Loading
+83 −19
Original line number Original line Diff line number Diff line
@@ -40,6 +40,7 @@
#include <media/IResourceManagerService.h>
#include <media/IResourceManagerService.h>
#include <media/MediaCodecBuffer.h>
#include <media/MediaCodecBuffer.h>
#include <media/MediaAnalyticsItem.h>
#include <media/MediaAnalyticsItem.h>
// RBE do i need to add this? #include <media/MediaMetrics.h>         // RBE
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/foundation/AMessage.h>
@@ -546,6 +547,14 @@ MediaCodec::~MediaCodec() {
    mResourceManagerService->removeResource(getId(mResourceManagerClient));
    mResourceManagerService->removeResource(getId(mResourceManagerClient));


    flushAnalyticsItem();
    flushAnalyticsItem();

    // clean up any saved AnalyticsItem stored in the configuration message
    if (mConfigureMsg != nullptr) {
        MediaAnalyticsItem *oldItem = nullptr;
        if (mConfigureMsg->findPointer("metrics", (void**) &oldItem)) {
            delete oldItem;
        }
    }
}
}


void MediaCodec::initAnalyticsItem() {
void MediaCodec::initAnalyticsItem() {
@@ -570,6 +579,8 @@ void MediaCodec::updateAnalyticsItem() {
        return;
        return;
    }
    }


    Mutex::Autolock _lock(mMetricsLock);

    if (mLatencyHist.getCount() != 0 ) {
    if (mLatencyHist.getCount() != 0 ) {
        mAnalyticsItem->setInt64(kCodecLatencyMax, mLatencyHist.getMax());
        mAnalyticsItem->setInt64(kCodecLatencyMax, mLatencyHist.getMax());
        mAnalyticsItem->setInt64(kCodecLatencyMin, mLatencyHist.getMin());
        mAnalyticsItem->setInt64(kCodecLatencyMin, mLatencyHist.getMin());
@@ -632,7 +643,10 @@ void MediaCodec::updateEphemeralAnalytics(MediaAnalyticsItem *item) {
}
}


void MediaCodec::flushAnalyticsItem() {
void MediaCodec::flushAnalyticsItem() {
    // update does its own mutex locking
    updateAnalyticsItem();
    updateAnalyticsItem();

    Mutex::Autolock _lock(mMetricsLock);
    if (mAnalyticsItem != NULL) {
    if (mAnalyticsItem != NULL) {
        // don't log empty records
        // don't log empty records
        if (mAnalyticsItem->count() > 0) {
        if (mAnalyticsItem->count() > 0) {
@@ -1018,16 +1032,22 @@ status_t MediaCodec::configure(
        uint32_t flags) {
        uint32_t flags) {
    sp<AMessage> msg = new AMessage(kWhatConfigure, this);
    sp<AMessage> msg = new AMessage(kWhatConfigure, this);


    if (mAnalyticsItem != NULL) {
    MediaAnalyticsItem *newItem = MediaAnalyticsItem::create(kCodecKeyName);

    if (newItem != NULL) {
        int32_t profile = 0;
        int32_t profile = 0;
        if (format->findInt32("profile", &profile)) {
        if (format->findInt32("profile", &profile)) {
            mAnalyticsItem->setInt32(kCodecProfile, profile);
            newItem->setInt32(kCodecProfile, profile);
        }
        }
        int32_t level = 0;
        int32_t level = 0;
        if (format->findInt32("level", &level)) {
        if (format->findInt32("level", &level)) {
            mAnalyticsItem->setInt32(kCodecLevel, level);
            newItem->setInt32(kCodecLevel, level);
        }
        }
        mAnalyticsItem->setInt32(kCodecEncoder, (flags & CONFIGURE_FLAG_ENCODE) ? 1 : 0);
        newItem->setInt32(kCodecEncoder, (flags & CONFIGURE_FLAG_ENCODE) ? 1 : 0);

        newItem->setCString(kCodecCodec, mInitName.c_str());
        newItem->setCString(kCodecMode, mIsVideo ? kCodecModeVideo : kCodecModeAudio);

    }
    }


    if (mIsVideo) {
    if (mIsVideo) {
@@ -1037,17 +1057,17 @@ status_t MediaCodec::configure(
            mRotationDegrees = 0;
            mRotationDegrees = 0;
        }
        }


        if (mAnalyticsItem != NULL) {
        if (newItem != NULL) {
            mAnalyticsItem->setInt32(kCodecWidth, mVideoWidth);
            newItem->setInt32(kCodecWidth, mVideoWidth);
            mAnalyticsItem->setInt32(kCodecHeight, mVideoHeight);
            newItem->setInt32(kCodecHeight, mVideoHeight);
            mAnalyticsItem->setInt32(kCodecRotation, mRotationDegrees);
            newItem->setInt32(kCodecRotation, mRotationDegrees);
            int32_t maxWidth = 0;
            int32_t maxWidth = 0;
            if (format->findInt32("max-width", &maxWidth)) {
            if (format->findInt32("max-width", &maxWidth)) {
                mAnalyticsItem->setInt32(kCodecMaxWidth, maxWidth);
                newItem->setInt32(kCodecMaxWidth, maxWidth);
            }
            }
            int32_t maxHeight = 0;
            int32_t maxHeight = 0;
            if (format->findInt32("max-height", &maxHeight)) {
            if (format->findInt32("max-height", &maxHeight)) {
                mAnalyticsItem->setInt32(kCodecMaxHeight, maxHeight);
                newItem->setInt32(kCodecMaxHeight, maxHeight);
            }
            }
        }
        }


@@ -1076,6 +1096,15 @@ status_t MediaCodec::configure(
        ALOGW("Crypto or descrambler should be given for secure codec");
        ALOGW("Crypto or descrambler should be given for secure codec");
    }
    }


    // recover space of any previous saved baseline analytics info
    if (mConfigureMsg != nullptr) {
        MediaAnalyticsItem *oldItem = nullptr;
        if (mConfigureMsg->findPointer("metrics", (void **) &oldItem)) {
            delete oldItem;
        }
    }
    msg->setPointer("metrics", newItem);

    // save msg for reset
    // save msg for reset
    mConfigureMsg = msg;
    mConfigureMsg = msg;


@@ -1532,20 +1561,36 @@ status_t MediaCodec::getMetrics(MediaAnalyticsItem * &reply) {


    reply = NULL;
    reply = NULL;


    // shouldn't happen, but be safe
    sp<AMessage> msg = new AMessage(kWhatGetMetrics, this);
    if (mAnalyticsItem == NULL) {
    sp<AMessage> response;
        return UNKNOWN_ERROR;
    status_t err;
    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
        return err;
    }
    }


    // update any in-flight data that's not carried within the record
    CHECK(response->findPointer("metrics", (void **) &reply));
    updateAnalyticsItem();


    // send it back to the caller.
    return OK;
    reply = mAnalyticsItem->dup();
}


    updateEphemeralAnalytics(reply);
// runs on the looper thread (for mutex purposes)
void MediaCodec::onGetMetrics(const sp<AMessage>& msg) {


    return OK;
    MediaAnalyticsItem *results = nullptr;

    sp<AReplyToken> replyID;
    CHECK(msg->senderAwaitsResponse(&replyID));

    // RBE is it always non-null at this point?
    if (mAnalyticsItem != nullptr) {
        updateAnalyticsItem();
        results = mAnalyticsItem->dup();
        updateEphemeralAnalytics(results);
    }

    sp<AMessage> response = new AMessage;
    response->setPointer("metrics", results);
    response->postReply(replyID);
}
}


status_t MediaCodec::getInputBuffers(Vector<sp<MediaCodecBuffer> > *buffers) const {
status_t MediaCodec::getInputBuffers(Vector<sp<MediaCodecBuffer> > *buffers) const {
@@ -2416,6 +2461,13 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
            break;
            break;
        }
        }


        case kWhatGetMetrics:
        {
            onGetMetrics(msg);
            break;
        }


        case kWhatConfigure:
        case kWhatConfigure:
        {
        {
            sp<AReplyToken> replyID;
            sp<AReplyToken> replyID;
@@ -2432,6 +2484,18 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
            sp<AMessage> format;
            sp<AMessage> format;
            CHECK(msg->findMessage("format", &format));
            CHECK(msg->findMessage("format", &format));


            // start with a copy of the passed metrics info for use in this run
            MediaAnalyticsItem *handle;
            CHECK(msg->findPointer("metrics", (void **) &handle));
            if (handle != nullptr) {
                if (mAnalyticsItem != nullptr) {
                    flushAnalyticsItem();
                }
                mAnalyticsItem = handle->dup();
                // and set some additional metrics values
                initAnalyticsItem();
            }

            int32_t push;
            int32_t push;
            if (msg->findInt32("push-blank-buffers-on-shutdown", &push) && push != 0) {
            if (msg->findInt32("push-blank-buffers-on-shutdown", &push) && push != 0) {
                mFlags |= kFlagPushBlankBuffersOnShutdown;
                mFlags |= kFlagPushBlankBuffersOnShutdown;
+3 −0
Original line number Original line Diff line number Diff line
@@ -257,6 +257,7 @@ private:
        kWhatSetCallback                    = 'setC',
        kWhatSetCallback                    = 'setC',
        kWhatSetNotification                = 'setN',
        kWhatSetNotification                = 'setN',
        kWhatDrmReleaseCrypto               = 'rDrm',
        kWhatDrmReleaseCrypto               = 'rDrm',
        kWhatGetMetrics                     = 'getM',
    };
    };


    enum {
    enum {
@@ -321,11 +322,13 @@ private:
    sp<Surface> mSurface;
    sp<Surface> mSurface;
    SoftwareRenderer *mSoftRenderer;
    SoftwareRenderer *mSoftRenderer;


    Mutex mMetricsLock;
    MediaAnalyticsItem *mAnalyticsItem;
    MediaAnalyticsItem *mAnalyticsItem;
    void initAnalyticsItem();
    void initAnalyticsItem();
    void updateAnalyticsItem();
    void updateAnalyticsItem();
    void flushAnalyticsItem();
    void flushAnalyticsItem();
    void updateEphemeralAnalytics(MediaAnalyticsItem *item);
    void updateEphemeralAnalytics(MediaAnalyticsItem *item);
    void onGetMetrics(const sp<AMessage>& msg);


    sp<AMessage> mOutputFormat;
    sp<AMessage> mOutputFormat;
    sp<AMessage> mInputFormat;
    sp<AMessage> mInputFormat;