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