ACodecBufferChannel.cpp revision d07c92742fc5801cab8e99801f591365986acbe9
1dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim/* 2dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim * Copyright 2016, The Android Open Source Project 3dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim * 4dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim * Licensed under the Apache License, Version 2.0 (the "License"); 5dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim * you may not use this file except in compliance with the License. 6dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim * You may obtain a copy of the License at 7dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim * 8dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim * http://www.apache.org/licenses/LICENSE-2.0 9dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim * 10dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim * Unless required by applicable law or agreed to in writing, software 11dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim * distributed under the License is distributed on an "AS IS" BASIS, 12dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim * See the License for the specific language governing permissions and 14dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim * limitations under the License. 15dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim */ 16dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 17dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim//#define LOG_NDEBUG 0 18dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#define LOG_TAG "ACodecBufferChannel" 19dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#include <utils/Log.h> 20dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 21dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#include <numeric> 22dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 233b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang#include <android/media/IDescrambler.h> 24dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#include <binder/MemoryDealer.h> 25dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#include <media/openmax/OMX_Core.h> 26dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#include <media/stagefright/foundation/AMessage.h> 27dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#include <media/stagefright/foundation/AUtils.h> 28dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#include <media/stagefright/MediaCodec.h> 29dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#include <media/MediaCodecBuffer.h> 30dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#include <system/window.h> 31dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 32dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#include "include/ACodecBufferChannel.h" 33dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#include "include/SecureBuffer.h" 34dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#include "include/SharedMemoryBuffer.h" 35dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 36dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimnamespace android { 373b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhangusing binder::Status; 383b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhangusing MediaDescrambler::DescrambleInfo; 39dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimusing BufferInfo = ACodecBufferChannel::BufferInfo; 40dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimusing BufferInfoIterator = std::vector<const BufferInfo>::const_iterator; 41dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 42d07c92742fc5801cab8e99801f591365986acbe9Chong ZhangACodecBufferChannel::~ACodecBufferChannel() { 43d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang if (mCrypto != nullptr && mDealer != nullptr) { 44d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang mCrypto->unsetHeap(mDealer->getMemoryHeap()); 45d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang } 46d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang} 47d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang 48dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimstatic BufferInfoIterator findClientBuffer( 49dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim const std::shared_ptr<const std::vector<const BufferInfo>> &array, 50dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim const sp<MediaCodecBuffer> &buffer) { 51dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return std::find_if( 52dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim array->begin(), array->end(), 53dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim [buffer](const BufferInfo &info) { return info.mClientBuffer == buffer; }); 54dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 55dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 56dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimstatic BufferInfoIterator findBufferId( 57dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim const std::shared_ptr<const std::vector<const BufferInfo>> &array, 58dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim IOMX::buffer_id bufferId) { 59dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return std::find_if( 60dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim array->begin(), array->end(), 61dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim [bufferId](const BufferInfo &info) { return bufferId == info.mBufferId; }); 62dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 63dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 64dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik KimACodecBufferChannel::BufferInfo::BufferInfo( 65dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim const sp<MediaCodecBuffer> &buffer, 66dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim IOMX::buffer_id bufferId, 67dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim const sp<IMemory> &sharedEncryptedBuffer) 68dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim : mClientBuffer( 69dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim (sharedEncryptedBuffer == nullptr) 70dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ? buffer 71dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim : new SharedMemoryBuffer(buffer->format(), sharedEncryptedBuffer)), 72dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim mCodecBuffer(buffer), 73dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim mBufferId(bufferId), 74dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim mSharedEncryptedBuffer(sharedEncryptedBuffer) { 75dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 76dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 77dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik KimACodecBufferChannel::ACodecBufferChannel( 78dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim const sp<AMessage> &inputBufferFilled, const sp<AMessage> &outputBufferDrained) 79dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim : mInputBufferFilled(inputBufferFilled), 80dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim mOutputBufferDrained(outputBufferDrained) { 81dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 82dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 83dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimstatus_t ACodecBufferChannel::queueInputBuffer(const sp<MediaCodecBuffer> &buffer) { 843c2c5556f44765abe7e3dc25584a2ccb316a9b14Wonsik Kim if (mDealer != nullptr) { 853c2c5556f44765abe7e3dc25584a2ccb316a9b14Wonsik Kim return -ENOSYS; 863c2c5556f44765abe7e3dc25584a2ccb316a9b14Wonsik Kim } 87dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::shared_ptr<const std::vector<const BufferInfo>> array( 88dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_load(&mInputBuffers)); 89dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim BufferInfoIterator it = findClientBuffer(array, buffer); 90dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it == array->end()) { 91dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return -ENOENT; 92dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 93dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ALOGV("queueInputBuffer #%d", it->mBufferId); 94dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim sp<AMessage> msg = mInputBufferFilled->dup(); 95dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setObject("buffer", it->mCodecBuffer); 96dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setInt32("buffer-id", it->mBufferId); 97dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->post(); 98dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return OK; 99dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 100dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 101dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimstatus_t ACodecBufferChannel::queueSecureInputBuffer( 102a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker const sp<MediaCodecBuffer> &buffer, bool secure, const uint8_t *key, 103a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker const uint8_t *iv, CryptoPlugin::Mode mode, CryptoPlugin::Pattern pattern, 104a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker const CryptoPlugin::SubSample *subSamples, size_t numSubSamples, 105dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim AString *errorDetailMsg) { 1063c2c5556f44765abe7e3dc25584a2ccb316a9b14Wonsik Kim if (!hasCryptoOrDescrambler() || mDealer == nullptr) { 107dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return -ENOSYS; 108dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 109dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::shared_ptr<const std::vector<const BufferInfo>> array( 110dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_load(&mInputBuffers)); 111dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim BufferInfoIterator it = findClientBuffer(array, buffer); 112dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it == array->end()) { 113dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return -ENOENT; 114dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 115dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 116a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker ICrypto::DestinationBuffer destination; 117dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (secure) { 118a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker sp<SecureBuffer> secureData = 119a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker static_cast<SecureBuffer *>(it->mCodecBuffer.get()); 120a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker destination.mType = secureData->getDestinationType(); 121a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker if (destination.mType != ICrypto::kDestinationTypeNativeHandle) { 122a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker return BAD_VALUE; 123a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker } 124a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker destination.mHandle = 125a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker static_cast<native_handle_t *>(secureData->getDestinationPointer()); 126dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } else { 127a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker destination.mType = ICrypto::kDestinationTypeSharedMemory; 128a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker destination.mSharedMemory = mDecryptDestination; 129dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 1303b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang 1313b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang ssize_t result = -1; 1323b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang if (mCrypto != NULL) { 1333b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang result = mCrypto->decrypt(key, iv, mode, pattern, 1343b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang it->mSharedEncryptedBuffer, it->mClientBuffer->offset(), 1353b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang subSamples, numSubSamples, destination, errorDetailMsg); 1363b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang } else { 1373b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang DescrambleInfo descrambleInfo; 1383b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang descrambleInfo.dstType = destination.mType == 1393b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang ICrypto::kDestinationTypeSharedMemory ? 1403b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang DescrambleInfo::kDestinationTypeVmPointer : 1413b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang DescrambleInfo::kDestinationTypeNativeHandle; 1423b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang descrambleInfo.scramblingControl = key != NULL ? 1433b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang (DescramblerPlugin::ScramblingControl)key[0] : 1443b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang DescramblerPlugin::kScrambling_Unscrambled; 1453b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang descrambleInfo.numSubSamples = numSubSamples; 1463b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang descrambleInfo.subSamples = (DescramblerPlugin::SubSample *)subSamples; 1473b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang descrambleInfo.srcMem = it->mSharedEncryptedBuffer; 1483b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang descrambleInfo.srcOffset = 0; 1493b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang descrambleInfo.dstPtr = NULL; 1503b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang descrambleInfo.dstOffset = 0; 1513b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang 1523b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang int32_t descrambleResult = -1; 1533b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang Status status = mDescrambler->descramble(descrambleInfo, &descrambleResult); 1543b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang 1553b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang if (status.isOk()) { 1563b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang result = descrambleResult; 1573b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang } 1583b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang 1593b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang if (result < 0) { 1603b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang ALOGE("descramble failed, exceptionCode=%d, err=%d, result=%zd", 1613b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang status.exceptionCode(), status.transactionError(), result); 1623b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang } else { 1633b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang ALOGV("descramble succeeded, result=%zd", result); 1643b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang } 1653b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang 1663b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang if (result > 0 && destination.mType == ICrypto::kDestinationTypeSharedMemory) { 1673b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang memcpy(destination.mSharedMemory->pointer(), 1683b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang (uint8_t*)it->mSharedEncryptedBuffer->pointer(), result); 1693b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang } 1703b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang } 171dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 172dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (result < 0) { 173dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return result; 174dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 175dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 176a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker if (destination.mType == ICrypto::kDestinationTypeSharedMemory) { 177a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker memcpy(it->mCodecBuffer->base(), destination.mSharedMemory->pointer(), result); 178a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker } 179a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker 180dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mCodecBuffer->setRange(0, result); 181dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 182dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim // Copy metadata from client to codec buffer. 183dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mCodecBuffer->meta()->clear(); 184dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim int64_t timeUs; 185dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim CHECK(it->mClientBuffer->meta()->findInt64("timeUs", &timeUs)); 186dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mCodecBuffer->meta()->setInt64("timeUs", timeUs); 187dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim int32_t eos; 188dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it->mClientBuffer->meta()->findInt32("eos", &eos)) { 189dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mCodecBuffer->meta()->setInt32("eos", eos); 190dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 191dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim int32_t csd; 192dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it->mClientBuffer->meta()->findInt32("csd", &csd)) { 193dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mCodecBuffer->meta()->setInt32("csd", csd); 194dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 195dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 196dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ALOGV("queueSecureInputBuffer #%d", it->mBufferId); 197dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim sp<AMessage> msg = mInputBufferFilled->dup(); 198dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setObject("buffer", it->mCodecBuffer); 199dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setInt32("buffer-id", it->mBufferId); 200dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->post(); 201dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return OK; 202dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 203dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 204dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimstatus_t ACodecBufferChannel::renderOutputBuffer( 205dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim const sp<MediaCodecBuffer> &buffer, int64_t timestampNs) { 206dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::shared_ptr<const std::vector<const BufferInfo>> array( 207dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_load(&mOutputBuffers)); 208dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim BufferInfoIterator it = findClientBuffer(array, buffer); 209dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it == array->end()) { 210dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return -ENOENT; 211dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 212dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 213dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ALOGV("renderOutputBuffer #%d", it->mBufferId); 214dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim sp<AMessage> msg = mOutputBufferDrained->dup(); 215dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setObject("buffer", buffer); 216dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setInt32("buffer-id", it->mBufferId); 217dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setInt32("render", true); 218dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setInt64("timestampNs", timestampNs); 219dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->post(); 220dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return OK; 221dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 222dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 223dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimstatus_t ACodecBufferChannel::discardBuffer(const sp<MediaCodecBuffer> &buffer) { 224dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::shared_ptr<const std::vector<const BufferInfo>> array( 225dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_load(&mInputBuffers)); 226dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim bool input = true; 227dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim BufferInfoIterator it = findClientBuffer(array, buffer); 228dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it == array->end()) { 229dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim array = std::atomic_load(&mOutputBuffers); 230dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim input = false; 231dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it = findClientBuffer(array, buffer); 232dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it == array->end()) { 233dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return -ENOENT; 234dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 235dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 236dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ALOGV("discardBuffer #%d", it->mBufferId); 237dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim sp<AMessage> msg = input ? mInputBufferFilled->dup() : mOutputBufferDrained->dup(); 238dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setObject("buffer", it->mCodecBuffer); 239dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setInt32("buffer-id", it->mBufferId); 240dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setInt32("discarded", true); 241dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->post(); 242dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return OK; 243dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 244dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 245dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid ACodecBufferChannel::getInputBufferArray(Vector<sp<MediaCodecBuffer>> *array) { 246dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::shared_ptr<const std::vector<const BufferInfo>> inputBuffers( 247dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_load(&mInputBuffers)); 248dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim array->clear(); 249dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim for (const BufferInfo &elem : *inputBuffers) { 250dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim array->push_back(elem.mClientBuffer); 251dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 252dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 253dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 254dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid ACodecBufferChannel::getOutputBufferArray(Vector<sp<MediaCodecBuffer>> *array) { 255dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::shared_ptr<const std::vector<const BufferInfo>> outputBuffers( 256dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_load(&mOutputBuffers)); 257dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim array->clear(); 258dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim for (const BufferInfo &elem : *outputBuffers) { 259dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim array->push_back(elem.mClientBuffer); 260dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 261dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 262dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 263d07c92742fc5801cab8e99801f591365986acbe9Chong Zhangsp<MemoryDealer> ACodecBufferChannel::makeMemoryDealer(size_t heapSize) { 264d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang sp<MemoryDealer> dealer; 265d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang if (mDealer != nullptr && mCrypto != nullptr) { 266d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang mCrypto->unsetHeap(mDealer->getMemoryHeap()); 267d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang } 268d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang dealer = new MemoryDealer(heapSize, "ACodecBufferChannel"); 269d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang if (mCrypto != nullptr) { 270d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang mCrypto->setHeap(dealer->getMemoryHeap()); 271d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang } 272d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang return dealer; 273d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang} 274d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang 275dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid ACodecBufferChannel::setInputBufferArray(const std::vector<BufferAndId> &array) { 2763b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang if (hasCryptoOrDescrambler()) { 277dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim size_t totalSize = std::accumulate( 278dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim array.begin(), array.end(), 0u, 279dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim [alignment = MemoryDealer::getAllocationAlignment()] 280dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim (size_t sum, const BufferAndId& elem) { 281dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return sum + align(elem.mBuffer->capacity(), alignment); 282dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim }); 283a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker size_t maxSize = std::accumulate( 284a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker array.begin(), array.end(), 0u, 285a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker [alignment = MemoryDealer::getAllocationAlignment()] 286a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker (size_t max, const BufferAndId& elem) { 287a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker return std::max(max, align(elem.mBuffer->capacity(), alignment)); 288a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker }); 289d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang size_t destinationBufferSize = maxSize; 290d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang size_t heapSize = totalSize + destinationBufferSize; 291d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang mDealer = makeMemoryDealer(heapSize); 292d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang mDecryptDestination = mDealer->allocate(destinationBufferSize); 293dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 294dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::vector<const BufferInfo> inputBuffers; 295dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim for (const BufferAndId &elem : array) { 296dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim sp<IMemory> sharedEncryptedBuffer; 2973b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang if (hasCryptoOrDescrambler()) { 298dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim sharedEncryptedBuffer = mDealer->allocate(elem.mBuffer->capacity()); 299dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 300dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim inputBuffers.emplace_back(elem.mBuffer, elem.mBufferId, sharedEncryptedBuffer); 301dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 302dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_store( 303dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim &mInputBuffers, 304dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::make_shared<const std::vector<const BufferInfo>>(inputBuffers)); 305dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 306dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 307dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid ACodecBufferChannel::setOutputBufferArray(const std::vector<BufferAndId> &array) { 308dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::vector<const BufferInfo> outputBuffers; 309dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim for (const BufferAndId &elem : array) { 310dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim outputBuffers.emplace_back(elem.mBuffer, elem.mBufferId, nullptr); 311dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 312dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_store( 313dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim &mOutputBuffers, 314dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::make_shared<const std::vector<const BufferInfo>>(outputBuffers)); 315dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 316dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 317dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid ACodecBufferChannel::fillThisBuffer(IOMX::buffer_id bufferId) { 318dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ALOGV("fillThisBuffer #%d", bufferId); 319dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::shared_ptr<const std::vector<const BufferInfo>> array( 320dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_load(&mInputBuffers)); 321dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim BufferInfoIterator it = findBufferId(array, bufferId); 322dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 323dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it == array->end()) { 324dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ALOGE("fillThisBuffer: unrecognized buffer #%d", bufferId); 325dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return; 326dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 327dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it->mClientBuffer != it->mCodecBuffer) { 328dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mClientBuffer->setFormat(it->mCodecBuffer->format()); 329dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 330dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 331dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim mCallback->onInputBufferAvailable( 332dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::distance(array->begin(), it), 333dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mClientBuffer); 334dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 335dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 336dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid ACodecBufferChannel::drainThisBuffer( 337dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim IOMX::buffer_id bufferId, 338dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim OMX_U32 omxFlags) { 339dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ALOGV("drainThisBuffer #%d", bufferId); 340dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::shared_ptr<const std::vector<const BufferInfo>> array( 341dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_load(&mOutputBuffers)); 342dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim BufferInfoIterator it = findBufferId(array, bufferId); 343dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 344dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it == array->end()) { 345dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ALOGE("drainThisBuffer: unrecognized buffer #%d", bufferId); 346dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return; 347dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 348dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it->mClientBuffer != it->mCodecBuffer) { 349dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mClientBuffer->setFormat(it->mCodecBuffer->format()); 350dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 351dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 352dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim uint32_t flags = 0; 353dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) { 354dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim flags |= MediaCodec::BUFFER_FLAG_SYNCFRAME; 355dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 356dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) { 357dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim flags |= MediaCodec::BUFFER_FLAG_CODECCONFIG; 358dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 359dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (omxFlags & OMX_BUFFERFLAG_EOS) { 360dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim flags |= MediaCodec::BUFFER_FLAG_EOS; 361dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 362dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mClientBuffer->meta()->setInt32("flags", flags); 363dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 364dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim mCallback->onOutputBufferAvailable( 365dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::distance(array->begin(), it), 366dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mClientBuffer); 367dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 368dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 369dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} // namespace android 370