1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker * Copyright 2019, The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker *
4*ec779b8eSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker *
8*ec779b8eSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker *
10*ec779b8eSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker */
16*ec779b8eSAndroid Build Coastguard Worker
17*ec779b8eSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
18*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "CCodecBuffers"
19*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
20*ec779b8eSAndroid Build Coastguard Worker
21*ec779b8eSAndroid Build Coastguard Worker #include <numeric>
22*ec779b8eSAndroid Build Coastguard Worker
23*ec779b8eSAndroid Build Coastguard Worker #include <C2AllocatorGralloc.h>
24*ec779b8eSAndroid Build Coastguard Worker #include <C2PlatformSupport.h>
25*ec779b8eSAndroid Build Coastguard Worker
26*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/ADebug.h>
27*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/AUtils.h>
28*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/MediaDefs.h>
29*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/CodecBase.h>
30*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/MediaCodecConstants.h>
31*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/SkipCutBuffer.h>
32*ec779b8eSAndroid Build Coastguard Worker #include <mediadrm/ICrypto.h>
33*ec779b8eSAndroid Build Coastguard Worker
34*ec779b8eSAndroid Build Coastguard Worker #include "CCodecBuffers.h"
35*ec779b8eSAndroid Build Coastguard Worker #include "Codec2Mapper.h"
36*ec779b8eSAndroid Build Coastguard Worker
37*ec779b8eSAndroid Build Coastguard Worker namespace android {
38*ec779b8eSAndroid Build Coastguard Worker
39*ec779b8eSAndroid Build Coastguard Worker namespace {
40*ec779b8eSAndroid Build Coastguard Worker
41*ec779b8eSAndroid Build Coastguard Worker constexpr uint32_t PIXEL_FORMAT_UNKNOWN = 0;
42*ec779b8eSAndroid Build Coastguard Worker
AllocateInputGraphicBuffer(const std::shared_ptr<C2BlockPool> & pool,const sp<AMessage> & format,uint32_t pixelFormat,const C2MemoryUsage & usage,const std::shared_ptr<LocalBufferPool> & localBufferPool)43*ec779b8eSAndroid Build Coastguard Worker sp<GraphicBlockBuffer> AllocateInputGraphicBuffer(
44*ec779b8eSAndroid Build Coastguard Worker const std::shared_ptr<C2BlockPool> &pool,
45*ec779b8eSAndroid Build Coastguard Worker const sp<AMessage> &format,
46*ec779b8eSAndroid Build Coastguard Worker uint32_t pixelFormat,
47*ec779b8eSAndroid Build Coastguard Worker const C2MemoryUsage &usage,
48*ec779b8eSAndroid Build Coastguard Worker const std::shared_ptr<LocalBufferPool> &localBufferPool) {
49*ec779b8eSAndroid Build Coastguard Worker int32_t width, height;
50*ec779b8eSAndroid Build Coastguard Worker if (!format->findInt32("width", &width) || !format->findInt32("height", &height)) {
51*ec779b8eSAndroid Build Coastguard Worker ALOGD("format lacks width or height");
52*ec779b8eSAndroid Build Coastguard Worker return nullptr;
53*ec779b8eSAndroid Build Coastguard Worker }
54*ec779b8eSAndroid Build Coastguard Worker
55*ec779b8eSAndroid Build Coastguard Worker int64_t usageValue = 0;
56*ec779b8eSAndroid Build Coastguard Worker (void)format->findInt64("android._C2MemoryUsage", &usageValue);
57*ec779b8eSAndroid Build Coastguard Worker C2MemoryUsage fullUsage{usageValue | usage.expected};
58*ec779b8eSAndroid Build Coastguard Worker
59*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<C2GraphicBlock> block;
60*ec779b8eSAndroid Build Coastguard Worker c2_status_t err = pool->fetchGraphicBlock(
61*ec779b8eSAndroid Build Coastguard Worker align(width, 2), align(height, 2), pixelFormat, fullUsage, &block);
62*ec779b8eSAndroid Build Coastguard Worker if (err != C2_OK) {
63*ec779b8eSAndroid Build Coastguard Worker ALOGD("fetch graphic block failed: %d", err);
64*ec779b8eSAndroid Build Coastguard Worker return nullptr;
65*ec779b8eSAndroid Build Coastguard Worker }
66*ec779b8eSAndroid Build Coastguard Worker
67*ec779b8eSAndroid Build Coastguard Worker return GraphicBlockBuffer::Allocate(
68*ec779b8eSAndroid Build Coastguard Worker format,
69*ec779b8eSAndroid Build Coastguard Worker block,
70*ec779b8eSAndroid Build Coastguard Worker [localBufferPool](size_t capacity) {
71*ec779b8eSAndroid Build Coastguard Worker return localBufferPool->newBuffer(capacity);
72*ec779b8eSAndroid Build Coastguard Worker });
73*ec779b8eSAndroid Build Coastguard Worker }
74*ec779b8eSAndroid Build Coastguard Worker
75*ec779b8eSAndroid Build Coastguard Worker } // namespace
76*ec779b8eSAndroid Build Coastguard Worker
77*ec779b8eSAndroid Build Coastguard Worker // CCodecBuffers
78*ec779b8eSAndroid Build Coastguard Worker
setFormat(const sp<AMessage> & format)79*ec779b8eSAndroid Build Coastguard Worker void CCodecBuffers::setFormat(const sp<AMessage> &format) {
80*ec779b8eSAndroid Build Coastguard Worker CHECK(format != nullptr);
81*ec779b8eSAndroid Build Coastguard Worker mFormat = format;
82*ec779b8eSAndroid Build Coastguard Worker }
83*ec779b8eSAndroid Build Coastguard Worker
dupFormat()84*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> CCodecBuffers::dupFormat() {
85*ec779b8eSAndroid Build Coastguard Worker return mFormat != nullptr ? mFormat->dup() : nullptr;
86*ec779b8eSAndroid Build Coastguard Worker }
87*ec779b8eSAndroid Build Coastguard Worker
handleImageData(const sp<Codec2Buffer> & buffer)88*ec779b8eSAndroid Build Coastguard Worker void CCodecBuffers::handleImageData(const sp<Codec2Buffer> &buffer) {
89*ec779b8eSAndroid Build Coastguard Worker sp<ABuffer> imageDataCandidate = buffer->getImageData();
90*ec779b8eSAndroid Build Coastguard Worker if (imageDataCandidate == nullptr) {
91*ec779b8eSAndroid Build Coastguard Worker if (mFormatWithImageData) {
92*ec779b8eSAndroid Build Coastguard Worker // We previously sent the format with image data, so use the same format.
93*ec779b8eSAndroid Build Coastguard Worker buffer->setFormat(mFormatWithImageData);
94*ec779b8eSAndroid Build Coastguard Worker }
95*ec779b8eSAndroid Build Coastguard Worker return;
96*ec779b8eSAndroid Build Coastguard Worker }
97*ec779b8eSAndroid Build Coastguard Worker if (!mLastImageData
98*ec779b8eSAndroid Build Coastguard Worker || imageDataCandidate->size() != mLastImageData->size()
99*ec779b8eSAndroid Build Coastguard Worker || memcmp(imageDataCandidate->data(),
100*ec779b8eSAndroid Build Coastguard Worker mLastImageData->data(),
101*ec779b8eSAndroid Build Coastguard Worker mLastImageData->size()) != 0) {
102*ec779b8eSAndroid Build Coastguard Worker ALOGD("[%s] updating image-data", mName);
103*ec779b8eSAndroid Build Coastguard Worker mFormatWithImageData = dupFormat();
104*ec779b8eSAndroid Build Coastguard Worker mLastImageData = imageDataCandidate;
105*ec779b8eSAndroid Build Coastguard Worker mFormatWithImageData->setBuffer("image-data", imageDataCandidate);
106*ec779b8eSAndroid Build Coastguard Worker MediaImage2 *img = (MediaImage2*)imageDataCandidate->data();
107*ec779b8eSAndroid Build Coastguard Worker if (img->mNumPlanes > 0 && img->mType != img->MEDIA_IMAGE_TYPE_UNKNOWN) {
108*ec779b8eSAndroid Build Coastguard Worker int32_t stride = img->mPlane[0].mRowInc;
109*ec779b8eSAndroid Build Coastguard Worker mFormatWithImageData->setInt32(KEY_STRIDE, stride);
110*ec779b8eSAndroid Build Coastguard Worker mFormatWithImageData->setInt32(KEY_WIDTH, img->mWidth);
111*ec779b8eSAndroid Build Coastguard Worker mFormatWithImageData->setInt32(KEY_HEIGHT, img->mHeight);
112*ec779b8eSAndroid Build Coastguard Worker ALOGD("[%s] updating stride = %d, width: %d, height: %d",
113*ec779b8eSAndroid Build Coastguard Worker mName, stride, img->mWidth, img->mHeight);
114*ec779b8eSAndroid Build Coastguard Worker if (img->mNumPlanes > 1 && stride > 0) {
115*ec779b8eSAndroid Build Coastguard Worker int64_t offsetDelta =
116*ec779b8eSAndroid Build Coastguard Worker (int64_t)img->mPlane[1].mOffset - (int64_t)img->mPlane[0].mOffset;
117*ec779b8eSAndroid Build Coastguard Worker int32_t vstride = int32_t(offsetDelta / stride);
118*ec779b8eSAndroid Build Coastguard Worker mFormatWithImageData->setInt32(KEY_SLICE_HEIGHT, vstride);
119*ec779b8eSAndroid Build Coastguard Worker ALOGD("[%s] updating vstride = %d", mName, vstride);
120*ec779b8eSAndroid Build Coastguard Worker buffer->setRange(
121*ec779b8eSAndroid Build Coastguard Worker img->mPlane[0].mOffset,
122*ec779b8eSAndroid Build Coastguard Worker buffer->size() - img->mPlane[0].mOffset);
123*ec779b8eSAndroid Build Coastguard Worker }
124*ec779b8eSAndroid Build Coastguard Worker }
125*ec779b8eSAndroid Build Coastguard Worker }
126*ec779b8eSAndroid Build Coastguard Worker buffer->setFormat(mFormatWithImageData);
127*ec779b8eSAndroid Build Coastguard Worker }
128*ec779b8eSAndroid Build Coastguard Worker
getPixelFormatIfApplicable()129*ec779b8eSAndroid Build Coastguard Worker uint32_t CCodecBuffers::getPixelFormatIfApplicable() { return PIXEL_FORMAT_UNKNOWN; }
130*ec779b8eSAndroid Build Coastguard Worker
resetPixelFormatIfApplicable()131*ec779b8eSAndroid Build Coastguard Worker bool CCodecBuffers::resetPixelFormatIfApplicable() { return false; }
132*ec779b8eSAndroid Build Coastguard Worker
133*ec779b8eSAndroid Build Coastguard Worker // InputBuffers
134*ec779b8eSAndroid Build Coastguard Worker
cloneAndReleaseBuffer(const sp<MediaCodecBuffer> & buffer)135*ec779b8eSAndroid Build Coastguard Worker sp<Codec2Buffer> InputBuffers::cloneAndReleaseBuffer(const sp<MediaCodecBuffer> &buffer) {
136*ec779b8eSAndroid Build Coastguard Worker sp<Codec2Buffer> copy = createNewBuffer();
137*ec779b8eSAndroid Build Coastguard Worker if (copy == nullptr) {
138*ec779b8eSAndroid Build Coastguard Worker return nullptr;
139*ec779b8eSAndroid Build Coastguard Worker }
140*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<C2Buffer> c2buffer;
141*ec779b8eSAndroid Build Coastguard Worker if (!releaseBuffer(buffer, &c2buffer, true)) {
142*ec779b8eSAndroid Build Coastguard Worker return nullptr;
143*ec779b8eSAndroid Build Coastguard Worker }
144*ec779b8eSAndroid Build Coastguard Worker if (!copy->canCopy(c2buffer)) {
145*ec779b8eSAndroid Build Coastguard Worker return nullptr;
146*ec779b8eSAndroid Build Coastguard Worker }
147*ec779b8eSAndroid Build Coastguard Worker if (!copy->copy(c2buffer)) {
148*ec779b8eSAndroid Build Coastguard Worker return nullptr;
149*ec779b8eSAndroid Build Coastguard Worker }
150*ec779b8eSAndroid Build Coastguard Worker copy->meta()->extend(buffer->meta());
151*ec779b8eSAndroid Build Coastguard Worker return copy;
152*ec779b8eSAndroid Build Coastguard Worker }
153*ec779b8eSAndroid Build Coastguard Worker
154*ec779b8eSAndroid Build Coastguard Worker // MultiAccessUnitSkipCutBuffer for buffer and bufferInfos
155*ec779b8eSAndroid Build Coastguard Worker
156*ec779b8eSAndroid Build Coastguard Worker class MultiAccessUnitSkipCutBuffer : public SkipCutBuffer {
157*ec779b8eSAndroid Build Coastguard Worker
158*ec779b8eSAndroid Build Coastguard Worker public:
MultiAccessUnitSkipCutBuffer(int32_t skip,int32_t cut,size_t num16BitChannels)159*ec779b8eSAndroid Build Coastguard Worker explicit MultiAccessUnitSkipCutBuffer(
160*ec779b8eSAndroid Build Coastguard Worker int32_t skip, int32_t cut, size_t num16BitChannels):
161*ec779b8eSAndroid Build Coastguard Worker SkipCutBuffer(skip, cut, num16BitChannels),
162*ec779b8eSAndroid Build Coastguard Worker mFrontPaddingDelay(0), mSize(0) {
163*ec779b8eSAndroid Build Coastguard Worker }
clearAll()164*ec779b8eSAndroid Build Coastguard Worker void clearAll() {
165*ec779b8eSAndroid Build Coastguard Worker mInfos.clear();
166*ec779b8eSAndroid Build Coastguard Worker mFrontPaddingDelay = 0;
167*ec779b8eSAndroid Build Coastguard Worker mSize = 0;
168*ec779b8eSAndroid Build Coastguard Worker SkipCutBuffer::clear();
169*ec779b8eSAndroid Build Coastguard Worker }
170*ec779b8eSAndroid Build Coastguard Worker
~MultiAccessUnitSkipCutBuffer()171*ec779b8eSAndroid Build Coastguard Worker virtual ~MultiAccessUnitSkipCutBuffer() {
172*ec779b8eSAndroid Build Coastguard Worker
173*ec779b8eSAndroid Build Coastguard Worker }
174*ec779b8eSAndroid Build Coastguard Worker
submitMultiAccessUnits(const sp<MediaCodecBuffer> & buffer,int32_t sampleRate,size_t num16BitChannels,std::shared_ptr<const C2AccessUnitInfos::output> & infos)175*ec779b8eSAndroid Build Coastguard Worker void submitMultiAccessUnits(
176*ec779b8eSAndroid Build Coastguard Worker const sp<MediaCodecBuffer>& buffer,
177*ec779b8eSAndroid Build Coastguard Worker int32_t sampleRate, size_t num16BitChannels,
178*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<const C2AccessUnitInfos::output> &infos) {
179*ec779b8eSAndroid Build Coastguard Worker if (infos == nullptr) {
180*ec779b8eSAndroid Build Coastguard Worker // there is nothing to do more.
181*ec779b8eSAndroid Build Coastguard Worker SkipCutBuffer::submit(buffer);
182*ec779b8eSAndroid Build Coastguard Worker return;
183*ec779b8eSAndroid Build Coastguard Worker }
184*ec779b8eSAndroid Build Coastguard Worker typedef WrapperObject<std::vector<AccessUnitInfo>> BufferInfosWrapper;
185*ec779b8eSAndroid Build Coastguard Worker CHECK_EQ(mSize, SkipCutBuffer::size());
186*ec779b8eSAndroid Build Coastguard Worker sp<BufferInfosWrapper> bufferInfos{new BufferInfosWrapper(decltype(bufferInfos->value)())};
187*ec779b8eSAndroid Build Coastguard Worker uint32_t availableSize = buffer->size() + SkipCutBuffer::size();
188*ec779b8eSAndroid Build Coastguard Worker uint32_t frontPadding = mFrontPadding;
189*ec779b8eSAndroid Build Coastguard Worker int32_t lastEmptyAccessUnitIndex = -1;
190*ec779b8eSAndroid Build Coastguard Worker int64_t byteInUs = 0;
191*ec779b8eSAndroid Build Coastguard Worker if (sampleRate > 0 && num16BitChannels > 0) {
192*ec779b8eSAndroid Build Coastguard Worker byteInUs = (1000000u / (sampleRate * num16BitChannels * 2));
193*ec779b8eSAndroid Build Coastguard Worker }
194*ec779b8eSAndroid Build Coastguard Worker if (frontPadding > 0) {
195*ec779b8eSAndroid Build Coastguard Worker mInfos.clear();
196*ec779b8eSAndroid Build Coastguard Worker mSize = 0;
197*ec779b8eSAndroid Build Coastguard Worker }
198*ec779b8eSAndroid Build Coastguard Worker for (int i = 0 ; i < infos->flexCount() && frontPadding > 0; i++) {
199*ec779b8eSAndroid Build Coastguard Worker uint32_t flagsInPadding = 0;
200*ec779b8eSAndroid Build Coastguard Worker int64_t timeInPadding = 0;
201*ec779b8eSAndroid Build Coastguard Worker if (infos->m.values[i].size <= frontPadding) {
202*ec779b8eSAndroid Build Coastguard Worker // we have more front padding so this buffer is not going to be used.
203*ec779b8eSAndroid Build Coastguard Worker int32_t consumed = infos->m.values[i].size;
204*ec779b8eSAndroid Build Coastguard Worker frontPadding -= consumed;
205*ec779b8eSAndroid Build Coastguard Worker mFrontPaddingDelay += byteInUs * (consumed);
206*ec779b8eSAndroid Build Coastguard Worker availableSize -= consumed;
207*ec779b8eSAndroid Build Coastguard Worker flagsInPadding |= toMediaCodecFlags(infos->m.values[i].flags);
208*ec779b8eSAndroid Build Coastguard Worker timeInPadding = infos->m.values[i].timestamp;
209*ec779b8eSAndroid Build Coastguard Worker } else {
210*ec779b8eSAndroid Build Coastguard Worker C2AccessUnitInfosStruct info = infos->m.values[i];
211*ec779b8eSAndroid Build Coastguard Worker mFrontPaddingDelay += byteInUs * (frontPadding);
212*ec779b8eSAndroid Build Coastguard Worker info.size -= frontPadding;
213*ec779b8eSAndroid Build Coastguard Worker info.timestamp -= mFrontPaddingDelay;
214*ec779b8eSAndroid Build Coastguard Worker availableSize -= frontPadding;
215*ec779b8eSAndroid Build Coastguard Worker flagsInPadding |= toMediaCodecFlags(infos->m.values[i].flags);
216*ec779b8eSAndroid Build Coastguard Worker timeInPadding = infos->m.values[i].timestamp;
217*ec779b8eSAndroid Build Coastguard Worker frontPadding = 0;
218*ec779b8eSAndroid Build Coastguard Worker mInfos.push_back(info);
219*ec779b8eSAndroid Build Coastguard Worker mSize += info.size;
220*ec779b8eSAndroid Build Coastguard Worker }
221*ec779b8eSAndroid Build Coastguard Worker if (flagsInPadding != 0) {
222*ec779b8eSAndroid Build Coastguard Worker bufferInfos->value.emplace_back(
223*ec779b8eSAndroid Build Coastguard Worker flagsInPadding, 0, timeInPadding);
224*ec779b8eSAndroid Build Coastguard Worker }
225*ec779b8eSAndroid Build Coastguard Worker lastEmptyAccessUnitIndex = i;
226*ec779b8eSAndroid Build Coastguard Worker }
227*ec779b8eSAndroid Build Coastguard Worker if (frontPadding <= 0) {
228*ec779b8eSAndroid Build Coastguard Worker // process what's already in the buffer first
229*ec779b8eSAndroid Build Coastguard Worker auto it = mInfos.begin();
230*ec779b8eSAndroid Build Coastguard Worker while (it != mInfos.end() && availableSize > mBackPadding) {
231*ec779b8eSAndroid Build Coastguard Worker // we have samples to send out.
232*ec779b8eSAndroid Build Coastguard Worker if ((availableSize - it->size) >= mBackPadding) {
233*ec779b8eSAndroid Build Coastguard Worker // this is totally used here.
234*ec779b8eSAndroid Build Coastguard Worker int32_t consumed = it->size;
235*ec779b8eSAndroid Build Coastguard Worker bufferInfos->value.emplace_back(
236*ec779b8eSAndroid Build Coastguard Worker toMediaCodecFlags(it->flags), consumed, it->timestamp);
237*ec779b8eSAndroid Build Coastguard Worker availableSize -= consumed;
238*ec779b8eSAndroid Build Coastguard Worker mSize -= consumed;
239*ec779b8eSAndroid Build Coastguard Worker it = mInfos.erase(it);
240*ec779b8eSAndroid Build Coastguard Worker } else {
241*ec779b8eSAndroid Build Coastguard Worker int32_t consumed = availableSize - mBackPadding;
242*ec779b8eSAndroid Build Coastguard Worker bufferInfos->value.emplace_back(
243*ec779b8eSAndroid Build Coastguard Worker toMediaCodecFlags(it->flags),
244*ec779b8eSAndroid Build Coastguard Worker consumed,
245*ec779b8eSAndroid Build Coastguard Worker it->timestamp);
246*ec779b8eSAndroid Build Coastguard Worker it->size -= consumed;
247*ec779b8eSAndroid Build Coastguard Worker it->timestamp += consumed * byteInUs;
248*ec779b8eSAndroid Build Coastguard Worker availableSize -= consumed;
249*ec779b8eSAndroid Build Coastguard Worker mSize -= consumed;
250*ec779b8eSAndroid Build Coastguard Worker it++;
251*ec779b8eSAndroid Build Coastguard Worker }
252*ec779b8eSAndroid Build Coastguard Worker }
253*ec779b8eSAndroid Build Coastguard Worker // if buffer has more process all of it and keep the remaining info.
254*ec779b8eSAndroid Build Coastguard Worker for (int i = (lastEmptyAccessUnitIndex + 1) ; i < infos->flexCount() ; i++) {
255*ec779b8eSAndroid Build Coastguard Worker // upddate updatedInfo and mInfos
256*ec779b8eSAndroid Build Coastguard Worker if (availableSize > mBackPadding) {
257*ec779b8eSAndroid Build Coastguard Worker // we have to take data from the new buffer.
258*ec779b8eSAndroid Build Coastguard Worker if (availableSize - infos->m.values[i].size >= mBackPadding) {
259*ec779b8eSAndroid Build Coastguard Worker // we are using this info
260*ec779b8eSAndroid Build Coastguard Worker int32_t consumed = infos->m.values[i].size;
261*ec779b8eSAndroid Build Coastguard Worker bufferInfos->value.emplace_back(
262*ec779b8eSAndroid Build Coastguard Worker toMediaCodecFlags(infos->m.values[i].flags),
263*ec779b8eSAndroid Build Coastguard Worker consumed,
264*ec779b8eSAndroid Build Coastguard Worker infos->m.values[i].timestamp - mFrontPaddingDelay);
265*ec779b8eSAndroid Build Coastguard Worker availableSize -= consumed;
266*ec779b8eSAndroid Build Coastguard Worker } else {
267*ec779b8eSAndroid Build Coastguard Worker // if we need to update the size
268*ec779b8eSAndroid Build Coastguard Worker C2AccessUnitInfosStruct info = infos->m.values[i];
269*ec779b8eSAndroid Build Coastguard Worker int32_t consumed = availableSize - mBackPadding;
270*ec779b8eSAndroid Build Coastguard Worker bufferInfos->value.emplace_back(
271*ec779b8eSAndroid Build Coastguard Worker toMediaCodecFlags(infos->m.values[i].flags),
272*ec779b8eSAndroid Build Coastguard Worker consumed,
273*ec779b8eSAndroid Build Coastguard Worker infos->m.values[i].timestamp - mFrontPaddingDelay);
274*ec779b8eSAndroid Build Coastguard Worker info.size -= consumed;
275*ec779b8eSAndroid Build Coastguard Worker info.timestamp = info.timestamp - mFrontPaddingDelay +
276*ec779b8eSAndroid Build Coastguard Worker consumed * byteInUs;
277*ec779b8eSAndroid Build Coastguard Worker mInfos.push_back(info);
278*ec779b8eSAndroid Build Coastguard Worker availableSize -= consumed;
279*ec779b8eSAndroid Build Coastguard Worker mSize += info.size;
280*ec779b8eSAndroid Build Coastguard Worker }
281*ec779b8eSAndroid Build Coastguard Worker } else {
282*ec779b8eSAndroid Build Coastguard Worker // we have to maintain infos
283*ec779b8eSAndroid Build Coastguard Worker C2AccessUnitInfosStruct info = infos->m.values[i];
284*ec779b8eSAndroid Build Coastguard Worker info.timestamp -= mFrontPaddingDelay;
285*ec779b8eSAndroid Build Coastguard Worker mInfos.push_back(info);
286*ec779b8eSAndroid Build Coastguard Worker mSize += info.size;
287*ec779b8eSAndroid Build Coastguard Worker }
288*ec779b8eSAndroid Build Coastguard Worker }
289*ec779b8eSAndroid Build Coastguard Worker }
290*ec779b8eSAndroid Build Coastguard Worker SkipCutBuffer::submit(buffer);
291*ec779b8eSAndroid Build Coastguard Worker infos = nullptr;
292*ec779b8eSAndroid Build Coastguard Worker if (!bufferInfos->value.empty()) {
293*ec779b8eSAndroid Build Coastguard Worker buffer->meta()->setObject("accessUnitInfo", bufferInfos);
294*ec779b8eSAndroid Build Coastguard Worker }
295*ec779b8eSAndroid Build Coastguard Worker }
296*ec779b8eSAndroid Build Coastguard Worker protected:
297*ec779b8eSAndroid Build Coastguard Worker // Flags can come with individual BufferInfos
298*ec779b8eSAndroid Build Coastguard Worker // when used with large frame audio
299*ec779b8eSAndroid Build Coastguard Worker constexpr static std::initializer_list<std::pair<uint32_t, uint32_t>> flagList = {
300*ec779b8eSAndroid Build Coastguard Worker {BUFFER_FLAG_CODEC_CONFIG, C2FrameData::FLAG_CODEC_CONFIG},
301*ec779b8eSAndroid Build Coastguard Worker {BUFFER_FLAG_END_OF_STREAM, C2FrameData::FLAG_END_OF_STREAM},
302*ec779b8eSAndroid Build Coastguard Worker {BUFFER_FLAG_DECODE_ONLY, C2FrameData::FLAG_DROP_FRAME}
303*ec779b8eSAndroid Build Coastguard Worker };
304*ec779b8eSAndroid Build Coastguard Worker
toMediaCodecFlags(uint32_t flags)305*ec779b8eSAndroid Build Coastguard Worker static uint32_t toMediaCodecFlags(uint32_t flags) {
306*ec779b8eSAndroid Build Coastguard Worker return std::transform_reduce(
307*ec779b8eSAndroid Build Coastguard Worker flagList.begin(), flagList.end(),
308*ec779b8eSAndroid Build Coastguard Worker 0u,
309*ec779b8eSAndroid Build Coastguard Worker std::bit_or{},
310*ec779b8eSAndroid Build Coastguard Worker [flags](const std::pair<uint32_t, uint32_t> &entry) {
311*ec779b8eSAndroid Build Coastguard Worker return (flags & entry.second) ? entry.first : 0;
312*ec779b8eSAndroid Build Coastguard Worker });
313*ec779b8eSAndroid Build Coastguard Worker }
314*ec779b8eSAndroid Build Coastguard Worker std::list<C2AccessUnitInfosStruct> mInfos;
315*ec779b8eSAndroid Build Coastguard Worker int64_t mFrontPaddingDelay;
316*ec779b8eSAndroid Build Coastguard Worker size_t mSize;
317*ec779b8eSAndroid Build Coastguard Worker };
318*ec779b8eSAndroid Build Coastguard Worker
319*ec779b8eSAndroid Build Coastguard Worker // OutputBuffers
320*ec779b8eSAndroid Build Coastguard Worker
OutputBuffers(const char * componentName,const char * name)321*ec779b8eSAndroid Build Coastguard Worker OutputBuffers::OutputBuffers(const char *componentName, const char *name)
322*ec779b8eSAndroid Build Coastguard Worker : CCodecBuffers(componentName, name) { }
323*ec779b8eSAndroid Build Coastguard Worker
324*ec779b8eSAndroid Build Coastguard Worker OutputBuffers::~OutputBuffers() = default;
325*ec779b8eSAndroid Build Coastguard Worker
initSkipCutBuffer(int32_t delay,int32_t padding,int32_t sampleRate,int32_t channelCount)326*ec779b8eSAndroid Build Coastguard Worker void OutputBuffers::initSkipCutBuffer(
327*ec779b8eSAndroid Build Coastguard Worker int32_t delay, int32_t padding, int32_t sampleRate, int32_t channelCount) {
328*ec779b8eSAndroid Build Coastguard Worker CHECK(mSkipCutBuffer == nullptr);
329*ec779b8eSAndroid Build Coastguard Worker mDelay = delay;
330*ec779b8eSAndroid Build Coastguard Worker mPadding = padding;
331*ec779b8eSAndroid Build Coastguard Worker mSampleRate = sampleRate;
332*ec779b8eSAndroid Build Coastguard Worker mChannelCount = channelCount;
333*ec779b8eSAndroid Build Coastguard Worker setSkipCutBuffer(delay, padding);
334*ec779b8eSAndroid Build Coastguard Worker }
335*ec779b8eSAndroid Build Coastguard Worker
updateSkipCutBuffer(int32_t sampleRate,int32_t channelCount)336*ec779b8eSAndroid Build Coastguard Worker void OutputBuffers::updateSkipCutBuffer(int32_t sampleRate, int32_t channelCount) {
337*ec779b8eSAndroid Build Coastguard Worker if (mSkipCutBuffer == nullptr) {
338*ec779b8eSAndroid Build Coastguard Worker return;
339*ec779b8eSAndroid Build Coastguard Worker }
340*ec779b8eSAndroid Build Coastguard Worker if (mSampleRate == sampleRate && mChannelCount == channelCount) {
341*ec779b8eSAndroid Build Coastguard Worker return;
342*ec779b8eSAndroid Build Coastguard Worker }
343*ec779b8eSAndroid Build Coastguard Worker int32_t delay = mDelay;
344*ec779b8eSAndroid Build Coastguard Worker int32_t padding = mPadding;
345*ec779b8eSAndroid Build Coastguard Worker if (sampleRate != mSampleRate) {
346*ec779b8eSAndroid Build Coastguard Worker delay = ((int64_t)delay * sampleRate) / mSampleRate;
347*ec779b8eSAndroid Build Coastguard Worker padding = ((int64_t)padding * sampleRate) / mSampleRate;
348*ec779b8eSAndroid Build Coastguard Worker }
349*ec779b8eSAndroid Build Coastguard Worker mSampleRate = sampleRate;
350*ec779b8eSAndroid Build Coastguard Worker mChannelCount = channelCount;
351*ec779b8eSAndroid Build Coastguard Worker setSkipCutBuffer(delay, padding);
352*ec779b8eSAndroid Build Coastguard Worker }
353*ec779b8eSAndroid Build Coastguard Worker
updateSkipCutBuffer(const sp<AMessage> & format)354*ec779b8eSAndroid Build Coastguard Worker void OutputBuffers::updateSkipCutBuffer(const sp<AMessage> &format) {
355*ec779b8eSAndroid Build Coastguard Worker AString mediaType;
356*ec779b8eSAndroid Build Coastguard Worker if (format->findString(KEY_MIME, &mediaType)
357*ec779b8eSAndroid Build Coastguard Worker && mediaType == MIMETYPE_AUDIO_RAW) {
358*ec779b8eSAndroid Build Coastguard Worker int32_t channelCount;
359*ec779b8eSAndroid Build Coastguard Worker int32_t sampleRate;
360*ec779b8eSAndroid Build Coastguard Worker if (format->findInt32(KEY_CHANNEL_COUNT, &channelCount)
361*ec779b8eSAndroid Build Coastguard Worker && format->findInt32(KEY_SAMPLE_RATE, &sampleRate)) {
362*ec779b8eSAndroid Build Coastguard Worker updateSkipCutBuffer(sampleRate, channelCount);
363*ec779b8eSAndroid Build Coastguard Worker }
364*ec779b8eSAndroid Build Coastguard Worker }
365*ec779b8eSAndroid Build Coastguard Worker }
366*ec779b8eSAndroid Build Coastguard Worker
submit(const sp<MediaCodecBuffer> & buffer)367*ec779b8eSAndroid Build Coastguard Worker void OutputBuffers::submit(const sp<MediaCodecBuffer> &buffer) {
368*ec779b8eSAndroid Build Coastguard Worker if (mSkipCutBuffer != nullptr) {
369*ec779b8eSAndroid Build Coastguard Worker mSkipCutBuffer->submit(buffer);
370*ec779b8eSAndroid Build Coastguard Worker }
371*ec779b8eSAndroid Build Coastguard Worker }
372*ec779b8eSAndroid Build Coastguard Worker
submit(const sp<MediaCodecBuffer> & buffer,int32_t sampleRate,int32_t channelCount,std::shared_ptr<const C2AccessUnitInfos::output> & infos)373*ec779b8eSAndroid Build Coastguard Worker bool OutputBuffers::submit(const sp<MediaCodecBuffer> &buffer, int32_t sampleRate,
374*ec779b8eSAndroid Build Coastguard Worker int32_t channelCount, std::shared_ptr<const C2AccessUnitInfos::output> &infos) {
375*ec779b8eSAndroid Build Coastguard Worker if (mSkipCutBuffer == nullptr) {
376*ec779b8eSAndroid Build Coastguard Worker return false;
377*ec779b8eSAndroid Build Coastguard Worker }
378*ec779b8eSAndroid Build Coastguard Worker mSkipCutBuffer->submitMultiAccessUnits(buffer, sampleRate, channelCount, infos);
379*ec779b8eSAndroid Build Coastguard Worker return true;
380*ec779b8eSAndroid Build Coastguard Worker }
381*ec779b8eSAndroid Build Coastguard Worker
setSkipCutBuffer(int32_t skip,int32_t cut)382*ec779b8eSAndroid Build Coastguard Worker void OutputBuffers::setSkipCutBuffer(int32_t skip, int32_t cut) {
383*ec779b8eSAndroid Build Coastguard Worker if (mSkipCutBuffer != nullptr) {
384*ec779b8eSAndroid Build Coastguard Worker size_t prevSize = mSkipCutBuffer->size();
385*ec779b8eSAndroid Build Coastguard Worker if (prevSize != 0u) {
386*ec779b8eSAndroid Build Coastguard Worker ALOGD("[%s] Replacing SkipCutBuffer holding %zu bytes", mName, prevSize);
387*ec779b8eSAndroid Build Coastguard Worker }
388*ec779b8eSAndroid Build Coastguard Worker }
389*ec779b8eSAndroid Build Coastguard Worker mSkipCutBuffer = new MultiAccessUnitSkipCutBuffer(skip, cut, mChannelCount);
390*ec779b8eSAndroid Build Coastguard Worker }
391*ec779b8eSAndroid Build Coastguard Worker
convert(const std::shared_ptr<C2Buffer> & src,sp<Codec2Buffer> * dst)392*ec779b8eSAndroid Build Coastguard Worker bool OutputBuffers::convert(
393*ec779b8eSAndroid Build Coastguard Worker const std::shared_ptr<C2Buffer> &src, sp<Codec2Buffer> *dst) {
394*ec779b8eSAndroid Build Coastguard Worker if (src && src->data().type() != C2BufferData::LINEAR) {
395*ec779b8eSAndroid Build Coastguard Worker return false;
396*ec779b8eSAndroid Build Coastguard Worker }
397*ec779b8eSAndroid Build Coastguard Worker int32_t configEncoding = kAudioEncodingPcm16bit;
398*ec779b8eSAndroid Build Coastguard Worker int32_t codecEncoding = kAudioEncodingPcm16bit;
399*ec779b8eSAndroid Build Coastguard Worker if (mFormat->findInt32("android._codec-pcm-encoding", &codecEncoding)
400*ec779b8eSAndroid Build Coastguard Worker && mFormat->findInt32("android._config-pcm-encoding", &configEncoding)) {
401*ec779b8eSAndroid Build Coastguard Worker if (mSrcEncoding != codecEncoding || mDstEncoding != configEncoding) {
402*ec779b8eSAndroid Build Coastguard Worker if (codecEncoding != configEncoding) {
403*ec779b8eSAndroid Build Coastguard Worker mDataConverter = AudioConverter::Create(
404*ec779b8eSAndroid Build Coastguard Worker (AudioEncoding)codecEncoding, (AudioEncoding)configEncoding);
405*ec779b8eSAndroid Build Coastguard Worker ALOGD_IF(mDataConverter, "[%s] Converter created from %d to %d",
406*ec779b8eSAndroid Build Coastguard Worker mName, codecEncoding, configEncoding);
407*ec779b8eSAndroid Build Coastguard Worker mFormatWithConverter = mFormat->dup();
408*ec779b8eSAndroid Build Coastguard Worker mFormatWithConverter->setInt32(KEY_PCM_ENCODING, configEncoding);
409*ec779b8eSAndroid Build Coastguard Worker } else {
410*ec779b8eSAndroid Build Coastguard Worker mDataConverter = nullptr;
411*ec779b8eSAndroid Build Coastguard Worker mFormatWithConverter = nullptr;
412*ec779b8eSAndroid Build Coastguard Worker }
413*ec779b8eSAndroid Build Coastguard Worker mSrcEncoding = codecEncoding;
414*ec779b8eSAndroid Build Coastguard Worker mDstEncoding = configEncoding;
415*ec779b8eSAndroid Build Coastguard Worker }
416*ec779b8eSAndroid Build Coastguard Worker if (int encoding; !mFormat->findInt32(KEY_PCM_ENCODING, &encoding)
417*ec779b8eSAndroid Build Coastguard Worker || encoding != mDstEncoding) {
418*ec779b8eSAndroid Build Coastguard Worker }
419*ec779b8eSAndroid Build Coastguard Worker }
420*ec779b8eSAndroid Build Coastguard Worker if (!mDataConverter) {
421*ec779b8eSAndroid Build Coastguard Worker return false;
422*ec779b8eSAndroid Build Coastguard Worker }
423*ec779b8eSAndroid Build Coastguard Worker sp<MediaCodecBuffer> srcBuffer;
424*ec779b8eSAndroid Build Coastguard Worker if (src) {
425*ec779b8eSAndroid Build Coastguard Worker srcBuffer = ConstLinearBlockBuffer::Allocate(mFormat, src);
426*ec779b8eSAndroid Build Coastguard Worker } else {
427*ec779b8eSAndroid Build Coastguard Worker srcBuffer = new MediaCodecBuffer(mFormat, new ABuffer(0));
428*ec779b8eSAndroid Build Coastguard Worker }
429*ec779b8eSAndroid Build Coastguard Worker if (!srcBuffer) {
430*ec779b8eSAndroid Build Coastguard Worker return false;
431*ec779b8eSAndroid Build Coastguard Worker }
432*ec779b8eSAndroid Build Coastguard Worker if (!*dst) {
433*ec779b8eSAndroid Build Coastguard Worker *dst = new Codec2Buffer(
434*ec779b8eSAndroid Build Coastguard Worker mFormat,
435*ec779b8eSAndroid Build Coastguard Worker new ABuffer(mDataConverter->targetSize(srcBuffer->size())));
436*ec779b8eSAndroid Build Coastguard Worker }
437*ec779b8eSAndroid Build Coastguard Worker sp<MediaCodecBuffer> dstBuffer = *dst;
438*ec779b8eSAndroid Build Coastguard Worker status_t err = mDataConverter->convert(srcBuffer, dstBuffer);
439*ec779b8eSAndroid Build Coastguard Worker if (err != OK) {
440*ec779b8eSAndroid Build Coastguard Worker ALOGD("[%s] buffer conversion failed: %d", mName, err);
441*ec779b8eSAndroid Build Coastguard Worker return false;
442*ec779b8eSAndroid Build Coastguard Worker }
443*ec779b8eSAndroid Build Coastguard Worker dstBuffer->setFormat(mFormatWithConverter);
444*ec779b8eSAndroid Build Coastguard Worker return true;
445*ec779b8eSAndroid Build Coastguard Worker }
446*ec779b8eSAndroid Build Coastguard Worker
clearStash()447*ec779b8eSAndroid Build Coastguard Worker void OutputBuffers::clearStash() {
448*ec779b8eSAndroid Build Coastguard Worker mPending.clear();
449*ec779b8eSAndroid Build Coastguard Worker mReorderStash.clear();
450*ec779b8eSAndroid Build Coastguard Worker mDepth = 0;
451*ec779b8eSAndroid Build Coastguard Worker mKey = C2Config::ORDINAL;
452*ec779b8eSAndroid Build Coastguard Worker }
453*ec779b8eSAndroid Build Coastguard Worker
flushStash()454*ec779b8eSAndroid Build Coastguard Worker void OutputBuffers::flushStash() {
455*ec779b8eSAndroid Build Coastguard Worker for (StashEntry& e : mPending) {
456*ec779b8eSAndroid Build Coastguard Worker e.notify = false;
457*ec779b8eSAndroid Build Coastguard Worker }
458*ec779b8eSAndroid Build Coastguard Worker for (StashEntry& e : mReorderStash) {
459*ec779b8eSAndroid Build Coastguard Worker e.notify = false;
460*ec779b8eSAndroid Build Coastguard Worker }
461*ec779b8eSAndroid Build Coastguard Worker }
462*ec779b8eSAndroid Build Coastguard Worker
getReorderDepth() const463*ec779b8eSAndroid Build Coastguard Worker uint32_t OutputBuffers::getReorderDepth() const {
464*ec779b8eSAndroid Build Coastguard Worker return mDepth;
465*ec779b8eSAndroid Build Coastguard Worker }
466*ec779b8eSAndroid Build Coastguard Worker
setReorderDepth(uint32_t depth)467*ec779b8eSAndroid Build Coastguard Worker void OutputBuffers::setReorderDepth(uint32_t depth) {
468*ec779b8eSAndroid Build Coastguard Worker mPending.splice(mPending.end(), mReorderStash);
469*ec779b8eSAndroid Build Coastguard Worker mDepth = depth;
470*ec779b8eSAndroid Build Coastguard Worker }
471*ec779b8eSAndroid Build Coastguard Worker
setReorderKey(C2Config::ordinal_key_t key)472*ec779b8eSAndroid Build Coastguard Worker void OutputBuffers::setReorderKey(C2Config::ordinal_key_t key) {
473*ec779b8eSAndroid Build Coastguard Worker mPending.splice(mPending.end(), mReorderStash);
474*ec779b8eSAndroid Build Coastguard Worker mKey = key;
475*ec779b8eSAndroid Build Coastguard Worker }
476*ec779b8eSAndroid Build Coastguard Worker
pushToStash(const std::shared_ptr<C2Buffer> & buffer,bool notify,int64_t timestamp,int32_t flags,const sp<AMessage> & format,const C2WorkOrdinalStruct & ordinal)477*ec779b8eSAndroid Build Coastguard Worker void OutputBuffers::pushToStash(
478*ec779b8eSAndroid Build Coastguard Worker const std::shared_ptr<C2Buffer>& buffer,
479*ec779b8eSAndroid Build Coastguard Worker bool notify,
480*ec779b8eSAndroid Build Coastguard Worker int64_t timestamp,
481*ec779b8eSAndroid Build Coastguard Worker int32_t flags,
482*ec779b8eSAndroid Build Coastguard Worker const sp<AMessage>& format,
483*ec779b8eSAndroid Build Coastguard Worker const C2WorkOrdinalStruct& ordinal) {
484*ec779b8eSAndroid Build Coastguard Worker bool eos = flags & BUFFER_FLAG_END_OF_STREAM;
485*ec779b8eSAndroid Build Coastguard Worker if (!buffer && eos) {
486*ec779b8eSAndroid Build Coastguard Worker // TRICKY: we may be violating ordering of the stash here. Because we
487*ec779b8eSAndroid Build Coastguard Worker // don't expect any more emplace() calls after this, the ordering should
488*ec779b8eSAndroid Build Coastguard Worker // not matter.
489*ec779b8eSAndroid Build Coastguard Worker mReorderStash.emplace_back(
490*ec779b8eSAndroid Build Coastguard Worker buffer, notify, timestamp, flags, format, ordinal);
491*ec779b8eSAndroid Build Coastguard Worker } else {
492*ec779b8eSAndroid Build Coastguard Worker flags = flags & ~BUFFER_FLAG_END_OF_STREAM;
493*ec779b8eSAndroid Build Coastguard Worker auto it = mReorderStash.begin();
494*ec779b8eSAndroid Build Coastguard Worker for (; it != mReorderStash.end(); ++it) {
495*ec779b8eSAndroid Build Coastguard Worker if (less(ordinal, it->ordinal)) {
496*ec779b8eSAndroid Build Coastguard Worker break;
497*ec779b8eSAndroid Build Coastguard Worker }
498*ec779b8eSAndroid Build Coastguard Worker }
499*ec779b8eSAndroid Build Coastguard Worker mReorderStash.emplace(it,
500*ec779b8eSAndroid Build Coastguard Worker buffer, notify, timestamp, flags, format, ordinal);
501*ec779b8eSAndroid Build Coastguard Worker if (eos) {
502*ec779b8eSAndroid Build Coastguard Worker mReorderStash.back().flags =
503*ec779b8eSAndroid Build Coastguard Worker mReorderStash.back().flags | BUFFER_FLAG_END_OF_STREAM;
504*ec779b8eSAndroid Build Coastguard Worker }
505*ec779b8eSAndroid Build Coastguard Worker }
506*ec779b8eSAndroid Build Coastguard Worker while (!mReorderStash.empty() && mReorderStash.size() > mDepth) {
507*ec779b8eSAndroid Build Coastguard Worker mPending.push_back(mReorderStash.front());
508*ec779b8eSAndroid Build Coastguard Worker mReorderStash.pop_front();
509*ec779b8eSAndroid Build Coastguard Worker }
510*ec779b8eSAndroid Build Coastguard Worker ALOGV("[%s] %s: pushToStash -- pending size = %zu", mName, __func__, mPending.size());
511*ec779b8eSAndroid Build Coastguard Worker }
512*ec779b8eSAndroid Build Coastguard Worker
popFromStashAndRegister(std::shared_ptr<C2Buffer> * c2Buffer,size_t * index,sp<MediaCodecBuffer> * outBuffer)513*ec779b8eSAndroid Build Coastguard Worker OutputBuffers::BufferAction OutputBuffers::popFromStashAndRegister(
514*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<C2Buffer>* c2Buffer,
515*ec779b8eSAndroid Build Coastguard Worker size_t* index,
516*ec779b8eSAndroid Build Coastguard Worker sp<MediaCodecBuffer>* outBuffer) {
517*ec779b8eSAndroid Build Coastguard Worker if (mPending.empty()) {
518*ec779b8eSAndroid Build Coastguard Worker return SKIP;
519*ec779b8eSAndroid Build Coastguard Worker }
520*ec779b8eSAndroid Build Coastguard Worker
521*ec779b8eSAndroid Build Coastguard Worker // Retrieve the first entry.
522*ec779b8eSAndroid Build Coastguard Worker StashEntry &entry = mPending.front();
523*ec779b8eSAndroid Build Coastguard Worker
524*ec779b8eSAndroid Build Coastguard Worker *c2Buffer = entry.buffer;
525*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> outputFormat = entry.format;
526*ec779b8eSAndroid Build Coastguard Worker
527*ec779b8eSAndroid Build Coastguard Worker if (entry.notify && mFormat != outputFormat) {
528*ec779b8eSAndroid Build Coastguard Worker updateSkipCutBuffer(outputFormat);
529*ec779b8eSAndroid Build Coastguard Worker // Trigger image data processing to the new format
530*ec779b8eSAndroid Build Coastguard Worker mLastImageData.clear();
531*ec779b8eSAndroid Build Coastguard Worker ALOGV("[%s] popFromStashAndRegister: output format reference changed: %p -> %p",
532*ec779b8eSAndroid Build Coastguard Worker mName, mFormat.get(), outputFormat.get());
533*ec779b8eSAndroid Build Coastguard Worker ALOGD("[%s] popFromStashAndRegister: at %lldus, output format changed to %s",
534*ec779b8eSAndroid Build Coastguard Worker mName, (long long)entry.timestamp, outputFormat->debugString().c_str());
535*ec779b8eSAndroid Build Coastguard Worker setFormat(outputFormat);
536*ec779b8eSAndroid Build Coastguard Worker }
537*ec779b8eSAndroid Build Coastguard Worker
538*ec779b8eSAndroid Build Coastguard Worker // Flushing mReorderStash because no other buffers should come after output
539*ec779b8eSAndroid Build Coastguard Worker // EOS.
540*ec779b8eSAndroid Build Coastguard Worker if (entry.flags & BUFFER_FLAG_END_OF_STREAM) {
541*ec779b8eSAndroid Build Coastguard Worker // Flush reorder stash
542*ec779b8eSAndroid Build Coastguard Worker setReorderDepth(0);
543*ec779b8eSAndroid Build Coastguard Worker }
544*ec779b8eSAndroid Build Coastguard Worker
545*ec779b8eSAndroid Build Coastguard Worker if (!entry.notify) {
546*ec779b8eSAndroid Build Coastguard Worker mPending.pop_front();
547*ec779b8eSAndroid Build Coastguard Worker return DISCARD;
548*ec779b8eSAndroid Build Coastguard Worker }
549*ec779b8eSAndroid Build Coastguard Worker
550*ec779b8eSAndroid Build Coastguard Worker // Try to register the buffer.
551*ec779b8eSAndroid Build Coastguard Worker status_t err = registerBuffer(*c2Buffer, index, outBuffer);
552*ec779b8eSAndroid Build Coastguard Worker if (err != OK) {
553*ec779b8eSAndroid Build Coastguard Worker if (err != WOULD_BLOCK) {
554*ec779b8eSAndroid Build Coastguard Worker return REALLOCATE;
555*ec779b8eSAndroid Build Coastguard Worker }
556*ec779b8eSAndroid Build Coastguard Worker return RETRY;
557*ec779b8eSAndroid Build Coastguard Worker }
558*ec779b8eSAndroid Build Coastguard Worker
559*ec779b8eSAndroid Build Coastguard Worker // Append information from the front stash entry to outBuffer.
560*ec779b8eSAndroid Build Coastguard Worker (*outBuffer)->meta()->setInt64("timeUs", entry.timestamp);
561*ec779b8eSAndroid Build Coastguard Worker (*outBuffer)->meta()->setInt32("flags", entry.flags);
562*ec779b8eSAndroid Build Coastguard Worker (*outBuffer)->meta()->setInt64("frameIndex", entry.ordinal.frameIndex.peekll());
563*ec779b8eSAndroid Build Coastguard Worker ALOGV("[%s] popFromStashAndRegister: "
564*ec779b8eSAndroid Build Coastguard Worker "out buffer index = %zu [%p] => %p + %zu (%lld)",
565*ec779b8eSAndroid Build Coastguard Worker mName, *index, outBuffer->get(),
566*ec779b8eSAndroid Build Coastguard Worker (*outBuffer)->data(), (*outBuffer)->size(),
567*ec779b8eSAndroid Build Coastguard Worker (long long)entry.timestamp);
568*ec779b8eSAndroid Build Coastguard Worker
569*ec779b8eSAndroid Build Coastguard Worker // The front entry of mPending will be removed now that the registration
570*ec779b8eSAndroid Build Coastguard Worker // succeeded.
571*ec779b8eSAndroid Build Coastguard Worker mPending.pop_front();
572*ec779b8eSAndroid Build Coastguard Worker return NOTIFY_CLIENT;
573*ec779b8eSAndroid Build Coastguard Worker }
574*ec779b8eSAndroid Build Coastguard Worker
popPending(StashEntry * entry)575*ec779b8eSAndroid Build Coastguard Worker bool OutputBuffers::popPending(StashEntry *entry) {
576*ec779b8eSAndroid Build Coastguard Worker if (mPending.empty()) {
577*ec779b8eSAndroid Build Coastguard Worker return false;
578*ec779b8eSAndroid Build Coastguard Worker }
579*ec779b8eSAndroid Build Coastguard Worker *entry = mPending.front();
580*ec779b8eSAndroid Build Coastguard Worker mPending.pop_front();
581*ec779b8eSAndroid Build Coastguard Worker return true;
582*ec779b8eSAndroid Build Coastguard Worker }
583*ec779b8eSAndroid Build Coastguard Worker
deferPending(const OutputBuffers::StashEntry & entry)584*ec779b8eSAndroid Build Coastguard Worker void OutputBuffers::deferPending(const OutputBuffers::StashEntry &entry) {
585*ec779b8eSAndroid Build Coastguard Worker mPending.push_front(entry);
586*ec779b8eSAndroid Build Coastguard Worker }
587*ec779b8eSAndroid Build Coastguard Worker
hasPending() const588*ec779b8eSAndroid Build Coastguard Worker bool OutputBuffers::hasPending() const {
589*ec779b8eSAndroid Build Coastguard Worker return !mPending.empty();
590*ec779b8eSAndroid Build Coastguard Worker }
591*ec779b8eSAndroid Build Coastguard Worker
less(const C2WorkOrdinalStruct & o1,const C2WorkOrdinalStruct & o2) const592*ec779b8eSAndroid Build Coastguard Worker bool OutputBuffers::less(
593*ec779b8eSAndroid Build Coastguard Worker const C2WorkOrdinalStruct &o1, const C2WorkOrdinalStruct &o2) const {
594*ec779b8eSAndroid Build Coastguard Worker switch (mKey) {
595*ec779b8eSAndroid Build Coastguard Worker case C2Config::ORDINAL: return o1.frameIndex < o2.frameIndex;
596*ec779b8eSAndroid Build Coastguard Worker case C2Config::TIMESTAMP: return o1.timestamp < o2.timestamp;
597*ec779b8eSAndroid Build Coastguard Worker case C2Config::CUSTOM: return o1.customOrdinal < o2.customOrdinal;
598*ec779b8eSAndroid Build Coastguard Worker default:
599*ec779b8eSAndroid Build Coastguard Worker ALOGD("Unrecognized key; default to timestamp");
600*ec779b8eSAndroid Build Coastguard Worker return o1.frameIndex < o2.frameIndex;
601*ec779b8eSAndroid Build Coastguard Worker }
602*ec779b8eSAndroid Build Coastguard Worker }
603*ec779b8eSAndroid Build Coastguard Worker
604*ec779b8eSAndroid Build Coastguard Worker // LocalBufferPool
605*ec779b8eSAndroid Build Coastguard Worker
606*ec779b8eSAndroid Build Coastguard Worker constexpr size_t kInitialPoolCapacity = kMaxLinearBufferSize;
607*ec779b8eSAndroid Build Coastguard Worker constexpr size_t kMaxPoolCapacity = kMaxLinearBufferSize * 32;
608*ec779b8eSAndroid Build Coastguard Worker
Create()609*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<LocalBufferPool> LocalBufferPool::Create() {
610*ec779b8eSAndroid Build Coastguard Worker return std::shared_ptr<LocalBufferPool>(new LocalBufferPool(kInitialPoolCapacity));
611*ec779b8eSAndroid Build Coastguard Worker }
612*ec779b8eSAndroid Build Coastguard Worker
newBuffer(size_t capacity)613*ec779b8eSAndroid Build Coastguard Worker sp<ABuffer> LocalBufferPool::newBuffer(size_t capacity) {
614*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
615*ec779b8eSAndroid Build Coastguard Worker auto it = std::find_if(
616*ec779b8eSAndroid Build Coastguard Worker mPool.begin(), mPool.end(),
617*ec779b8eSAndroid Build Coastguard Worker [capacity](const std::vector<uint8_t> &vec) {
618*ec779b8eSAndroid Build Coastguard Worker return vec.capacity() >= capacity;
619*ec779b8eSAndroid Build Coastguard Worker });
620*ec779b8eSAndroid Build Coastguard Worker if (it != mPool.end()) {
621*ec779b8eSAndroid Build Coastguard Worker sp<ABuffer> buffer = new VectorBuffer(std::move(*it), shared_from_this());
622*ec779b8eSAndroid Build Coastguard Worker mPool.erase(it);
623*ec779b8eSAndroid Build Coastguard Worker return buffer;
624*ec779b8eSAndroid Build Coastguard Worker }
625*ec779b8eSAndroid Build Coastguard Worker if (mUsedSize + capacity > mPoolCapacity) {
626*ec779b8eSAndroid Build Coastguard Worker while (!mPool.empty()) {
627*ec779b8eSAndroid Build Coastguard Worker mUsedSize -= mPool.back().capacity();
628*ec779b8eSAndroid Build Coastguard Worker mPool.pop_back();
629*ec779b8eSAndroid Build Coastguard Worker }
630*ec779b8eSAndroid Build Coastguard Worker while (mUsedSize + capacity > mPoolCapacity && mPoolCapacity * 2 <= kMaxPoolCapacity) {
631*ec779b8eSAndroid Build Coastguard Worker ALOGD("Increasing local buffer pool capacity from %zu to %zu",
632*ec779b8eSAndroid Build Coastguard Worker mPoolCapacity, mPoolCapacity * 2);
633*ec779b8eSAndroid Build Coastguard Worker mPoolCapacity *= 2;
634*ec779b8eSAndroid Build Coastguard Worker }
635*ec779b8eSAndroid Build Coastguard Worker if (mUsedSize + capacity > mPoolCapacity) {
636*ec779b8eSAndroid Build Coastguard Worker ALOGD("mUsedSize = %zu, capacity = %zu, mPoolCapacity = %zu",
637*ec779b8eSAndroid Build Coastguard Worker mUsedSize, capacity, mPoolCapacity);
638*ec779b8eSAndroid Build Coastguard Worker return nullptr;
639*ec779b8eSAndroid Build Coastguard Worker }
640*ec779b8eSAndroid Build Coastguard Worker }
641*ec779b8eSAndroid Build Coastguard Worker std::vector<uint8_t> vec(capacity);
642*ec779b8eSAndroid Build Coastguard Worker mUsedSize += vec.capacity();
643*ec779b8eSAndroid Build Coastguard Worker return new VectorBuffer(std::move(vec), shared_from_this());
644*ec779b8eSAndroid Build Coastguard Worker }
645*ec779b8eSAndroid Build Coastguard Worker
VectorBuffer(std::vector<uint8_t> && vec,const std::shared_ptr<LocalBufferPool> & pool)646*ec779b8eSAndroid Build Coastguard Worker LocalBufferPool::VectorBuffer::VectorBuffer(
647*ec779b8eSAndroid Build Coastguard Worker std::vector<uint8_t> &&vec, const std::shared_ptr<LocalBufferPool> &pool)
648*ec779b8eSAndroid Build Coastguard Worker : ABuffer(vec.data(), vec.capacity()),
649*ec779b8eSAndroid Build Coastguard Worker mVec(std::move(vec)),
650*ec779b8eSAndroid Build Coastguard Worker mPool(pool) {
651*ec779b8eSAndroid Build Coastguard Worker }
652*ec779b8eSAndroid Build Coastguard Worker
~VectorBuffer()653*ec779b8eSAndroid Build Coastguard Worker LocalBufferPool::VectorBuffer::~VectorBuffer() {
654*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<LocalBufferPool> pool = mPool.lock();
655*ec779b8eSAndroid Build Coastguard Worker if (pool) {
656*ec779b8eSAndroid Build Coastguard Worker // If pool is alive, return the vector back to the pool so that
657*ec779b8eSAndroid Build Coastguard Worker // it can be recycled.
658*ec779b8eSAndroid Build Coastguard Worker pool->returnVector(std::move(mVec));
659*ec779b8eSAndroid Build Coastguard Worker }
660*ec779b8eSAndroid Build Coastguard Worker }
661*ec779b8eSAndroid Build Coastguard Worker
returnVector(std::vector<uint8_t> && vec)662*ec779b8eSAndroid Build Coastguard Worker void LocalBufferPool::returnVector(std::vector<uint8_t> &&vec) {
663*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
664*ec779b8eSAndroid Build Coastguard Worker mPool.push_front(std::move(vec));
665*ec779b8eSAndroid Build Coastguard Worker }
666*ec779b8eSAndroid Build Coastguard Worker
667*ec779b8eSAndroid Build Coastguard Worker // FlexBuffersImpl
668*ec779b8eSAndroid Build Coastguard Worker
assignSlot(const sp<Codec2Buffer> & buffer)669*ec779b8eSAndroid Build Coastguard Worker size_t FlexBuffersImpl::assignSlot(const sp<Codec2Buffer> &buffer) {
670*ec779b8eSAndroid Build Coastguard Worker for (size_t i = 0; i < mBuffers.size(); ++i) {
671*ec779b8eSAndroid Build Coastguard Worker if (mBuffers[i].clientBuffer == nullptr
672*ec779b8eSAndroid Build Coastguard Worker && mBuffers[i].compBuffer.expired()) {
673*ec779b8eSAndroid Build Coastguard Worker mBuffers[i].clientBuffer = buffer;
674*ec779b8eSAndroid Build Coastguard Worker return i;
675*ec779b8eSAndroid Build Coastguard Worker }
676*ec779b8eSAndroid Build Coastguard Worker }
677*ec779b8eSAndroid Build Coastguard Worker mBuffers.push_back({ buffer, std::weak_ptr<C2Buffer>() });
678*ec779b8eSAndroid Build Coastguard Worker return mBuffers.size() - 1;
679*ec779b8eSAndroid Build Coastguard Worker }
680*ec779b8eSAndroid Build Coastguard Worker
releaseSlot(const sp<MediaCodecBuffer> & buffer,std::shared_ptr<C2Buffer> * c2buffer,bool release)681*ec779b8eSAndroid Build Coastguard Worker bool FlexBuffersImpl::releaseSlot(
682*ec779b8eSAndroid Build Coastguard Worker const sp<MediaCodecBuffer> &buffer,
683*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<C2Buffer> *c2buffer,
684*ec779b8eSAndroid Build Coastguard Worker bool release) {
685*ec779b8eSAndroid Build Coastguard Worker sp<Codec2Buffer> clientBuffer;
686*ec779b8eSAndroid Build Coastguard Worker size_t index = mBuffers.size();
687*ec779b8eSAndroid Build Coastguard Worker for (size_t i = 0; i < mBuffers.size(); ++i) {
688*ec779b8eSAndroid Build Coastguard Worker if (mBuffers[i].clientBuffer == buffer) {
689*ec779b8eSAndroid Build Coastguard Worker clientBuffer = mBuffers[i].clientBuffer;
690*ec779b8eSAndroid Build Coastguard Worker if (release) {
691*ec779b8eSAndroid Build Coastguard Worker mBuffers[i].clientBuffer.clear();
692*ec779b8eSAndroid Build Coastguard Worker }
693*ec779b8eSAndroid Build Coastguard Worker index = i;
694*ec779b8eSAndroid Build Coastguard Worker break;
695*ec779b8eSAndroid Build Coastguard Worker }
696*ec779b8eSAndroid Build Coastguard Worker }
697*ec779b8eSAndroid Build Coastguard Worker if (clientBuffer == nullptr) {
698*ec779b8eSAndroid Build Coastguard Worker ALOGV("[%s] %s: No matching buffer found", mName, __func__);
699*ec779b8eSAndroid Build Coastguard Worker return false;
700*ec779b8eSAndroid Build Coastguard Worker }
701*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<C2Buffer> result = mBuffers[index].compBuffer.lock();
702*ec779b8eSAndroid Build Coastguard Worker if (!result) {
703*ec779b8eSAndroid Build Coastguard Worker result = clientBuffer->asC2Buffer();
704*ec779b8eSAndroid Build Coastguard Worker clientBuffer->clearC2BufferRefs();
705*ec779b8eSAndroid Build Coastguard Worker mBuffers[index].compBuffer = result;
706*ec779b8eSAndroid Build Coastguard Worker }
707*ec779b8eSAndroid Build Coastguard Worker if (c2buffer) {
708*ec779b8eSAndroid Build Coastguard Worker *c2buffer = result;
709*ec779b8eSAndroid Build Coastguard Worker }
710*ec779b8eSAndroid Build Coastguard Worker return true;
711*ec779b8eSAndroid Build Coastguard Worker }
712*ec779b8eSAndroid Build Coastguard Worker
expireComponentBuffer(const std::shared_ptr<C2Buffer> & c2buffer)713*ec779b8eSAndroid Build Coastguard Worker bool FlexBuffersImpl::expireComponentBuffer(const std::shared_ptr<C2Buffer> &c2buffer) {
714*ec779b8eSAndroid Build Coastguard Worker for (size_t i = 0; i < mBuffers.size(); ++i) {
715*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<C2Buffer> compBuffer =
716*ec779b8eSAndroid Build Coastguard Worker mBuffers[i].compBuffer.lock();
717*ec779b8eSAndroid Build Coastguard Worker if (!compBuffer || compBuffer != c2buffer) {
718*ec779b8eSAndroid Build Coastguard Worker continue;
719*ec779b8eSAndroid Build Coastguard Worker }
720*ec779b8eSAndroid Build Coastguard Worker mBuffers[i].compBuffer.reset();
721*ec779b8eSAndroid Build Coastguard Worker ALOGV("[%s] codec released buffer #%zu", mName, i);
722*ec779b8eSAndroid Build Coastguard Worker return true;
723*ec779b8eSAndroid Build Coastguard Worker }
724*ec779b8eSAndroid Build Coastguard Worker ALOGV("[%s] codec released an unknown buffer", mName);
725*ec779b8eSAndroid Build Coastguard Worker return false;
726*ec779b8eSAndroid Build Coastguard Worker }
727*ec779b8eSAndroid Build Coastguard Worker
flush()728*ec779b8eSAndroid Build Coastguard Worker void FlexBuffersImpl::flush() {
729*ec779b8eSAndroid Build Coastguard Worker ALOGV("[%s] buffers are flushed %zu", mName, mBuffers.size());
730*ec779b8eSAndroid Build Coastguard Worker mBuffers.clear();
731*ec779b8eSAndroid Build Coastguard Worker }
732*ec779b8eSAndroid Build Coastguard Worker
numActiveSlots() const733*ec779b8eSAndroid Build Coastguard Worker size_t FlexBuffersImpl::numActiveSlots() const {
734*ec779b8eSAndroid Build Coastguard Worker return std::count_if(
735*ec779b8eSAndroid Build Coastguard Worker mBuffers.begin(), mBuffers.end(),
736*ec779b8eSAndroid Build Coastguard Worker [](const Entry &entry) {
737*ec779b8eSAndroid Build Coastguard Worker return (entry.clientBuffer != nullptr
738*ec779b8eSAndroid Build Coastguard Worker || !entry.compBuffer.expired());
739*ec779b8eSAndroid Build Coastguard Worker });
740*ec779b8eSAndroid Build Coastguard Worker }
741*ec779b8eSAndroid Build Coastguard Worker
numComponentBuffers() const742*ec779b8eSAndroid Build Coastguard Worker size_t FlexBuffersImpl::numComponentBuffers() const {
743*ec779b8eSAndroid Build Coastguard Worker return std::count_if(
744*ec779b8eSAndroid Build Coastguard Worker mBuffers.begin(), mBuffers.end(),
745*ec779b8eSAndroid Build Coastguard Worker [](const Entry &entry) {
746*ec779b8eSAndroid Build Coastguard Worker return !entry.compBuffer.expired();
747*ec779b8eSAndroid Build Coastguard Worker });
748*ec779b8eSAndroid Build Coastguard Worker }
749*ec779b8eSAndroid Build Coastguard Worker
750*ec779b8eSAndroid Build Coastguard Worker // BuffersArrayImpl
751*ec779b8eSAndroid Build Coastguard Worker
initialize(const FlexBuffersImpl & impl,size_t minSize,std::function<sp<Codec2Buffer> ()> allocate)752*ec779b8eSAndroid Build Coastguard Worker void BuffersArrayImpl::initialize(
753*ec779b8eSAndroid Build Coastguard Worker const FlexBuffersImpl &impl,
754*ec779b8eSAndroid Build Coastguard Worker size_t minSize,
755*ec779b8eSAndroid Build Coastguard Worker std::function<sp<Codec2Buffer>()> allocate) {
756*ec779b8eSAndroid Build Coastguard Worker mImplName = impl.mImplName + "[N]";
757*ec779b8eSAndroid Build Coastguard Worker mName = mImplName.c_str();
758*ec779b8eSAndroid Build Coastguard Worker for (size_t i = 0; i < impl.mBuffers.size(); ++i) {
759*ec779b8eSAndroid Build Coastguard Worker sp<Codec2Buffer> clientBuffer = impl.mBuffers[i].clientBuffer;
760*ec779b8eSAndroid Build Coastguard Worker bool ownedByClient = (clientBuffer != nullptr);
761*ec779b8eSAndroid Build Coastguard Worker if (!ownedByClient) {
762*ec779b8eSAndroid Build Coastguard Worker clientBuffer = allocate();
763*ec779b8eSAndroid Build Coastguard Worker }
764*ec779b8eSAndroid Build Coastguard Worker mBuffers.push_back({ clientBuffer, impl.mBuffers[i].compBuffer, ownedByClient });
765*ec779b8eSAndroid Build Coastguard Worker }
766*ec779b8eSAndroid Build Coastguard Worker ALOGV("[%s] converted %zu buffers to array mode of %zu", mName, mBuffers.size(), minSize);
767*ec779b8eSAndroid Build Coastguard Worker for (size_t i = impl.mBuffers.size(); i < minSize; ++i) {
768*ec779b8eSAndroid Build Coastguard Worker mBuffers.push_back({ allocate(), std::weak_ptr<C2Buffer>(), false });
769*ec779b8eSAndroid Build Coastguard Worker }
770*ec779b8eSAndroid Build Coastguard Worker }
771*ec779b8eSAndroid Build Coastguard Worker
grabBuffer(size_t * index,sp<Codec2Buffer> * buffer,std::function<bool (const sp<Codec2Buffer> &)> match)772*ec779b8eSAndroid Build Coastguard Worker status_t BuffersArrayImpl::grabBuffer(
773*ec779b8eSAndroid Build Coastguard Worker size_t *index,
774*ec779b8eSAndroid Build Coastguard Worker sp<Codec2Buffer> *buffer,
775*ec779b8eSAndroid Build Coastguard Worker std::function<bool(const sp<Codec2Buffer> &)> match) {
776*ec779b8eSAndroid Build Coastguard Worker // allBuffersDontMatch remains true if all buffers are available but
777*ec779b8eSAndroid Build Coastguard Worker // match() returns false for every buffer.
778*ec779b8eSAndroid Build Coastguard Worker bool allBuffersDontMatch = true;
779*ec779b8eSAndroid Build Coastguard Worker for (size_t i = 0; i < mBuffers.size(); ++i) {
780*ec779b8eSAndroid Build Coastguard Worker if (!mBuffers[i].ownedByClient && mBuffers[i].compBuffer.expired()) {
781*ec779b8eSAndroid Build Coastguard Worker if (match(mBuffers[i].clientBuffer)) {
782*ec779b8eSAndroid Build Coastguard Worker mBuffers[i].ownedByClient = true;
783*ec779b8eSAndroid Build Coastguard Worker *buffer = mBuffers[i].clientBuffer;
784*ec779b8eSAndroid Build Coastguard Worker (*buffer)->meta()->clear();
785*ec779b8eSAndroid Build Coastguard Worker (*buffer)->setRange(0, (*buffer)->capacity());
786*ec779b8eSAndroid Build Coastguard Worker *index = i;
787*ec779b8eSAndroid Build Coastguard Worker return OK;
788*ec779b8eSAndroid Build Coastguard Worker }
789*ec779b8eSAndroid Build Coastguard Worker } else {
790*ec779b8eSAndroid Build Coastguard Worker allBuffersDontMatch = false;
791*ec779b8eSAndroid Build Coastguard Worker }
792*ec779b8eSAndroid Build Coastguard Worker }
793*ec779b8eSAndroid Build Coastguard Worker return allBuffersDontMatch ? NO_MEMORY : WOULD_BLOCK;
794*ec779b8eSAndroid Build Coastguard Worker }
795*ec779b8eSAndroid Build Coastguard Worker
returnBuffer(const sp<MediaCodecBuffer> & buffer,std::shared_ptr<C2Buffer> * c2buffer,bool release)796*ec779b8eSAndroid Build Coastguard Worker bool BuffersArrayImpl::returnBuffer(
797*ec779b8eSAndroid Build Coastguard Worker const sp<MediaCodecBuffer> &buffer,
798*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<C2Buffer> *c2buffer,
799*ec779b8eSAndroid Build Coastguard Worker bool release) {
800*ec779b8eSAndroid Build Coastguard Worker sp<Codec2Buffer> clientBuffer;
801*ec779b8eSAndroid Build Coastguard Worker size_t index = mBuffers.size();
802*ec779b8eSAndroid Build Coastguard Worker for (size_t i = 0; i < mBuffers.size(); ++i) {
803*ec779b8eSAndroid Build Coastguard Worker if (mBuffers[i].clientBuffer == buffer) {
804*ec779b8eSAndroid Build Coastguard Worker if (!mBuffers[i].ownedByClient) {
805*ec779b8eSAndroid Build Coastguard Worker ALOGD("[%s] Client returned a buffer it does not own according to our record: %zu",
806*ec779b8eSAndroid Build Coastguard Worker mName, i);
807*ec779b8eSAndroid Build Coastguard Worker }
808*ec779b8eSAndroid Build Coastguard Worker clientBuffer = mBuffers[i].clientBuffer;
809*ec779b8eSAndroid Build Coastguard Worker if (release) {
810*ec779b8eSAndroid Build Coastguard Worker mBuffers[i].ownedByClient = false;
811*ec779b8eSAndroid Build Coastguard Worker }
812*ec779b8eSAndroid Build Coastguard Worker index = i;
813*ec779b8eSAndroid Build Coastguard Worker break;
814*ec779b8eSAndroid Build Coastguard Worker }
815*ec779b8eSAndroid Build Coastguard Worker }
816*ec779b8eSAndroid Build Coastguard Worker if (clientBuffer == nullptr) {
817*ec779b8eSAndroid Build Coastguard Worker ALOGV("[%s] %s: No matching buffer found", mName, __func__);
818*ec779b8eSAndroid Build Coastguard Worker return false;
819*ec779b8eSAndroid Build Coastguard Worker }
820*ec779b8eSAndroid Build Coastguard Worker ALOGV("[%s] %s: matching buffer found (index=%zu)", mName, __func__, index);
821*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<C2Buffer> result = mBuffers[index].compBuffer.lock();
822*ec779b8eSAndroid Build Coastguard Worker if (!result) {
823*ec779b8eSAndroid Build Coastguard Worker result = clientBuffer->asC2Buffer();
824*ec779b8eSAndroid Build Coastguard Worker clientBuffer->clearC2BufferRefs();
825*ec779b8eSAndroid Build Coastguard Worker mBuffers[index].compBuffer = result;
826*ec779b8eSAndroid Build Coastguard Worker }
827*ec779b8eSAndroid Build Coastguard Worker if (c2buffer) {
828*ec779b8eSAndroid Build Coastguard Worker *c2buffer = result;
829*ec779b8eSAndroid Build Coastguard Worker }
830*ec779b8eSAndroid Build Coastguard Worker return true;
831*ec779b8eSAndroid Build Coastguard Worker }
832*ec779b8eSAndroid Build Coastguard Worker
expireComponentBuffer(const std::shared_ptr<C2Buffer> & c2buffer)833*ec779b8eSAndroid Build Coastguard Worker bool BuffersArrayImpl::expireComponentBuffer(const std::shared_ptr<C2Buffer> &c2buffer) {
834*ec779b8eSAndroid Build Coastguard Worker for (size_t i = 0; i < mBuffers.size(); ++i) {
835*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<C2Buffer> compBuffer =
836*ec779b8eSAndroid Build Coastguard Worker mBuffers[i].compBuffer.lock();
837*ec779b8eSAndroid Build Coastguard Worker if (!compBuffer) {
838*ec779b8eSAndroid Build Coastguard Worker continue;
839*ec779b8eSAndroid Build Coastguard Worker }
840*ec779b8eSAndroid Build Coastguard Worker if (c2buffer == compBuffer) {
841*ec779b8eSAndroid Build Coastguard Worker if (mBuffers[i].ownedByClient) {
842*ec779b8eSAndroid Build Coastguard Worker // This should not happen.
843*ec779b8eSAndroid Build Coastguard Worker ALOGD("[%s] codec released a buffer owned by client "
844*ec779b8eSAndroid Build Coastguard Worker "(index %zu)", mName, i);
845*ec779b8eSAndroid Build Coastguard Worker }
846*ec779b8eSAndroid Build Coastguard Worker mBuffers[i].compBuffer.reset();
847*ec779b8eSAndroid Build Coastguard Worker ALOGV("[%s] codec released buffer #%zu(array mode)", mName, i);
848*ec779b8eSAndroid Build Coastguard Worker return true;
849*ec779b8eSAndroid Build Coastguard Worker }
850*ec779b8eSAndroid Build Coastguard Worker }
851*ec779b8eSAndroid Build Coastguard Worker ALOGV("[%s] codec released an unknown buffer (array mode)", mName);
852*ec779b8eSAndroid Build Coastguard Worker return false;
853*ec779b8eSAndroid Build Coastguard Worker }
854*ec779b8eSAndroid Build Coastguard Worker
getArray(Vector<sp<MediaCodecBuffer>> * array) const855*ec779b8eSAndroid Build Coastguard Worker void BuffersArrayImpl::getArray(Vector<sp<MediaCodecBuffer>> *array) const {
856*ec779b8eSAndroid Build Coastguard Worker array->clear();
857*ec779b8eSAndroid Build Coastguard Worker for (const Entry &entry : mBuffers) {
858*ec779b8eSAndroid Build Coastguard Worker array->push(entry.clientBuffer);
859*ec779b8eSAndroid Build Coastguard Worker }
860*ec779b8eSAndroid Build Coastguard Worker }
861*ec779b8eSAndroid Build Coastguard Worker
flush()862*ec779b8eSAndroid Build Coastguard Worker void BuffersArrayImpl::flush() {
863*ec779b8eSAndroid Build Coastguard Worker for (Entry &entry : mBuffers) {
864*ec779b8eSAndroid Build Coastguard Worker entry.ownedByClient = false;
865*ec779b8eSAndroid Build Coastguard Worker }
866*ec779b8eSAndroid Build Coastguard Worker }
867*ec779b8eSAndroid Build Coastguard Worker
realloc(std::function<sp<Codec2Buffer> ()> alloc)868*ec779b8eSAndroid Build Coastguard Worker void BuffersArrayImpl::realloc(std::function<sp<Codec2Buffer>()> alloc) {
869*ec779b8eSAndroid Build Coastguard Worker size_t size = mBuffers.size();
870*ec779b8eSAndroid Build Coastguard Worker mBuffers.clear();
871*ec779b8eSAndroid Build Coastguard Worker for (size_t i = 0; i < size; ++i) {
872*ec779b8eSAndroid Build Coastguard Worker mBuffers.push_back({ alloc(), std::weak_ptr<C2Buffer>(), false });
873*ec779b8eSAndroid Build Coastguard Worker }
874*ec779b8eSAndroid Build Coastguard Worker }
875*ec779b8eSAndroid Build Coastguard Worker
grow(size_t newSize,std::function<sp<Codec2Buffer> ()> alloc)876*ec779b8eSAndroid Build Coastguard Worker void BuffersArrayImpl::grow(
877*ec779b8eSAndroid Build Coastguard Worker size_t newSize, std::function<sp<Codec2Buffer>()> alloc) {
878*ec779b8eSAndroid Build Coastguard Worker CHECK_LT(mBuffers.size(), newSize);
879*ec779b8eSAndroid Build Coastguard Worker while (mBuffers.size() < newSize) {
880*ec779b8eSAndroid Build Coastguard Worker mBuffers.push_back({ alloc(), std::weak_ptr<C2Buffer>(), false });
881*ec779b8eSAndroid Build Coastguard Worker }
882*ec779b8eSAndroid Build Coastguard Worker }
883*ec779b8eSAndroid Build Coastguard Worker
numActiveSlots() const884*ec779b8eSAndroid Build Coastguard Worker size_t BuffersArrayImpl::numActiveSlots() const {
885*ec779b8eSAndroid Build Coastguard Worker return std::count_if(
886*ec779b8eSAndroid Build Coastguard Worker mBuffers.begin(), mBuffers.end(),
887*ec779b8eSAndroid Build Coastguard Worker [](const Entry &entry) {
888*ec779b8eSAndroid Build Coastguard Worker return entry.ownedByClient || !entry.compBuffer.expired();
889*ec779b8eSAndroid Build Coastguard Worker });
890*ec779b8eSAndroid Build Coastguard Worker }
891*ec779b8eSAndroid Build Coastguard Worker
arraySize() const892*ec779b8eSAndroid Build Coastguard Worker size_t BuffersArrayImpl::arraySize() const {
893*ec779b8eSAndroid Build Coastguard Worker return mBuffers.size();
894*ec779b8eSAndroid Build Coastguard Worker }
895*ec779b8eSAndroid Build Coastguard Worker
896*ec779b8eSAndroid Build Coastguard Worker // InputBuffersArray
897*ec779b8eSAndroid Build Coastguard Worker
initialize(const FlexBuffersImpl & impl,size_t minSize,std::function<sp<Codec2Buffer> ()> allocate)898*ec779b8eSAndroid Build Coastguard Worker void InputBuffersArray::initialize(
899*ec779b8eSAndroid Build Coastguard Worker const FlexBuffersImpl &impl,
900*ec779b8eSAndroid Build Coastguard Worker size_t minSize,
901*ec779b8eSAndroid Build Coastguard Worker std::function<sp<Codec2Buffer>()> allocate) {
902*ec779b8eSAndroid Build Coastguard Worker mAllocate = allocate;
903*ec779b8eSAndroid Build Coastguard Worker mImpl.initialize(impl, minSize, allocate);
904*ec779b8eSAndroid Build Coastguard Worker }
905*ec779b8eSAndroid Build Coastguard Worker
getArray(Vector<sp<MediaCodecBuffer>> * array) const906*ec779b8eSAndroid Build Coastguard Worker void InputBuffersArray::getArray(Vector<sp<MediaCodecBuffer>> *array) const {
907*ec779b8eSAndroid Build Coastguard Worker mImpl.getArray(array);
908*ec779b8eSAndroid Build Coastguard Worker }
909*ec779b8eSAndroid Build Coastguard Worker
requestNewBuffer(size_t * index,sp<MediaCodecBuffer> * buffer)910*ec779b8eSAndroid Build Coastguard Worker bool InputBuffersArray::requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) {
911*ec779b8eSAndroid Build Coastguard Worker sp<Codec2Buffer> c2Buffer;
912*ec779b8eSAndroid Build Coastguard Worker status_t err = mImpl.grabBuffer(index, &c2Buffer);
913*ec779b8eSAndroid Build Coastguard Worker if (err == OK) {
914*ec779b8eSAndroid Build Coastguard Worker c2Buffer->setFormat(mFormat);
915*ec779b8eSAndroid Build Coastguard Worker handleImageData(c2Buffer);
916*ec779b8eSAndroid Build Coastguard Worker *buffer = c2Buffer;
917*ec779b8eSAndroid Build Coastguard Worker return true;
918*ec779b8eSAndroid Build Coastguard Worker }
919*ec779b8eSAndroid Build Coastguard Worker return false;
920*ec779b8eSAndroid Build Coastguard Worker }
921*ec779b8eSAndroid Build Coastguard Worker
releaseBuffer(const sp<MediaCodecBuffer> & buffer,std::shared_ptr<C2Buffer> * c2buffer,bool release)922*ec779b8eSAndroid Build Coastguard Worker bool InputBuffersArray::releaseBuffer(
923*ec779b8eSAndroid Build Coastguard Worker const sp<MediaCodecBuffer> &buffer,
924*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<C2Buffer> *c2buffer,
925*ec779b8eSAndroid Build Coastguard Worker bool release) {
926*ec779b8eSAndroid Build Coastguard Worker return mImpl.returnBuffer(buffer, c2buffer, release);
927*ec779b8eSAndroid Build Coastguard Worker }
928*ec779b8eSAndroid Build Coastguard Worker
expireComponentBuffer(const std::shared_ptr<C2Buffer> & c2buffer)929*ec779b8eSAndroid Build Coastguard Worker bool InputBuffersArray::expireComponentBuffer(
930*ec779b8eSAndroid Build Coastguard Worker const std::shared_ptr<C2Buffer> &c2buffer) {
931*ec779b8eSAndroid Build Coastguard Worker return mImpl.expireComponentBuffer(c2buffer);
932*ec779b8eSAndroid Build Coastguard Worker }
933*ec779b8eSAndroid Build Coastguard Worker
flush()934*ec779b8eSAndroid Build Coastguard Worker void InputBuffersArray::flush() {
935*ec779b8eSAndroid Build Coastguard Worker mImpl.flush();
936*ec779b8eSAndroid Build Coastguard Worker }
937*ec779b8eSAndroid Build Coastguard Worker
numActiveSlots() const938*ec779b8eSAndroid Build Coastguard Worker size_t InputBuffersArray::numActiveSlots() const {
939*ec779b8eSAndroid Build Coastguard Worker return mImpl.numActiveSlots();
940*ec779b8eSAndroid Build Coastguard Worker }
941*ec779b8eSAndroid Build Coastguard Worker
createNewBuffer()942*ec779b8eSAndroid Build Coastguard Worker sp<Codec2Buffer> InputBuffersArray::createNewBuffer() {
943*ec779b8eSAndroid Build Coastguard Worker return mAllocate();
944*ec779b8eSAndroid Build Coastguard Worker }
945*ec779b8eSAndroid Build Coastguard Worker
946*ec779b8eSAndroid Build Coastguard Worker // SlotInputBuffers
947*ec779b8eSAndroid Build Coastguard Worker
requestNewBuffer(size_t * index,sp<MediaCodecBuffer> * buffer)948*ec779b8eSAndroid Build Coastguard Worker bool SlotInputBuffers::requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) {
949*ec779b8eSAndroid Build Coastguard Worker sp<Codec2Buffer> newBuffer = createNewBuffer();
950*ec779b8eSAndroid Build Coastguard Worker *index = mImpl.assignSlot(newBuffer);
951*ec779b8eSAndroid Build Coastguard Worker *buffer = newBuffer;
952*ec779b8eSAndroid Build Coastguard Worker return true;
953*ec779b8eSAndroid Build Coastguard Worker }
954*ec779b8eSAndroid Build Coastguard Worker
releaseBuffer(const sp<MediaCodecBuffer> & buffer,std::shared_ptr<C2Buffer> * c2buffer,bool release)955*ec779b8eSAndroid Build Coastguard Worker bool SlotInputBuffers::releaseBuffer(
956*ec779b8eSAndroid Build Coastguard Worker const sp<MediaCodecBuffer> &buffer,
957*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<C2Buffer> *c2buffer,
958*ec779b8eSAndroid Build Coastguard Worker bool release) {
959*ec779b8eSAndroid Build Coastguard Worker return mImpl.releaseSlot(buffer, c2buffer, release);
960*ec779b8eSAndroid Build Coastguard Worker }
961*ec779b8eSAndroid Build Coastguard Worker
expireComponentBuffer(const std::shared_ptr<C2Buffer> & c2buffer)962*ec779b8eSAndroid Build Coastguard Worker bool SlotInputBuffers::expireComponentBuffer(
963*ec779b8eSAndroid Build Coastguard Worker const std::shared_ptr<C2Buffer> &c2buffer) {
964*ec779b8eSAndroid Build Coastguard Worker return mImpl.expireComponentBuffer(c2buffer);
965*ec779b8eSAndroid Build Coastguard Worker }
966*ec779b8eSAndroid Build Coastguard Worker
flush()967*ec779b8eSAndroid Build Coastguard Worker void SlotInputBuffers::flush() {
968*ec779b8eSAndroid Build Coastguard Worker mImpl.flush();
969*ec779b8eSAndroid Build Coastguard Worker }
970*ec779b8eSAndroid Build Coastguard Worker
toArrayMode(size_t)971*ec779b8eSAndroid Build Coastguard Worker std::unique_ptr<InputBuffers> SlotInputBuffers::toArrayMode(size_t) {
972*ec779b8eSAndroid Build Coastguard Worker TRESPASS("Array mode should not be called at non-legacy mode");
973*ec779b8eSAndroid Build Coastguard Worker return nullptr;
974*ec779b8eSAndroid Build Coastguard Worker }
975*ec779b8eSAndroid Build Coastguard Worker
numActiveSlots() const976*ec779b8eSAndroid Build Coastguard Worker size_t SlotInputBuffers::numActiveSlots() const {
977*ec779b8eSAndroid Build Coastguard Worker return mImpl.numActiveSlots();
978*ec779b8eSAndroid Build Coastguard Worker }
979*ec779b8eSAndroid Build Coastguard Worker
createNewBuffer()980*ec779b8eSAndroid Build Coastguard Worker sp<Codec2Buffer> SlotInputBuffers::createNewBuffer() {
981*ec779b8eSAndroid Build Coastguard Worker return new DummyContainerBuffer{mFormat, nullptr};
982*ec779b8eSAndroid Build Coastguard Worker }
983*ec779b8eSAndroid Build Coastguard Worker
984*ec779b8eSAndroid Build Coastguard Worker // LinearInputBuffers
985*ec779b8eSAndroid Build Coastguard Worker
requestNewBuffer(size_t * index,sp<MediaCodecBuffer> * buffer)986*ec779b8eSAndroid Build Coastguard Worker bool LinearInputBuffers::requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) {
987*ec779b8eSAndroid Build Coastguard Worker sp<Codec2Buffer> newBuffer = createNewBuffer();
988*ec779b8eSAndroid Build Coastguard Worker if (newBuffer == nullptr) {
989*ec779b8eSAndroid Build Coastguard Worker return false;
990*ec779b8eSAndroid Build Coastguard Worker }
991*ec779b8eSAndroid Build Coastguard Worker *index = mImpl.assignSlot(newBuffer);
992*ec779b8eSAndroid Build Coastguard Worker *buffer = newBuffer;
993*ec779b8eSAndroid Build Coastguard Worker return true;
994*ec779b8eSAndroid Build Coastguard Worker }
995*ec779b8eSAndroid Build Coastguard Worker
releaseBuffer(const sp<MediaCodecBuffer> & buffer,std::shared_ptr<C2Buffer> * c2buffer,bool release)996*ec779b8eSAndroid Build Coastguard Worker bool LinearInputBuffers::releaseBuffer(
997*ec779b8eSAndroid Build Coastguard Worker const sp<MediaCodecBuffer> &buffer,
998*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<C2Buffer> *c2buffer,
999*ec779b8eSAndroid Build Coastguard Worker bool release) {
1000*ec779b8eSAndroid Build Coastguard Worker return mImpl.releaseSlot(buffer, c2buffer, release);
1001*ec779b8eSAndroid Build Coastguard Worker }
1002*ec779b8eSAndroid Build Coastguard Worker
expireComponentBuffer(const std::shared_ptr<C2Buffer> & c2buffer)1003*ec779b8eSAndroid Build Coastguard Worker bool LinearInputBuffers::expireComponentBuffer(
1004*ec779b8eSAndroid Build Coastguard Worker const std::shared_ptr<C2Buffer> &c2buffer) {
1005*ec779b8eSAndroid Build Coastguard Worker return mImpl.expireComponentBuffer(c2buffer);
1006*ec779b8eSAndroid Build Coastguard Worker }
1007*ec779b8eSAndroid Build Coastguard Worker
flush()1008*ec779b8eSAndroid Build Coastguard Worker void LinearInputBuffers::flush() {
1009*ec779b8eSAndroid Build Coastguard Worker // This is no-op by default unless we're in array mode where we need to keep
1010*ec779b8eSAndroid Build Coastguard Worker // track of the flushed work.
1011*ec779b8eSAndroid Build Coastguard Worker mImpl.flush();
1012*ec779b8eSAndroid Build Coastguard Worker }
1013*ec779b8eSAndroid Build Coastguard Worker
toArrayMode(size_t size)1014*ec779b8eSAndroid Build Coastguard Worker std::unique_ptr<InputBuffers> LinearInputBuffers::toArrayMode(size_t size) {
1015*ec779b8eSAndroid Build Coastguard Worker std::unique_ptr<InputBuffersArray> array(
1016*ec779b8eSAndroid Build Coastguard Worker new InputBuffersArray(mComponentName.c_str(), "1D-Input[N]"));
1017*ec779b8eSAndroid Build Coastguard Worker array->setPool(mPool);
1018*ec779b8eSAndroid Build Coastguard Worker array->setFormat(mFormat);
1019*ec779b8eSAndroid Build Coastguard Worker array->initialize(
1020*ec779b8eSAndroid Build Coastguard Worker mImpl,
1021*ec779b8eSAndroid Build Coastguard Worker size,
1022*ec779b8eSAndroid Build Coastguard Worker [pool = mPool, format = mFormat] () -> sp<Codec2Buffer> {
1023*ec779b8eSAndroid Build Coastguard Worker return Alloc(pool, format);
1024*ec779b8eSAndroid Build Coastguard Worker });
1025*ec779b8eSAndroid Build Coastguard Worker return std::move(array);
1026*ec779b8eSAndroid Build Coastguard Worker }
1027*ec779b8eSAndroid Build Coastguard Worker
numActiveSlots() const1028*ec779b8eSAndroid Build Coastguard Worker size_t LinearInputBuffers::numActiveSlots() const {
1029*ec779b8eSAndroid Build Coastguard Worker return mImpl.numActiveSlots();
1030*ec779b8eSAndroid Build Coastguard Worker }
1031*ec779b8eSAndroid Build Coastguard Worker
1032*ec779b8eSAndroid Build Coastguard Worker // static
Alloc(const std::shared_ptr<C2BlockPool> & pool,const sp<AMessage> & format)1033*ec779b8eSAndroid Build Coastguard Worker sp<Codec2Buffer> LinearInputBuffers::Alloc(
1034*ec779b8eSAndroid Build Coastguard Worker const std::shared_ptr<C2BlockPool> &pool, const sp<AMessage> &format) {
1035*ec779b8eSAndroid Build Coastguard Worker int32_t capacity = kLinearBufferSize;
1036*ec779b8eSAndroid Build Coastguard Worker (void)format->findInt32(KEY_MAX_INPUT_SIZE, &capacity);
1037*ec779b8eSAndroid Build Coastguard Worker if ((size_t)capacity > kMaxLinearBufferSize) {
1038*ec779b8eSAndroid Build Coastguard Worker ALOGD("client requested %d, capped to %zu", capacity, kMaxLinearBufferSize);
1039*ec779b8eSAndroid Build Coastguard Worker capacity = kMaxLinearBufferSize;
1040*ec779b8eSAndroid Build Coastguard Worker }
1041*ec779b8eSAndroid Build Coastguard Worker
1042*ec779b8eSAndroid Build Coastguard Worker int64_t usageValue = 0;
1043*ec779b8eSAndroid Build Coastguard Worker (void)format->findInt64("android._C2MemoryUsage", &usageValue);
1044*ec779b8eSAndroid Build Coastguard Worker C2MemoryUsage usage{usageValue | C2MemoryUsage::CPU_READ | C2MemoryUsage::CPU_WRITE};
1045*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<C2LinearBlock> block;
1046*ec779b8eSAndroid Build Coastguard Worker
1047*ec779b8eSAndroid Build Coastguard Worker c2_status_t err = pool->fetchLinearBlock(capacity, usage, &block);
1048*ec779b8eSAndroid Build Coastguard Worker if (err != C2_OK) {
1049*ec779b8eSAndroid Build Coastguard Worker return nullptr;
1050*ec779b8eSAndroid Build Coastguard Worker }
1051*ec779b8eSAndroid Build Coastguard Worker
1052*ec779b8eSAndroid Build Coastguard Worker return LinearBlockBuffer::Allocate(format, block);
1053*ec779b8eSAndroid Build Coastguard Worker }
1054*ec779b8eSAndroid Build Coastguard Worker
createNewBuffer()1055*ec779b8eSAndroid Build Coastguard Worker sp<Codec2Buffer> LinearInputBuffers::createNewBuffer() {
1056*ec779b8eSAndroid Build Coastguard Worker return Alloc(mPool, mFormat);
1057*ec779b8eSAndroid Build Coastguard Worker }
1058*ec779b8eSAndroid Build Coastguard Worker
1059*ec779b8eSAndroid Build Coastguard Worker // EncryptedLinearInputBuffers
1060*ec779b8eSAndroid Build Coastguard Worker
EncryptedLinearInputBuffers(bool secure,const sp<MemoryDealer> & dealer,const sp<ICrypto> & crypto,int32_t heapSeqNum,size_t capacity,size_t numInputSlots,const char * componentName,const char * name)1061*ec779b8eSAndroid Build Coastguard Worker EncryptedLinearInputBuffers::EncryptedLinearInputBuffers(
1062*ec779b8eSAndroid Build Coastguard Worker bool secure,
1063*ec779b8eSAndroid Build Coastguard Worker const sp<MemoryDealer> &dealer,
1064*ec779b8eSAndroid Build Coastguard Worker const sp<ICrypto> &crypto,
1065*ec779b8eSAndroid Build Coastguard Worker int32_t heapSeqNum,
1066*ec779b8eSAndroid Build Coastguard Worker size_t capacity,
1067*ec779b8eSAndroid Build Coastguard Worker size_t numInputSlots,
1068*ec779b8eSAndroid Build Coastguard Worker const char *componentName, const char *name)
1069*ec779b8eSAndroid Build Coastguard Worker : LinearInputBuffers(componentName, name),
1070*ec779b8eSAndroid Build Coastguard Worker mUsage({0, 0}),
1071*ec779b8eSAndroid Build Coastguard Worker mDealer(dealer),
1072*ec779b8eSAndroid Build Coastguard Worker mCrypto(crypto),
1073*ec779b8eSAndroid Build Coastguard Worker mMemoryVector(new std::vector<Entry>){
1074*ec779b8eSAndroid Build Coastguard Worker if (secure) {
1075*ec779b8eSAndroid Build Coastguard Worker mUsage = { C2MemoryUsage::READ_PROTECTED, 0 };
1076*ec779b8eSAndroid Build Coastguard Worker } else {
1077*ec779b8eSAndroid Build Coastguard Worker mUsage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
1078*ec779b8eSAndroid Build Coastguard Worker }
1079*ec779b8eSAndroid Build Coastguard Worker for (size_t i = 0; i < numInputSlots; ++i) {
1080*ec779b8eSAndroid Build Coastguard Worker sp<IMemory> memory = mDealer->allocate(capacity);
1081*ec779b8eSAndroid Build Coastguard Worker if (memory == nullptr) {
1082*ec779b8eSAndroid Build Coastguard Worker ALOGD("[%s] Failed to allocate memory from dealer: only %zu slots allocated",
1083*ec779b8eSAndroid Build Coastguard Worker mName, i);
1084*ec779b8eSAndroid Build Coastguard Worker break;
1085*ec779b8eSAndroid Build Coastguard Worker }
1086*ec779b8eSAndroid Build Coastguard Worker mMemoryVector->push_back({std::weak_ptr<C2LinearBlock>(), memory, heapSeqNum});
1087*ec779b8eSAndroid Build Coastguard Worker }
1088*ec779b8eSAndroid Build Coastguard Worker }
1089*ec779b8eSAndroid Build Coastguard Worker
toArrayMode(size_t size)1090*ec779b8eSAndroid Build Coastguard Worker std::unique_ptr<InputBuffers> EncryptedLinearInputBuffers::toArrayMode(size_t size) {
1091*ec779b8eSAndroid Build Coastguard Worker std::unique_ptr<InputBuffersArray> array(
1092*ec779b8eSAndroid Build Coastguard Worker new InputBuffersArray(mComponentName.c_str(), "1D-EncryptedInput[N]"));
1093*ec779b8eSAndroid Build Coastguard Worker array->setPool(mPool);
1094*ec779b8eSAndroid Build Coastguard Worker array->setFormat(mFormat);
1095*ec779b8eSAndroid Build Coastguard Worker array->initialize(
1096*ec779b8eSAndroid Build Coastguard Worker mImpl,
1097*ec779b8eSAndroid Build Coastguard Worker size,
1098*ec779b8eSAndroid Build Coastguard Worker [pool = mPool,
1099*ec779b8eSAndroid Build Coastguard Worker format = mFormat,
1100*ec779b8eSAndroid Build Coastguard Worker usage = mUsage,
1101*ec779b8eSAndroid Build Coastguard Worker memoryVector = mMemoryVector] () -> sp<Codec2Buffer> {
1102*ec779b8eSAndroid Build Coastguard Worker return Alloc(pool, format, usage, memoryVector);
1103*ec779b8eSAndroid Build Coastguard Worker });
1104*ec779b8eSAndroid Build Coastguard Worker return std::move(array);
1105*ec779b8eSAndroid Build Coastguard Worker }
1106*ec779b8eSAndroid Build Coastguard Worker
1107*ec779b8eSAndroid Build Coastguard Worker
1108*ec779b8eSAndroid Build Coastguard Worker // static
Alloc(const std::shared_ptr<C2BlockPool> & pool,const sp<AMessage> & format,C2MemoryUsage usage,const std::shared_ptr<std::vector<EncryptedLinearInputBuffers::Entry>> & memoryVector)1109*ec779b8eSAndroid Build Coastguard Worker sp<Codec2Buffer> EncryptedLinearInputBuffers::Alloc(
1110*ec779b8eSAndroid Build Coastguard Worker const std::shared_ptr<C2BlockPool> &pool,
1111*ec779b8eSAndroid Build Coastguard Worker const sp<AMessage> &format,
1112*ec779b8eSAndroid Build Coastguard Worker C2MemoryUsage usage,
1113*ec779b8eSAndroid Build Coastguard Worker const std::shared_ptr<std::vector<EncryptedLinearInputBuffers::Entry>> &memoryVector) {
1114*ec779b8eSAndroid Build Coastguard Worker int32_t capacity = kLinearBufferSize;
1115*ec779b8eSAndroid Build Coastguard Worker (void)format->findInt32(KEY_MAX_INPUT_SIZE, &capacity);
1116*ec779b8eSAndroid Build Coastguard Worker if ((size_t)capacity > kMaxLinearBufferSize) {
1117*ec779b8eSAndroid Build Coastguard Worker ALOGD("client requested %d, capped to %zu", capacity, kMaxLinearBufferSize);
1118*ec779b8eSAndroid Build Coastguard Worker capacity = kMaxLinearBufferSize;
1119*ec779b8eSAndroid Build Coastguard Worker }
1120*ec779b8eSAndroid Build Coastguard Worker
1121*ec779b8eSAndroid Build Coastguard Worker sp<IMemory> memory;
1122*ec779b8eSAndroid Build Coastguard Worker size_t slot = 0;
1123*ec779b8eSAndroid Build Coastguard Worker int32_t heapSeqNum = -1;
1124*ec779b8eSAndroid Build Coastguard Worker for (; slot < memoryVector->size(); ++slot) {
1125*ec779b8eSAndroid Build Coastguard Worker if (memoryVector->at(slot).block.expired()) {
1126*ec779b8eSAndroid Build Coastguard Worker memory = memoryVector->at(slot).memory;
1127*ec779b8eSAndroid Build Coastguard Worker heapSeqNum = memoryVector->at(slot).heapSeqNum;
1128*ec779b8eSAndroid Build Coastguard Worker break;
1129*ec779b8eSAndroid Build Coastguard Worker }
1130*ec779b8eSAndroid Build Coastguard Worker }
1131*ec779b8eSAndroid Build Coastguard Worker if (memory == nullptr) {
1132*ec779b8eSAndroid Build Coastguard Worker return nullptr;
1133*ec779b8eSAndroid Build Coastguard Worker }
1134*ec779b8eSAndroid Build Coastguard Worker
1135*ec779b8eSAndroid Build Coastguard Worker int64_t usageValue = 0;
1136*ec779b8eSAndroid Build Coastguard Worker (void)format->findInt64("android._C2MemoryUsage", &usageValue);
1137*ec779b8eSAndroid Build Coastguard Worker usage = C2MemoryUsage(usage.expected | usageValue);
1138*ec779b8eSAndroid Build Coastguard Worker
1139*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<C2LinearBlock> block;
1140*ec779b8eSAndroid Build Coastguard Worker c2_status_t err = pool->fetchLinearBlock(capacity, usage, &block);
1141*ec779b8eSAndroid Build Coastguard Worker if (err != C2_OK || block == nullptr) {
1142*ec779b8eSAndroid Build Coastguard Worker return nullptr;
1143*ec779b8eSAndroid Build Coastguard Worker }
1144*ec779b8eSAndroid Build Coastguard Worker
1145*ec779b8eSAndroid Build Coastguard Worker memoryVector->at(slot).block = block;
1146*ec779b8eSAndroid Build Coastguard Worker return new EncryptedLinearBlockBuffer(format, block, memory, heapSeqNum);
1147*ec779b8eSAndroid Build Coastguard Worker }
1148*ec779b8eSAndroid Build Coastguard Worker
createNewBuffer()1149*ec779b8eSAndroid Build Coastguard Worker sp<Codec2Buffer> EncryptedLinearInputBuffers::createNewBuffer() {
1150*ec779b8eSAndroid Build Coastguard Worker // TODO: android_2020
1151*ec779b8eSAndroid Build Coastguard Worker return nullptr;
1152*ec779b8eSAndroid Build Coastguard Worker }
1153*ec779b8eSAndroid Build Coastguard Worker
1154*ec779b8eSAndroid Build Coastguard Worker // GraphicMetadataInputBuffers
1155*ec779b8eSAndroid Build Coastguard Worker
GraphicMetadataInputBuffers(const char * componentName,const char * name)1156*ec779b8eSAndroid Build Coastguard Worker GraphicMetadataInputBuffers::GraphicMetadataInputBuffers(
1157*ec779b8eSAndroid Build Coastguard Worker const char *componentName, const char *name)
1158*ec779b8eSAndroid Build Coastguard Worker : InputBuffers(componentName, name),
1159*ec779b8eSAndroid Build Coastguard Worker mImpl(mName),
1160*ec779b8eSAndroid Build Coastguard Worker mStore(GetCodec2PlatformAllocatorStore()) { }
1161*ec779b8eSAndroid Build Coastguard Worker
requestNewBuffer(size_t * index,sp<MediaCodecBuffer> * buffer)1162*ec779b8eSAndroid Build Coastguard Worker bool GraphicMetadataInputBuffers::requestNewBuffer(
1163*ec779b8eSAndroid Build Coastguard Worker size_t *index, sp<MediaCodecBuffer> *buffer) {
1164*ec779b8eSAndroid Build Coastguard Worker sp<Codec2Buffer> newBuffer = createNewBuffer();
1165*ec779b8eSAndroid Build Coastguard Worker if (newBuffer == nullptr) {
1166*ec779b8eSAndroid Build Coastguard Worker return false;
1167*ec779b8eSAndroid Build Coastguard Worker }
1168*ec779b8eSAndroid Build Coastguard Worker *index = mImpl.assignSlot(newBuffer);
1169*ec779b8eSAndroid Build Coastguard Worker *buffer = newBuffer;
1170*ec779b8eSAndroid Build Coastguard Worker return true;
1171*ec779b8eSAndroid Build Coastguard Worker }
1172*ec779b8eSAndroid Build Coastguard Worker
releaseBuffer(const sp<MediaCodecBuffer> & buffer,std::shared_ptr<C2Buffer> * c2buffer,bool release)1173*ec779b8eSAndroid Build Coastguard Worker bool GraphicMetadataInputBuffers::releaseBuffer(
1174*ec779b8eSAndroid Build Coastguard Worker const sp<MediaCodecBuffer> &buffer,
1175*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<C2Buffer> *c2buffer,
1176*ec779b8eSAndroid Build Coastguard Worker bool release) {
1177*ec779b8eSAndroid Build Coastguard Worker return mImpl.releaseSlot(buffer, c2buffer, release);
1178*ec779b8eSAndroid Build Coastguard Worker }
1179*ec779b8eSAndroid Build Coastguard Worker
expireComponentBuffer(const std::shared_ptr<C2Buffer> & c2buffer)1180*ec779b8eSAndroid Build Coastguard Worker bool GraphicMetadataInputBuffers::expireComponentBuffer(
1181*ec779b8eSAndroid Build Coastguard Worker const std::shared_ptr<C2Buffer> &c2buffer) {
1182*ec779b8eSAndroid Build Coastguard Worker return mImpl.expireComponentBuffer(c2buffer);
1183*ec779b8eSAndroid Build Coastguard Worker }
1184*ec779b8eSAndroid Build Coastguard Worker
flush()1185*ec779b8eSAndroid Build Coastguard Worker void GraphicMetadataInputBuffers::flush() {
1186*ec779b8eSAndroid Build Coastguard Worker // This is no-op by default unless we're in array mode where we need to keep
1187*ec779b8eSAndroid Build Coastguard Worker // track of the flushed work.
1188*ec779b8eSAndroid Build Coastguard Worker }
1189*ec779b8eSAndroid Build Coastguard Worker
toArrayMode(size_t size)1190*ec779b8eSAndroid Build Coastguard Worker std::unique_ptr<InputBuffers> GraphicMetadataInputBuffers::toArrayMode(
1191*ec779b8eSAndroid Build Coastguard Worker size_t size) {
1192*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<C2Allocator> alloc;
1193*ec779b8eSAndroid Build Coastguard Worker c2_status_t err = mStore->fetchAllocator(mPool->getAllocatorId(), &alloc);
1194*ec779b8eSAndroid Build Coastguard Worker if (err != C2_OK) {
1195*ec779b8eSAndroid Build Coastguard Worker return nullptr;
1196*ec779b8eSAndroid Build Coastguard Worker }
1197*ec779b8eSAndroid Build Coastguard Worker std::unique_ptr<InputBuffersArray> array(
1198*ec779b8eSAndroid Build Coastguard Worker new InputBuffersArray(mComponentName.c_str(), "2D-MetaInput[N]"));
1199*ec779b8eSAndroid Build Coastguard Worker array->setPool(mPool);
1200*ec779b8eSAndroid Build Coastguard Worker array->setFormat(mFormat);
1201*ec779b8eSAndroid Build Coastguard Worker array->initialize(
1202*ec779b8eSAndroid Build Coastguard Worker mImpl,
1203*ec779b8eSAndroid Build Coastguard Worker size,
1204*ec779b8eSAndroid Build Coastguard Worker [format = mFormat, alloc]() -> sp<Codec2Buffer> {
1205*ec779b8eSAndroid Build Coastguard Worker return new GraphicMetadataBuffer(format, alloc);
1206*ec779b8eSAndroid Build Coastguard Worker });
1207*ec779b8eSAndroid Build Coastguard Worker return std::move(array);
1208*ec779b8eSAndroid Build Coastguard Worker }
1209*ec779b8eSAndroid Build Coastguard Worker
numActiveSlots() const1210*ec779b8eSAndroid Build Coastguard Worker size_t GraphicMetadataInputBuffers::numActiveSlots() const {
1211*ec779b8eSAndroid Build Coastguard Worker return mImpl.numActiveSlots();
1212*ec779b8eSAndroid Build Coastguard Worker }
1213*ec779b8eSAndroid Build Coastguard Worker
createNewBuffer()1214*ec779b8eSAndroid Build Coastguard Worker sp<Codec2Buffer> GraphicMetadataInputBuffers::createNewBuffer() {
1215*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<C2Allocator> alloc;
1216*ec779b8eSAndroid Build Coastguard Worker c2_status_t err = mStore->fetchAllocator(mPool->getAllocatorId(), &alloc);
1217*ec779b8eSAndroid Build Coastguard Worker if (err != C2_OK) {
1218*ec779b8eSAndroid Build Coastguard Worker return nullptr;
1219*ec779b8eSAndroid Build Coastguard Worker }
1220*ec779b8eSAndroid Build Coastguard Worker return new GraphicMetadataBuffer(mFormat, alloc);
1221*ec779b8eSAndroid Build Coastguard Worker }
1222*ec779b8eSAndroid Build Coastguard Worker
1223*ec779b8eSAndroid Build Coastguard Worker // GraphicInputBuffers
1224*ec779b8eSAndroid Build Coastguard Worker
GraphicInputBuffers(const char * componentName,const char * name)1225*ec779b8eSAndroid Build Coastguard Worker GraphicInputBuffers::GraphicInputBuffers(
1226*ec779b8eSAndroid Build Coastguard Worker const char *componentName, const char *name)
1227*ec779b8eSAndroid Build Coastguard Worker : InputBuffers(componentName, name),
1228*ec779b8eSAndroid Build Coastguard Worker mImpl(mName),
1229*ec779b8eSAndroid Build Coastguard Worker mLocalBufferPool(LocalBufferPool::Create()),
1230*ec779b8eSAndroid Build Coastguard Worker mPixelFormat(PIXEL_FORMAT_UNKNOWN) { }
1231*ec779b8eSAndroid Build Coastguard Worker
requestNewBuffer(size_t * index,sp<MediaCodecBuffer> * buffer)1232*ec779b8eSAndroid Build Coastguard Worker bool GraphicInputBuffers::requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) {
1233*ec779b8eSAndroid Build Coastguard Worker sp<Codec2Buffer> newBuffer = createNewBuffer();
1234*ec779b8eSAndroid Build Coastguard Worker if (newBuffer == nullptr) {
1235*ec779b8eSAndroid Build Coastguard Worker return false;
1236*ec779b8eSAndroid Build Coastguard Worker }
1237*ec779b8eSAndroid Build Coastguard Worker *index = mImpl.assignSlot(newBuffer);
1238*ec779b8eSAndroid Build Coastguard Worker handleImageData(newBuffer);
1239*ec779b8eSAndroid Build Coastguard Worker *buffer = newBuffer;
1240*ec779b8eSAndroid Build Coastguard Worker return true;
1241*ec779b8eSAndroid Build Coastguard Worker }
1242*ec779b8eSAndroid Build Coastguard Worker
releaseBuffer(const sp<MediaCodecBuffer> & buffer,std::shared_ptr<C2Buffer> * c2buffer,bool release)1243*ec779b8eSAndroid Build Coastguard Worker bool GraphicInputBuffers::releaseBuffer(
1244*ec779b8eSAndroid Build Coastguard Worker const sp<MediaCodecBuffer> &buffer,
1245*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<C2Buffer> *c2buffer,
1246*ec779b8eSAndroid Build Coastguard Worker bool release) {
1247*ec779b8eSAndroid Build Coastguard Worker return mImpl.releaseSlot(buffer, c2buffer, release);
1248*ec779b8eSAndroid Build Coastguard Worker }
1249*ec779b8eSAndroid Build Coastguard Worker
expireComponentBuffer(const std::shared_ptr<C2Buffer> & c2buffer)1250*ec779b8eSAndroid Build Coastguard Worker bool GraphicInputBuffers::expireComponentBuffer(
1251*ec779b8eSAndroid Build Coastguard Worker const std::shared_ptr<C2Buffer> &c2buffer) {
1252*ec779b8eSAndroid Build Coastguard Worker return mImpl.expireComponentBuffer(c2buffer);
1253*ec779b8eSAndroid Build Coastguard Worker }
1254*ec779b8eSAndroid Build Coastguard Worker
flush()1255*ec779b8eSAndroid Build Coastguard Worker void GraphicInputBuffers::flush() {
1256*ec779b8eSAndroid Build Coastguard Worker // This is no-op by default unless we're in array mode where we need to keep
1257*ec779b8eSAndroid Build Coastguard Worker // track of the flushed work.
1258*ec779b8eSAndroid Build Coastguard Worker }
1259*ec779b8eSAndroid Build Coastguard Worker
extractPixelFormat(const sp<AMessage> & format)1260*ec779b8eSAndroid Build Coastguard Worker static uint32_t extractPixelFormat(const sp<AMessage> &format) {
1261*ec779b8eSAndroid Build Coastguard Worker int32_t frameworkColorFormat = 0;
1262*ec779b8eSAndroid Build Coastguard Worker if (!format->findInt32("android._color-format", &frameworkColorFormat)) {
1263*ec779b8eSAndroid Build Coastguard Worker return PIXEL_FORMAT_UNKNOWN;
1264*ec779b8eSAndroid Build Coastguard Worker }
1265*ec779b8eSAndroid Build Coastguard Worker uint32_t pixelFormat = PIXEL_FORMAT_UNKNOWN;
1266*ec779b8eSAndroid Build Coastguard Worker if (C2Mapper::mapPixelFormatFrameworkToCodec(frameworkColorFormat, &pixelFormat)) {
1267*ec779b8eSAndroid Build Coastguard Worker return pixelFormat;
1268*ec779b8eSAndroid Build Coastguard Worker }
1269*ec779b8eSAndroid Build Coastguard Worker return PIXEL_FORMAT_UNKNOWN;
1270*ec779b8eSAndroid Build Coastguard Worker }
1271*ec779b8eSAndroid Build Coastguard Worker
toArrayMode(size_t size)1272*ec779b8eSAndroid Build Coastguard Worker std::unique_ptr<InputBuffers> GraphicInputBuffers::toArrayMode(size_t size) {
1273*ec779b8eSAndroid Build Coastguard Worker std::unique_ptr<InputBuffersArray> array(
1274*ec779b8eSAndroid Build Coastguard Worker new InputBuffersArray(mComponentName.c_str(), "2D-BB-Input[N]"));
1275*ec779b8eSAndroid Build Coastguard Worker array->setPool(mPool);
1276*ec779b8eSAndroid Build Coastguard Worker array->setFormat(mFormat);
1277*ec779b8eSAndroid Build Coastguard Worker uint32_t pixelFormat = extractPixelFormat(mFormat);
1278*ec779b8eSAndroid Build Coastguard Worker array->initialize(
1279*ec779b8eSAndroid Build Coastguard Worker mImpl,
1280*ec779b8eSAndroid Build Coastguard Worker size,
1281*ec779b8eSAndroid Build Coastguard Worker [pool = mPool, format = mFormat, lbp = mLocalBufferPool, pixelFormat]()
1282*ec779b8eSAndroid Build Coastguard Worker -> sp<Codec2Buffer> {
1283*ec779b8eSAndroid Build Coastguard Worker C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
1284*ec779b8eSAndroid Build Coastguard Worker return AllocateInputGraphicBuffer(
1285*ec779b8eSAndroid Build Coastguard Worker pool, format, pixelFormat, usage, lbp);
1286*ec779b8eSAndroid Build Coastguard Worker });
1287*ec779b8eSAndroid Build Coastguard Worker return std::move(array);
1288*ec779b8eSAndroid Build Coastguard Worker }
1289*ec779b8eSAndroid Build Coastguard Worker
numActiveSlots() const1290*ec779b8eSAndroid Build Coastguard Worker size_t GraphicInputBuffers::numActiveSlots() const {
1291*ec779b8eSAndroid Build Coastguard Worker return mImpl.numActiveSlots();
1292*ec779b8eSAndroid Build Coastguard Worker }
1293*ec779b8eSAndroid Build Coastguard Worker
createNewBuffer()1294*ec779b8eSAndroid Build Coastguard Worker sp<Codec2Buffer> GraphicInputBuffers::createNewBuffer() {
1295*ec779b8eSAndroid Build Coastguard Worker C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
1296*ec779b8eSAndroid Build Coastguard Worker mPixelFormat = extractPixelFormat(mFormat);
1297*ec779b8eSAndroid Build Coastguard Worker return AllocateInputGraphicBuffer(
1298*ec779b8eSAndroid Build Coastguard Worker mPool, mFormat, mPixelFormat, usage, mLocalBufferPool);
1299*ec779b8eSAndroid Build Coastguard Worker }
1300*ec779b8eSAndroid Build Coastguard Worker
getPixelFormatIfApplicable()1301*ec779b8eSAndroid Build Coastguard Worker uint32_t GraphicInputBuffers::getPixelFormatIfApplicable() { return mPixelFormat; }
1302*ec779b8eSAndroid Build Coastguard Worker
resetPixelFormatIfApplicable()1303*ec779b8eSAndroid Build Coastguard Worker bool GraphicInputBuffers::resetPixelFormatIfApplicable() {
1304*ec779b8eSAndroid Build Coastguard Worker mPixelFormat = PIXEL_FORMAT_UNKNOWN;
1305*ec779b8eSAndroid Build Coastguard Worker return true;
1306*ec779b8eSAndroid Build Coastguard Worker }
1307*ec779b8eSAndroid Build Coastguard Worker
1308*ec779b8eSAndroid Build Coastguard Worker // OutputBuffersArray
1309*ec779b8eSAndroid Build Coastguard Worker
initialize(const FlexBuffersImpl & impl,size_t minSize,std::function<sp<Codec2Buffer> ()> allocate)1310*ec779b8eSAndroid Build Coastguard Worker void OutputBuffersArray::initialize(
1311*ec779b8eSAndroid Build Coastguard Worker const FlexBuffersImpl &impl,
1312*ec779b8eSAndroid Build Coastguard Worker size_t minSize,
1313*ec779b8eSAndroid Build Coastguard Worker std::function<sp<Codec2Buffer>()> allocate) {
1314*ec779b8eSAndroid Build Coastguard Worker mAlloc = allocate;
1315*ec779b8eSAndroid Build Coastguard Worker mImpl.initialize(impl, minSize, allocate);
1316*ec779b8eSAndroid Build Coastguard Worker }
1317*ec779b8eSAndroid Build Coastguard Worker
registerBuffer(const std::shared_ptr<C2Buffer> & buffer,size_t * index,sp<MediaCodecBuffer> * clientBuffer)1318*ec779b8eSAndroid Build Coastguard Worker status_t OutputBuffersArray::registerBuffer(
1319*ec779b8eSAndroid Build Coastguard Worker const std::shared_ptr<C2Buffer> &buffer,
1320*ec779b8eSAndroid Build Coastguard Worker size_t *index,
1321*ec779b8eSAndroid Build Coastguard Worker sp<MediaCodecBuffer> *clientBuffer) {
1322*ec779b8eSAndroid Build Coastguard Worker sp<Codec2Buffer> c2Buffer;
1323*ec779b8eSAndroid Build Coastguard Worker status_t err = mImpl.grabBuffer(
1324*ec779b8eSAndroid Build Coastguard Worker index,
1325*ec779b8eSAndroid Build Coastguard Worker &c2Buffer,
1326*ec779b8eSAndroid Build Coastguard Worker [buffer](const sp<Codec2Buffer> &clientBuffer) {
1327*ec779b8eSAndroid Build Coastguard Worker return clientBuffer->canCopy(buffer);
1328*ec779b8eSAndroid Build Coastguard Worker });
1329*ec779b8eSAndroid Build Coastguard Worker if (err == WOULD_BLOCK) {
1330*ec779b8eSAndroid Build Coastguard Worker ALOGV("[%s] buffers temporarily not available", mName);
1331*ec779b8eSAndroid Build Coastguard Worker return err;
1332*ec779b8eSAndroid Build Coastguard Worker } else if (err != OK) {
1333*ec779b8eSAndroid Build Coastguard Worker ALOGD("[%s] grabBuffer failed: %d", mName, err);
1334*ec779b8eSAndroid Build Coastguard Worker return err;
1335*ec779b8eSAndroid Build Coastguard Worker }
1336*ec779b8eSAndroid Build Coastguard Worker c2Buffer->setFormat(mFormat);
1337*ec779b8eSAndroid Build Coastguard Worker if (!convert(buffer, &c2Buffer) && !c2Buffer->copy(buffer)) {
1338*ec779b8eSAndroid Build Coastguard Worker ALOGD("[%s] copy buffer failed", mName);
1339*ec779b8eSAndroid Build Coastguard Worker return WOULD_BLOCK;
1340*ec779b8eSAndroid Build Coastguard Worker }
1341*ec779b8eSAndroid Build Coastguard Worker if (buffer && buffer->hasInfo(C2AccessUnitInfos::output::PARAM_TYPE)) {
1342*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<const C2AccessUnitInfos::output> bufferMetadata =
1343*ec779b8eSAndroid Build Coastguard Worker std::static_pointer_cast<const C2AccessUnitInfos::output>(
1344*ec779b8eSAndroid Build Coastguard Worker buffer->getInfo(C2AccessUnitInfos::output::PARAM_TYPE));
1345*ec779b8eSAndroid Build Coastguard Worker if (submit(c2Buffer, mSampleRate, mChannelCount, bufferMetadata)) {
1346*ec779b8eSAndroid Build Coastguard Worker buffer->removeInfo(C2AccessUnitInfos::output::PARAM_TYPE);
1347*ec779b8eSAndroid Build Coastguard Worker }
1348*ec779b8eSAndroid Build Coastguard Worker } else {
1349*ec779b8eSAndroid Build Coastguard Worker submit(c2Buffer);
1350*ec779b8eSAndroid Build Coastguard Worker }
1351*ec779b8eSAndroid Build Coastguard Worker handleImageData(c2Buffer);
1352*ec779b8eSAndroid Build Coastguard Worker *clientBuffer = c2Buffer;
1353*ec779b8eSAndroid Build Coastguard Worker ALOGV("[%s] grabbed buffer %zu", mName, *index);
1354*ec779b8eSAndroid Build Coastguard Worker return OK;
1355*ec779b8eSAndroid Build Coastguard Worker }
1356*ec779b8eSAndroid Build Coastguard Worker
registerCsd(const C2StreamInitDataInfo::output * csd,size_t * index,sp<MediaCodecBuffer> * clientBuffer)1357*ec779b8eSAndroid Build Coastguard Worker status_t OutputBuffersArray::registerCsd(
1358*ec779b8eSAndroid Build Coastguard Worker const C2StreamInitDataInfo::output *csd,
1359*ec779b8eSAndroid Build Coastguard Worker size_t *index,
1360*ec779b8eSAndroid Build Coastguard Worker sp<MediaCodecBuffer> *clientBuffer) {
1361*ec779b8eSAndroid Build Coastguard Worker sp<Codec2Buffer> c2Buffer;
1362*ec779b8eSAndroid Build Coastguard Worker status_t err = mImpl.grabBuffer(
1363*ec779b8eSAndroid Build Coastguard Worker index,
1364*ec779b8eSAndroid Build Coastguard Worker &c2Buffer,
1365*ec779b8eSAndroid Build Coastguard Worker [csd](const sp<Codec2Buffer> &clientBuffer) {
1366*ec779b8eSAndroid Build Coastguard Worker return clientBuffer->base() != nullptr
1367*ec779b8eSAndroid Build Coastguard Worker && clientBuffer->capacity() >= csd->flexCount();
1368*ec779b8eSAndroid Build Coastguard Worker });
1369*ec779b8eSAndroid Build Coastguard Worker if (err != OK) {
1370*ec779b8eSAndroid Build Coastguard Worker return err;
1371*ec779b8eSAndroid Build Coastguard Worker }
1372*ec779b8eSAndroid Build Coastguard Worker memcpy(c2Buffer->base(), csd->m.value, csd->flexCount());
1373*ec779b8eSAndroid Build Coastguard Worker c2Buffer->setRange(0, csd->flexCount());
1374*ec779b8eSAndroid Build Coastguard Worker c2Buffer->setFormat(mFormat);
1375*ec779b8eSAndroid Build Coastguard Worker *clientBuffer = c2Buffer;
1376*ec779b8eSAndroid Build Coastguard Worker return OK;
1377*ec779b8eSAndroid Build Coastguard Worker }
1378*ec779b8eSAndroid Build Coastguard Worker
releaseBuffer(const sp<MediaCodecBuffer> & buffer,std::shared_ptr<C2Buffer> * c2buffer)1379*ec779b8eSAndroid Build Coastguard Worker bool OutputBuffersArray::releaseBuffer(
1380*ec779b8eSAndroid Build Coastguard Worker const sp<MediaCodecBuffer> &buffer, std::shared_ptr<C2Buffer> *c2buffer) {
1381*ec779b8eSAndroid Build Coastguard Worker return mImpl.returnBuffer(buffer, c2buffer, true);
1382*ec779b8eSAndroid Build Coastguard Worker }
1383*ec779b8eSAndroid Build Coastguard Worker
flush(const std::list<std::unique_ptr<C2Work>> & flushedWork)1384*ec779b8eSAndroid Build Coastguard Worker void OutputBuffersArray::flush(const std::list<std::unique_ptr<C2Work>> &flushedWork) {
1385*ec779b8eSAndroid Build Coastguard Worker (void)flushedWork;
1386*ec779b8eSAndroid Build Coastguard Worker mImpl.flush();
1387*ec779b8eSAndroid Build Coastguard Worker if (mSkipCutBuffer != nullptr) {
1388*ec779b8eSAndroid Build Coastguard Worker mSkipCutBuffer->clearAll();
1389*ec779b8eSAndroid Build Coastguard Worker }
1390*ec779b8eSAndroid Build Coastguard Worker }
1391*ec779b8eSAndroid Build Coastguard Worker
getArray(Vector<sp<MediaCodecBuffer>> * array) const1392*ec779b8eSAndroid Build Coastguard Worker void OutputBuffersArray::getArray(Vector<sp<MediaCodecBuffer>> *array) const {
1393*ec779b8eSAndroid Build Coastguard Worker mImpl.getArray(array);
1394*ec779b8eSAndroid Build Coastguard Worker }
1395*ec779b8eSAndroid Build Coastguard Worker
numActiveSlots() const1396*ec779b8eSAndroid Build Coastguard Worker size_t OutputBuffersArray::numActiveSlots() const {
1397*ec779b8eSAndroid Build Coastguard Worker return mImpl.numActiveSlots();
1398*ec779b8eSAndroid Build Coastguard Worker }
1399*ec779b8eSAndroid Build Coastguard Worker
realloc(const std::shared_ptr<C2Buffer> & c2buffer)1400*ec779b8eSAndroid Build Coastguard Worker void OutputBuffersArray::realloc(const std::shared_ptr<C2Buffer> &c2buffer) {
1401*ec779b8eSAndroid Build Coastguard Worker switch (c2buffer->data().type()) {
1402*ec779b8eSAndroid Build Coastguard Worker case C2BufferData::LINEAR: {
1403*ec779b8eSAndroid Build Coastguard Worker uint32_t size = kLinearBufferSize;
1404*ec779b8eSAndroid Build Coastguard Worker const std::vector<C2ConstLinearBlock> &linear_blocks = c2buffer->data().linearBlocks();
1405*ec779b8eSAndroid Build Coastguard Worker const uint32_t block_size = linear_blocks.front().size();
1406*ec779b8eSAndroid Build Coastguard Worker if (block_size < kMaxLinearBufferSize / 2) {
1407*ec779b8eSAndroid Build Coastguard Worker size = block_size * 2;
1408*ec779b8eSAndroid Build Coastguard Worker } else {
1409*ec779b8eSAndroid Build Coastguard Worker size = kMaxLinearBufferSize;
1410*ec779b8eSAndroid Build Coastguard Worker }
1411*ec779b8eSAndroid Build Coastguard Worker mAlloc = [format = mFormat, size] {
1412*ec779b8eSAndroid Build Coastguard Worker return new LocalLinearBuffer(format, new ABuffer(size));
1413*ec779b8eSAndroid Build Coastguard Worker };
1414*ec779b8eSAndroid Build Coastguard Worker ALOGD("[%s] reallocating with linear buffer of size %u", mName, size);
1415*ec779b8eSAndroid Build Coastguard Worker break;
1416*ec779b8eSAndroid Build Coastguard Worker }
1417*ec779b8eSAndroid Build Coastguard Worker
1418*ec779b8eSAndroid Build Coastguard Worker case C2BufferData::GRAPHIC: {
1419*ec779b8eSAndroid Build Coastguard Worker // This is only called for RawGraphicOutputBuffers.
1420*ec779b8eSAndroid Build Coastguard Worker mAlloc = [format = mFormat,
1421*ec779b8eSAndroid Build Coastguard Worker lbp = LocalBufferPool::Create()] {
1422*ec779b8eSAndroid Build Coastguard Worker return ConstGraphicBlockBuffer::AllocateEmpty(
1423*ec779b8eSAndroid Build Coastguard Worker format,
1424*ec779b8eSAndroid Build Coastguard Worker [lbp](size_t capacity) {
1425*ec779b8eSAndroid Build Coastguard Worker return lbp->newBuffer(capacity);
1426*ec779b8eSAndroid Build Coastguard Worker });
1427*ec779b8eSAndroid Build Coastguard Worker };
1428*ec779b8eSAndroid Build Coastguard Worker ALOGD("[%s] reallocating with graphic buffer: format = %s",
1429*ec779b8eSAndroid Build Coastguard Worker mName, mFormat->debugString().c_str());
1430*ec779b8eSAndroid Build Coastguard Worker break;
1431*ec779b8eSAndroid Build Coastguard Worker }
1432*ec779b8eSAndroid Build Coastguard Worker
1433*ec779b8eSAndroid Build Coastguard Worker case C2BufferData::INVALID: [[fallthrough]];
1434*ec779b8eSAndroid Build Coastguard Worker case C2BufferData::LINEAR_CHUNKS: [[fallthrough]];
1435*ec779b8eSAndroid Build Coastguard Worker case C2BufferData::GRAPHIC_CHUNKS: [[fallthrough]];
1436*ec779b8eSAndroid Build Coastguard Worker default:
1437*ec779b8eSAndroid Build Coastguard Worker ALOGD("Unsupported type: %d", (int)c2buffer->data().type());
1438*ec779b8eSAndroid Build Coastguard Worker return;
1439*ec779b8eSAndroid Build Coastguard Worker }
1440*ec779b8eSAndroid Build Coastguard Worker mImpl.realloc(mAlloc);
1441*ec779b8eSAndroid Build Coastguard Worker }
1442*ec779b8eSAndroid Build Coastguard Worker
grow(size_t newSize)1443*ec779b8eSAndroid Build Coastguard Worker void OutputBuffersArray::grow(size_t newSize) {
1444*ec779b8eSAndroid Build Coastguard Worker mImpl.grow(newSize, mAlloc);
1445*ec779b8eSAndroid Build Coastguard Worker }
1446*ec779b8eSAndroid Build Coastguard Worker
transferFrom(OutputBuffers * source)1447*ec779b8eSAndroid Build Coastguard Worker void OutputBuffersArray::transferFrom(OutputBuffers* source) {
1448*ec779b8eSAndroid Build Coastguard Worker mFormat = source->mFormat;
1449*ec779b8eSAndroid Build Coastguard Worker mSkipCutBuffer = source->mSkipCutBuffer;
1450*ec779b8eSAndroid Build Coastguard Worker mPending = std::move(source->mPending);
1451*ec779b8eSAndroid Build Coastguard Worker mReorderStash = std::move(source->mReorderStash);
1452*ec779b8eSAndroid Build Coastguard Worker mDepth = source->mDepth;
1453*ec779b8eSAndroid Build Coastguard Worker mKey = source->mKey;
1454*ec779b8eSAndroid Build Coastguard Worker }
1455*ec779b8eSAndroid Build Coastguard Worker
1456*ec779b8eSAndroid Build Coastguard Worker // FlexOutputBuffers
1457*ec779b8eSAndroid Build Coastguard Worker
registerBuffer(const std::shared_ptr<C2Buffer> & buffer,size_t * index,sp<MediaCodecBuffer> * clientBuffer)1458*ec779b8eSAndroid Build Coastguard Worker status_t FlexOutputBuffers::registerBuffer(
1459*ec779b8eSAndroid Build Coastguard Worker const std::shared_ptr<C2Buffer> &buffer,
1460*ec779b8eSAndroid Build Coastguard Worker size_t *index,
1461*ec779b8eSAndroid Build Coastguard Worker sp<MediaCodecBuffer> *clientBuffer) {
1462*ec779b8eSAndroid Build Coastguard Worker sp<Codec2Buffer> newBuffer;
1463*ec779b8eSAndroid Build Coastguard Worker if (!convert(buffer, &newBuffer)) {
1464*ec779b8eSAndroid Build Coastguard Worker newBuffer = wrap(buffer);
1465*ec779b8eSAndroid Build Coastguard Worker if (newBuffer == nullptr) {
1466*ec779b8eSAndroid Build Coastguard Worker return NO_MEMORY;
1467*ec779b8eSAndroid Build Coastguard Worker }
1468*ec779b8eSAndroid Build Coastguard Worker newBuffer->setFormat(mFormat);
1469*ec779b8eSAndroid Build Coastguard Worker }
1470*ec779b8eSAndroid Build Coastguard Worker *index = mImpl.assignSlot(newBuffer);
1471*ec779b8eSAndroid Build Coastguard Worker handleImageData(newBuffer);
1472*ec779b8eSAndroid Build Coastguard Worker *clientBuffer = newBuffer;
1473*ec779b8eSAndroid Build Coastguard Worker
1474*ec779b8eSAndroid Build Coastguard Worker extractPixelFormatFromC2Buffer(buffer);
1475*ec779b8eSAndroid Build Coastguard Worker ALOGV("[%s] registered buffer %zu", mName, *index);
1476*ec779b8eSAndroid Build Coastguard Worker return OK;
1477*ec779b8eSAndroid Build Coastguard Worker }
1478*ec779b8eSAndroid Build Coastguard Worker
registerCsd(const C2StreamInitDataInfo::output * csd,size_t * index,sp<MediaCodecBuffer> * clientBuffer)1479*ec779b8eSAndroid Build Coastguard Worker status_t FlexOutputBuffers::registerCsd(
1480*ec779b8eSAndroid Build Coastguard Worker const C2StreamInitDataInfo::output *csd,
1481*ec779b8eSAndroid Build Coastguard Worker size_t *index,
1482*ec779b8eSAndroid Build Coastguard Worker sp<MediaCodecBuffer> *clientBuffer) {
1483*ec779b8eSAndroid Build Coastguard Worker sp<Codec2Buffer> newBuffer = new LocalLinearBuffer(
1484*ec779b8eSAndroid Build Coastguard Worker mFormat, ABuffer::CreateAsCopy(csd->m.value, csd->flexCount()));
1485*ec779b8eSAndroid Build Coastguard Worker *index = mImpl.assignSlot(newBuffer);
1486*ec779b8eSAndroid Build Coastguard Worker *clientBuffer = newBuffer;
1487*ec779b8eSAndroid Build Coastguard Worker return OK;
1488*ec779b8eSAndroid Build Coastguard Worker }
1489*ec779b8eSAndroid Build Coastguard Worker
releaseBuffer(const sp<MediaCodecBuffer> & buffer,std::shared_ptr<C2Buffer> * c2buffer)1490*ec779b8eSAndroid Build Coastguard Worker bool FlexOutputBuffers::releaseBuffer(
1491*ec779b8eSAndroid Build Coastguard Worker const sp<MediaCodecBuffer> &buffer,
1492*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<C2Buffer> *c2buffer) {
1493*ec779b8eSAndroid Build Coastguard Worker return mImpl.releaseSlot(buffer, c2buffer, true);
1494*ec779b8eSAndroid Build Coastguard Worker }
1495*ec779b8eSAndroid Build Coastguard Worker
flush(const std::list<std::unique_ptr<C2Work>> & flushedWork)1496*ec779b8eSAndroid Build Coastguard Worker void FlexOutputBuffers::flush(
1497*ec779b8eSAndroid Build Coastguard Worker const std::list<std::unique_ptr<C2Work>> &flushedWork) {
1498*ec779b8eSAndroid Build Coastguard Worker (void) flushedWork;
1499*ec779b8eSAndroid Build Coastguard Worker // This is no-op by default unless we're in array mode where we need to keep
1500*ec779b8eSAndroid Build Coastguard Worker // track of the flushed work.
1501*ec779b8eSAndroid Build Coastguard Worker }
1502*ec779b8eSAndroid Build Coastguard Worker
toArrayMode(size_t size)1503*ec779b8eSAndroid Build Coastguard Worker std::unique_ptr<OutputBuffersArray> FlexOutputBuffers::toArrayMode(size_t size) {
1504*ec779b8eSAndroid Build Coastguard Worker std::unique_ptr<OutputBuffersArray> array(new OutputBuffersArray(mComponentName.c_str()));
1505*ec779b8eSAndroid Build Coastguard Worker array->transferFrom(this);
1506*ec779b8eSAndroid Build Coastguard Worker std::function<sp<Codec2Buffer>()> alloc = getAlloc();
1507*ec779b8eSAndroid Build Coastguard Worker array->initialize(mImpl, size, alloc);
1508*ec779b8eSAndroid Build Coastguard Worker return array;
1509*ec779b8eSAndroid Build Coastguard Worker }
1510*ec779b8eSAndroid Build Coastguard Worker
numActiveSlots() const1511*ec779b8eSAndroid Build Coastguard Worker size_t FlexOutputBuffers::numActiveSlots() const {
1512*ec779b8eSAndroid Build Coastguard Worker return mImpl.numActiveSlots();
1513*ec779b8eSAndroid Build Coastguard Worker }
1514*ec779b8eSAndroid Build Coastguard Worker
extractPixelFormatFromC2Buffer(const std::shared_ptr<C2Buffer> & buffer)1515*ec779b8eSAndroid Build Coastguard Worker bool FlexOutputBuffers::extractPixelFormatFromC2Buffer(const std::shared_ptr<C2Buffer> &buffer) {
1516*ec779b8eSAndroid Build Coastguard Worker if (buffer == nullptr) {
1517*ec779b8eSAndroid Build Coastguard Worker return false;
1518*ec779b8eSAndroid Build Coastguard Worker }
1519*ec779b8eSAndroid Build Coastguard Worker const C2BufferData &data = buffer->data();
1520*ec779b8eSAndroid Build Coastguard Worker // only extract the first pixel format in a metric session.
1521*ec779b8eSAndroid Build Coastguard Worker if (mPixelFormat != PIXEL_FORMAT_UNKNOWN || data.type() != C2BufferData::GRAPHIC
1522*ec779b8eSAndroid Build Coastguard Worker || data.graphicBlocks().empty()) {
1523*ec779b8eSAndroid Build Coastguard Worker return false;
1524*ec779b8eSAndroid Build Coastguard Worker }
1525*ec779b8eSAndroid Build Coastguard Worker const C2Handle *const handle = data.graphicBlocks().front().handle();
1526*ec779b8eSAndroid Build Coastguard Worker uint32_t pf = ExtractFormatFromCodec2GrallocHandle(handle);
1527*ec779b8eSAndroid Build Coastguard Worker if (pf == PIXEL_FORMAT_UNKNOWN) {
1528*ec779b8eSAndroid Build Coastguard Worker return false;
1529*ec779b8eSAndroid Build Coastguard Worker }
1530*ec779b8eSAndroid Build Coastguard Worker mPixelFormat = pf;
1531*ec779b8eSAndroid Build Coastguard Worker return true;
1532*ec779b8eSAndroid Build Coastguard Worker }
1533*ec779b8eSAndroid Build Coastguard Worker
resetPixelFormatIfApplicable()1534*ec779b8eSAndroid Build Coastguard Worker bool FlexOutputBuffers::resetPixelFormatIfApplicable() {
1535*ec779b8eSAndroid Build Coastguard Worker mPixelFormat = PIXEL_FORMAT_UNKNOWN;
1536*ec779b8eSAndroid Build Coastguard Worker return true;
1537*ec779b8eSAndroid Build Coastguard Worker }
1538*ec779b8eSAndroid Build Coastguard Worker
getPixelFormatIfApplicable()1539*ec779b8eSAndroid Build Coastguard Worker uint32_t FlexOutputBuffers::getPixelFormatIfApplicable() { return mPixelFormat; }
1540*ec779b8eSAndroid Build Coastguard Worker
1541*ec779b8eSAndroid Build Coastguard Worker // LinearOutputBuffers
1542*ec779b8eSAndroid Build Coastguard Worker
flush(const std::list<std::unique_ptr<C2Work>> & flushedWork)1543*ec779b8eSAndroid Build Coastguard Worker void LinearOutputBuffers::flush(
1544*ec779b8eSAndroid Build Coastguard Worker const std::list<std::unique_ptr<C2Work>> &flushedWork) {
1545*ec779b8eSAndroid Build Coastguard Worker if (mSkipCutBuffer != nullptr) {
1546*ec779b8eSAndroid Build Coastguard Worker mSkipCutBuffer->clearAll();
1547*ec779b8eSAndroid Build Coastguard Worker }
1548*ec779b8eSAndroid Build Coastguard Worker FlexOutputBuffers::flush(flushedWork);
1549*ec779b8eSAndroid Build Coastguard Worker }
1550*ec779b8eSAndroid Build Coastguard Worker
wrap(const std::shared_ptr<C2Buffer> & buffer)1551*ec779b8eSAndroid Build Coastguard Worker sp<Codec2Buffer> LinearOutputBuffers::wrap(const std::shared_ptr<C2Buffer> &buffer) {
1552*ec779b8eSAndroid Build Coastguard Worker if (buffer == nullptr) {
1553*ec779b8eSAndroid Build Coastguard Worker ALOGD("[%s] received null buffer", mName);
1554*ec779b8eSAndroid Build Coastguard Worker return new LocalLinearBuffer(mFormat, new ABuffer(0));
1555*ec779b8eSAndroid Build Coastguard Worker }
1556*ec779b8eSAndroid Build Coastguard Worker if (buffer->data().type() != C2BufferData::LINEAR) {
1557*ec779b8eSAndroid Build Coastguard Worker ALOGW("[%s] non-linear buffer %d", mName, buffer->data().type());
1558*ec779b8eSAndroid Build Coastguard Worker // We expect linear output buffers from the component.
1559*ec779b8eSAndroid Build Coastguard Worker return nullptr;
1560*ec779b8eSAndroid Build Coastguard Worker }
1561*ec779b8eSAndroid Build Coastguard Worker if (buffer->data().linearBlocks().size() != 1u) {
1562*ec779b8eSAndroid Build Coastguard Worker ALOGW("[%s] no linear buffers", mName);
1563*ec779b8eSAndroid Build Coastguard Worker // We expect one and only one linear block from the component.
1564*ec779b8eSAndroid Build Coastguard Worker return nullptr;
1565*ec779b8eSAndroid Build Coastguard Worker }
1566*ec779b8eSAndroid Build Coastguard Worker if (buffer->data().linearBlocks().front().size() == 0) {
1567*ec779b8eSAndroid Build Coastguard Worker ALOGD("[%s] received 0-sized buffer", mName);
1568*ec779b8eSAndroid Build Coastguard Worker return new LocalLinearBuffer(mFormat, new ABuffer(0));
1569*ec779b8eSAndroid Build Coastguard Worker }
1570*ec779b8eSAndroid Build Coastguard Worker sp<Codec2Buffer> clientBuffer = ConstLinearBlockBuffer::Allocate(mFormat, buffer);
1571*ec779b8eSAndroid Build Coastguard Worker if (clientBuffer == nullptr) {
1572*ec779b8eSAndroid Build Coastguard Worker ALOGD("[%s] ConstLinearBlockBuffer::Allocate failed", mName);
1573*ec779b8eSAndroid Build Coastguard Worker return nullptr;
1574*ec779b8eSAndroid Build Coastguard Worker }
1575*ec779b8eSAndroid Build Coastguard Worker submit(clientBuffer);
1576*ec779b8eSAndroid Build Coastguard Worker return clientBuffer;
1577*ec779b8eSAndroid Build Coastguard Worker }
1578*ec779b8eSAndroid Build Coastguard Worker
getAlloc()1579*ec779b8eSAndroid Build Coastguard Worker std::function<sp<Codec2Buffer>()> LinearOutputBuffers::getAlloc() {
1580*ec779b8eSAndroid Build Coastguard Worker return [format = mFormat]{
1581*ec779b8eSAndroid Build Coastguard Worker // TODO: proper max output size
1582*ec779b8eSAndroid Build Coastguard Worker return new LocalLinearBuffer(format, new ABuffer(kLinearBufferSize));
1583*ec779b8eSAndroid Build Coastguard Worker };
1584*ec779b8eSAndroid Build Coastguard Worker }
1585*ec779b8eSAndroid Build Coastguard Worker
1586*ec779b8eSAndroid Build Coastguard Worker // GraphicOutputBuffers
1587*ec779b8eSAndroid Build Coastguard Worker
wrap(const std::shared_ptr<C2Buffer> & buffer)1588*ec779b8eSAndroid Build Coastguard Worker sp<Codec2Buffer> GraphicOutputBuffers::wrap(const std::shared_ptr<C2Buffer> &buffer) {
1589*ec779b8eSAndroid Build Coastguard Worker return new DummyContainerBuffer(mFormat, buffer);
1590*ec779b8eSAndroid Build Coastguard Worker }
1591*ec779b8eSAndroid Build Coastguard Worker
getAlloc()1592*ec779b8eSAndroid Build Coastguard Worker std::function<sp<Codec2Buffer>()> GraphicOutputBuffers::getAlloc() {
1593*ec779b8eSAndroid Build Coastguard Worker return [format = mFormat]{
1594*ec779b8eSAndroid Build Coastguard Worker return new DummyContainerBuffer(format);
1595*ec779b8eSAndroid Build Coastguard Worker };
1596*ec779b8eSAndroid Build Coastguard Worker }
1597*ec779b8eSAndroid Build Coastguard Worker
1598*ec779b8eSAndroid Build Coastguard Worker // RawGraphicOutputBuffers
1599*ec779b8eSAndroid Build Coastguard Worker
RawGraphicOutputBuffers(const char * componentName,const char * name)1600*ec779b8eSAndroid Build Coastguard Worker RawGraphicOutputBuffers::RawGraphicOutputBuffers(
1601*ec779b8eSAndroid Build Coastguard Worker const char *componentName, const char *name)
1602*ec779b8eSAndroid Build Coastguard Worker : FlexOutputBuffers(componentName, name),
1603*ec779b8eSAndroid Build Coastguard Worker mLocalBufferPool(LocalBufferPool::Create()) { }
1604*ec779b8eSAndroid Build Coastguard Worker
wrap(const std::shared_ptr<C2Buffer> & buffer)1605*ec779b8eSAndroid Build Coastguard Worker sp<Codec2Buffer> RawGraphicOutputBuffers::wrap(const std::shared_ptr<C2Buffer> &buffer) {
1606*ec779b8eSAndroid Build Coastguard Worker if (buffer == nullptr) {
1607*ec779b8eSAndroid Build Coastguard Worker return new Codec2Buffer(mFormat, new ABuffer(nullptr, 0));
1608*ec779b8eSAndroid Build Coastguard Worker } else {
1609*ec779b8eSAndroid Build Coastguard Worker return ConstGraphicBlockBuffer::Allocate(
1610*ec779b8eSAndroid Build Coastguard Worker mFormat,
1611*ec779b8eSAndroid Build Coastguard Worker buffer,
1612*ec779b8eSAndroid Build Coastguard Worker [lbp = mLocalBufferPool](size_t capacity) {
1613*ec779b8eSAndroid Build Coastguard Worker return lbp->newBuffer(capacity);
1614*ec779b8eSAndroid Build Coastguard Worker });
1615*ec779b8eSAndroid Build Coastguard Worker }
1616*ec779b8eSAndroid Build Coastguard Worker }
1617*ec779b8eSAndroid Build Coastguard Worker
getAlloc()1618*ec779b8eSAndroid Build Coastguard Worker std::function<sp<Codec2Buffer>()> RawGraphicOutputBuffers::getAlloc() {
1619*ec779b8eSAndroid Build Coastguard Worker return [format = mFormat, lbp = mLocalBufferPool]{
1620*ec779b8eSAndroid Build Coastguard Worker return ConstGraphicBlockBuffer::AllocateEmpty(
1621*ec779b8eSAndroid Build Coastguard Worker format,
1622*ec779b8eSAndroid Build Coastguard Worker [lbp](size_t capacity) {
1623*ec779b8eSAndroid Build Coastguard Worker return lbp->newBuffer(capacity);
1624*ec779b8eSAndroid Build Coastguard Worker });
1625*ec779b8eSAndroid Build Coastguard Worker };
1626*ec779b8eSAndroid Build Coastguard Worker }
1627*ec779b8eSAndroid Build Coastguard Worker
1628*ec779b8eSAndroid Build Coastguard Worker } // namespace android
1629