1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker * Copyright 2018, 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 "Codec2Buffer"
19*ec779b8eSAndroid Build Coastguard Worker #define ATRACE_TAG ATRACE_TAG_VIDEO
20*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
21*ec779b8eSAndroid Build Coastguard Worker #include <utils/Trace.h>
22*ec779b8eSAndroid Build Coastguard Worker
23*ec779b8eSAndroid Build Coastguard Worker #include <android_media_codec.h>
24*ec779b8eSAndroid Build Coastguard Worker
25*ec779b8eSAndroid Build Coastguard Worker #include <aidl/android/hardware/graphics/common/Cta861_3.h>
26*ec779b8eSAndroid Build Coastguard Worker #include <aidl/android/hardware/graphics/common/Smpte2086.h>
27*ec779b8eSAndroid Build Coastguard Worker #include <android-base/no_destructor.h>
28*ec779b8eSAndroid Build Coastguard Worker #include <android-base/properties.h>
29*ec779b8eSAndroid Build Coastguard Worker #include <android/hardware/cas/native/1.0/types.h>
30*ec779b8eSAndroid Build Coastguard Worker #include <android/hardware/drm/1.0/types.h>
31*ec779b8eSAndroid Build Coastguard Worker #include <hidlmemory/FrameworkUtils.h>
32*ec779b8eSAndroid Build Coastguard Worker #include <media/hardware/HardwareAPI.h>
33*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/CodecBase.h>
34*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/MediaCodecConstants.h>
35*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/ABuffer.h>
36*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/AMessage.h>
37*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/AUtils.h>
38*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/ColorUtils.h>
39*ec779b8eSAndroid Build Coastguard Worker #include <mediadrm/ICrypto.h>
40*ec779b8eSAndroid Build Coastguard Worker #include <nativebase/nativebase.h>
41*ec779b8eSAndroid Build Coastguard Worker #include <ui/GraphicBufferMapper.h>
42*ec779b8eSAndroid Build Coastguard Worker #include <ui/Fence.h>
43*ec779b8eSAndroid Build Coastguard Worker
44*ec779b8eSAndroid Build Coastguard Worker #include <C2AllocatorGralloc.h>
45*ec779b8eSAndroid Build Coastguard Worker #include <C2BlockInternal.h>
46*ec779b8eSAndroid Build Coastguard Worker #include <C2Debug.h>
47*ec779b8eSAndroid Build Coastguard Worker
48*ec779b8eSAndroid Build Coastguard Worker #include "Codec2Buffer.h"
49*ec779b8eSAndroid Build Coastguard Worker #include "Codec2BufferUtils.h"
50*ec779b8eSAndroid Build Coastguard Worker
51*ec779b8eSAndroid Build Coastguard Worker namespace android {
52*ec779b8eSAndroid Build Coastguard Worker
53*ec779b8eSAndroid Build Coastguard Worker // Codec2Buffer
54*ec779b8eSAndroid Build Coastguard Worker
canCopyLinear(const std::shared_ptr<C2Buffer> & buffer) const55*ec779b8eSAndroid Build Coastguard Worker bool Codec2Buffer::canCopyLinear(const std::shared_ptr<C2Buffer> &buffer) const {
56*ec779b8eSAndroid Build Coastguard Worker if (const_cast<Codec2Buffer *>(this)->base() == nullptr) {
57*ec779b8eSAndroid Build Coastguard Worker return false;
58*ec779b8eSAndroid Build Coastguard Worker }
59*ec779b8eSAndroid Build Coastguard Worker if (!buffer) {
60*ec779b8eSAndroid Build Coastguard Worker // Nothing to copy, so we can copy by doing nothing.
61*ec779b8eSAndroid Build Coastguard Worker return true;
62*ec779b8eSAndroid Build Coastguard Worker }
63*ec779b8eSAndroid Build Coastguard Worker if (buffer->data().type() != C2BufferData::LINEAR) {
64*ec779b8eSAndroid Build Coastguard Worker return false;
65*ec779b8eSAndroid Build Coastguard Worker }
66*ec779b8eSAndroid Build Coastguard Worker if (buffer->data().linearBlocks().size() == 0u) {
67*ec779b8eSAndroid Build Coastguard Worker // Nothing to copy, so we can copy by doing nothing.
68*ec779b8eSAndroid Build Coastguard Worker return true;
69*ec779b8eSAndroid Build Coastguard Worker } else if (buffer->data().linearBlocks().size() > 1u) {
70*ec779b8eSAndroid Build Coastguard Worker // We don't know how to copy more than one blocks.
71*ec779b8eSAndroid Build Coastguard Worker return false;
72*ec779b8eSAndroid Build Coastguard Worker }
73*ec779b8eSAndroid Build Coastguard Worker if (buffer->data().linearBlocks()[0].size() > capacity()) {
74*ec779b8eSAndroid Build Coastguard Worker // It won't fit.
75*ec779b8eSAndroid Build Coastguard Worker return false;
76*ec779b8eSAndroid Build Coastguard Worker }
77*ec779b8eSAndroid Build Coastguard Worker return true;
78*ec779b8eSAndroid Build Coastguard Worker }
79*ec779b8eSAndroid Build Coastguard Worker
copyLinear(const std::shared_ptr<C2Buffer> & buffer)80*ec779b8eSAndroid Build Coastguard Worker bool Codec2Buffer::copyLinear(const std::shared_ptr<C2Buffer> &buffer) {
81*ec779b8eSAndroid Build Coastguard Worker // We assume that all canCopyLinear() checks passed.
82*ec779b8eSAndroid Build Coastguard Worker if (!buffer || buffer->data().linearBlocks().size() == 0u
83*ec779b8eSAndroid Build Coastguard Worker || buffer->data().linearBlocks()[0].size() == 0u) {
84*ec779b8eSAndroid Build Coastguard Worker setRange(0, 0);
85*ec779b8eSAndroid Build Coastguard Worker return true;
86*ec779b8eSAndroid Build Coastguard Worker }
87*ec779b8eSAndroid Build Coastguard Worker C2ReadView view = buffer->data().linearBlocks()[0].map().get();
88*ec779b8eSAndroid Build Coastguard Worker if (view.error() != C2_OK) {
89*ec779b8eSAndroid Build Coastguard Worker ALOGD("Error while mapping: %d", view.error());
90*ec779b8eSAndroid Build Coastguard Worker return false;
91*ec779b8eSAndroid Build Coastguard Worker }
92*ec779b8eSAndroid Build Coastguard Worker if (view.capacity() > capacity()) {
93*ec779b8eSAndroid Build Coastguard Worker ALOGD("C2ConstLinearBlock lied --- it actually doesn't fit: view(%u) > this(%zu)",
94*ec779b8eSAndroid Build Coastguard Worker view.capacity(), capacity());
95*ec779b8eSAndroid Build Coastguard Worker return false;
96*ec779b8eSAndroid Build Coastguard Worker }
97*ec779b8eSAndroid Build Coastguard Worker memcpy(base(), view.data(), view.capacity());
98*ec779b8eSAndroid Build Coastguard Worker setRange(0, view.capacity());
99*ec779b8eSAndroid Build Coastguard Worker return true;
100*ec779b8eSAndroid Build Coastguard Worker }
101*ec779b8eSAndroid Build Coastguard Worker
setImageData(const sp<ABuffer> & imageData)102*ec779b8eSAndroid Build Coastguard Worker void Codec2Buffer::setImageData(const sp<ABuffer> &imageData) {
103*ec779b8eSAndroid Build Coastguard Worker mImageData = imageData;
104*ec779b8eSAndroid Build Coastguard Worker }
105*ec779b8eSAndroid Build Coastguard Worker
106*ec779b8eSAndroid Build Coastguard Worker // LocalLinearBuffer
107*ec779b8eSAndroid Build Coastguard Worker
canCopy(const std::shared_ptr<C2Buffer> & buffer) const108*ec779b8eSAndroid Build Coastguard Worker bool LocalLinearBuffer::canCopy(const std::shared_ptr<C2Buffer> &buffer) const {
109*ec779b8eSAndroid Build Coastguard Worker return canCopyLinear(buffer);
110*ec779b8eSAndroid Build Coastguard Worker }
111*ec779b8eSAndroid Build Coastguard Worker
copy(const std::shared_ptr<C2Buffer> & buffer)112*ec779b8eSAndroid Build Coastguard Worker bool LocalLinearBuffer::copy(const std::shared_ptr<C2Buffer> &buffer) {
113*ec779b8eSAndroid Build Coastguard Worker return copyLinear(buffer);
114*ec779b8eSAndroid Build Coastguard Worker }
115*ec779b8eSAndroid Build Coastguard Worker
116*ec779b8eSAndroid Build Coastguard Worker // DummyContainerBuffer
117*ec779b8eSAndroid Build Coastguard Worker
118*ec779b8eSAndroid Build Coastguard Worker static uint8_t sDummyByte[1] = { 0 };
119*ec779b8eSAndroid Build Coastguard Worker
DummyContainerBuffer(const sp<AMessage> & format,const std::shared_ptr<C2Buffer> & buffer)120*ec779b8eSAndroid Build Coastguard Worker DummyContainerBuffer::DummyContainerBuffer(
121*ec779b8eSAndroid Build Coastguard Worker const sp<AMessage> &format, const std::shared_ptr<C2Buffer> &buffer)
122*ec779b8eSAndroid Build Coastguard Worker : Codec2Buffer(format, new ABuffer(sDummyByte, 1)),
123*ec779b8eSAndroid Build Coastguard Worker mBufferRef(buffer) {
124*ec779b8eSAndroid Build Coastguard Worker setRange(0, buffer ? 1 : 0);
125*ec779b8eSAndroid Build Coastguard Worker }
126*ec779b8eSAndroid Build Coastguard Worker
asC2Buffer()127*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<C2Buffer> DummyContainerBuffer::asC2Buffer() {
128*ec779b8eSAndroid Build Coastguard Worker return mBufferRef;
129*ec779b8eSAndroid Build Coastguard Worker }
130*ec779b8eSAndroid Build Coastguard Worker
clearC2BufferRefs()131*ec779b8eSAndroid Build Coastguard Worker void DummyContainerBuffer::clearC2BufferRefs() {
132*ec779b8eSAndroid Build Coastguard Worker mBufferRef.reset();
133*ec779b8eSAndroid Build Coastguard Worker }
134*ec779b8eSAndroid Build Coastguard Worker
canCopy(const std::shared_ptr<C2Buffer> &) const135*ec779b8eSAndroid Build Coastguard Worker bool DummyContainerBuffer::canCopy(const std::shared_ptr<C2Buffer> &) const {
136*ec779b8eSAndroid Build Coastguard Worker return !mBufferRef;
137*ec779b8eSAndroid Build Coastguard Worker }
138*ec779b8eSAndroid Build Coastguard Worker
copy(const std::shared_ptr<C2Buffer> & buffer)139*ec779b8eSAndroid Build Coastguard Worker bool DummyContainerBuffer::copy(const std::shared_ptr<C2Buffer> &buffer) {
140*ec779b8eSAndroid Build Coastguard Worker mBufferRef = buffer;
141*ec779b8eSAndroid Build Coastguard Worker setRange(0, mBufferRef ? 1 : 0);
142*ec779b8eSAndroid Build Coastguard Worker return true;
143*ec779b8eSAndroid Build Coastguard Worker }
144*ec779b8eSAndroid Build Coastguard Worker
145*ec779b8eSAndroid Build Coastguard Worker // LinearBlockBuffer
146*ec779b8eSAndroid Build Coastguard Worker
147*ec779b8eSAndroid Build Coastguard Worker // static
Allocate(const sp<AMessage> & format,const std::shared_ptr<C2LinearBlock> & block)148*ec779b8eSAndroid Build Coastguard Worker sp<LinearBlockBuffer> LinearBlockBuffer::Allocate(
149*ec779b8eSAndroid Build Coastguard Worker const sp<AMessage> &format, const std::shared_ptr<C2LinearBlock> &block) {
150*ec779b8eSAndroid Build Coastguard Worker C2WriteView writeView(block->map().get());
151*ec779b8eSAndroid Build Coastguard Worker if (writeView.error() != C2_OK) {
152*ec779b8eSAndroid Build Coastguard Worker return nullptr;
153*ec779b8eSAndroid Build Coastguard Worker }
154*ec779b8eSAndroid Build Coastguard Worker return new LinearBlockBuffer(format, std::move(writeView), block);
155*ec779b8eSAndroid Build Coastguard Worker }
156*ec779b8eSAndroid Build Coastguard Worker
asC2Buffer()157*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<C2Buffer> LinearBlockBuffer::asC2Buffer() {
158*ec779b8eSAndroid Build Coastguard Worker return C2Buffer::CreateLinearBuffer(mBlock->share(offset(), size(), C2Fence()));
159*ec779b8eSAndroid Build Coastguard Worker }
160*ec779b8eSAndroid Build Coastguard Worker
canCopy(const std::shared_ptr<C2Buffer> & buffer) const161*ec779b8eSAndroid Build Coastguard Worker bool LinearBlockBuffer::canCopy(const std::shared_ptr<C2Buffer> &buffer) const {
162*ec779b8eSAndroid Build Coastguard Worker return canCopyLinear(buffer);
163*ec779b8eSAndroid Build Coastguard Worker }
164*ec779b8eSAndroid Build Coastguard Worker
copy(const std::shared_ptr<C2Buffer> & buffer)165*ec779b8eSAndroid Build Coastguard Worker bool LinearBlockBuffer::copy(const std::shared_ptr<C2Buffer> &buffer) {
166*ec779b8eSAndroid Build Coastguard Worker return copyLinear(buffer);
167*ec779b8eSAndroid Build Coastguard Worker }
168*ec779b8eSAndroid Build Coastguard Worker
LinearBlockBuffer(const sp<AMessage> & format,C2WriteView && writeView,const std::shared_ptr<C2LinearBlock> & block)169*ec779b8eSAndroid Build Coastguard Worker LinearBlockBuffer::LinearBlockBuffer(
170*ec779b8eSAndroid Build Coastguard Worker const sp<AMessage> &format,
171*ec779b8eSAndroid Build Coastguard Worker C2WriteView&& writeView,
172*ec779b8eSAndroid Build Coastguard Worker const std::shared_ptr<C2LinearBlock> &block)
173*ec779b8eSAndroid Build Coastguard Worker : Codec2Buffer(format, new ABuffer(writeView.data(), writeView.size())),
174*ec779b8eSAndroid Build Coastguard Worker mWriteView(writeView),
175*ec779b8eSAndroid Build Coastguard Worker mBlock(block) {
176*ec779b8eSAndroid Build Coastguard Worker }
177*ec779b8eSAndroid Build Coastguard Worker
178*ec779b8eSAndroid Build Coastguard Worker // ConstLinearBlockBuffer
179*ec779b8eSAndroid Build Coastguard Worker
180*ec779b8eSAndroid Build Coastguard Worker // static
Allocate(const sp<AMessage> & format,const std::shared_ptr<C2Buffer> & buffer)181*ec779b8eSAndroid Build Coastguard Worker sp<ConstLinearBlockBuffer> ConstLinearBlockBuffer::Allocate(
182*ec779b8eSAndroid Build Coastguard Worker const sp<AMessage> &format, const std::shared_ptr<C2Buffer> &buffer) {
183*ec779b8eSAndroid Build Coastguard Worker if (!buffer
184*ec779b8eSAndroid Build Coastguard Worker || buffer->data().type() != C2BufferData::LINEAR
185*ec779b8eSAndroid Build Coastguard Worker || buffer->data().linearBlocks().size() != 1u) {
186*ec779b8eSAndroid Build Coastguard Worker if (!buffer) {
187*ec779b8eSAndroid Build Coastguard Worker ALOGD("ConstLinearBlockBuffer::Allocate: null buffer");
188*ec779b8eSAndroid Build Coastguard Worker } else {
189*ec779b8eSAndroid Build Coastguard Worker ALOGW("ConstLinearBlockBuffer::Allocate: type=%d # linear blocks=%zu",
190*ec779b8eSAndroid Build Coastguard Worker buffer->data().type(), buffer->data().linearBlocks().size());
191*ec779b8eSAndroid Build Coastguard Worker }
192*ec779b8eSAndroid Build Coastguard Worker return nullptr;
193*ec779b8eSAndroid Build Coastguard Worker }
194*ec779b8eSAndroid Build Coastguard Worker C2ReadView readView(buffer->data().linearBlocks()[0].map().get());
195*ec779b8eSAndroid Build Coastguard Worker if (readView.error() != C2_OK) {
196*ec779b8eSAndroid Build Coastguard Worker ALOGW("ConstLinearBlockBuffer::Allocate: readView.error()=%d", readView.error());
197*ec779b8eSAndroid Build Coastguard Worker return nullptr;
198*ec779b8eSAndroid Build Coastguard Worker }
199*ec779b8eSAndroid Build Coastguard Worker return new ConstLinearBlockBuffer(format, std::move(readView), buffer);
200*ec779b8eSAndroid Build Coastguard Worker }
201*ec779b8eSAndroid Build Coastguard Worker
ConstLinearBlockBuffer(const sp<AMessage> & format,C2ReadView && readView,const std::shared_ptr<C2Buffer> & buffer)202*ec779b8eSAndroid Build Coastguard Worker ConstLinearBlockBuffer::ConstLinearBlockBuffer(
203*ec779b8eSAndroid Build Coastguard Worker const sp<AMessage> &format,
204*ec779b8eSAndroid Build Coastguard Worker C2ReadView&& readView,
205*ec779b8eSAndroid Build Coastguard Worker const std::shared_ptr<C2Buffer> &buffer)
206*ec779b8eSAndroid Build Coastguard Worker : Codec2Buffer(format, new ABuffer(
207*ec779b8eSAndroid Build Coastguard Worker // NOTE: ABuffer only takes non-const pointer but this data is
208*ec779b8eSAndroid Build Coastguard Worker // supposed to be read-only.
209*ec779b8eSAndroid Build Coastguard Worker const_cast<uint8_t *>(readView.data()), readView.capacity())),
210*ec779b8eSAndroid Build Coastguard Worker mReadView(readView),
211*ec779b8eSAndroid Build Coastguard Worker mBufferRef(buffer) {
212*ec779b8eSAndroid Build Coastguard Worker }
213*ec779b8eSAndroid Build Coastguard Worker
asC2Buffer()214*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<C2Buffer> ConstLinearBlockBuffer::asC2Buffer() {
215*ec779b8eSAndroid Build Coastguard Worker return mBufferRef;
216*ec779b8eSAndroid Build Coastguard Worker }
217*ec779b8eSAndroid Build Coastguard Worker
clearC2BufferRefs()218*ec779b8eSAndroid Build Coastguard Worker void ConstLinearBlockBuffer::clearC2BufferRefs() {
219*ec779b8eSAndroid Build Coastguard Worker mBufferRef.reset();
220*ec779b8eSAndroid Build Coastguard Worker }
221*ec779b8eSAndroid Build Coastguard Worker
222*ec779b8eSAndroid Build Coastguard Worker // GraphicBlockBuffer
223*ec779b8eSAndroid Build Coastguard Worker
224*ec779b8eSAndroid Build Coastguard Worker // static
Allocate(const sp<AMessage> & format,const std::shared_ptr<C2GraphicBlock> & block,std::function<sp<ABuffer> (size_t)> alloc)225*ec779b8eSAndroid Build Coastguard Worker sp<GraphicBlockBuffer> GraphicBlockBuffer::Allocate(
226*ec779b8eSAndroid Build Coastguard Worker const sp<AMessage> &format,
227*ec779b8eSAndroid Build Coastguard Worker const std::shared_ptr<C2GraphicBlock> &block,
228*ec779b8eSAndroid Build Coastguard Worker std::function<sp<ABuffer>(size_t)> alloc) {
229*ec779b8eSAndroid Build Coastguard Worker ATRACE_BEGIN("GraphicBlockBuffer::Allocate block->map()");
230*ec779b8eSAndroid Build Coastguard Worker C2GraphicView view(block->map().get());
231*ec779b8eSAndroid Build Coastguard Worker ATRACE_END();
232*ec779b8eSAndroid Build Coastguard Worker if (view.error() != C2_OK) {
233*ec779b8eSAndroid Build Coastguard Worker ALOGD("C2GraphicBlock::map failed: %d", view.error());
234*ec779b8eSAndroid Build Coastguard Worker return nullptr;
235*ec779b8eSAndroid Build Coastguard Worker }
236*ec779b8eSAndroid Build Coastguard Worker
237*ec779b8eSAndroid Build Coastguard Worker GraphicView2MediaImageConverter converter(view, format, false /* copy */);
238*ec779b8eSAndroid Build Coastguard Worker if (converter.initCheck() != OK) {
239*ec779b8eSAndroid Build Coastguard Worker ALOGD("Converter init failed: %d", converter.initCheck());
240*ec779b8eSAndroid Build Coastguard Worker return nullptr;
241*ec779b8eSAndroid Build Coastguard Worker }
242*ec779b8eSAndroid Build Coastguard Worker bool wrapped = true;
243*ec779b8eSAndroid Build Coastguard Worker sp<ABuffer> buffer = converter.wrap();
244*ec779b8eSAndroid Build Coastguard Worker if (buffer == nullptr) {
245*ec779b8eSAndroid Build Coastguard Worker buffer = alloc(converter.backBufferSize());
246*ec779b8eSAndroid Build Coastguard Worker if (!converter.setBackBuffer(buffer)) {
247*ec779b8eSAndroid Build Coastguard Worker ALOGD("Converter failed to set back buffer");
248*ec779b8eSAndroid Build Coastguard Worker return nullptr;
249*ec779b8eSAndroid Build Coastguard Worker }
250*ec779b8eSAndroid Build Coastguard Worker wrapped = false;
251*ec779b8eSAndroid Build Coastguard Worker }
252*ec779b8eSAndroid Build Coastguard Worker return new GraphicBlockBuffer(
253*ec779b8eSAndroid Build Coastguard Worker format,
254*ec779b8eSAndroid Build Coastguard Worker buffer,
255*ec779b8eSAndroid Build Coastguard Worker std::move(view),
256*ec779b8eSAndroid Build Coastguard Worker block,
257*ec779b8eSAndroid Build Coastguard Worker converter.imageData(),
258*ec779b8eSAndroid Build Coastguard Worker wrapped);
259*ec779b8eSAndroid Build Coastguard Worker }
260*ec779b8eSAndroid Build Coastguard Worker
GraphicBlockBuffer(const sp<AMessage> & format,const sp<ABuffer> & buffer,C2GraphicView && view,const std::shared_ptr<C2GraphicBlock> & block,const sp<ABuffer> & imageData,bool wrapped)261*ec779b8eSAndroid Build Coastguard Worker GraphicBlockBuffer::GraphicBlockBuffer(
262*ec779b8eSAndroid Build Coastguard Worker const sp<AMessage> &format,
263*ec779b8eSAndroid Build Coastguard Worker const sp<ABuffer> &buffer,
264*ec779b8eSAndroid Build Coastguard Worker C2GraphicView &&view,
265*ec779b8eSAndroid Build Coastguard Worker const std::shared_ptr<C2GraphicBlock> &block,
266*ec779b8eSAndroid Build Coastguard Worker const sp<ABuffer> &imageData,
267*ec779b8eSAndroid Build Coastguard Worker bool wrapped)
268*ec779b8eSAndroid Build Coastguard Worker : Codec2Buffer(format, buffer),
269*ec779b8eSAndroid Build Coastguard Worker mView(view),
270*ec779b8eSAndroid Build Coastguard Worker mBlock(block),
271*ec779b8eSAndroid Build Coastguard Worker mWrapped(wrapped) {
272*ec779b8eSAndroid Build Coastguard Worker setImageData(imageData);
273*ec779b8eSAndroid Build Coastguard Worker }
274*ec779b8eSAndroid Build Coastguard Worker
asC2Buffer()275*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<C2Buffer> GraphicBlockBuffer::asC2Buffer() {
276*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
277*ec779b8eSAndroid Build Coastguard Worker uint32_t width = mView.width();
278*ec779b8eSAndroid Build Coastguard Worker uint32_t height = mView.height();
279*ec779b8eSAndroid Build Coastguard Worker if (!mWrapped) {
280*ec779b8eSAndroid Build Coastguard Worker (void)ImageCopy(mView, base(), imageData());
281*ec779b8eSAndroid Build Coastguard Worker }
282*ec779b8eSAndroid Build Coastguard Worker return C2Buffer::CreateGraphicBuffer(
283*ec779b8eSAndroid Build Coastguard Worker mBlock->share(C2Rect(width, height), C2Fence()));
284*ec779b8eSAndroid Build Coastguard Worker }
285*ec779b8eSAndroid Build Coastguard Worker
286*ec779b8eSAndroid Build Coastguard Worker // GraphicMetadataBuffer
GraphicMetadataBuffer(const sp<AMessage> & format,const std::shared_ptr<C2Allocator> & alloc)287*ec779b8eSAndroid Build Coastguard Worker GraphicMetadataBuffer::GraphicMetadataBuffer(
288*ec779b8eSAndroid Build Coastguard Worker const sp<AMessage> &format,
289*ec779b8eSAndroid Build Coastguard Worker const std::shared_ptr<C2Allocator> &alloc)
290*ec779b8eSAndroid Build Coastguard Worker : Codec2Buffer(format, new ABuffer(sizeof(VideoNativeMetadata))),
291*ec779b8eSAndroid Build Coastguard Worker mAlloc(alloc) {
292*ec779b8eSAndroid Build Coastguard Worker ((VideoNativeMetadata *)base())->pBuffer = nullptr;
293*ec779b8eSAndroid Build Coastguard Worker }
294*ec779b8eSAndroid Build Coastguard Worker
asC2Buffer()295*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<C2Buffer> GraphicMetadataBuffer::asC2Buffer() {
296*ec779b8eSAndroid Build Coastguard Worker #ifdef __LP64__
297*ec779b8eSAndroid Build Coastguard Worker static std::once_flag s_checkOnce;
298*ec779b8eSAndroid Build Coastguard Worker static bool s_is64bitOk {true};
299*ec779b8eSAndroid Build Coastguard Worker std::call_once(s_checkOnce, [&](){
300*ec779b8eSAndroid Build Coastguard Worker const std::string abi32list =
301*ec779b8eSAndroid Build Coastguard Worker ::android::base::GetProperty("ro.product.cpu.abilist32", "");
302*ec779b8eSAndroid Build Coastguard Worker if (!abi32list.empty()) {
303*ec779b8eSAndroid Build Coastguard Worker int32_t inputSurfaceSetting =
304*ec779b8eSAndroid Build Coastguard Worker ::android::base::GetIntProperty("debug.stagefright.c2inputsurface", int32_t(0));
305*ec779b8eSAndroid Build Coastguard Worker s_is64bitOk = inputSurfaceSetting != 0;
306*ec779b8eSAndroid Build Coastguard Worker }
307*ec779b8eSAndroid Build Coastguard Worker });
308*ec779b8eSAndroid Build Coastguard Worker
309*ec779b8eSAndroid Build Coastguard Worker if (!s_is64bitOk) {
310*ec779b8eSAndroid Build Coastguard Worker ALOGE("GraphicMetadataBuffer does not work in 32+64 system if compiled as 64-bit object"\
311*ec779b8eSAndroid Build Coastguard Worker "when debug.stagefright.c2inputsurface is set to 0");
312*ec779b8eSAndroid Build Coastguard Worker return nullptr;
313*ec779b8eSAndroid Build Coastguard Worker }
314*ec779b8eSAndroid Build Coastguard Worker #endif
315*ec779b8eSAndroid Build Coastguard Worker
316*ec779b8eSAndroid Build Coastguard Worker VideoNativeMetadata *meta = (VideoNativeMetadata *)base();
317*ec779b8eSAndroid Build Coastguard Worker ANativeWindowBuffer *buffer = (ANativeWindowBuffer *)meta->pBuffer;
318*ec779b8eSAndroid Build Coastguard Worker if (buffer == nullptr) {
319*ec779b8eSAndroid Build Coastguard Worker ALOGD("VideoNativeMetadata contains null buffer");
320*ec779b8eSAndroid Build Coastguard Worker return nullptr;
321*ec779b8eSAndroid Build Coastguard Worker }
322*ec779b8eSAndroid Build Coastguard Worker
323*ec779b8eSAndroid Build Coastguard Worker ALOGV("VideoNativeMetadata: %dx%d", buffer->width, buffer->height);
324*ec779b8eSAndroid Build Coastguard Worker C2Handle *handle = WrapNativeCodec2GrallocHandle(
325*ec779b8eSAndroid Build Coastguard Worker buffer->handle,
326*ec779b8eSAndroid Build Coastguard Worker buffer->width,
327*ec779b8eSAndroid Build Coastguard Worker buffer->height,
328*ec779b8eSAndroid Build Coastguard Worker buffer->format,
329*ec779b8eSAndroid Build Coastguard Worker buffer->usage,
330*ec779b8eSAndroid Build Coastguard Worker buffer->stride);
331*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<C2GraphicAllocation> alloc;
332*ec779b8eSAndroid Build Coastguard Worker c2_status_t err = mAlloc->priorGraphicAllocation(handle, &alloc);
333*ec779b8eSAndroid Build Coastguard Worker if (err != C2_OK) {
334*ec779b8eSAndroid Build Coastguard Worker ALOGD("Failed to wrap VideoNativeMetadata into C2GraphicAllocation");
335*ec779b8eSAndroid Build Coastguard Worker native_handle_close(handle);
336*ec779b8eSAndroid Build Coastguard Worker native_handle_delete(handle);
337*ec779b8eSAndroid Build Coastguard Worker return nullptr;
338*ec779b8eSAndroid Build Coastguard Worker }
339*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<C2GraphicBlock> block = _C2BlockFactory::CreateGraphicBlock(alloc);
340*ec779b8eSAndroid Build Coastguard Worker
341*ec779b8eSAndroid Build Coastguard Worker meta->pBuffer = 0;
342*ec779b8eSAndroid Build Coastguard Worker // TODO: wrap this in C2Fence so that the component can wait when it
343*ec779b8eSAndroid Build Coastguard Worker // actually starts processing.
344*ec779b8eSAndroid Build Coastguard Worker if (meta->nFenceFd >= 0) {
345*ec779b8eSAndroid Build Coastguard Worker sp<Fence> fence(new Fence(meta->nFenceFd));
346*ec779b8eSAndroid Build Coastguard Worker fence->waitForever(LOG_TAG);
347*ec779b8eSAndroid Build Coastguard Worker }
348*ec779b8eSAndroid Build Coastguard Worker return C2Buffer::CreateGraphicBuffer(
349*ec779b8eSAndroid Build Coastguard Worker block->share(C2Rect(buffer->width, buffer->height), C2Fence()));
350*ec779b8eSAndroid Build Coastguard Worker }
351*ec779b8eSAndroid Build Coastguard Worker
352*ec779b8eSAndroid Build Coastguard Worker // ConstGraphicBlockBuffer
353*ec779b8eSAndroid Build Coastguard Worker
354*ec779b8eSAndroid Build Coastguard Worker // static
Allocate(const sp<AMessage> & format,const std::shared_ptr<C2Buffer> & buffer,std::function<sp<ABuffer> (size_t)> alloc)355*ec779b8eSAndroid Build Coastguard Worker sp<ConstGraphicBlockBuffer> ConstGraphicBlockBuffer::Allocate(
356*ec779b8eSAndroid Build Coastguard Worker const sp<AMessage> &format,
357*ec779b8eSAndroid Build Coastguard Worker const std::shared_ptr<C2Buffer> &buffer,
358*ec779b8eSAndroid Build Coastguard Worker std::function<sp<ABuffer>(size_t)> alloc) {
359*ec779b8eSAndroid Build Coastguard Worker if (!buffer
360*ec779b8eSAndroid Build Coastguard Worker || buffer->data().type() != C2BufferData::GRAPHIC
361*ec779b8eSAndroid Build Coastguard Worker || buffer->data().graphicBlocks().size() != 1u) {
362*ec779b8eSAndroid Build Coastguard Worker ALOGD("C2Buffer precond fail");
363*ec779b8eSAndroid Build Coastguard Worker return nullptr;
364*ec779b8eSAndroid Build Coastguard Worker }
365*ec779b8eSAndroid Build Coastguard Worker ATRACE_BEGIN("ConstGraphicBlockBuffer::Allocate block->map()");
366*ec779b8eSAndroid Build Coastguard Worker std::unique_ptr<const C2GraphicView> view(std::make_unique<const C2GraphicView>(
367*ec779b8eSAndroid Build Coastguard Worker buffer->data().graphicBlocks()[0].map().get()));
368*ec779b8eSAndroid Build Coastguard Worker ATRACE_END();
369*ec779b8eSAndroid Build Coastguard Worker std::unique_ptr<const C2GraphicView> holder;
370*ec779b8eSAndroid Build Coastguard Worker
371*ec779b8eSAndroid Build Coastguard Worker GraphicView2MediaImageConverter converter(*view, format, false /* copy */);
372*ec779b8eSAndroid Build Coastguard Worker if (converter.initCheck() != OK) {
373*ec779b8eSAndroid Build Coastguard Worker ALOGD("Converter init failed: %d", converter.initCheck());
374*ec779b8eSAndroid Build Coastguard Worker return nullptr;
375*ec779b8eSAndroid Build Coastguard Worker }
376*ec779b8eSAndroid Build Coastguard Worker bool wrapped = true;
377*ec779b8eSAndroid Build Coastguard Worker sp<ABuffer> aBuffer = converter.wrap();
378*ec779b8eSAndroid Build Coastguard Worker if (aBuffer == nullptr) {
379*ec779b8eSAndroid Build Coastguard Worker aBuffer = alloc(converter.backBufferSize());
380*ec779b8eSAndroid Build Coastguard Worker if (!converter.setBackBuffer(aBuffer)) {
381*ec779b8eSAndroid Build Coastguard Worker ALOGD("Converter failed to set back buffer");
382*ec779b8eSAndroid Build Coastguard Worker return nullptr;
383*ec779b8eSAndroid Build Coastguard Worker }
384*ec779b8eSAndroid Build Coastguard Worker wrapped = false;
385*ec779b8eSAndroid Build Coastguard Worker converter.copyToMediaImage();
386*ec779b8eSAndroid Build Coastguard Worker // We don't need the view.
387*ec779b8eSAndroid Build Coastguard Worker holder = std::move(view);
388*ec779b8eSAndroid Build Coastguard Worker }
389*ec779b8eSAndroid Build Coastguard Worker return new ConstGraphicBlockBuffer(
390*ec779b8eSAndroid Build Coastguard Worker format,
391*ec779b8eSAndroid Build Coastguard Worker aBuffer,
392*ec779b8eSAndroid Build Coastguard Worker std::move(view),
393*ec779b8eSAndroid Build Coastguard Worker buffer,
394*ec779b8eSAndroid Build Coastguard Worker converter.imageData(),
395*ec779b8eSAndroid Build Coastguard Worker wrapped);
396*ec779b8eSAndroid Build Coastguard Worker }
397*ec779b8eSAndroid Build Coastguard Worker
398*ec779b8eSAndroid Build Coastguard Worker // static
AllocateEmpty(const sp<AMessage> & format,std::function<sp<ABuffer> (size_t)> alloc)399*ec779b8eSAndroid Build Coastguard Worker sp<ConstGraphicBlockBuffer> ConstGraphicBlockBuffer::AllocateEmpty(
400*ec779b8eSAndroid Build Coastguard Worker const sp<AMessage> &format,
401*ec779b8eSAndroid Build Coastguard Worker std::function<sp<ABuffer>(size_t)> alloc) {
402*ec779b8eSAndroid Build Coastguard Worker int32_t width, height;
403*ec779b8eSAndroid Build Coastguard Worker if (!format->findInt32("width", &width)
404*ec779b8eSAndroid Build Coastguard Worker || !format->findInt32("height", &height)) {
405*ec779b8eSAndroid Build Coastguard Worker ALOGD("format had no width / height");
406*ec779b8eSAndroid Build Coastguard Worker return nullptr;
407*ec779b8eSAndroid Build Coastguard Worker }
408*ec779b8eSAndroid Build Coastguard Worker int32_t colorFormat = COLOR_FormatYUV420Flexible;
409*ec779b8eSAndroid Build Coastguard Worker int32_t bpp = 12; // 8(Y) + 2(U) + 2(V)
410*ec779b8eSAndroid Build Coastguard Worker if (format->findInt32(KEY_COLOR_FORMAT, &colorFormat)) {
411*ec779b8eSAndroid Build Coastguard Worker if (colorFormat == COLOR_FormatYUVP010) {
412*ec779b8eSAndroid Build Coastguard Worker bpp = 24; // 16(Y) + 4(U) + 4(V)
413*ec779b8eSAndroid Build Coastguard Worker }
414*ec779b8eSAndroid Build Coastguard Worker }
415*ec779b8eSAndroid Build Coastguard Worker sp<ABuffer> aBuffer(alloc(align(width, 16) * align(height, 16) * bpp / 8));
416*ec779b8eSAndroid Build Coastguard Worker if (aBuffer == nullptr) {
417*ec779b8eSAndroid Build Coastguard Worker ALOGD("%s: failed to allocate buffer", __func__);
418*ec779b8eSAndroid Build Coastguard Worker return nullptr;
419*ec779b8eSAndroid Build Coastguard Worker }
420*ec779b8eSAndroid Build Coastguard Worker return new ConstGraphicBlockBuffer(
421*ec779b8eSAndroid Build Coastguard Worker format,
422*ec779b8eSAndroid Build Coastguard Worker aBuffer,
423*ec779b8eSAndroid Build Coastguard Worker nullptr,
424*ec779b8eSAndroid Build Coastguard Worker nullptr,
425*ec779b8eSAndroid Build Coastguard Worker nullptr,
426*ec779b8eSAndroid Build Coastguard Worker false);
427*ec779b8eSAndroid Build Coastguard Worker }
428*ec779b8eSAndroid Build Coastguard Worker
ConstGraphicBlockBuffer(const sp<AMessage> & format,const sp<ABuffer> & aBuffer,std::unique_ptr<const C2GraphicView> && view,const std::shared_ptr<C2Buffer> & buffer,const sp<ABuffer> & imageData,bool wrapped)429*ec779b8eSAndroid Build Coastguard Worker ConstGraphicBlockBuffer::ConstGraphicBlockBuffer(
430*ec779b8eSAndroid Build Coastguard Worker const sp<AMessage> &format,
431*ec779b8eSAndroid Build Coastguard Worker const sp<ABuffer> &aBuffer,
432*ec779b8eSAndroid Build Coastguard Worker std::unique_ptr<const C2GraphicView> &&view,
433*ec779b8eSAndroid Build Coastguard Worker const std::shared_ptr<C2Buffer> &buffer,
434*ec779b8eSAndroid Build Coastguard Worker const sp<ABuffer> &imageData,
435*ec779b8eSAndroid Build Coastguard Worker bool wrapped)
436*ec779b8eSAndroid Build Coastguard Worker : Codec2Buffer(format, aBuffer),
437*ec779b8eSAndroid Build Coastguard Worker mView(std::move(view)),
438*ec779b8eSAndroid Build Coastguard Worker mBufferRef(buffer),
439*ec779b8eSAndroid Build Coastguard Worker mWrapped(wrapped) {
440*ec779b8eSAndroid Build Coastguard Worker setImageData(imageData);
441*ec779b8eSAndroid Build Coastguard Worker }
442*ec779b8eSAndroid Build Coastguard Worker
asC2Buffer()443*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<C2Buffer> ConstGraphicBlockBuffer::asC2Buffer() {
444*ec779b8eSAndroid Build Coastguard Worker return mBufferRef;
445*ec779b8eSAndroid Build Coastguard Worker }
446*ec779b8eSAndroid Build Coastguard Worker
clearC2BufferRefs()447*ec779b8eSAndroid Build Coastguard Worker void ConstGraphicBlockBuffer::clearC2BufferRefs() {
448*ec779b8eSAndroid Build Coastguard Worker mView.reset();
449*ec779b8eSAndroid Build Coastguard Worker mBufferRef.reset();
450*ec779b8eSAndroid Build Coastguard Worker }
451*ec779b8eSAndroid Build Coastguard Worker
canCopy(const std::shared_ptr<C2Buffer> & buffer) const452*ec779b8eSAndroid Build Coastguard Worker bool ConstGraphicBlockBuffer::canCopy(const std::shared_ptr<C2Buffer> &buffer) const {
453*ec779b8eSAndroid Build Coastguard Worker if (mWrapped || mBufferRef) {
454*ec779b8eSAndroid Build Coastguard Worker ALOGD("ConstGraphicBlockBuffer::canCopy: %swrapped ; buffer ref %s",
455*ec779b8eSAndroid Build Coastguard Worker mWrapped ? "" : "not ", mBufferRef ? "exists" : "doesn't exist");
456*ec779b8eSAndroid Build Coastguard Worker return false;
457*ec779b8eSAndroid Build Coastguard Worker }
458*ec779b8eSAndroid Build Coastguard Worker if (!buffer) {
459*ec779b8eSAndroid Build Coastguard Worker // Nothing to copy, so we can copy by doing nothing.
460*ec779b8eSAndroid Build Coastguard Worker return true;
461*ec779b8eSAndroid Build Coastguard Worker }
462*ec779b8eSAndroid Build Coastguard Worker if (buffer->data().type() != C2BufferData::GRAPHIC) {
463*ec779b8eSAndroid Build Coastguard Worker ALOGD("ConstGraphicBlockBuffer::canCopy: buffer precondition unsatisfied");
464*ec779b8eSAndroid Build Coastguard Worker return false;
465*ec779b8eSAndroid Build Coastguard Worker }
466*ec779b8eSAndroid Build Coastguard Worker if (buffer->data().graphicBlocks().size() == 0) {
467*ec779b8eSAndroid Build Coastguard Worker return true;
468*ec779b8eSAndroid Build Coastguard Worker } else if (buffer->data().graphicBlocks().size() != 1u) {
469*ec779b8eSAndroid Build Coastguard Worker ALOGD("ConstGraphicBlockBuffer::canCopy: too many blocks");
470*ec779b8eSAndroid Build Coastguard Worker return false;
471*ec779b8eSAndroid Build Coastguard Worker }
472*ec779b8eSAndroid Build Coastguard Worker
473*ec779b8eSAndroid Build Coastguard Worker ATRACE_BEGIN("ConstGraphicBlockBuffer::canCopy block->map()");
474*ec779b8eSAndroid Build Coastguard Worker GraphicView2MediaImageConverter converter(
475*ec779b8eSAndroid Build Coastguard Worker buffer->data().graphicBlocks()[0].map().get(),
476*ec779b8eSAndroid Build Coastguard Worker // FIXME: format() is not const, but we cannot change it, so do a const cast here
477*ec779b8eSAndroid Build Coastguard Worker const_cast<ConstGraphicBlockBuffer *>(this)->format(),
478*ec779b8eSAndroid Build Coastguard Worker true /* copy */);
479*ec779b8eSAndroid Build Coastguard Worker ATRACE_END();
480*ec779b8eSAndroid Build Coastguard Worker if (converter.initCheck() != OK) {
481*ec779b8eSAndroid Build Coastguard Worker ALOGD("ConstGraphicBlockBuffer::canCopy: converter init failed: %d", converter.initCheck());
482*ec779b8eSAndroid Build Coastguard Worker return false;
483*ec779b8eSAndroid Build Coastguard Worker }
484*ec779b8eSAndroid Build Coastguard Worker if (converter.backBufferSize() > capacity()) {
485*ec779b8eSAndroid Build Coastguard Worker ALOGD("ConstGraphicBlockBuffer::canCopy: insufficient capacity: req %u has %zu",
486*ec779b8eSAndroid Build Coastguard Worker converter.backBufferSize(), capacity());
487*ec779b8eSAndroid Build Coastguard Worker return false;
488*ec779b8eSAndroid Build Coastguard Worker }
489*ec779b8eSAndroid Build Coastguard Worker return true;
490*ec779b8eSAndroid Build Coastguard Worker }
491*ec779b8eSAndroid Build Coastguard Worker
copy(const std::shared_ptr<C2Buffer> & buffer)492*ec779b8eSAndroid Build Coastguard Worker bool ConstGraphicBlockBuffer::copy(const std::shared_ptr<C2Buffer> &buffer) {
493*ec779b8eSAndroid Build Coastguard Worker if (!buffer || buffer->data().graphicBlocks().size() == 0) {
494*ec779b8eSAndroid Build Coastguard Worker setRange(0, 0);
495*ec779b8eSAndroid Build Coastguard Worker return true;
496*ec779b8eSAndroid Build Coastguard Worker }
497*ec779b8eSAndroid Build Coastguard Worker
498*ec779b8eSAndroid Build Coastguard Worker GraphicView2MediaImageConverter converter(
499*ec779b8eSAndroid Build Coastguard Worker buffer->data().graphicBlocks()[0].map().get(), format(), true /* copy */);
500*ec779b8eSAndroid Build Coastguard Worker if (converter.initCheck() != OK) {
501*ec779b8eSAndroid Build Coastguard Worker ALOGD("ConstGraphicBlockBuffer::copy: converter init failed: %d", converter.initCheck());
502*ec779b8eSAndroid Build Coastguard Worker return false;
503*ec779b8eSAndroid Build Coastguard Worker }
504*ec779b8eSAndroid Build Coastguard Worker sp<ABuffer> aBuffer = new ABuffer(base(), capacity());
505*ec779b8eSAndroid Build Coastguard Worker if (!converter.setBackBuffer(aBuffer)) {
506*ec779b8eSAndroid Build Coastguard Worker ALOGD("ConstGraphicBlockBuffer::copy: set back buffer failed");
507*ec779b8eSAndroid Build Coastguard Worker return false;
508*ec779b8eSAndroid Build Coastguard Worker }
509*ec779b8eSAndroid Build Coastguard Worker setRange(0, aBuffer->size()); // align size info
510*ec779b8eSAndroid Build Coastguard Worker converter.copyToMediaImage();
511*ec779b8eSAndroid Build Coastguard Worker setImageData(converter.imageData());
512*ec779b8eSAndroid Build Coastguard Worker mBufferRef = buffer;
513*ec779b8eSAndroid Build Coastguard Worker return true;
514*ec779b8eSAndroid Build Coastguard Worker }
515*ec779b8eSAndroid Build Coastguard Worker
516*ec779b8eSAndroid Build Coastguard Worker // EncryptedLinearBlockBuffer
517*ec779b8eSAndroid Build Coastguard Worker
EncryptedLinearBlockBuffer(const sp<AMessage> & format,const std::shared_ptr<C2LinearBlock> & block,const sp<IMemory> & memory,int32_t heapSeqNum)518*ec779b8eSAndroid Build Coastguard Worker EncryptedLinearBlockBuffer::EncryptedLinearBlockBuffer(
519*ec779b8eSAndroid Build Coastguard Worker const sp<AMessage> &format,
520*ec779b8eSAndroid Build Coastguard Worker const std::shared_ptr<C2LinearBlock> &block,
521*ec779b8eSAndroid Build Coastguard Worker const sp<IMemory> &memory,
522*ec779b8eSAndroid Build Coastguard Worker int32_t heapSeqNum)
523*ec779b8eSAndroid Build Coastguard Worker // TODO: Using unsecurePointer() has some associated security pitfalls
524*ec779b8eSAndroid Build Coastguard Worker // (see declaration for details).
525*ec779b8eSAndroid Build Coastguard Worker // Either document why it is safe in this case or address the
526*ec779b8eSAndroid Build Coastguard Worker // issue (e.g. by copying).
527*ec779b8eSAndroid Build Coastguard Worker : Codec2Buffer(format, new ABuffer(memory->unsecurePointer(), memory->size())),
528*ec779b8eSAndroid Build Coastguard Worker mBlock(block),
529*ec779b8eSAndroid Build Coastguard Worker mMemory(memory),
530*ec779b8eSAndroid Build Coastguard Worker mHeapSeqNum(heapSeqNum) {
531*ec779b8eSAndroid Build Coastguard Worker }
532*ec779b8eSAndroid Build Coastguard Worker
asC2Buffer()533*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<C2Buffer> EncryptedLinearBlockBuffer::asC2Buffer() {
534*ec779b8eSAndroid Build Coastguard Worker return C2Buffer::CreateLinearBuffer(mBlock->share(offset(), size(), C2Fence()));
535*ec779b8eSAndroid Build Coastguard Worker }
536*ec779b8eSAndroid Build Coastguard Worker
fillSourceBuffer(hardware::drm::V1_0::SharedBuffer * source)537*ec779b8eSAndroid Build Coastguard Worker void EncryptedLinearBlockBuffer::fillSourceBuffer(
538*ec779b8eSAndroid Build Coastguard Worker hardware::drm::V1_0::SharedBuffer *source) {
539*ec779b8eSAndroid Build Coastguard Worker BufferChannelBase::IMemoryToSharedBuffer(mMemory, mHeapSeqNum, source);
540*ec779b8eSAndroid Build Coastguard Worker }
541*ec779b8eSAndroid Build Coastguard Worker
fillSourceBuffer(hardware::cas::native::V1_0::SharedBuffer * source)542*ec779b8eSAndroid Build Coastguard Worker void EncryptedLinearBlockBuffer::fillSourceBuffer(
543*ec779b8eSAndroid Build Coastguard Worker hardware::cas::native::V1_0::SharedBuffer *source) {
544*ec779b8eSAndroid Build Coastguard Worker ssize_t offset;
545*ec779b8eSAndroid Build Coastguard Worker size_t size;
546*ec779b8eSAndroid Build Coastguard Worker
547*ec779b8eSAndroid Build Coastguard Worker mHidlMemory = hardware::fromHeap(mMemory->getMemory(&offset, &size));
548*ec779b8eSAndroid Build Coastguard Worker source->heapBase = *mHidlMemory;
549*ec779b8eSAndroid Build Coastguard Worker source->offset = offset;
550*ec779b8eSAndroid Build Coastguard Worker source->size = size;
551*ec779b8eSAndroid Build Coastguard Worker }
552*ec779b8eSAndroid Build Coastguard Worker
copyDecryptedContent(const sp<IMemory> & decrypted,size_t length)553*ec779b8eSAndroid Build Coastguard Worker bool EncryptedLinearBlockBuffer::copyDecryptedContent(
554*ec779b8eSAndroid Build Coastguard Worker const sp<IMemory> &decrypted, size_t length) {
555*ec779b8eSAndroid Build Coastguard Worker C2WriteView view = mBlock->map().get();
556*ec779b8eSAndroid Build Coastguard Worker if (view.error() != C2_OK) {
557*ec779b8eSAndroid Build Coastguard Worker return false;
558*ec779b8eSAndroid Build Coastguard Worker }
559*ec779b8eSAndroid Build Coastguard Worker if (view.size() < length) {
560*ec779b8eSAndroid Build Coastguard Worker return false;
561*ec779b8eSAndroid Build Coastguard Worker }
562*ec779b8eSAndroid Build Coastguard Worker memcpy(view.data(), decrypted->unsecurePointer(), length);
563*ec779b8eSAndroid Build Coastguard Worker return true;
564*ec779b8eSAndroid Build Coastguard Worker }
565*ec779b8eSAndroid Build Coastguard Worker
copyDecryptedContentFromMemory(size_t length)566*ec779b8eSAndroid Build Coastguard Worker bool EncryptedLinearBlockBuffer::copyDecryptedContentFromMemory(size_t length) {
567*ec779b8eSAndroid Build Coastguard Worker return copyDecryptedContent(mMemory, length);
568*ec779b8eSAndroid Build Coastguard Worker }
569*ec779b8eSAndroid Build Coastguard Worker
handle() const570*ec779b8eSAndroid Build Coastguard Worker native_handle_t *EncryptedLinearBlockBuffer::handle() const {
571*ec779b8eSAndroid Build Coastguard Worker return const_cast<native_handle_t *>(mBlock->handle());
572*ec779b8eSAndroid Build Coastguard Worker }
573*ec779b8eSAndroid Build Coastguard Worker
getMappedBlock(std::unique_ptr<MappedBlock> * const mappedBlock) const574*ec779b8eSAndroid Build Coastguard Worker void EncryptedLinearBlockBuffer::getMappedBlock(
575*ec779b8eSAndroid Build Coastguard Worker std::unique_ptr<MappedBlock> * const mappedBlock) const {
576*ec779b8eSAndroid Build Coastguard Worker if (mappedBlock) {
577*ec779b8eSAndroid Build Coastguard Worker mappedBlock->reset(new EncryptedLinearBlockBuffer::MappedBlock(mBlock));
578*ec779b8eSAndroid Build Coastguard Worker }
579*ec779b8eSAndroid Build Coastguard Worker return;
580*ec779b8eSAndroid Build Coastguard Worker }
581*ec779b8eSAndroid Build Coastguard Worker
MappedBlock(const std::shared_ptr<C2LinearBlock> & block)582*ec779b8eSAndroid Build Coastguard Worker EncryptedLinearBlockBuffer::MappedBlock::MappedBlock(
583*ec779b8eSAndroid Build Coastguard Worker const std::shared_ptr<C2LinearBlock> &block) : mView(block->map().get()) {
584*ec779b8eSAndroid Build Coastguard Worker }
585*ec779b8eSAndroid Build Coastguard Worker
copyDecryptedContent(const sp<IMemory> & decrypted,size_t length)586*ec779b8eSAndroid Build Coastguard Worker bool EncryptedLinearBlockBuffer::MappedBlock::copyDecryptedContent(
587*ec779b8eSAndroid Build Coastguard Worker const sp<IMemory> &decrypted, size_t length) {
588*ec779b8eSAndroid Build Coastguard Worker if (mView.error() != C2_OK) {
589*ec779b8eSAndroid Build Coastguard Worker return false;
590*ec779b8eSAndroid Build Coastguard Worker }
591*ec779b8eSAndroid Build Coastguard Worker if (mView.size() < length) {
592*ec779b8eSAndroid Build Coastguard Worker ALOGE("View size(%d) less than decrypted length(%zu)",
593*ec779b8eSAndroid Build Coastguard Worker mView.size(), length);
594*ec779b8eSAndroid Build Coastguard Worker return false;
595*ec779b8eSAndroid Build Coastguard Worker }
596*ec779b8eSAndroid Build Coastguard Worker memcpy(mView.data(), decrypted->unsecurePointer(), length);
597*ec779b8eSAndroid Build Coastguard Worker mView.setOffset(mView.offset() + length);
598*ec779b8eSAndroid Build Coastguard Worker return true;
599*ec779b8eSAndroid Build Coastguard Worker }
600*ec779b8eSAndroid Build Coastguard Worker
~MappedBlock()601*ec779b8eSAndroid Build Coastguard Worker EncryptedLinearBlockBuffer::MappedBlock::~MappedBlock() {
602*ec779b8eSAndroid Build Coastguard Worker mView.setOffset(0);
603*ec779b8eSAndroid Build Coastguard Worker }
604*ec779b8eSAndroid Build Coastguard Worker
605*ec779b8eSAndroid Build Coastguard Worker using ::aidl::android::hardware::graphics::common::Cta861_3;
606*ec779b8eSAndroid Build Coastguard Worker using ::aidl::android::hardware::graphics::common::Smpte2086;
607*ec779b8eSAndroid Build Coastguard Worker
608*ec779b8eSAndroid Build Coastguard Worker namespace {
609*ec779b8eSAndroid Build Coastguard Worker
610*ec779b8eSAndroid Build Coastguard Worker class GrallocBuffer {
611*ec779b8eSAndroid Build Coastguard Worker public:
GrallocBuffer(const C2Handle * const handle)612*ec779b8eSAndroid Build Coastguard Worker GrallocBuffer(const C2Handle *const handle) : mBuffer(nullptr) {
613*ec779b8eSAndroid Build Coastguard Worker GraphicBufferMapper& mapper = GraphicBufferMapper::get();
614*ec779b8eSAndroid Build Coastguard Worker
615*ec779b8eSAndroid Build Coastguard Worker // Unwrap raw buffer handle from the C2Handle
616*ec779b8eSAndroid Build Coastguard Worker native_handle_t *nh = UnwrapNativeCodec2GrallocHandle(handle);
617*ec779b8eSAndroid Build Coastguard Worker if (!nh) {
618*ec779b8eSAndroid Build Coastguard Worker ALOGE("handle is not compatible to any gralloc C2Handle types");
619*ec779b8eSAndroid Build Coastguard Worker return;
620*ec779b8eSAndroid Build Coastguard Worker }
621*ec779b8eSAndroid Build Coastguard Worker // Import the raw handle so IMapper can use the buffer. The imported
622*ec779b8eSAndroid Build Coastguard Worker // handle must be freed when the client is done with the buffer.
623*ec779b8eSAndroid Build Coastguard Worker status_t status = mapper.importBufferNoValidate(
624*ec779b8eSAndroid Build Coastguard Worker nh,
625*ec779b8eSAndroid Build Coastguard Worker &mBuffer);
626*ec779b8eSAndroid Build Coastguard Worker
627*ec779b8eSAndroid Build Coastguard Worker if (status != OK) {
628*ec779b8eSAndroid Build Coastguard Worker ALOGE("Failed to import buffer. Status: %d.", status);
629*ec779b8eSAndroid Build Coastguard Worker return;
630*ec779b8eSAndroid Build Coastguard Worker }
631*ec779b8eSAndroid Build Coastguard Worker
632*ec779b8eSAndroid Build Coastguard Worker // TRICKY: UnwrapNativeCodec2GrallocHandle creates a new handle but
633*ec779b8eSAndroid Build Coastguard Worker // does not clone the fds. Thus we need to delete the handle
634*ec779b8eSAndroid Build Coastguard Worker // without closing it.
635*ec779b8eSAndroid Build Coastguard Worker native_handle_delete(nh);
636*ec779b8eSAndroid Build Coastguard Worker }
637*ec779b8eSAndroid Build Coastguard Worker
~GrallocBuffer()638*ec779b8eSAndroid Build Coastguard Worker ~GrallocBuffer() {
639*ec779b8eSAndroid Build Coastguard Worker GraphicBufferMapper& mapper = GraphicBufferMapper::get();
640*ec779b8eSAndroid Build Coastguard Worker if (mBuffer) {
641*ec779b8eSAndroid Build Coastguard Worker // Free the imported buffer handle. This does not release the
642*ec779b8eSAndroid Build Coastguard Worker // underlying buffer itself.
643*ec779b8eSAndroid Build Coastguard Worker mapper.freeBuffer(mBuffer);
644*ec779b8eSAndroid Build Coastguard Worker }
645*ec779b8eSAndroid Build Coastguard Worker }
646*ec779b8eSAndroid Build Coastguard Worker
get() const647*ec779b8eSAndroid Build Coastguard Worker buffer_handle_t get() const { return mBuffer; }
operator bool() const648*ec779b8eSAndroid Build Coastguard Worker operator bool() const { return (mBuffer != nullptr); }
649*ec779b8eSAndroid Build Coastguard Worker private:
650*ec779b8eSAndroid Build Coastguard Worker buffer_handle_t mBuffer;
651*ec779b8eSAndroid Build Coastguard Worker };
652*ec779b8eSAndroid Build Coastguard Worker
653*ec779b8eSAndroid Build Coastguard Worker } // namspace
654*ec779b8eSAndroid Build Coastguard Worker
GetHdrMetadataFromGralloc4Handle(const C2Handle * const handle,std::shared_ptr<C2StreamHdrStaticMetadataInfo::input> * staticInfo,std::shared_ptr<C2StreamHdrDynamicMetadataInfo::input> * dynamicInfo)655*ec779b8eSAndroid Build Coastguard Worker c2_status_t GetHdrMetadataFromGralloc4Handle(
656*ec779b8eSAndroid Build Coastguard Worker const C2Handle *const handle,
657*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<C2StreamHdrStaticMetadataInfo::input> *staticInfo,
658*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<C2StreamHdrDynamicMetadataInfo::input> *dynamicInfo) {
659*ec779b8eSAndroid Build Coastguard Worker c2_status_t err = C2_OK;
660*ec779b8eSAndroid Build Coastguard Worker GraphicBufferMapper& mapper = GraphicBufferMapper::get();
661*ec779b8eSAndroid Build Coastguard Worker GrallocBuffer buffer(handle);
662*ec779b8eSAndroid Build Coastguard Worker if (!buffer) {
663*ec779b8eSAndroid Build Coastguard Worker // Gralloc4 not supported; nothing to do
664*ec779b8eSAndroid Build Coastguard Worker return err;
665*ec779b8eSAndroid Build Coastguard Worker }
666*ec779b8eSAndroid Build Coastguard Worker if (staticInfo) {
667*ec779b8eSAndroid Build Coastguard Worker ALOGV("Grabbing static HDR info from gralloc metadata");
668*ec779b8eSAndroid Build Coastguard Worker staticInfo->reset(new C2StreamHdrStaticMetadataInfo::input(0u));
669*ec779b8eSAndroid Build Coastguard Worker memset(&(*staticInfo)->mastering, 0, sizeof((*staticInfo)->mastering));
670*ec779b8eSAndroid Build Coastguard Worker (*staticInfo)->maxCll = 0;
671*ec779b8eSAndroid Build Coastguard Worker (*staticInfo)->maxFall = 0;
672*ec779b8eSAndroid Build Coastguard Worker
673*ec779b8eSAndroid Build Coastguard Worker std::optional<Smpte2086> smpte2086;
674*ec779b8eSAndroid Build Coastguard Worker status_t status = mapper.getSmpte2086(buffer.get(), &smpte2086);
675*ec779b8eSAndroid Build Coastguard Worker if (status != OK || !smpte2086) {
676*ec779b8eSAndroid Build Coastguard Worker err = C2_CORRUPTED;
677*ec779b8eSAndroid Build Coastguard Worker } else {
678*ec779b8eSAndroid Build Coastguard Worker if (smpte2086) {
679*ec779b8eSAndroid Build Coastguard Worker (*staticInfo)->mastering.red.x = smpte2086->primaryRed.x;
680*ec779b8eSAndroid Build Coastguard Worker (*staticInfo)->mastering.red.y = smpte2086->primaryRed.y;
681*ec779b8eSAndroid Build Coastguard Worker (*staticInfo)->mastering.green.x = smpte2086->primaryGreen.x;
682*ec779b8eSAndroid Build Coastguard Worker (*staticInfo)->mastering.green.y = smpte2086->primaryGreen.y;
683*ec779b8eSAndroid Build Coastguard Worker (*staticInfo)->mastering.blue.x = smpte2086->primaryBlue.x;
684*ec779b8eSAndroid Build Coastguard Worker (*staticInfo)->mastering.blue.y = smpte2086->primaryBlue.y;
685*ec779b8eSAndroid Build Coastguard Worker (*staticInfo)->mastering.white.x = smpte2086->whitePoint.x;
686*ec779b8eSAndroid Build Coastguard Worker (*staticInfo)->mastering.white.y = smpte2086->whitePoint.y;
687*ec779b8eSAndroid Build Coastguard Worker
688*ec779b8eSAndroid Build Coastguard Worker (*staticInfo)->mastering.maxLuminance = smpte2086->maxLuminance;
689*ec779b8eSAndroid Build Coastguard Worker (*staticInfo)->mastering.minLuminance = smpte2086->minLuminance;
690*ec779b8eSAndroid Build Coastguard Worker }
691*ec779b8eSAndroid Build Coastguard Worker }
692*ec779b8eSAndroid Build Coastguard Worker
693*ec779b8eSAndroid Build Coastguard Worker std::optional<Cta861_3> cta861_3;
694*ec779b8eSAndroid Build Coastguard Worker status = mapper.getCta861_3(buffer.get(), &cta861_3);
695*ec779b8eSAndroid Build Coastguard Worker if (status != OK || !cta861_3) {
696*ec779b8eSAndroid Build Coastguard Worker err = C2_CORRUPTED;
697*ec779b8eSAndroid Build Coastguard Worker } else {
698*ec779b8eSAndroid Build Coastguard Worker if (cta861_3) {
699*ec779b8eSAndroid Build Coastguard Worker (*staticInfo)->maxCll = cta861_3->maxContentLightLevel;
700*ec779b8eSAndroid Build Coastguard Worker (*staticInfo)->maxFall = cta861_3->maxFrameAverageLightLevel;
701*ec779b8eSAndroid Build Coastguard Worker }
702*ec779b8eSAndroid Build Coastguard Worker }
703*ec779b8eSAndroid Build Coastguard Worker }
704*ec779b8eSAndroid Build Coastguard Worker
705*ec779b8eSAndroid Build Coastguard Worker if (err != C2_OK) {
706*ec779b8eSAndroid Build Coastguard Worker staticInfo->reset();
707*ec779b8eSAndroid Build Coastguard Worker }
708*ec779b8eSAndroid Build Coastguard Worker
709*ec779b8eSAndroid Build Coastguard Worker if (dynamicInfo) {
710*ec779b8eSAndroid Build Coastguard Worker ALOGV("Grabbing dynamic HDR info from gralloc metadata");
711*ec779b8eSAndroid Build Coastguard Worker dynamicInfo->reset();
712*ec779b8eSAndroid Build Coastguard Worker std::optional<std::vector<uint8_t>> vec;
713*ec779b8eSAndroid Build Coastguard Worker status_t status = mapper.getSmpte2094_40(buffer.get(), &vec);
714*ec779b8eSAndroid Build Coastguard Worker if (status != OK || !vec) {
715*ec779b8eSAndroid Build Coastguard Worker dynamicInfo->reset();
716*ec779b8eSAndroid Build Coastguard Worker err = C2_CORRUPTED;
717*ec779b8eSAndroid Build Coastguard Worker } else {
718*ec779b8eSAndroid Build Coastguard Worker if (vec) {
719*ec779b8eSAndroid Build Coastguard Worker *dynamicInfo = C2StreamHdrDynamicMetadataInfo::input::AllocShared(
720*ec779b8eSAndroid Build Coastguard Worker vec->size(), 0u, C2Config::HDR_DYNAMIC_METADATA_TYPE_SMPTE_2094_40);
721*ec779b8eSAndroid Build Coastguard Worker memcpy((*dynamicInfo)->m.data, vec->data(), vec->size());
722*ec779b8eSAndroid Build Coastguard Worker }
723*ec779b8eSAndroid Build Coastguard Worker }
724*ec779b8eSAndroid Build Coastguard Worker }
725*ec779b8eSAndroid Build Coastguard Worker
726*ec779b8eSAndroid Build Coastguard Worker return err;
727*ec779b8eSAndroid Build Coastguard Worker }
728*ec779b8eSAndroid Build Coastguard Worker
SetMetadataToGralloc4Handle(android_dataspace_t dataSpace,const std::shared_ptr<const C2StreamHdrStaticMetadataInfo::output> & staticInfo,const std::shared_ptr<const C2StreamHdrDynamicMetadataInfo::output> & dynamicInfo,const C2Handle * const handle)729*ec779b8eSAndroid Build Coastguard Worker c2_status_t SetMetadataToGralloc4Handle(
730*ec779b8eSAndroid Build Coastguard Worker android_dataspace_t dataSpace,
731*ec779b8eSAndroid Build Coastguard Worker const std::shared_ptr<const C2StreamHdrStaticMetadataInfo::output> &staticInfo,
732*ec779b8eSAndroid Build Coastguard Worker const std::shared_ptr<const C2StreamHdrDynamicMetadataInfo::output> &dynamicInfo,
733*ec779b8eSAndroid Build Coastguard Worker const C2Handle *const handle) {
734*ec779b8eSAndroid Build Coastguard Worker c2_status_t err = C2_OK;
735*ec779b8eSAndroid Build Coastguard Worker GraphicBufferMapper& mapper = GraphicBufferMapper::get();
736*ec779b8eSAndroid Build Coastguard Worker GrallocBuffer buffer(handle);
737*ec779b8eSAndroid Build Coastguard Worker if (!buffer) {
738*ec779b8eSAndroid Build Coastguard Worker // Gralloc4 not supported; nothing to do
739*ec779b8eSAndroid Build Coastguard Worker return err;
740*ec779b8eSAndroid Build Coastguard Worker }
741*ec779b8eSAndroid Build Coastguard Worker // Use V0 dataspaces for Gralloc4+
742*ec779b8eSAndroid Build Coastguard Worker if (android::media::codec::provider_->dataspace_v0_partial()) {
743*ec779b8eSAndroid Build Coastguard Worker ColorUtils::convertDataSpaceToV0(dataSpace);
744*ec779b8eSAndroid Build Coastguard Worker }
745*ec779b8eSAndroid Build Coastguard Worker status_t status = mapper.setDataspace(buffer.get(), static_cast<ui::Dataspace>(dataSpace));
746*ec779b8eSAndroid Build Coastguard Worker if (status != OK) {
747*ec779b8eSAndroid Build Coastguard Worker err = C2_CORRUPTED;
748*ec779b8eSAndroid Build Coastguard Worker }
749*ec779b8eSAndroid Build Coastguard Worker if (staticInfo && *staticInfo) {
750*ec779b8eSAndroid Build Coastguard Worker ALOGV("Setting static HDR info as gralloc metadata");
751*ec779b8eSAndroid Build Coastguard Worker std::optional<Smpte2086> smpte2086 = Smpte2086{
752*ec779b8eSAndroid Build Coastguard Worker {staticInfo->mastering.red.x, staticInfo->mastering.red.y},
753*ec779b8eSAndroid Build Coastguard Worker {staticInfo->mastering.green.x, staticInfo->mastering.green.y},
754*ec779b8eSAndroid Build Coastguard Worker {staticInfo->mastering.blue.x, staticInfo->mastering.blue.y},
755*ec779b8eSAndroid Build Coastguard Worker {staticInfo->mastering.white.x, staticInfo->mastering.white.y},
756*ec779b8eSAndroid Build Coastguard Worker staticInfo->mastering.maxLuminance,
757*ec779b8eSAndroid Build Coastguard Worker staticInfo->mastering.minLuminance,
758*ec779b8eSAndroid Build Coastguard Worker };
759*ec779b8eSAndroid Build Coastguard Worker if (0.0 <= smpte2086->primaryRed.x && smpte2086->primaryRed.x <= 1.0
760*ec779b8eSAndroid Build Coastguard Worker && 0.0 <= smpte2086->primaryRed.y && smpte2086->primaryRed.y <= 1.0
761*ec779b8eSAndroid Build Coastguard Worker && 0.0 <= smpte2086->primaryGreen.x && smpte2086->primaryGreen.x <= 1.0
762*ec779b8eSAndroid Build Coastguard Worker && 0.0 <= smpte2086->primaryGreen.y && smpte2086->primaryGreen.y <= 1.0
763*ec779b8eSAndroid Build Coastguard Worker && 0.0 <= smpte2086->primaryBlue.x && smpte2086->primaryBlue.x <= 1.0
764*ec779b8eSAndroid Build Coastguard Worker && 0.0 <= smpte2086->primaryBlue.y && smpte2086->primaryBlue.y <= 1.0
765*ec779b8eSAndroid Build Coastguard Worker && 0.0 <= smpte2086->whitePoint.x && smpte2086->whitePoint.x <= 1.0
766*ec779b8eSAndroid Build Coastguard Worker && 0.0 <= smpte2086->whitePoint.y && smpte2086->whitePoint.y <= 1.0
767*ec779b8eSAndroid Build Coastguard Worker && 0.0 <= smpte2086->maxLuminance && 0.0 <= smpte2086->minLuminance) {
768*ec779b8eSAndroid Build Coastguard Worker status = mapper.setSmpte2086(buffer.get(), smpte2086);
769*ec779b8eSAndroid Build Coastguard Worker if (status != OK) {
770*ec779b8eSAndroid Build Coastguard Worker err = C2_CORRUPTED;
771*ec779b8eSAndroid Build Coastguard Worker }
772*ec779b8eSAndroid Build Coastguard Worker }
773*ec779b8eSAndroid Build Coastguard Worker std::optional<Cta861_3> cta861_3 = Cta861_3{
774*ec779b8eSAndroid Build Coastguard Worker staticInfo->maxCll,
775*ec779b8eSAndroid Build Coastguard Worker staticInfo->maxFall,
776*ec779b8eSAndroid Build Coastguard Worker };
777*ec779b8eSAndroid Build Coastguard Worker if (0.0 <= cta861_3->maxContentLightLevel && 0.0 <= cta861_3->maxFrameAverageLightLevel) {
778*ec779b8eSAndroid Build Coastguard Worker status = mapper.setCta861_3(buffer.get(), cta861_3);
779*ec779b8eSAndroid Build Coastguard Worker if (status != OK) {
780*ec779b8eSAndroid Build Coastguard Worker err = C2_CORRUPTED;
781*ec779b8eSAndroid Build Coastguard Worker }
782*ec779b8eSAndroid Build Coastguard Worker }
783*ec779b8eSAndroid Build Coastguard Worker }
784*ec779b8eSAndroid Build Coastguard Worker if (dynamicInfo && *dynamicInfo && dynamicInfo->flexCount() > 0) {
785*ec779b8eSAndroid Build Coastguard Worker ALOGV("Setting dynamic HDR info as gralloc metadata");
786*ec779b8eSAndroid Build Coastguard Worker if (dynamicInfo->m.type_ == C2Config::HDR_DYNAMIC_METADATA_TYPE_SMPTE_2094_40) {
787*ec779b8eSAndroid Build Coastguard Worker std::optional<std::vector<uint8_t>> smpte2094_40 = std::vector<uint8_t>();
788*ec779b8eSAndroid Build Coastguard Worker smpte2094_40->resize(dynamicInfo->flexCount());
789*ec779b8eSAndroid Build Coastguard Worker memcpy(smpte2094_40->data(), dynamicInfo->m.data, dynamicInfo->flexCount());
790*ec779b8eSAndroid Build Coastguard Worker
791*ec779b8eSAndroid Build Coastguard Worker status = mapper.setSmpte2094_40(buffer.get(), smpte2094_40);
792*ec779b8eSAndroid Build Coastguard Worker if (status != OK) {
793*ec779b8eSAndroid Build Coastguard Worker err = C2_CORRUPTED;
794*ec779b8eSAndroid Build Coastguard Worker }
795*ec779b8eSAndroid Build Coastguard Worker } else {
796*ec779b8eSAndroid Build Coastguard Worker err = C2_BAD_VALUE;
797*ec779b8eSAndroid Build Coastguard Worker }
798*ec779b8eSAndroid Build Coastguard Worker }
799*ec779b8eSAndroid Build Coastguard Worker
800*ec779b8eSAndroid Build Coastguard Worker return err;
801*ec779b8eSAndroid Build Coastguard Worker }
802*ec779b8eSAndroid Build Coastguard Worker
803*ec779b8eSAndroid Build Coastguard Worker } // namespace android
804