diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp index e748b01445..7fb545597f 100644 --- a/media/libstagefright/MediaCodec.cpp +++ b/media/libstagefright/MediaCodec.cpp @@ -15,6 +15,7 @@ */ //#define LOG_NDEBUG 0 +#include "hidl/HidlSupport.h" #define LOG_TAG "MediaCodec" #include @@ -37,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -3431,19 +3433,42 @@ status_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) { sp csd = *mCSD.begin(); mCSD.erase(mCSD.begin()); std::shared_ptr c2Buffer; + sp memory; + size_t offset = 0; if ((mFlags & kFlagUseBlockModel) && mOwnerName.startsWith("codec2::")) { - std::shared_ptr block = - FetchLinearBlock(csd->size(), {std::string{mComponentName.c_str()}}); - C2WriteView view{block->map().get()}; - if (view.error() != C2_OK) { - return -EINVAL; - } - if (csd->size() > view.capacity()) { - return -EINVAL; + if (mCrypto) { + constexpr size_t kInitialDealerCapacity = 1048576; // 1MB + thread_local sp sDealer = new MemoryDealer( + kInitialDealerCapacity, "CSD(1MB)"); + sp mem = sDealer->allocate(csd->size()); + if (mem == nullptr) { + size_t newDealerCapacity = sDealer->getMemoryHeap()->getSize() * 2; + while (csd->size() * 2 > newDealerCapacity) { + newDealerCapacity *= 2; + } + sDealer = new MemoryDealer( + newDealerCapacity, + AStringPrintf("CSD(%dMB)", newDealerCapacity / 1048576).c_str()); + mem = sDealer->allocate(csd->size()); + } + memcpy(mem->unsecurePointer(), csd->data(), csd->size()); + ssize_t heapOffset; + memory = hardware::fromHeap(mem->getMemory(&heapOffset, nullptr)); + offset += heapOffset; + } else { + std::shared_ptr block = + FetchLinearBlock(csd->size(), {std::string{mComponentName.c_str()}}); + C2WriteView view{block->map().get()}; + if (view.error() != C2_OK) { + return -EINVAL; + } + if (csd->size() > view.capacity()) { + return -EINVAL; + } + memcpy(view.base(), csd->data(), csd->size()); + c2Buffer = C2Buffer::CreateLinearBuffer(block->share(0, csd->size(), C2Fence{})); } - memcpy(view.base(), csd->data(), csd->size()); - c2Buffer = C2Buffer::CreateLinearBuffer(block->share(0, csd->size(), C2Fence{})); } else { const BufferInfo &info = mPortBuffers[kPortIndexInput][bufferIndex]; const sp &codecInputData = info.mData; @@ -3473,6 +3498,11 @@ status_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) { new WrapperObject>{c2Buffer}}; msg->setObject("c2buffer", obj); msg->setMessage("tunings", new AMessage); + } else if (memory) { + sp>> obj{ + new WrapperObject>{memory}}; + msg->setObject("memory", obj); + msg->setMessage("tunings", new AMessage); } return onQueueInputBuffer(msg); @@ -3590,6 +3620,7 @@ status_t MediaCodec::onQueueInputBuffer(const sp &msg) { } else if (msg->findObject("memory", &obj)) { CHECK(obj); memory = static_cast> *>(obj.get())->value; + CHECK(msg->findSize("offset", &offset)); } else { CHECK(msg->findSize("offset", &offset)); } @@ -3688,7 +3719,7 @@ status_t MediaCodec::onQueueInputBuffer(const sp &msg) { } status_t err = OK; - if (hasCryptoOrDescrambler()) { + if (hasCryptoOrDescrambler() && !c2Buffer && !memory) { AString *errorDetailMsg; CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg));