Loading include/media/stagefright/ACodec.h +16 −0 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading @@ -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(); Loading Loading @@ -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; Loading media/libmedia/OMXBuffer.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -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; } Loading media/libstagefright/ACodec.cpp +152 −28 Original line number Diff line number Diff line Loading @@ -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> Loading @@ -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; Loading Loading @@ -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> ¬ify) : mNotify(notify) { } Loading @@ -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() {} Loading Loading @@ -560,6 +574,8 @@ ACodec::ACodec() memset(&mLastNativeWindowCrop, 0, sizeof(mLastNativeWindowCrop)); changeState(mUninitializedState); updateTrebleFlag(); } ACodec::~ACodec() { Loading Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; } Loading Loading @@ -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(); } Loading Loading @@ -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; } Loading Loading @@ -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); Loading Loading @@ -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( Loading Loading @@ -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; } Loading Loading @@ -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 media/libstagefright/Android.mk +2 −0 Original line number Diff line number Diff line Loading @@ -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 \ Loading media/libstagefright/BufferImpl.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
include/media/stagefright/ACodec.h +16 −0 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading @@ -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(); Loading Loading @@ -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; Loading
media/libmedia/OMXBuffer.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -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; } Loading
media/libstagefright/ACodec.cpp +152 −28 Original line number Diff line number Diff line Loading @@ -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> Loading @@ -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; Loading Loading @@ -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> ¬ify) : mNotify(notify) { } Loading @@ -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() {} Loading Loading @@ -560,6 +574,8 @@ ACodec::ACodec() memset(&mLastNativeWindowCrop, 0, sizeof(mLastNativeWindowCrop)); changeState(mUninitializedState); updateTrebleFlag(); } ACodec::~ACodec() { Loading Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; } Loading Loading @@ -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(); } Loading Loading @@ -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; } Loading Loading @@ -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); Loading Loading @@ -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( Loading Loading @@ -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; } Loading Loading @@ -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
media/libstagefright/Android.mk +2 −0 Original line number Diff line number Diff line Loading @@ -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 \ Loading
media/libstagefright/BufferImpl.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -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