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

Commit 4c6398b1 authored by Chong Zhang's avatar Chong Zhang
Browse files

stagefright: explicitly release extractor in StagefrightMetadataRetriever

Extractor dtor on media.extractor side happens asynchronously with the
dtor of StagefrightMetadataRetriever. If the extractor calls back into
the DataSource after mediaserver side released the reference to it, the
binder transaction could get stuck.

Adding an explicity release() and call it before StagefrightMetadataRetriever
continues to destruct the DataSource. Only implement it for MPEG4Extractor
to avoid impacting other extractors at this stage.

Also adding some code to aggressively release the extractor and data
source in HeifDecoderImpl to free up memory.

bug: 65463215

Change-Id: I84c442a1e010dd37a976af5453a353e43f672e22
parent faf18c58
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -401,6 +401,10 @@ bool HeifDecoderImpl::decode(HeifFrameInfo* frameInfo) {
                videoFrame->getFlattenedIccData());
    }
    mFrameDecoded = true;

    // Aggressive clear to avoid holding on to resources
    mRetriever.clear();
    mDataSource.clear();
    return true;
}

+15 −1
Original line number Diff line number Diff line
@@ -38,7 +38,8 @@ enum {
    SETMEDIACAS,
    SETUID,
    NAME,
    GETMETRICS
    GETMETRICS,
    RELEASE,
};

class BpMediaExtractor : public BpInterface<IMediaExtractor> {
@@ -138,6 +139,13 @@ public:
        ALOGV("name NOT IMPLEMENTED");
        return NULL;
    }

    virtual void release() {
        ALOGV("release");
        Parcel data, reply;
        data.writeInterfaceToken(BpMediaExtractor::getInterfaceDescriptor());
        remote()->transact(RELEASE, data, &reply);
    }
};

IMPLEMENT_META_INTERFACE(MediaExtractor, "android.media.IMediaExtractor");
@@ -215,6 +223,12 @@ status_t BnMediaExtractor::onTransact(
            reply->writeInt32(setMediaCas(casToken));
            return OK;
        }
        case RELEASE: {
            ALOGV("release");
            CHECK_INTERFACE(IMediaExtractor, data, reply);
            release();
            return OK;
        }
        default:
            return BBinder::onTransact(code, data, reply, flags);
    }
+2 −0
Original line number Diff line number Diff line
@@ -68,6 +68,8 @@ public:
    virtual void setUID(uid_t uid)  = 0;

    virtual const char * name() = 0;

    virtual void release() = 0;
};


+10 −0
Original line number Diff line number Diff line
@@ -354,6 +354,10 @@ MPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source)
}

MPEG4Extractor::~MPEG4Extractor() {
    release();
}

void MPEG4Extractor::release() {
    Track *track = mFirstTrack;
    while (track) {
        Track *next = track->next;
@@ -375,6 +379,12 @@ MPEG4Extractor::~MPEG4Extractor() {
    for (size_t i = 0; i < mPssh.size(); i++) {
        delete [] mPssh[i].data;
    }
    mPssh.clear();

    if (mDataSource != NULL) {
        mDataSource->close();
        mDataSource.clear();
    }
}

uint32_t MPEG4Extractor::flags() const {
+6 −0
Original line number Diff line number Diff line
@@ -60,6 +60,12 @@ StagefrightMetadataRetriever::StagefrightMetadataRetriever()
StagefrightMetadataRetriever::~StagefrightMetadataRetriever() {
    ALOGV("~StagefrightMetadataRetriever()");
    clearMetadata();
    // Explicitly release extractor before continuing with the destructor,
    // some extractors might need to callback to close off the DataSource
    // and we need to make sure it's still there.
    if (mExtractor != NULL) {
        mExtractor->release();
    }
    if (mSource != NULL) {
        mSource->close();
    }
Loading