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