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

Commit 67999b02 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Modify ACodec to allow using Treble."

parents 03682cda 8a21c019
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -41,6 +41,14 @@ class MemoryDealer;
struct DescribeColorFormat2Params;
struct DataConverter;

// Treble shared memory
namespace hidl { namespace memory { namespace V1_0 {
struct IAllocator;
struct IMemory;
}}};
typedef hidl::memory::V1_0::IAllocator TAllocator;
typedef hidl::memory::V1_0::IMemory TMemory;

struct ACodec : public AHierarchicalStateMachine, public CodecBase {
    ACodec();

@@ -86,6 +94,12 @@ struct ACodec : public AHierarchicalStateMachine, public CodecBase {

    static status_t getOMXChannelMapping(size_t numChannels, OMX_AUDIO_CHANNELTYPE map[]);

    // Read the flag from "media.use_treble_omx", save it locally, and return
    // it.
    bool updateTrebleFlag();
    // Return the saved flag.
    bool getTrebleFlag() const;

protected:
    virtual ~ACodec();

@@ -218,6 +232,8 @@ private:
    sp<IOMX> mOMX;
    sp<IOMXNode> mOMXNode;
    int32_t mNodeGeneration;
    bool mTrebleFlag;
    sp<TAllocator> mAllocator[2];
    sp<MemoryDealer> mDealer[2];

    bool mUsingNativeWindow;
+1 −1
Original line number Diff line number Diff line
@@ -166,7 +166,7 @@ OMXBuffer& OMXBuffer::operator=(OMXBuffer&& source) {
    mMem = std::move(source.mMem);
    mGraphicBuffer = std::move(source.mGraphicBuffer);
    mNativeHandle = std::move(source.mNativeHandle);
    mHidlMemory = source.mHidlMemory; // TODO(b/34093434): Use move when available
    mHidlMemory = std::move(source.mHidlMemory);
    return *this;
}

+152 −28
Original line number Diff line number Diff line
@@ -46,6 +46,8 @@
#include <media/hardware/HardwareAPI.h>
#include <media/OMXBuffer.h>

#include <hidlmemory/mapping.h>

#include <OMX_AudioExt.h>
#include <OMX_VideoExt.h>
#include <OMX_Component.h>
@@ -59,6 +61,10 @@
#include "include/SharedMemoryBuffer.h"
#include "omx/OMXUtils.h"

#include <android/hidl/memory/1.0/IAllocator.h>
#include <android/hidl/memory/1.0/IMemory.h>
#include "omx/hal/1.0/utils/WOmxNode.h"

namespace android {

using binder::Status;
@@ -282,7 +288,9 @@ private:

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

struct ACodec::DeathNotifier : public IBinder::DeathRecipient {
struct ACodec::DeathNotifier :
        public IBinder::DeathRecipient,
        public ::android::hardware::hidl_death_recipient {
    explicit DeathNotifier(const sp<AMessage> &notify)
        : mNotify(notify) {
    }
@@ -291,6 +299,12 @@ struct ACodec::DeathNotifier : public IBinder::DeathRecipient {
        mNotify->post();
    }

    virtual void serviceDied(
            uint64_t /* cookie */,
            const wp<::android::hidl::base::V1_0::IBase>& /* who */) {
        mNotify->post();
    }

protected:
    virtual ~DeathNotifier() {}

@@ -560,6 +574,8 @@ ACodec::ACodec()
    memset(&mLastNativeWindowCrop, 0, sizeof(mLastNativeWindowCrop));

    changeState(mUninitializedState);

    updateTrebleFlag();
}

ACodec::~ACodec() {
@@ -811,7 +827,11 @@ status_t ACodec::setPortMode(int32_t portIndex, IOMX::PortMode mode) {
status_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);

    if (getTrebleFlag()) {
        CHECK(mAllocator[portIndex] == NULL);
    } else {
        CHECK(mDealer[portIndex] == NULL);
    }
    CHECK(mBuffers[portIndex].isEmpty());

    status_t err;
@@ -874,14 +894,26 @@ status_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
                return NO_MEMORY;
            }

            size_t totalSize = def.nBufferCountActual * (alignedSize + alignedConvSize);
            if (mode != IOMX::kPortModePresetSecureBuffer) {
                if (getTrebleFlag()) {
                    mAllocator[portIndex] = TAllocator::getService("ashmem");
                    if (mAllocator[portIndex] == nullptr) {
                        ALOGE("hidl allocator on port %d is null",
                                (int)portIndex);
                        return NO_MEMORY;
                    }
                } else {
                    size_t totalSize = def.nBufferCountActual *
                            (alignedSize + alignedConvSize);
                    mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
                }
            }

            const sp<AMessage> &format =
                    portIndex == kPortIndexInput ? mInputFormat : mOutputFormat;
            for (OMX_U32 i = 0; i < def.nBufferCountActual && err == OK; ++i) {
                hidl_memory hidlMemToken;
                sp<TMemory> hidlMem;
                sp<IMemory> mem;

                BufferInfo info;
@@ -902,31 +934,87 @@ status_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
                            ? new SecureBuffer(format, ptr, bufSize)
                            : new SecureBuffer(format, native_handle, bufSize);
                    info.mCodecData = info.mData;
                } else {
                    if (getTrebleFlag()) {
                        bool success;
                        auto transStatus = mAllocator[portIndex]->allocate(
                                bufSize,
                                [&success, &hidlMemToken](
                                        bool s,
                                        hidl_memory const& m) {
                                    success = s;
                                    hidlMemToken = m;
                                });

                        if (!transStatus.isOk()) {
                            ALOGE("hidl's AshmemAllocator failed at the "
                                    "transport: %s",
                                    transStatus.description().c_str());
                            return NO_MEMORY;
                        }
                        if (!success) {
                            return NO_MEMORY;
                        }
                        hidlMem = mapMemory(hidlMemToken);

                        err = mOMXNode->useBuffer(
                                portIndex, hidlMemToken, &info.mBufferID);
                    } else {
                        mem = mDealer[portIndex]->allocate(bufSize);
                        if (mem == NULL || mem->pointer() == NULL) {
                            return NO_MEMORY;
                        }

                    err = mOMXNode->useBuffer(portIndex, mem, &info.mBufferID);
                        err = mOMXNode->useBuffer(
                                portIndex, mem, &info.mBufferID);
                    }

                    if (mode == IOMX::kPortModeDynamicANWBuffer) {
                        ((VideoNativeMetadata *)mem->pointer())->nFenceFd = -1;
                        VideoNativeMetadata* metaData = (VideoNativeMetadata*)(
                                getTrebleFlag() ?
                                (void*)hidlMem->getPointer() : mem->pointer());
                        metaData->nFenceFd = -1;
                    }

                    info.mCodecData = new SharedMemoryBuffer(format, mem);
                    if (getTrebleFlag()) {
                        info.mCodecData = new SharedMemoryBuffer(
                                format, hidlMem);
                        info.mCodecRef = hidlMem;
                    } else {
                        info.mCodecData = new SharedMemoryBuffer(
                                format, mem);
                        info.mCodecRef = mem;
                    }

                    // if we require conversion, allocate conversion buffer for client use;
                    // otherwise, reuse codec buffer
                    if (mConverter[portIndex] != NULL) {
                        CHECK_GT(conversionBufferSize, (size_t)0);
                        mem = mDealer[portIndex]->allocate(conversionBufferSize);
                        if (getTrebleFlag()) {
                            bool success;
                            mAllocator[portIndex]->allocate(
                                    conversionBufferSize,
                                    [&success, &hidlMemToken](
                                            bool s,
                                            hidl_memory const& m) {
                                        success = s;
                                        hidlMemToken = m;
                                    });
                            if (!success) {
                                return NO_MEMORY;
                            }
                            hidlMem = mapMemory(hidlMemToken);
                            info.mData = new SharedMemoryBuffer(format, hidlMem);
                            info.mMemRef = hidlMem;
                        } else {
                            mem = mDealer[portIndex]->allocate(
                                    conversionBufferSize);
                            if (mem == NULL|| mem->pointer() == NULL) {
                                return NO_MEMORY;
                            }
                            info.mData = new SharedMemoryBuffer(format, mem);
                            info.mMemRef = mem;
                        }
                    } else {
                        info.mData = info.mCodecData;
                        info.mMemRef = info.mCodecRef;
@@ -1458,8 +1546,11 @@ status_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
        }
    }

    // clear mDealer even on an error
    if (getTrebleFlag()) {
        mAllocator[portIndex].clear();
    } else {
        mDealer[portIndex].clear();
    }
    return err;
}

@@ -6041,9 +6132,17 @@ void ACodec::UninitializedState::stateEntered() {

    if (mDeathNotifier != NULL) {
        if (mCodec->mOMXNode != NULL) {
            if (mCodec->getTrebleFlag()) {
                auto tOmxNode =
                        (static_cast<
                        ::android::hardware::media::omx::V1_0::utils::
                        LWOmxNode*>(mCodec->mOMXNode.get()))->mBase;
                tOmxNode->unlinkToDeath(mDeathNotifier);
            } else {
                sp<IBinder> binder = IInterface::asBinder(mCodec->mOMXNode);
                binder->unlinkToDeath(mDeathNotifier);
            }
        }
        mDeathNotifier.clear();
    }

@@ -6130,7 +6229,8 @@ bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
    CHECK(mCodec->mOMXNode == NULL);

    OMXClient client;
    if (client.connect() != OK) {
    if ((mCodec->updateTrebleFlag() ?
            client.connectTreble() : client.connect()) != OK) {
        mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
        return false;
    }
@@ -6202,11 +6302,19 @@ bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
    }

    mDeathNotifier = new DeathNotifier(notify);
    if (mCodec->getTrebleFlag()) {
        auto tOmxNode = (static_cast<::android::hardware::media::omx::V1_0::
                utils::LWOmxNode*>(omxNode.get()))->mBase;
        if (!tOmxNode->linkToDeath(mDeathNotifier, 0)) {
            mDeathNotifier.clear();
        }
    } else {
        if (IInterface::asBinder(omxNode)->linkToDeath(mDeathNotifier) != OK) {
            // This was a local binder, if it dies so do we, we won't care
            // about any notifications in the afterlife.
            mDeathNotifier.clear();
        }
    }

    notify = new AMessage(kWhatOMXMessageList, mCodec);
    notify->setInt32("generation", ++mCodec->mNodeGeneration);
@@ -7180,9 +7288,13 @@ bool ACodec::OutputPortSettingsChangedState::onOMXEvent(
                    ALOGE("disabled port should be empty, but has %zu buffers",
                            mCodec->mBuffers[kPortIndexOutput].size());
                    err = FAILED_TRANSACTION;
                } else {
                    if (mCodec->getTrebleFlag()) {
                        mCodec->mAllocator[kPortIndexOutput].clear();
                    } else {
                        mCodec->mDealer[kPortIndexOutput].clear();
                    }
                }

                if (err == OK) {
                    err = mCodec->mOMXNode->sendCommand(
@@ -7564,7 +7676,8 @@ status_t ACodec::queryCapabilities(
    }

    OMXClient client;
    status_t err = client.connect();
    status_t err = getTrebleFlag() ?
            client.connectTreble() : client.connect();
    if (err != OK) {
        return err;
    }
@@ -7780,4 +7893,15 @@ status_t ACodec::getOMXChannelMapping(size_t numChannels, OMX_AUDIO_CHANNELTYPE
    return OK;
}

bool ACodec::updateTrebleFlag() {
    mTrebleFlag = bool(property_get_bool("debug.treble_omx", 0));
    ALOGV("updateTrebleFlag() returns %s",
            mTrebleFlag ? "true" : "false");
    return mTrebleFlag;
}

bool ACodec::getTrebleFlag() const {
    return mTrebleFlag;
}

}  // namespace android
+2 −0
Original line number Diff line number Diff line
@@ -114,6 +114,8 @@ LOCAL_SHARED_LIBRARIES += \
        libdl \
        libRScpp \
        libhidlbase \
        libhidlmemory \
        android.hidl.memory@1.0 \
        android.hardware.media.omx@1.0 \
        android.hardware.media.omx@1.0-utils \

+5 −0
Original line number Diff line number Diff line
@@ -34,6 +34,11 @@ SharedMemoryBuffer::SharedMemoryBuffer(const sp<AMessage> &format, const sp<IMem
      mMemory(mem) {
}

SharedMemoryBuffer::SharedMemoryBuffer(const sp<AMessage> &format, const sp<TMemory> &mem)
    : MediaCodecBuffer(format, new ABuffer(mem->getPointer(), mem->getSize())),
      mTMemory(mem) {
}

SecureBuffer::SecureBuffer(const sp<AMessage> &format, const void *ptr, size_t size)
    : MediaCodecBuffer(format, new ABuffer(nullptr, size)),
      mPointer(ptr) {
Loading