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 23d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang#include <android/hardware/cas/native/1.0/IDescrambler.h> 24dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#include <binder/MemoryDealer.h> 2558ddee30e6cefde8a8f3d4d4aa55954e16c7bb18Chong Zhang#include <hidlmemory/FrameworkUtils.h> 26dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#include <media/openmax/OMX_Core.h> 27dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#include <media/stagefright/foundation/AMessage.h> 28dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#include <media/stagefright/foundation/AUtils.h> 29dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#include <media/stagefright/MediaCodec.h> 30dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#include <media/MediaCodecBuffer.h> 31dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#include <system/window.h> 32dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 33dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#include "include/ACodecBufferChannel.h" 34dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#include "include/SecureBuffer.h" 35dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#include "include/SharedMemoryBuffer.h" 36dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 37dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimnamespace android { 3858ddee30e6cefde8a8f3d4d4aa55954e16c7bb18Chong Zhangusing hardware::fromHeap; 39d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhangusing hardware::hidl_handle; 40d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhangusing hardware::hidl_string; 41d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhangusing hardware::hidl_vec; 42d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhangusing namespace hardware::cas::V1_0; 43d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhangusing namespace hardware::cas::native::V1_0; 44dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimusing BufferInfo = ACodecBufferChannel::BufferInfo; 45dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimusing BufferInfoIterator = std::vector<const BufferInfo>::const_iterator; 46dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 47d07c92742fc5801cab8e99801f591365986acbe9Chong ZhangACodecBufferChannel::~ACodecBufferChannel() { 486dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang if (mCrypto != nullptr && mDealer != nullptr && mHeapSeqNum >= 0) { 496dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang mCrypto->unsetHeap(mHeapSeqNum); 50d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang } 51d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang} 52d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang 53dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimstatic BufferInfoIterator findClientBuffer( 54dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim const std::shared_ptr<const std::vector<const BufferInfo>> &array, 55dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim const sp<MediaCodecBuffer> &buffer) { 56dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return std::find_if( 57dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim array->begin(), array->end(), 58dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim [buffer](const BufferInfo &info) { return info.mClientBuffer == buffer; }); 59dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 60dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 61dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimstatic BufferInfoIterator findBufferId( 62dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim const std::shared_ptr<const std::vector<const BufferInfo>> &array, 63dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim IOMX::buffer_id bufferId) { 64dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return std::find_if( 65dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim array->begin(), array->end(), 66dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim [bufferId](const BufferInfo &info) { return bufferId == info.mBufferId; }); 67dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 68dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 69dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik KimACodecBufferChannel::BufferInfo::BufferInfo( 70dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim const sp<MediaCodecBuffer> &buffer, 71dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim IOMX::buffer_id bufferId, 72dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim const sp<IMemory> &sharedEncryptedBuffer) 73dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim : mClientBuffer( 74dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim (sharedEncryptedBuffer == nullptr) 75dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ? buffer 76dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim : new SharedMemoryBuffer(buffer->format(), sharedEncryptedBuffer)), 77dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim mCodecBuffer(buffer), 78dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim mBufferId(bufferId), 79dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim mSharedEncryptedBuffer(sharedEncryptedBuffer) { 80dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 81dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 82dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik KimACodecBufferChannel::ACodecBufferChannel( 83dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim const sp<AMessage> &inputBufferFilled, const sp<AMessage> &outputBufferDrained) 84dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim : mInputBufferFilled(inputBufferFilled), 856dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang mOutputBufferDrained(outputBufferDrained), 866dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang mHeapSeqNum(-1) { 87dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 88dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 89dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimstatus_t ACodecBufferChannel::queueInputBuffer(const sp<MediaCodecBuffer> &buffer) { 903c2c5556f44765abe7e3dc25584a2ccb316a9b14Wonsik Kim if (mDealer != nullptr) { 913c2c5556f44765abe7e3dc25584a2ccb316a9b14Wonsik Kim return -ENOSYS; 923c2c5556f44765abe7e3dc25584a2ccb316a9b14Wonsik Kim } 93dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::shared_ptr<const std::vector<const BufferInfo>> array( 94dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_load(&mInputBuffers)); 95dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim BufferInfoIterator it = findClientBuffer(array, buffer); 96dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it == array->end()) { 97dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return -ENOENT; 98dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 99dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ALOGV("queueInputBuffer #%d", it->mBufferId); 100dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim sp<AMessage> msg = mInputBufferFilled->dup(); 101dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setObject("buffer", it->mCodecBuffer); 102dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setInt32("buffer-id", it->mBufferId); 103dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->post(); 104dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return OK; 105dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 106dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 107dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimstatus_t ACodecBufferChannel::queueSecureInputBuffer( 108a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker const sp<MediaCodecBuffer> &buffer, bool secure, const uint8_t *key, 109a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker const uint8_t *iv, CryptoPlugin::Mode mode, CryptoPlugin::Pattern pattern, 110a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker const CryptoPlugin::SubSample *subSamples, size_t numSubSamples, 111dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim AString *errorDetailMsg) { 1123c2c5556f44765abe7e3dc25584a2ccb316a9b14Wonsik Kim if (!hasCryptoOrDescrambler() || mDealer == nullptr) { 113dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return -ENOSYS; 114dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 115dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::shared_ptr<const std::vector<const BufferInfo>> array( 116dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_load(&mInputBuffers)); 117dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim BufferInfoIterator it = findClientBuffer(array, buffer); 118dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it == array->end()) { 119dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return -ENOENT; 120dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 121dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 122d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang native_handle_t *secureHandle = NULL; 123dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (secure) { 124a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker sp<SecureBuffer> secureData = 125a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker static_cast<SecureBuffer *>(it->mCodecBuffer.get()); 126d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang if (secureData->getDestinationType() != ICrypto::kDestinationTypeNativeHandle) { 127a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker return BAD_VALUE; 128a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker } 129d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang secureHandle = static_cast<native_handle_t *>(secureData->getDestinationPointer()); 130dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 1313b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang ssize_t result = -1; 1323b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang if (mCrypto != NULL) { 133d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang ICrypto::DestinationBuffer destination; 134d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang if (secure) { 135d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang destination.mType = ICrypto::kDestinationTypeNativeHandle; 136d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang destination.mHandle = secureHandle; 137d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang } else { 138d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang destination.mType = ICrypto::kDestinationTypeSharedMemory; 139d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang destination.mSharedMemory = mDecryptDestination; 140d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang } 141d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang 142d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang ICrypto::SourceBuffer source; 143d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang source.mSharedMemory = it->mSharedEncryptedBuffer; 144d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang source.mHeapSeqNum = mHeapSeqNum; 145d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang 1463b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang result = mCrypto->decrypt(key, iv, mode, pattern, 1476dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang source, it->mClientBuffer->offset(), 1486dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang subSamples, numSubSamples, destination, errorDetailMsg); 1493b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang 1503b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang if (result < 0) { 151d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang return result; 152d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang } 153d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang 154d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang if (destination.mType == ICrypto::kDestinationTypeSharedMemory) { 155d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang memcpy(it->mCodecBuffer->base(), destination.mSharedMemory->pointer(), result); 156d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang } 157d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang } else { 158d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang // Here we cast CryptoPlugin::SubSample to hardware::cas::native::V1_0::SubSample 159d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang // directly, the structure definitions should match as checked in DescramblerImpl.cpp. 160d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang hidl_vec<SubSample> hidlSubSamples; 161d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang hidlSubSamples.setToExternal((SubSample *)subSamples, numSubSamples, false /*own*/); 162d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang 163d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang ssize_t offset; 164d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang size_t size; 165d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang it->mSharedEncryptedBuffer->getMemory(&offset, &size); 166d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang hardware::cas::native::V1_0::SharedBuffer srcBuffer = { 16758ddee30e6cefde8a8f3d4d4aa55954e16c7bb18Chong Zhang .heapBase = *mHidlMemory, 168d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang .offset = (uint64_t) offset, 169d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang .size = size 170d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang }; 171d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang 172d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang DestinationBuffer dstBuffer; 173d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang if (secure) { 174d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang dstBuffer.type = BufferType::NATIVE_HANDLE; 175d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang dstBuffer.secureMemory = hidl_handle(secureHandle); 1763b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang } else { 177d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang dstBuffer.type = BufferType::SHARED_MEMORY; 178d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang dstBuffer.nonsecureMemory = srcBuffer; 1793b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang } 1803b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang 181d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang Status status = Status::OK; 182d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang hidl_string detailedError; 183d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang 184d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang auto returnVoid = mDescrambler->descramble( 185d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang key != NULL ? (ScramblingControl)key[0] : ScramblingControl::UNSCRAMBLED, 186d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang hidlSubSamples, 187d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang srcBuffer, 188d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang 0, 189d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang dstBuffer, 190d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang 0, 191d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang [&status, &result, &detailedError] ( 192d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang Status _status, uint32_t _bytesWritten, 193d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang const hidl_string& _detailedError) { 194d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang status = _status; 195d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang result = (ssize_t)_bytesWritten; 196d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang detailedError = _detailedError; 197d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang }); 198d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang 199d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang if (!returnVoid.isOk() || status != Status::OK || result < 0) { 200d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang ALOGE("descramble failed, trans=%s, status=%d, result=%zd", 201d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang returnVoid.description().c_str(), status, result); 202d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang return UNKNOWN_ERROR; 2033b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang } 204dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 205d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang ALOGV("descramble succeeded, %zd bytes", result); 206dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 207d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang if (dstBuffer.type == BufferType::SHARED_MEMORY) { 208d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang memcpy(it->mCodecBuffer->base(), 209d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang (uint8_t*)it->mSharedEncryptedBuffer->pointer(), result); 210d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang } 211a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker } 212a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker 213dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mCodecBuffer->setRange(0, result); 214dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 215dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim // Copy metadata from client to codec buffer. 216dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mCodecBuffer->meta()->clear(); 217dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim int64_t timeUs; 218dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim CHECK(it->mClientBuffer->meta()->findInt64("timeUs", &timeUs)); 219dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mCodecBuffer->meta()->setInt64("timeUs", timeUs); 220dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim int32_t eos; 221dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it->mClientBuffer->meta()->findInt32("eos", &eos)) { 222dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mCodecBuffer->meta()->setInt32("eos", eos); 223dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 224dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim int32_t csd; 225dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it->mClientBuffer->meta()->findInt32("csd", &csd)) { 226dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mCodecBuffer->meta()->setInt32("csd", csd); 227dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 228dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 229dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ALOGV("queueSecureInputBuffer #%d", it->mBufferId); 230dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim sp<AMessage> msg = mInputBufferFilled->dup(); 231dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setObject("buffer", it->mCodecBuffer); 232dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setInt32("buffer-id", it->mBufferId); 233dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->post(); 234dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return OK; 235dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 236dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 237dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimstatus_t ACodecBufferChannel::renderOutputBuffer( 238dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim const sp<MediaCodecBuffer> &buffer, int64_t timestampNs) { 239dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::shared_ptr<const std::vector<const BufferInfo>> array( 240dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_load(&mOutputBuffers)); 241dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim BufferInfoIterator it = findClientBuffer(array, buffer); 242dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it == array->end()) { 243dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return -ENOENT; 244dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 245dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 246dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ALOGV("renderOutputBuffer #%d", it->mBufferId); 247dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim sp<AMessage> msg = mOutputBufferDrained->dup(); 248dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setObject("buffer", buffer); 249dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setInt32("buffer-id", it->mBufferId); 250dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setInt32("render", true); 251dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setInt64("timestampNs", timestampNs); 252dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->post(); 253dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return OK; 254dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 255dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 256dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimstatus_t ACodecBufferChannel::discardBuffer(const sp<MediaCodecBuffer> &buffer) { 257dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::shared_ptr<const std::vector<const BufferInfo>> array( 258dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_load(&mInputBuffers)); 259dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim bool input = true; 260dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim BufferInfoIterator it = findClientBuffer(array, buffer); 261dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it == array->end()) { 262dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim array = std::atomic_load(&mOutputBuffers); 263dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim input = false; 264dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it = findClientBuffer(array, buffer); 265dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it == array->end()) { 266dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return -ENOENT; 267dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 268dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 269dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ALOGV("discardBuffer #%d", it->mBufferId); 270dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim sp<AMessage> msg = input ? mInputBufferFilled->dup() : mOutputBufferDrained->dup(); 271dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setObject("buffer", it->mCodecBuffer); 272dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setInt32("buffer-id", it->mBufferId); 273dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->setInt32("discarded", true); 274dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim msg->post(); 275dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return OK; 276dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 277dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 278dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid ACodecBufferChannel::getInputBufferArray(Vector<sp<MediaCodecBuffer>> *array) { 279dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::shared_ptr<const std::vector<const BufferInfo>> inputBuffers( 280dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_load(&mInputBuffers)); 281dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim array->clear(); 282dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim for (const BufferInfo &elem : *inputBuffers) { 283dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim array->push_back(elem.mClientBuffer); 284dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 285dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 286dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 287dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid ACodecBufferChannel::getOutputBufferArray(Vector<sp<MediaCodecBuffer>> *array) { 288dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::shared_ptr<const std::vector<const BufferInfo>> outputBuffers( 289dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_load(&mOutputBuffers)); 290dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim array->clear(); 291dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim for (const BufferInfo &elem : *outputBuffers) { 292dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim array->push_back(elem.mClientBuffer); 293dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 294dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 295dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 296d07c92742fc5801cab8e99801f591365986acbe9Chong Zhangsp<MemoryDealer> ACodecBufferChannel::makeMemoryDealer(size_t heapSize) { 297d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang sp<MemoryDealer> dealer; 2986dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang if (mDealer != nullptr && mCrypto != nullptr && mHeapSeqNum >= 0) { 2996dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang mCrypto->unsetHeap(mHeapSeqNum); 300d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang } 301d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang dealer = new MemoryDealer(heapSize, "ACodecBufferChannel"); 302d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang if (mCrypto != nullptr) { 3036dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang int32_t seqNum = mCrypto->setHeap(dealer->getMemoryHeap()); 3046dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang if (seqNum >= 0) { 3056dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang mHeapSeqNum = seqNum; 306d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang ALOGV("setHeap returned mHeapSeqNum=%d", mHeapSeqNum); 3076dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang } else { 3086dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang mHeapSeqNum = -1; 309d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang ALOGE("setHeap failed, setting mHeapSeqNum=-1"); 310d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang } 311d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang } else if (mDescrambler != nullptr) { 312d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang sp<IMemoryHeap> heap = dealer->getMemoryHeap(); 31358ddee30e6cefde8a8f3d4d4aa55954e16c7bb18Chong Zhang mHidlMemory = fromHeap(heap); 31458ddee30e6cefde8a8f3d4d4aa55954e16c7bb18Chong Zhang if (mHidlMemory != NULL) { 315d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang ALOGV("created hidl_memory for descrambler"); 316d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang } else { 317d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang ALOGE("failed to create hidl_memory for descrambler"); 3186dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang } 319d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang } 320d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang return dealer; 321d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang} 322d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang 3234a9ab2a382558941ea7fe92324a3d97848686ca8Dongwon Kangvoid ACodecBufferChannel::setInputBufferArray(const std::vector<BufferAndId> &array) { 3243b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang if (hasCryptoOrDescrambler()) { 325dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim size_t totalSize = std::accumulate( 326dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim array.begin(), array.end(), 0u, 327dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim [alignment = MemoryDealer::getAllocationAlignment()] 328dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim (size_t sum, const BufferAndId& elem) { 329dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return sum + align(elem.mBuffer->capacity(), alignment); 330dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim }); 331a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker size_t maxSize = std::accumulate( 332a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker array.begin(), array.end(), 0u, 333a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker [alignment = MemoryDealer::getAllocationAlignment()] 334a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker (size_t max, const BufferAndId& elem) { 335a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker return std::max(max, align(elem.mBuffer->capacity(), alignment)); 336a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker }); 337d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang size_t destinationBufferSize = maxSize; 338d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang size_t heapSize = totalSize + destinationBufferSize; 3394c161506a542671f96177b16830f9b362f7a6c61Jeff Tinker if (heapSize > 0) { 3404c161506a542671f96177b16830f9b362f7a6c61Jeff Tinker mDealer = makeMemoryDealer(heapSize); 3414c161506a542671f96177b16830f9b362f7a6c61Jeff Tinker mDecryptDestination = mDealer->allocate(destinationBufferSize); 3424c161506a542671f96177b16830f9b362f7a6c61Jeff Tinker } 343dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 344dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::vector<const BufferInfo> inputBuffers; 345dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim for (const BufferAndId &elem : array) { 346dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim sp<IMemory> sharedEncryptedBuffer; 3473b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang if (hasCryptoOrDescrambler()) { 348dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim sharedEncryptedBuffer = mDealer->allocate(elem.mBuffer->capacity()); 349dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 350dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim inputBuffers.emplace_back(elem.mBuffer, elem.mBufferId, sharedEncryptedBuffer); 351dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 352dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_store( 353dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim &mInputBuffers, 354dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::make_shared<const std::vector<const BufferInfo>>(inputBuffers)); 355dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 356dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 357dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid ACodecBufferChannel::setOutputBufferArray(const std::vector<BufferAndId> &array) { 358dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::vector<const BufferInfo> outputBuffers; 359dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim for (const BufferAndId &elem : array) { 360dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim outputBuffers.emplace_back(elem.mBuffer, elem.mBufferId, nullptr); 361dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 362dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_store( 363dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim &mOutputBuffers, 364dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::make_shared<const std::vector<const BufferInfo>>(outputBuffers)); 365dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 366dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 367dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid ACodecBufferChannel::fillThisBuffer(IOMX::buffer_id bufferId) { 368dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ALOGV("fillThisBuffer #%d", bufferId); 369dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::shared_ptr<const std::vector<const BufferInfo>> array( 370dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_load(&mInputBuffers)); 371dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim BufferInfoIterator it = findBufferId(array, bufferId); 372dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 373dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it == array->end()) { 374dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ALOGE("fillThisBuffer: unrecognized buffer #%d", bufferId); 375dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return; 376dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 377dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it->mClientBuffer != it->mCodecBuffer) { 378dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mClientBuffer->setFormat(it->mCodecBuffer->format()); 379dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 380dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 381dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim mCallback->onInputBufferAvailable( 382dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::distance(array->begin(), it), 383dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mClientBuffer); 384dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 385dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 386dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid ACodecBufferChannel::drainThisBuffer( 387dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim IOMX::buffer_id bufferId, 388dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim OMX_U32 omxFlags) { 389dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ALOGV("drainThisBuffer #%d", bufferId); 390dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::shared_ptr<const std::vector<const BufferInfo>> array( 391dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::atomic_load(&mOutputBuffers)); 392dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim BufferInfoIterator it = findBufferId(array, bufferId); 393dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 394dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it == array->end()) { 395dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim ALOGE("drainThisBuffer: unrecognized buffer #%d", bufferId); 396dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim return; 397dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 398dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (it->mClientBuffer != it->mCodecBuffer) { 399dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mClientBuffer->setFormat(it->mCodecBuffer->format()); 400dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 401dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 402dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim uint32_t flags = 0; 403dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) { 404dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim flags |= MediaCodec::BUFFER_FLAG_SYNCFRAME; 405dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 406dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) { 407dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim flags |= MediaCodec::BUFFER_FLAG_CODECCONFIG; 408dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 409dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim if (omxFlags & OMX_BUFFERFLAG_EOS) { 410dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim flags |= MediaCodec::BUFFER_FLAG_EOS; 411dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim } 412dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mClientBuffer->meta()->setInt32("flags", flags); 413dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 414dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim mCallback->onOutputBufferAvailable( 415dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim std::distance(array->begin(), it), 416dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim it->mClientBuffer); 417dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} 418dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim 419dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim} // namespace android 420