ACodecBufferChannel.cpp revision dff26e5f53b248fd8cc6605850240c7e7c5438dc
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 23dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#include <binder/MemoryDealer.h> 24dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#include <media/openmax/OMX_Core.h> 25dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#include <media/stagefright/foundation/AMessage.h> 26dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#include <media/stagefright/foundation/AUtils.h> 27dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#include <media/stagefright/MediaCodec.h> 28dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#include <media/MediaCodecBuffer.h> 29dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#include <system/window.h> 30dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 31dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#include "include/ACodecBufferChannel.h" 32dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#include "include/SecureBuffer.h" 33dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#include "include/SharedMemoryBuffer.h" 34dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 35dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimnamespace android { 36dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 37dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimusing BufferInfo = ACodecBufferChannel::BufferInfo; 38dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimusing BufferInfoIterator = std::vector<const BufferInfo>::const_iterator; 39dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 40dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimstatic BufferInfoIterator findClientBuffer( 41dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim const std::shared_ptr<const std::vector<const BufferInfo>> &array, 42dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim const sp<MediaCodecBuffer> &buffer) { 43dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return std::find_if( 44dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim array->begin(), array->end(), 45dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim [buffer](const BufferInfo &info) { return info.mClientBuffer == buffer; }); 46dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 47dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 48dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimstatic BufferInfoIterator findBufferId( 49dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim const std::shared_ptr<const std::vector<const BufferInfo>> &array, 50dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim IOMX::buffer_id bufferId) { 51dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return std::find_if( 52dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim array->begin(), array->end(), 53dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim [bufferId](const BufferInfo &info) { return bufferId == info.mBufferId; }); 54dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 55dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 56dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik KimACodecBufferChannel::BufferInfo::BufferInfo( 57dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim const sp<MediaCodecBuffer> &buffer, 58dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim IOMX::buffer_id bufferId, 59dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim const sp<IMemory> &sharedEncryptedBuffer) 60dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim : mClientBuffer( 61dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim (sharedEncryptedBuffer == nullptr) 62dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ? buffer 63dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim : new SharedMemoryBuffer(buffer->format(), sharedEncryptedBuffer)), 64dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim mCodecBuffer(buffer), 65dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim mBufferId(bufferId), 66dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim mSharedEncryptedBuffer(sharedEncryptedBuffer) { 67dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 68dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 69dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik KimACodecBufferChannel::ACodecBufferChannel( 70dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim const sp<AMessage> &inputBufferFilled, const sp<AMessage> &outputBufferDrained) 71dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim : mInputBufferFilled(inputBufferFilled), 72dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim mOutputBufferDrained(outputBufferDrained) { 73dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 74dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 75dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimstatus_t ACodecBufferChannel::queueInputBuffer(const sp<MediaCodecBuffer> &buffer) { 76dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::shared_ptr<const std::vector<const BufferInfo>> array( 77dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_load(&mInputBuffers)); 78dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim BufferInfoIterator it = findClientBuffer(array, buffer); 79dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it == array->end()) { 80dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return -ENOENT; 81dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 82dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ALOGV("queueInputBuffer #%d", it->mBufferId); 83dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim sp<AMessage> msg = mInputBufferFilled->dup(); 84dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setObject("buffer", it->mCodecBuffer); 85dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setInt32("buffer-id", it->mBufferId); 86dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->post(); 87dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return OK; 88dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 89dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 90dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimstatus_t ACodecBufferChannel::queueSecureInputBuffer( 91dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim const sp<MediaCodecBuffer> &buffer, 92dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim bool secure, 93dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim const uint8_t *key, 94dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim const uint8_t *iv, 95dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim CryptoPlugin::Mode mode, 96dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim CryptoPlugin::Pattern pattern, 97dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim const CryptoPlugin::SubSample *subSamples, 98dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim size_t numSubSamples, 99dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim AString *errorDetailMsg) { 100dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (mCrypto == nullptr) { 101dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return -ENOSYS; 102dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 103dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::shared_ptr<const std::vector<const BufferInfo>> array( 104dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_load(&mInputBuffers)); 105dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim BufferInfoIterator it = findClientBuffer(array, buffer); 106dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it == array->end()) { 107dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return -ENOENT; 108dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 109dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 110dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim void *dst_pointer = nullptr; 111dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ICrypto::DestinationType dst_type = ICrypto::kDestinationTypeOpaqueHandle; 112dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 113dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (secure) { 114dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim sp<SecureBuffer> secureData = static_cast<SecureBuffer *>(it->mCodecBuffer.get()); 115dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim dst_pointer = secureData->getDestinationPointer(); 116dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim dst_type = secureData->getDestinationType(); 117dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } else { 118dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim dst_pointer = it->mCodecBuffer->base(); 119dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim dst_type = ICrypto::kDestinationTypeVmPointer; 120dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 121dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 122dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ssize_t result = mCrypto->decrypt( 123dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim dst_type, 124dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim key, 125dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim iv, 126dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim mode, 127dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim pattern, 128dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mSharedEncryptedBuffer, 129dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mClientBuffer->offset(), 130dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim subSamples, 131dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim numSubSamples, 132dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim dst_pointer, 133dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim errorDetailMsg); 134dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 135dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (result < 0) { 136dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return result; 137dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 138dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 139dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mCodecBuffer->setRange(0, result); 140dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 141dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim // Copy metadata from client to codec buffer. 142dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mCodecBuffer->meta()->clear(); 143dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim int64_t timeUs; 144dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim CHECK(it->mClientBuffer->meta()->findInt64("timeUs", &timeUs)); 145dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mCodecBuffer->meta()->setInt64("timeUs", timeUs); 146dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim int32_t eos; 147dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it->mClientBuffer->meta()->findInt32("eos", &eos)) { 148dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mCodecBuffer->meta()->setInt32("eos", eos); 149dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 150dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim int32_t csd; 151dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it->mClientBuffer->meta()->findInt32("csd", &csd)) { 152dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mCodecBuffer->meta()->setInt32("csd", csd); 153dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 154dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 155dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ALOGV("queueSecureInputBuffer #%d", it->mBufferId); 156dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim sp<AMessage> msg = mInputBufferFilled->dup(); 157dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setObject("buffer", it->mCodecBuffer); 158dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setInt32("buffer-id", it->mBufferId); 159dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->post(); 160dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return OK; 161dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 162dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 163dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimstatus_t ACodecBufferChannel::renderOutputBuffer( 164dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim const sp<MediaCodecBuffer> &buffer, int64_t timestampNs) { 165dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::shared_ptr<const std::vector<const BufferInfo>> array( 166dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_load(&mOutputBuffers)); 167dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim BufferInfoIterator it = findClientBuffer(array, buffer); 168dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it == array->end()) { 169dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return -ENOENT; 170dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 171dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 172dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ALOGV("renderOutputBuffer #%d", it->mBufferId); 173dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim sp<AMessage> msg = mOutputBufferDrained->dup(); 174dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setObject("buffer", buffer); 175dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setInt32("buffer-id", it->mBufferId); 176dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setInt32("render", true); 177dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setInt64("timestampNs", timestampNs); 178dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->post(); 179dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return OK; 180dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 181dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 182dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimstatus_t ACodecBufferChannel::discardBuffer(const sp<MediaCodecBuffer> &buffer) { 183dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::shared_ptr<const std::vector<const BufferInfo>> array( 184dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_load(&mInputBuffers)); 185dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim bool input = true; 186dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim BufferInfoIterator it = findClientBuffer(array, buffer); 187dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it == array->end()) { 188dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim array = std::atomic_load(&mOutputBuffers); 189dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim input = false; 190dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it = findClientBuffer(array, buffer); 191dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it == array->end()) { 192dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return -ENOENT; 193dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 194dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 195dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ALOGV("discardBuffer #%d", it->mBufferId); 196dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim sp<AMessage> msg = input ? mInputBufferFilled->dup() : mOutputBufferDrained->dup(); 197dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setObject("buffer", it->mCodecBuffer); 198dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setInt32("buffer-id", it->mBufferId); 199dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setInt32("discarded", true); 200dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->post(); 201dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return OK; 202dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 203dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 204dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid ACodecBufferChannel::getInputBufferArray(Vector<sp<MediaCodecBuffer>> *array) { 205dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::shared_ptr<const std::vector<const BufferInfo>> inputBuffers( 206dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_load(&mInputBuffers)); 207dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim array->clear(); 208dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim for (const BufferInfo &elem : *inputBuffers) { 209dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim array->push_back(elem.mClientBuffer); 210dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 211dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 212dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 213dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid ACodecBufferChannel::getOutputBufferArray(Vector<sp<MediaCodecBuffer>> *array) { 214dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::shared_ptr<const std::vector<const BufferInfo>> outputBuffers( 215dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_load(&mOutputBuffers)); 216dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim array->clear(); 217dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim for (const BufferInfo &elem : *outputBuffers) { 218dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim array->push_back(elem.mClientBuffer); 219dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 220dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 221dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 222dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid ACodecBufferChannel::setInputBufferArray(const std::vector<BufferAndId> &array) { 223dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim bool secure = (mCrypto != nullptr); 224dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (secure) { 225dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim size_t totalSize = std::accumulate( 226dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim array.begin(), array.end(), 0u, 227dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim [alignment = MemoryDealer::getAllocationAlignment()] 228dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim (size_t sum, const BufferAndId& elem) { 229dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return sum + align(elem.mBuffer->capacity(), alignment); 230dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim }); 231dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim mDealer = new MemoryDealer(totalSize, "ACodecBufferChannel"); 232dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 233dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::vector<const BufferInfo> inputBuffers; 234dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim for (const BufferAndId &elem : array) { 235dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim sp<IMemory> sharedEncryptedBuffer; 236dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (secure) { 237dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim sharedEncryptedBuffer = mDealer->allocate(elem.mBuffer->capacity()); 238dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 239dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim inputBuffers.emplace_back(elem.mBuffer, elem.mBufferId, sharedEncryptedBuffer); 240dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 241dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_store( 242dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim &mInputBuffers, 243dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::make_shared<const std::vector<const BufferInfo>>(inputBuffers)); 244dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 245dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 246dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid ACodecBufferChannel::setOutputBufferArray(const std::vector<BufferAndId> &array) { 247dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::vector<const BufferInfo> outputBuffers; 248dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim for (const BufferAndId &elem : array) { 249dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim outputBuffers.emplace_back(elem.mBuffer, elem.mBufferId, nullptr); 250dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 251dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_store( 252dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim &mOutputBuffers, 253dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::make_shared<const std::vector<const BufferInfo>>(outputBuffers)); 254dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 255dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 256dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid ACodecBufferChannel::fillThisBuffer(IOMX::buffer_id bufferId) { 257dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ALOGV("fillThisBuffer #%d", bufferId); 258dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::shared_ptr<const std::vector<const BufferInfo>> array( 259dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_load(&mInputBuffers)); 260dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim BufferInfoIterator it = findBufferId(array, bufferId); 261dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 262dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it == array->end()) { 263dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ALOGE("fillThisBuffer: unrecognized buffer #%d", bufferId); 264dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return; 265dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 266dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it->mClientBuffer != it->mCodecBuffer) { 267dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mClientBuffer->setFormat(it->mCodecBuffer->format()); 268dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 269dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 270dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim mCallback->onInputBufferAvailable( 271dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::distance(array->begin(), it), 272dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mClientBuffer); 273dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 274dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 275dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid ACodecBufferChannel::drainThisBuffer( 276dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim IOMX::buffer_id bufferId, 277dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim OMX_U32 omxFlags) { 278dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ALOGV("drainThisBuffer #%d", bufferId); 279dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::shared_ptr<const std::vector<const BufferInfo>> array( 280dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_load(&mOutputBuffers)); 281dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim BufferInfoIterator it = findBufferId(array, bufferId); 282dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 283dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it == array->end()) { 284dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ALOGE("drainThisBuffer: unrecognized buffer #%d", bufferId); 285dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return; 286dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 287dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it->mClientBuffer != it->mCodecBuffer) { 288dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mClientBuffer->setFormat(it->mCodecBuffer->format()); 289dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 290dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 291dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim uint32_t flags = 0; 292dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) { 293dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim flags |= MediaCodec::BUFFER_FLAG_SYNCFRAME; 294dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 295dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) { 296dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim flags |= MediaCodec::BUFFER_FLAG_CODECCONFIG; 297dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 298dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (omxFlags & OMX_BUFFERFLAG_EOS) { 299dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim flags |= MediaCodec::BUFFER_FLAG_EOS; 300dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 301dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mClientBuffer->meta()->setInt32("flags", flags); 302dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 303dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim mCallback->onOutputBufferAvailable( 304dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::distance(array->begin(), it), 305dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mClientBuffer); 306dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 307dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 308dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} // namespace android 309