ACodecBufferChannel.cpp revision 3b2847fa5506dc265d2e46f067bfbb66ae209f74
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 42dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimstatic BufferInfoIterator findClientBuffer( 43dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim const std::shared_ptr<const std::vector<const BufferInfo>> &array, 44dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim const sp<MediaCodecBuffer> &buffer) { 45dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return std::find_if( 46dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim array->begin(), array->end(), 47dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim [buffer](const BufferInfo &info) { return info.mClientBuffer == buffer; }); 48dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 49dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 50dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimstatic BufferInfoIterator findBufferId( 51dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim const std::shared_ptr<const std::vector<const BufferInfo>> &array, 52dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim IOMX::buffer_id bufferId) { 53dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return std::find_if( 54dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim array->begin(), array->end(), 55dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim [bufferId](const BufferInfo &info) { return bufferId == info.mBufferId; }); 56dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 57dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 58dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik KimACodecBufferChannel::BufferInfo::BufferInfo( 59dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim const sp<MediaCodecBuffer> &buffer, 60dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim IOMX::buffer_id bufferId, 61dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim const sp<IMemory> &sharedEncryptedBuffer) 62dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim : mClientBuffer( 63dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim (sharedEncryptedBuffer == nullptr) 64dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ? buffer 65dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim : new SharedMemoryBuffer(buffer->format(), sharedEncryptedBuffer)), 66dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim mCodecBuffer(buffer), 67dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim mBufferId(bufferId), 68dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim mSharedEncryptedBuffer(sharedEncryptedBuffer) { 69dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 70dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 71dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik KimACodecBufferChannel::ACodecBufferChannel( 72dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim const sp<AMessage> &inputBufferFilled, const sp<AMessage> &outputBufferDrained) 73dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim : mInputBufferFilled(inputBufferFilled), 74dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim mOutputBufferDrained(outputBufferDrained) { 75dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 76dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 77dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimstatus_t ACodecBufferChannel::queueInputBuffer(const sp<MediaCodecBuffer> &buffer) { 78dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::shared_ptr<const std::vector<const BufferInfo>> array( 79dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_load(&mInputBuffers)); 80dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim BufferInfoIterator it = findClientBuffer(array, buffer); 81dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it == array->end()) { 82dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return -ENOENT; 83dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 84dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ALOGV("queueInputBuffer #%d", it->mBufferId); 85dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim sp<AMessage> msg = mInputBufferFilled->dup(); 86dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setObject("buffer", it->mCodecBuffer); 87dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setInt32("buffer-id", it->mBufferId); 88dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->post(); 89dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return OK; 90dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 91dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 92dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimstatus_t ACodecBufferChannel::queueSecureInputBuffer( 93a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker const sp<MediaCodecBuffer> &buffer, bool secure, const uint8_t *key, 94a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker const uint8_t *iv, CryptoPlugin::Mode mode, CryptoPlugin::Pattern pattern, 95a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker const CryptoPlugin::SubSample *subSamples, size_t numSubSamples, 96dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim AString *errorDetailMsg) { 973b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang if (!hasCryptoOrDescrambler()) { 98dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return -ENOSYS; 99dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 100dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::shared_ptr<const std::vector<const BufferInfo>> array( 101dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_load(&mInputBuffers)); 102dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim BufferInfoIterator it = findClientBuffer(array, buffer); 103dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it == array->end()) { 104dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return -ENOENT; 105dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 106dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 107a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker ICrypto::DestinationBuffer destination; 108dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (secure) { 109a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker sp<SecureBuffer> secureData = 110a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker static_cast<SecureBuffer *>(it->mCodecBuffer.get()); 111a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker destination.mType = secureData->getDestinationType(); 112a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker if (destination.mType != ICrypto::kDestinationTypeNativeHandle) { 113a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker return BAD_VALUE; 114a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker } 115a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker destination.mHandle = 116a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker static_cast<native_handle_t *>(secureData->getDestinationPointer()); 117dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } else { 118a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker destination.mType = ICrypto::kDestinationTypeSharedMemory; 119a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker destination.mSharedMemory = mDecryptDestination; 120dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 1213b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang 1223b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang ssize_t result = -1; 1233b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang if (mCrypto != NULL) { 1243b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang result = mCrypto->decrypt(key, iv, mode, pattern, 1253b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang it->mSharedEncryptedBuffer, it->mClientBuffer->offset(), 1263b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang subSamples, numSubSamples, destination, errorDetailMsg); 1273b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang } else { 1283b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang DescrambleInfo descrambleInfo; 1293b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang descrambleInfo.dstType = destination.mType == 1303b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang ICrypto::kDestinationTypeSharedMemory ? 1313b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang DescrambleInfo::kDestinationTypeVmPointer : 1323b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang DescrambleInfo::kDestinationTypeNativeHandle; 1333b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang descrambleInfo.scramblingControl = key != NULL ? 1343b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang (DescramblerPlugin::ScramblingControl)key[0] : 1353b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang DescramblerPlugin::kScrambling_Unscrambled; 1363b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang descrambleInfo.numSubSamples = numSubSamples; 1373b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang descrambleInfo.subSamples = (DescramblerPlugin::SubSample *)subSamples; 1383b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang descrambleInfo.srcMem = it->mSharedEncryptedBuffer; 1393b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang descrambleInfo.srcOffset = 0; 1403b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang descrambleInfo.dstPtr = NULL; 1413b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang descrambleInfo.dstOffset = 0; 1423b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang 1433b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang int32_t descrambleResult = -1; 1443b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang Status status = mDescrambler->descramble(descrambleInfo, &descrambleResult); 1453b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang 1463b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang if (status.isOk()) { 1473b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang result = descrambleResult; 1483b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang } 1493b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang 1503b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang if (result < 0) { 1513b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang ALOGE("descramble failed, exceptionCode=%d, err=%d, result=%zd", 1523b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang status.exceptionCode(), status.transactionError(), result); 1533b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang } else { 1543b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang ALOGV("descramble succeeded, result=%zd", result); 1553b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang } 1563b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang 1573b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang if (result > 0 && destination.mType == ICrypto::kDestinationTypeSharedMemory) { 1583b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang memcpy(destination.mSharedMemory->pointer(), 1593b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang (uint8_t*)it->mSharedEncryptedBuffer->pointer(), result); 1603b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang } 1613b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang } 162dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 163dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (result < 0) { 164dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return result; 165dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 166dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 167a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker if (destination.mType == ICrypto::kDestinationTypeSharedMemory) { 168a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker memcpy(it->mCodecBuffer->base(), destination.mSharedMemory->pointer(), result); 169a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker } 170a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker 171dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mCodecBuffer->setRange(0, result); 172dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 173dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim // Copy metadata from client to codec buffer. 174dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mCodecBuffer->meta()->clear(); 175dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim int64_t timeUs; 176dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim CHECK(it->mClientBuffer->meta()->findInt64("timeUs", &timeUs)); 177dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mCodecBuffer->meta()->setInt64("timeUs", timeUs); 178dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim int32_t eos; 179dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it->mClientBuffer->meta()->findInt32("eos", &eos)) { 180dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mCodecBuffer->meta()->setInt32("eos", eos); 181dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 182dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim int32_t csd; 183dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it->mClientBuffer->meta()->findInt32("csd", &csd)) { 184dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mCodecBuffer->meta()->setInt32("csd", csd); 185dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 186dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 187dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ALOGV("queueSecureInputBuffer #%d", it->mBufferId); 188dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim sp<AMessage> msg = mInputBufferFilled->dup(); 189dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setObject("buffer", it->mCodecBuffer); 190dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setInt32("buffer-id", it->mBufferId); 191dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->post(); 192dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return OK; 193dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 194dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 195dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimstatus_t ACodecBufferChannel::renderOutputBuffer( 196dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim const sp<MediaCodecBuffer> &buffer, int64_t timestampNs) { 197dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::shared_ptr<const std::vector<const BufferInfo>> array( 198dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_load(&mOutputBuffers)); 199dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim BufferInfoIterator it = findClientBuffer(array, buffer); 200dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it == array->end()) { 201dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return -ENOENT; 202dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 203dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 204dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ALOGV("renderOutputBuffer #%d", it->mBufferId); 205dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim sp<AMessage> msg = mOutputBufferDrained->dup(); 206dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setObject("buffer", buffer); 207dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setInt32("buffer-id", it->mBufferId); 208dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setInt32("render", true); 209dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setInt64("timestampNs", timestampNs); 210dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->post(); 211dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return OK; 212dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 213dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 214dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimstatus_t ACodecBufferChannel::discardBuffer(const sp<MediaCodecBuffer> &buffer) { 215dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::shared_ptr<const std::vector<const BufferInfo>> array( 216dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_load(&mInputBuffers)); 217dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim bool input = true; 218dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim BufferInfoIterator it = findClientBuffer(array, buffer); 219dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it == array->end()) { 220dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim array = std::atomic_load(&mOutputBuffers); 221dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim input = false; 222dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it = findClientBuffer(array, buffer); 223dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it == array->end()) { 224dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return -ENOENT; 225dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 226dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 227dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ALOGV("discardBuffer #%d", it->mBufferId); 228dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim sp<AMessage> msg = input ? mInputBufferFilled->dup() : mOutputBufferDrained->dup(); 229dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setObject("buffer", it->mCodecBuffer); 230dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setInt32("buffer-id", it->mBufferId); 231dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setInt32("discarded", true); 232dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->post(); 233dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return OK; 234dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 235dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 236dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid ACodecBufferChannel::getInputBufferArray(Vector<sp<MediaCodecBuffer>> *array) { 237dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::shared_ptr<const std::vector<const BufferInfo>> inputBuffers( 238dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_load(&mInputBuffers)); 239dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim array->clear(); 240dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim for (const BufferInfo &elem : *inputBuffers) { 241dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim array->push_back(elem.mClientBuffer); 242dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 243dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 244dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 245dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid ACodecBufferChannel::getOutputBufferArray(Vector<sp<MediaCodecBuffer>> *array) { 246dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::shared_ptr<const std::vector<const BufferInfo>> outputBuffers( 247dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_load(&mOutputBuffers)); 248dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim array->clear(); 249dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim for (const BufferInfo &elem : *outputBuffers) { 250dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim array->push_back(elem.mClientBuffer); 251dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 252dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 253dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 254dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid ACodecBufferChannel::setInputBufferArray(const std::vector<BufferAndId> &array) { 2553b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang if (hasCryptoOrDescrambler()) { 256dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim size_t totalSize = std::accumulate( 257dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim array.begin(), array.end(), 0u, 258dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim [alignment = MemoryDealer::getAllocationAlignment()] 259dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim (size_t sum, const BufferAndId& elem) { 260dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return sum + align(elem.mBuffer->capacity(), alignment); 261dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim }); 262a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker size_t maxSize = std::accumulate( 263a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker array.begin(), array.end(), 0u, 264a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker [alignment = MemoryDealer::getAllocationAlignment()] 265a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker (size_t max, const BufferAndId& elem) { 266a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker return std::max(max, align(elem.mBuffer->capacity(), alignment)); 267a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker }); 268a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker mDealer = new MemoryDealer(totalSize + maxSize, "ACodecBufferChannel"); 269a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker mDecryptDestination = mDealer->allocate(maxSize); 270dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 271dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::vector<const BufferInfo> inputBuffers; 272dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim for (const BufferAndId &elem : array) { 273dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim sp<IMemory> sharedEncryptedBuffer; 2743b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang if (hasCryptoOrDescrambler()) { 275dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim sharedEncryptedBuffer = mDealer->allocate(elem.mBuffer->capacity()); 276dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 277dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim inputBuffers.emplace_back(elem.mBuffer, elem.mBufferId, sharedEncryptedBuffer); 278dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 279dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_store( 280dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim &mInputBuffers, 281dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::make_shared<const std::vector<const BufferInfo>>(inputBuffers)); 282dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 283dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 284dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid ACodecBufferChannel::setOutputBufferArray(const std::vector<BufferAndId> &array) { 285dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::vector<const BufferInfo> outputBuffers; 286dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim for (const BufferAndId &elem : array) { 287dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim outputBuffers.emplace_back(elem.mBuffer, elem.mBufferId, nullptr); 288dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 289dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_store( 290dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim &mOutputBuffers, 291dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::make_shared<const std::vector<const BufferInfo>>(outputBuffers)); 292dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 293dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 294dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid ACodecBufferChannel::fillThisBuffer(IOMX::buffer_id bufferId) { 295dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ALOGV("fillThisBuffer #%d", bufferId); 296dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::shared_ptr<const std::vector<const BufferInfo>> array( 297dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_load(&mInputBuffers)); 298dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim BufferInfoIterator it = findBufferId(array, bufferId); 299dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 300dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it == array->end()) { 301dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ALOGE("fillThisBuffer: unrecognized buffer #%d", bufferId); 302dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return; 303dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 304dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it->mClientBuffer != it->mCodecBuffer) { 305dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mClientBuffer->setFormat(it->mCodecBuffer->format()); 306dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 307dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 308dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim mCallback->onInputBufferAvailable( 309dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::distance(array->begin(), it), 310dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mClientBuffer); 311dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 312dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 313dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid ACodecBufferChannel::drainThisBuffer( 314dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim IOMX::buffer_id bufferId, 315dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim OMX_U32 omxFlags) { 316dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ALOGV("drainThisBuffer #%d", bufferId); 317dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::shared_ptr<const std::vector<const BufferInfo>> array( 318dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_load(&mOutputBuffers)); 319dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim BufferInfoIterator it = findBufferId(array, bufferId); 320dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 321dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it == array->end()) { 322dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ALOGE("drainThisBuffer: unrecognized buffer #%d", bufferId); 323dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return; 324dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 325dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it->mClientBuffer != it->mCodecBuffer) { 326dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mClientBuffer->setFormat(it->mCodecBuffer->format()); 327dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 328dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 329dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim uint32_t flags = 0; 330dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) { 331dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim flags |= MediaCodec::BUFFER_FLAG_SYNCFRAME; 332dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 333dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) { 334dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim flags |= MediaCodec::BUFFER_FLAG_CODECCONFIG; 335dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 336dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (omxFlags & OMX_BUFFERFLAG_EOS) { 337dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim flags |= MediaCodec::BUFFER_FLAG_EOS; 338dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 339dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mClientBuffer->meta()->setInt32("flags", flags); 340dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 341dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim mCallback->onOutputBufferAvailable( 342dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::distance(array->begin(), it), 343dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mClientBuffer); 344dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 345dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 346dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} // namespace android 347