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

Commit e8adebef authored by Wonsik Kim's avatar Wonsik Kim Committed by Automerger Merge Worker
Browse files

Merge "RELAND: "stagefright: MediaCodec::releaseAsync()"" into rvc-dev am:...

Merge "RELAND: "stagefright: MediaCodec::releaseAsync()"" into rvc-dev am: 929c3645 am: 5242549c am: 8d009d9e

Change-Id: Ic54d23306f468552dd8752ff1ca713238b0f6379
parents 1e7f59ce 8d009d9e
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -94,4 +94,12 @@ interface IResourceManagerService {
     *        remove existing override on originalPid if newPid is -1.
     */
    void overridePid(int originalPid, int newPid);

    /**
     * Mark a client for pending removal
     *
     * @param pid pid from which the client's resources will be removed.
     * @param clientId clientId within the pid that will be removed.
     */
    void markClientForPendingRemoval(int pid, long clientId);
}
+71 −1
Original line number Diff line number Diff line
@@ -199,6 +199,7 @@ struct MediaCodec::ResourceManagerServiceProxy : public RefBase {
    void addResource(const MediaResourceParcel &resource);
    void removeResource(const MediaResourceParcel &resource);
    void removeClient();
    void markClientForPendingRemoval();
    bool reclaimResource(const std::vector<MediaResourceParcel> &resources);

private:
@@ -280,6 +281,14 @@ void MediaCodec::ResourceManagerServiceProxy::removeClient() {
    mService->removeClient(mPid, getId(mClient));
}

void MediaCodec::ResourceManagerServiceProxy::markClientForPendingRemoval() {
    Mutex::Autolock _l(mLock);
    if (mService == nullptr) {
        return;
    }
    mService->markClientForPendingRemoval(mPid, getId(mClient));
}

bool MediaCodec::ResourceManagerServiceProxy::reclaimResource(
        const std::vector<MediaResourceParcel> &resources) {
    Mutex::Autolock _l(mLock);
@@ -297,6 +306,33 @@ MediaCodec::BufferInfo::BufferInfo() : mOwnedByClient(false) {}

////////////////////////////////////////////////////////////////////////////////

class MediaCodec::ReleaseSurface {
public:
    ReleaseSurface() {
        BufferQueue::createBufferQueue(&mProducer, &mConsumer);
        mSurface = new Surface(mProducer, false /* controlledByApp */);
        struct ConsumerListener : public BnConsumerListener {
            void onFrameAvailable(const BufferItem&) override {}
            void onBuffersReleased() override {}
            void onSidebandStreamChanged() override {}
        };
        sp<ConsumerListener> listener{new ConsumerListener};
        mConsumer->consumerConnect(listener, false);
        mConsumer->setConsumerName(String8{"MediaCodec.release"});
    }

    const sp<Surface> &getSurface() {
        return mSurface;
    }

private:
    sp<IGraphicBufferProducer> mProducer;
    sp<IGraphicBufferConsumer> mConsumer;
    sp<Surface> mSurface;
};

////////////////////////////////////////////////////////////////////////////////

namespace {

enum {
@@ -1432,7 +1468,13 @@ status_t MediaCodec::reclaim(bool force) {

status_t MediaCodec::release() {
    sp<AMessage> msg = new AMessage(kWhatRelease, this);
    sp<AMessage> response;
    return PostAndAwaitResponse(msg, &response);
}

status_t MediaCodec::releaseAsync() {
    sp<AMessage> msg = new AMessage(kWhatRelease, this);
    msg->setInt32("async", 1);
    sp<AMessage> response;
    return PostAndAwaitResponse(msg, &response);
}
@@ -2600,7 +2642,9 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {

                    mResourceManagerProxy->removeClient();

                    if (mReplyID != nullptr) {
                        (new AMessage)->postReply(mReplyID);
                    }
                    break;
                }

@@ -2987,6 +3031,26 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
                break;
            }

            int32_t async = 0;
            if (msg->findInt32("async", &async) && async) {
                if ((mState ==  CONFIGURED || mState == STARTED || mState == FLUSHED)
                       && mSurface != NULL) {
                    if (!mReleaseSurface) {
                        mReleaseSurface.reset(new ReleaseSurface);
                    }
                    status_t err = connectToSurface(mReleaseSurface->getSurface());
                    ALOGW_IF(err != OK, "error connecting to release surface: err = %d", err);
                    if (err == OK && !(mFlags & kFlagUsesSoftwareRenderer)) {
                        err = mCodec->setSurface(mReleaseSurface->getSurface());
                        ALOGW_IF(err != OK, "error setting release surface: err = %d", err);
                    }
                    if (err == OK) {
                        (void)disconnectFromSurface();
                        mSurface = mReleaseSurface->getSurface();
                    }
                }
            }

            mReplyID = replyID;
            setState(msg->what() == kWhatStop ? STOPPING : RELEASING);

@@ -2999,6 +3063,12 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
                pushBlankBuffersToNativeWindow(mSurface.get());
            }

            if (async) {
                mResourceManagerProxy->markClientForPendingRemoval();
                (new AMessage)->postReply(mReplyID);
                mReplyID = 0;
            }

            break;
        }

+5 −0
Original line number Diff line number Diff line
@@ -139,6 +139,8 @@ struct MediaCodec : public AHandler {
    // object.
    status_t release();

    status_t releaseAsync();

    status_t flush();

    status_t queueInputBuffer(
@@ -509,6 +511,9 @@ private:
                                                 // when low latency is on
    int64_t mInputBufferCounter;  // number of input buffers queued since last reset/flush

    class ReleaseSurface;
    std::unique_ptr<ReleaseSurface> mReleaseSurface;

    sp<BatteryChecker> mBatteryChecker;

    void statsBufferSent(int64_t presentationUs);
+42 −1
Original line number Diff line number Diff line
@@ -114,6 +114,7 @@ static ResourceInfo& getResourceInfoForEdit(
        info.uid = uid;
        info.clientId = clientId;
        info.client = client;
        info.pendingRemoval = false;

        index = infos.add(clientId, info);
    }
@@ -648,6 +649,36 @@ Status ResourceManagerService::overridePid(
    return Status::ok();
}

Status ResourceManagerService::markClientForPendingRemoval(int32_t pid, int64_t clientId) {
    String8 log = String8::format(
            "markClientForPendingRemoval(pid %d, clientId %lld)",
            pid, (long long) clientId);
    mServiceLog->add(log);

    Mutex::Autolock lock(mLock);
    if (!mProcessInfo->isValidPid(pid)) {
        ALOGE("Rejected markClientForPendingRemoval call with invalid pid.");
        return Status::fromServiceSpecificError(BAD_VALUE);
    }
    ssize_t index = mMap.indexOfKey(pid);
    if (index < 0) {
        ALOGV("markClientForPendingRemoval: didn't find pid %d for clientId %lld",
              pid, (long long)clientId);
        return Status::ok();
    }
    ResourceInfos &infos = mMap.editValueAt(index);

    index = infos.indexOfKey(clientId);
    if (index < 0) {
        ALOGV("markClientForPendingRemoval: didn't find clientId %lld", (long long) clientId);
        return Status::ok();
    }

    ResourceInfo &info = infos.editValueAt(index);
    info.pendingRemoval = true;
    return Status::ok();
}

bool ResourceManagerService::getPriority_l(int pid, int* priority) {
    int newPid = pid;

@@ -693,6 +724,12 @@ bool ResourceManagerService::getLowestPriorityBiggestClient_l(
    int lowestPriorityPid;
    int lowestPriority;
    int callingPriority;

    // Before looking into other processes, check if we have clients marked for
    // pending removal in the same process.
    if (getBiggestClient_l(callingPid, type, client, true /* pendingRemovalOnly */)) {
        return true;
    }
    if (!getPriority_l(callingPid, &callingPriority)) {
        ALOGE("getLowestPriorityBiggestClient_l: can't get process priority for pid %d",
                callingPid);
@@ -761,7 +798,8 @@ bool ResourceManagerService::isCallingPriorityHigher_l(int callingPid, int pid)
}

bool ResourceManagerService::getBiggestClient_l(
        int pid, MediaResource::Type type, std::shared_ptr<IResourceManagerClient> *client) {
        int pid, MediaResource::Type type, std::shared_ptr<IResourceManagerClient> *client,
        bool pendingRemovalOnly) {
    ssize_t index = mMap.indexOfKey(pid);
    if (index < 0) {
        ALOGE("getBiggestClient_l: can't find resource info for pid %d", pid);
@@ -773,6 +811,9 @@ bool ResourceManagerService::getBiggestClient_l(
    const ResourceInfos &infos = mMap.valueAt(index);
    for (size_t i = 0; i < infos.size(); ++i) {
        const ResourceList &resources = infos[i].resources;
        if (pendingRemovalOnly && !infos[i].pendingRemoval) {
            continue;
        }
        for (auto it = resources.begin(); it != resources.end(); it++) {
            const MediaResourceParcel &resource = it->second;
            if (resource.type == type) {
+7 −1
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@
#ifndef ANDROID_MEDIA_RESOURCEMANAGERSERVICE_H
#define ANDROID_MEDIA_RESOURCEMANAGERSERVICE_H

#include <map>

#include <aidl/android/media/BnResourceManagerService.h>
#include <arpa/inet.h>
#include <media/MediaResource.h>
@@ -50,6 +52,7 @@ struct ResourceInfo {
    std::shared_ptr<IResourceManagerClient> client;
    sp<DeathNotifier> deathNotifier;
    ResourceList resources;
    bool pendingRemoval{false};
};

// TODO: convert these to std::map
@@ -122,6 +125,8 @@ public:
            int originalPid,
            int newPid) override;

    Status markClientForPendingRemoval(int32_t pid, int64_t clientId) override;

    Status removeResource(int pid, int64_t clientId, bool checkValid);

private:
@@ -146,7 +151,8 @@ private:
    // Gets the client who owns biggest piece of specified resource type from pid.
    // Returns false if failed. The client will remain unchanged if failed.
    bool getBiggestClient_l(int pid, MediaResource::Type type,
            std::shared_ptr<IResourceManagerClient> *client);
            std::shared_ptr<IResourceManagerClient> *client,
            bool pendingRemovalOnly = false);

    bool isCallingPriorityHigher_l(int callingPid, int pid);

Loading