blob: 6e92b6f03a8a9caec2c9774a3fa667323318fb59 [file] [log] [blame]
Fyodor Kyslovdd7d5992024-11-05 21:40:16 +00001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "C2SoftApvDec"
19#include <log/log.h>
20
21#include <android_media_swcodec_flags.h>
22
23#include <media/stagefright/foundation/AUtils.h>
24#include <media/stagefright/foundation/MediaDefs.h>
25
26#include <C2Debug.h>
27#include <C2PlatformSupport.h>
28#include <Codec2BufferUtils.h>
29#include <Codec2CommonUtils.h>
30#include <Codec2Mapper.h>
31#include <SimpleC2Interface.h>
32#include "C2SoftApvDec.h"
33
34#include <cutils/properties.h>
35
36const char* MEDIA_MIMETYPE_VIDEO_APV = "video/apv";
37
38#define MAX_NUM_FRMS (1) // supports only 1-frame output
39#define FRM_IDX (0) // supports only 1-frame output
40// check generic frame or not
41#define IS_NON_AUX_FRM(frm) \
42 (((frm)->pbu_type == OAPV_PBU_TYPE_PRIMARY_FRAME) || \
43 ((frm)->pbu_type == OAPV_PBU_TYPE_NON_PRIMARY_FRAME))
44// check auxiliary frame or not
45#define IS_AUX_FRM(frm) (!(IS_NON_AUX_FRM(frm)))
46#define OUTPUT_CSP_NATIVE (0)
47#define OUTPUT_CSP_P210 (1)
48
49namespace android {
50namespace {
51constexpr char COMPONENT_NAME[] = "c2.android.apv.decoder";
52constexpr uint32_t kDefaultOutputDelay = 8;
53constexpr uint32_t kMaxOutputDelay = 16;
54constexpr size_t kMinInputBufferSize = 2 * 1024 * 1024;
55} // namespace
56
57class C2SoftApvDec::IntfImpl : public SimpleInterface<void>::BaseParams {
58 public:
59 explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper>& helper)
60 : SimpleInterface<void>::BaseParams(helper, COMPONENT_NAME, C2Component::KIND_DECODER,
61 C2Component::DOMAIN_VIDEO, MEDIA_MIMETYPE_VIDEO_APV) {
62 noPrivateBuffers(); // TODO: account for our buffers here.
63 noInputReferences();
64 noOutputReferences();
65 noInputLatency();
66 noTimeStretch();
67
68 addParameter(DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
69 .withConstValue(new C2ComponentAttributesSetting(
70 C2Component::ATTRIB_IS_TEMPORAL))
71 .build());
72
73 addParameter(DefineParam(mSize, C2_PARAMKEY_PICTURE_SIZE)
74 .withDefault(new C2StreamPictureSizeInfo::output(0u, 320, 240))
75 .withFields({
76 C2F(mSize, width).inRange(2, 4096),
77 C2F(mSize, height).inRange(2, 4096),
78 })
79 .withSetter(SizeSetter)
80 .build());
81
82 addParameter(
83 DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
84 .withDefault(new C2StreamProfileLevelInfo::input(
85 0u, C2Config::PROFILE_APV_422_10))
86 .withFields(
87 {C2F(mProfileLevel, profile).oneOf({C2Config::PROFILE_APV_422_10}),
88 C2F(mProfileLevel, level)
89 .oneOf({
90 C2Config::LEVEL_APV_1_BAND_0,
91 C2Config::LEVEL_APV_1_1_BAND_0,
92 C2Config::LEVEL_APV_2_BAND_0,
93 C2Config::LEVEL_APV_2_1_BAND_0,
94 C2Config::LEVEL_APV_3_BAND_0,
95 C2Config::LEVEL_APV_3_1_BAND_0,
96 C2Config::LEVEL_APV_4_BAND_0,
97 C2Config::LEVEL_APV_4_1_BAND_0,
98 C2Config::LEVEL_APV_5_BAND_0,
99 C2Config::LEVEL_APV_5_1_BAND_0,
100 C2Config::LEVEL_APV_6_BAND_0,
101 C2Config::LEVEL_APV_6_1_BAND_0,
102 C2Config::LEVEL_APV_7_BAND_0,
103 C2Config::LEVEL_APV_7_1_BAND_0,
104 C2Config::LEVEL_APV_1_BAND_1,
105 C2Config::LEVEL_APV_1_1_BAND_1,
106 C2Config::LEVEL_APV_2_BAND_1,
107 C2Config::LEVEL_APV_2_1_BAND_1,
108 C2Config::LEVEL_APV_3_BAND_1,
109 C2Config::LEVEL_APV_3_1_BAND_1,
110 C2Config::LEVEL_APV_4_BAND_1,
111 C2Config::LEVEL_APV_4_1_BAND_1,
112 C2Config::LEVEL_APV_5_BAND_1,
113 C2Config::LEVEL_APV_5_1_BAND_1,
114 C2Config::LEVEL_APV_6_BAND_1,
115 C2Config::LEVEL_APV_6_1_BAND_1,
116 C2Config::LEVEL_APV_7_BAND_1,
117 C2Config::LEVEL_APV_7_1_BAND_1,
118 C2Config::LEVEL_APV_1_BAND_2,
119 C2Config::LEVEL_APV_1_1_BAND_2,
120 C2Config::LEVEL_APV_2_BAND_2,
121 C2Config::LEVEL_APV_2_1_BAND_2,
122 C2Config::LEVEL_APV_3_BAND_2,
123 C2Config::LEVEL_APV_3_1_BAND_2,
124 C2Config::LEVEL_APV_4_BAND_2,
125 C2Config::LEVEL_APV_4_1_BAND_2,
126 C2Config::LEVEL_APV_5_BAND_2,
127 C2Config::LEVEL_APV_5_1_BAND_2,
128 C2Config::LEVEL_APV_6_BAND_2,
129 C2Config::LEVEL_APV_6_1_BAND_2,
130 C2Config::LEVEL_APV_7_BAND_2,
131 C2Config::LEVEL_APV_7_1_BAND_2,
132 C2Config::LEVEL_APV_1_BAND_3,
133 C2Config::LEVEL_APV_1_1_BAND_3,
134 C2Config::LEVEL_APV_2_BAND_3,
135 C2Config::LEVEL_APV_2_1_BAND_3,
136 C2Config::LEVEL_APV_3_BAND_3,
137 C2Config::LEVEL_APV_3_1_BAND_3,
138 C2Config::LEVEL_APV_4_BAND_3,
139 C2Config::LEVEL_APV_4_1_BAND_3,
140 C2Config::LEVEL_APV_5_BAND_3,
141 C2Config::LEVEL_APV_5_1_BAND_3,
142 C2Config::LEVEL_APV_6_BAND_3,
143 C2Config::LEVEL_APV_6_1_BAND_3,
144 C2Config::LEVEL_APV_7_BAND_3,
145 C2Config::LEVEL_APV_7_1_BAND_3,
146 })})
147 .withSetter(ProfileLevelSetter, mSize)
148 .build());
149
150 mHdr10PlusInfoInput = C2StreamHdr10PlusInfo::input::AllocShared(0);
151 addParameter(DefineParam(mHdr10PlusInfoInput, C2_PARAMKEY_INPUT_HDR10_PLUS_INFO)
152 .withDefault(mHdr10PlusInfoInput)
153 .withFields({
154 C2F(mHdr10PlusInfoInput, m.value).any(),
155 })
156 .withSetter(Hdr10PlusInfoInputSetter)
157 .build());
158
159 mHdr10PlusInfoOutput = C2StreamHdr10PlusInfo::output::AllocShared(0);
160 addParameter(DefineParam(mHdr10PlusInfoOutput, C2_PARAMKEY_OUTPUT_HDR10_PLUS_INFO)
161 .withDefault(mHdr10PlusInfoOutput)
162 .withFields({
163 C2F(mHdr10PlusInfoOutput, m.value).any(),
164 })
165 .withSetter(Hdr10PlusInfoOutputSetter)
166 .build());
167
168 // default static info
169 C2HdrStaticMetadataStruct defaultStaticInfo{};
170 helper->addStructDescriptors<C2MasteringDisplayColorVolumeStruct, C2ColorXyStruct>();
171 addParameter(
172 DefineParam(mHdrStaticInfo, C2_PARAMKEY_HDR_STATIC_INFO)
173 .withDefault(new C2StreamHdrStaticInfo::output(0u, defaultStaticInfo))
174 .withFields({C2F(mHdrStaticInfo, mastering.red.x).inRange(0, 1),
175 C2F(mHdrStaticInfo, mastering.red.y).inRange(0, 1),
176 C2F(mHdrStaticInfo, mastering.green.x).inRange(0, 1),
177 C2F(mHdrStaticInfo, mastering.green.y).inRange(0, 1),
178 C2F(mHdrStaticInfo, mastering.blue.x).inRange(0, 1),
179 C2F(mHdrStaticInfo, mastering.blue.y).inRange(0, 1),
180 C2F(mHdrStaticInfo, mastering.white.x).inRange(0, 1),
181 C2F(mHdrStaticInfo, mastering.white.x).inRange(0, 1),
182 C2F(mHdrStaticInfo, mastering.maxLuminance).inRange(0, 65535),
183 C2F(mHdrStaticInfo, mastering.minLuminance).inRange(0, 6.5535),
184 C2F(mHdrStaticInfo, maxCll).inRange(0, 0XFFFF),
185 C2F(mHdrStaticInfo, maxFall).inRange(0, 0XFFFF)})
186 .withSetter(HdrStaticInfoSetter)
187 .build());
188
189 addParameter(DefineParam(mMaxSize, C2_PARAMKEY_MAX_PICTURE_SIZE)
190 .withDefault(new C2StreamMaxPictureSizeTuning::output(0u, 320, 240))
191 .withFields({
192 C2F(mSize, width).inRange(2, 4096, 2),
193 C2F(mSize, height).inRange(2, 4096, 2),
194 })
195 .withSetter(MaxPictureSizeSetter, mSize)
196 .build());
197
198 addParameter(
199 DefineParam(mMaxInputSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
200 .withDefault(new C2StreamMaxBufferSizeInfo::input(0u, kMinInputBufferSize))
201 .withFields({
202 C2F(mMaxInputSize, value).any(),
203 })
204 .calculatedAs(MaxInputSizeSetter, mMaxSize)
205 .build());
206
207 C2ChromaOffsetStruct locations[1] = {C2ChromaOffsetStruct::ITU_YUV_420_0()};
208 std::shared_ptr<C2StreamColorInfo::output> defaultColorInfo =
209 C2StreamColorInfo::output::AllocShared(1u, 0u, 8u /* bitDepth */, C2Color::YUV_420);
210 memcpy(defaultColorInfo->m.locations, locations, sizeof(locations));
211
212 defaultColorInfo = C2StreamColorInfo::output::AllocShared(
213 {C2ChromaOffsetStruct::ITU_YUV_420_0()}, 0u, 8u /* bitDepth */, C2Color::YUV_420);
214 helper->addStructDescriptors<C2ChromaOffsetStruct>();
215 addParameter(DefineParam(mColorInfo, C2_PARAMKEY_CODED_COLOR_INFO)
216 .withConstValue(defaultColorInfo)
217 .build());
218
219 addParameter(DefineParam(mDefaultColorAspects, C2_PARAMKEY_DEFAULT_COLOR_ASPECTS)
220 .withDefault(new C2StreamColorAspectsTuning::output(
221 0u, C2Color::RANGE_UNSPECIFIED, C2Color::PRIMARIES_UNSPECIFIED,
222 C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
223 .withFields({C2F(mDefaultColorAspects, range)
224 .inRange(C2Color::RANGE_UNSPECIFIED,
225 C2Color::RANGE_OTHER),
226 C2F(mDefaultColorAspects, primaries)
227 .inRange(C2Color::PRIMARIES_UNSPECIFIED,
228 C2Color::PRIMARIES_OTHER),
229 C2F(mDefaultColorAspects, transfer)
230 .inRange(C2Color::TRANSFER_UNSPECIFIED,
231 C2Color::TRANSFER_OTHER),
232 C2F(mDefaultColorAspects, matrix)
233 .inRange(C2Color::MATRIX_UNSPECIFIED,
234 C2Color::MATRIX_OTHER)})
235 .withSetter(DefaultColorAspectsSetter)
236 .build());
237
238 addParameter(DefineParam(mCodedColorAspects, C2_PARAMKEY_VUI_COLOR_ASPECTS)
239 .withDefault(new C2StreamColorAspectsInfo::input(
240 0u, C2Color::RANGE_LIMITED, C2Color::PRIMARIES_UNSPECIFIED,
241 C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
242 .withFields({C2F(mCodedColorAspects, range)
243 .inRange(C2Color::RANGE_UNSPECIFIED,
244 C2Color::RANGE_OTHER),
245 C2F(mCodedColorAspects, primaries)
246 .inRange(C2Color::PRIMARIES_UNSPECIFIED,
247 C2Color::PRIMARIES_OTHER),
248 C2F(mCodedColorAspects, transfer)
249 .inRange(C2Color::TRANSFER_UNSPECIFIED,
250 C2Color::TRANSFER_OTHER),
251 C2F(mCodedColorAspects, matrix)
252 .inRange(C2Color::MATRIX_UNSPECIFIED,
253 C2Color::MATRIX_OTHER)})
254 .withSetter(CodedColorAspectsSetter)
255 .build());
256
257 addParameter(
258 DefineParam(mColorAspects, C2_PARAMKEY_COLOR_ASPECTS)
259 .withDefault(new C2StreamColorAspectsInfo::output(
260 0u, C2Color::RANGE_UNSPECIFIED, C2Color::PRIMARIES_UNSPECIFIED,
261 C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
262 .withFields(
263 {C2F(mColorAspects, range)
264 .inRange(C2Color::RANGE_UNSPECIFIED, C2Color::RANGE_OTHER),
265 C2F(mColorAspects, primaries)
266 .inRange(C2Color::PRIMARIES_UNSPECIFIED,
267 C2Color::PRIMARIES_OTHER),
268 C2F(mColorAspects, transfer)
269 .inRange(C2Color::TRANSFER_UNSPECIFIED,
270 C2Color::TRANSFER_OTHER),
271 C2F(mColorAspects, matrix)
272 .inRange(C2Color::MATRIX_UNSPECIFIED,
273 C2Color::MATRIX_OTHER)})
274 .withSetter(ColorAspectsSetter, mDefaultColorAspects, mCodedColorAspects)
275 .build());
276
277 // TODO: support more formats?
278 std::vector<uint32_t> pixelFormats = {HAL_PIXEL_FORMAT_YCBCR_420_888};
279 if (isHalPixelFormatSupported((AHardwareBuffer_Format)HAL_PIXEL_FORMAT_YCBCR_P010)) {
280 pixelFormats.push_back(HAL_PIXEL_FORMAT_YCBCR_P010);
281 }
282 // If color format surface isn't added to supported formats, there is no way to know
283 // when the color-format is configured to surface. This is necessary to be able to
284 // choose 10-bit format while decoding 10-bit clips in surface mode.
285 pixelFormats.push_back(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED);
286 addParameter(DefineParam(mPixelFormat, C2_PARAMKEY_PIXEL_FORMAT)
287 .withDefault(new C2StreamPixelFormatInfo::output(
288 0u, HAL_PIXEL_FORMAT_YCBCR_420_888))
289 .withFields({C2F(mPixelFormat, value).oneOf(pixelFormats)})
290 .withSetter((Setter<decltype(*mPixelFormat)>::StrictValueWithNoDeps))
291 .build());
292 }
293
294 static C2R SizeSetter(bool mayBlock, const C2P<C2StreamPictureSizeInfo::output>& oldMe,
295 C2P<C2StreamPictureSizeInfo::output>& me) {
296 (void)mayBlock;
297 ALOGV("%s - %d x %d", __FUNCTION__, me.v.width, me.v.height);
298 C2R res = C2R::Ok();
299 if (!me.F(me.v.width).supportsAtAll(me.v.width)) {
300 res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.width)));
301 me.set().width = oldMe.v.width;
302 }
303 if (!me.F(me.v.height).supportsAtAll(me.v.height)) {
304 res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.height)));
305 me.set().height = oldMe.v.height;
306 }
307 return res;
308 }
309
310 static C2R MaxPictureSizeSetter(bool mayBlock, C2P<C2StreamMaxPictureSizeTuning::output>& me,
311 const C2P<C2StreamPictureSizeInfo::output>& size) {
312 (void)mayBlock;
313 ALOGV("%s - %d x %d", __FUNCTION__, me.v.width, me.v.height);
314 // TODO: get max width/height from the size's field helpers vs.
315 // hardcoding
316 me.set().width = c2_min(c2_max(me.v.width, size.v.width), 4096u);
317 me.set().height = c2_min(c2_max(me.v.height, size.v.height), 4096u);
318 return C2R::Ok();
319 }
320
321 static C2R MaxInputSizeSetter(bool mayBlock, C2P<C2StreamMaxBufferSizeInfo::input>& me,
322 const C2P<C2StreamMaxPictureSizeTuning::output>& maxSize) {
323 (void)mayBlock;
324 ALOGV("%s", __FUNCTION__);
325 // assume compression ratio of 2, but enforce a floor
326 me.set().value =
327 c2_max((((maxSize.v.width + 63) / 64) * ((maxSize.v.height + 63) / 64) * 3072),
328 kMinInputBufferSize);
329 return C2R::Ok();
330 }
331
332 static C2R DefaultColorAspectsSetter(bool mayBlock,
333 C2P<C2StreamColorAspectsTuning::output>& me) {
334 (void)mayBlock;
335 ALOGV("%s - range: %u, primary: %u, transfer: %u, matrix: %u", __FUNCTION__, me.v.range,
336 me.v.primaries, me.v.transfer, me.v.matrix);
337 if (me.v.range > C2Color::RANGE_OTHER) {
338 me.set().range = C2Color::RANGE_OTHER;
339 }
340 if (me.v.primaries > C2Color::PRIMARIES_OTHER) {
341 me.set().primaries = C2Color::PRIMARIES_OTHER;
342 }
343 if (me.v.transfer > C2Color::TRANSFER_OTHER) {
344 me.set().transfer = C2Color::TRANSFER_OTHER;
345 }
346 if (me.v.matrix > C2Color::MATRIX_OTHER) {
347 me.set().matrix = C2Color::MATRIX_OTHER;
348 }
349 return C2R::Ok();
350 }
351
352 static C2R CodedColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::input>& me) {
353 (void)mayBlock;
354 ALOGV("%s - range: %u, primaries: %u, transfer: %u, matrix: %u", __func__, me.v.range,
355 me.v.primaries, me.v.transfer, me.v.matrix);
356 if (me.v.range > C2Color::RANGE_OTHER) {
357 me.set().range = C2Color::RANGE_OTHER;
358 }
359 if (me.v.primaries > C2Color::PRIMARIES_OTHER) {
360 me.set().primaries = C2Color::PRIMARIES_OTHER;
361 }
362 if (me.v.transfer > C2Color::TRANSFER_OTHER) {
363 me.set().transfer = C2Color::TRANSFER_OTHER;
364 }
365 if (me.v.matrix > C2Color::MATRIX_OTHER) {
366 me.set().matrix = C2Color::MATRIX_OTHER;
367 }
368 return C2R::Ok();
369 }
370
371 static C2R ColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::output>& me,
372 const C2P<C2StreamColorAspectsTuning::output>& def,
373 const C2P<C2StreamColorAspectsInfo::input>& coded) {
374 (void)mayBlock;
375 ALOGV("%s", __FUNCTION__);
376 // take default values for all unspecified fields, and coded values for specified ones
377 me.set().range = coded.v.range == RANGE_UNSPECIFIED ? def.v.range : coded.v.range;
378 me.set().primaries =
379 coded.v.primaries == PRIMARIES_UNSPECIFIED ? def.v.primaries : coded.v.primaries;
380 me.set().transfer =
381 coded.v.transfer == TRANSFER_UNSPECIFIED ? def.v.transfer : coded.v.transfer;
382 me.set().matrix = coded.v.matrix == MATRIX_UNSPECIFIED ? def.v.matrix : coded.v.matrix;
383 ALOGV("%s - me.v.range = %u, me.v.primaries = %u, me.v.transfer = %u, me.v.matrix = %u",
384 __func__, me.v.range, me.v.primaries, me.v.transfer, me.v.matrix);
385 return C2R::Ok();
386 }
387
388 static C2R ProfileLevelSetter(bool mayBlock, C2P<C2StreamProfileLevelInfo::input>& me,
389 const C2P<C2StreamPictureSizeInfo::output>& size) {
390 (void)mayBlock;
391 ALOGV("%s", __FUNCTION__);
392 (void)size;
393 (void)me; // TODO: validate
394 return C2R::Ok();
395 }
396
397 std::shared_ptr<C2StreamColorAspectsTuning::output> getDefaultColorAspects_l() {
398 ALOGV("%s - mDefaultColorAspects: %u", __FUNCTION__, mDefaultColorAspects->primaries);
399 return mDefaultColorAspects;
400 }
401
402 std::shared_ptr<C2StreamColorAspectsInfo::output> getColorAspects_l() {
403 ALOGV("%s - mColorAspects: %u", __FUNCTION__, mColorAspects->primaries);
404 return mColorAspects;
405 }
406
407 static C2R Hdr10PlusInfoInputSetter(bool mayBlock, C2P<C2StreamHdr10PlusInfo::input>& me) {
408 (void)mayBlock;
409 ALOGV("%s", __FUNCTION__);
410 (void)me; // TODO: validate
411 return C2R::Ok();
412 }
413
414 static C2R Hdr10PlusInfoOutputSetter(bool mayBlock, C2P<C2StreamHdr10PlusInfo::output>& me) {
415 (void)mayBlock;
416 ALOGV("%s", __FUNCTION__);
417 (void)me; // TODO: validate
418 return C2R::Ok();
419 }
420
421 // unsafe getters
422 std::shared_ptr<C2StreamPixelFormatInfo::output> getPixelFormat_l() const {
423 return mPixelFormat;
424 }
425
426 static C2R HdrStaticInfoSetter(bool mayBlock, C2P<C2StreamHdrStaticInfo::output>& me) {
427 (void)mayBlock;
428 ALOGV("%s", __FUNCTION__);
429 if (me.v.mastering.red.x > 1) {
430 me.set().mastering.red.x = 1;
431 }
432 if (me.v.mastering.red.y > 1) {
433 me.set().mastering.red.y = 1;
434 }
435 if (me.v.mastering.green.x > 1) {
436 me.set().mastering.green.x = 1;
437 }
438 if (me.v.mastering.green.y > 1) {
439 me.set().mastering.green.y = 1;
440 }
441 if (me.v.mastering.blue.x > 1) {
442 me.set().mastering.blue.x = 1;
443 }
444 if (me.v.mastering.blue.y > 1) {
445 me.set().mastering.blue.y = 1;
446 }
447 if (me.v.mastering.white.x > 1) {
448 me.set().mastering.white.x = 1;
449 }
450 if (me.v.mastering.white.y > 1) {
451 me.set().mastering.white.y = 1;
452 }
453 if (me.v.mastering.maxLuminance > 65535.0) {
454 me.set().mastering.maxLuminance = 65535.0;
455 }
456 if (me.v.mastering.minLuminance > 6.5535) {
457 me.set().mastering.minLuminance = 6.5535;
458 }
459 if (me.v.maxCll > 65535.0) {
460 me.set().maxCll = 65535.0;
461 }
462 if (me.v.maxFall > 65535.0) {
463 me.set().maxFall = 65535.0;
464 }
465 return C2R::Ok();
466 }
467
468 private:
469 std::shared_ptr<C2StreamProfileLevelInfo::input> mProfileLevel;
470 std::shared_ptr<C2StreamPictureSizeInfo::output> mSize;
471 std::shared_ptr<C2StreamMaxPictureSizeTuning::output> mMaxSize;
472 std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mMaxInputSize;
473 std::shared_ptr<C2StreamColorInfo::output> mColorInfo;
474 std::shared_ptr<C2StreamPixelFormatInfo::output> mPixelFormat;
475 std::shared_ptr<C2StreamColorAspectsTuning::output> mDefaultColorAspects;
476 std::shared_ptr<C2StreamColorAspectsInfo::input> mCodedColorAspects;
477 std::shared_ptr<C2StreamColorAspectsInfo::output> mColorAspects;
478 std::shared_ptr<C2StreamHdr10PlusInfo::input> mHdr10PlusInfoInput;
479 std::shared_ptr<C2StreamHdr10PlusInfo::output> mHdr10PlusInfoOutput;
480 std::shared_ptr<C2StreamHdrStaticInfo::output> mHdrStaticInfo;
481};
482
483static void ivd_aligned_free(void* ctxt, void* mem) {
484 (void)ctxt;
485 free(mem);
486}
487
488C2SoftApvDec::C2SoftApvDec(const char* name, c2_node_id_t id,
489 const std::shared_ptr<IntfImpl>& intfImpl)
490 : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
491 mIntf(intfImpl),
492 mDecHandle(nullptr),
493 mOutBufferFlush(nullptr),
494 mIvColorformat(IV_YUV_420P),
495 mOutputDelay(kDefaultOutputDelay),
496 mWidth(320),
497 mHeight(240),
498 mHeaderDecoded(false),
499 mOutIndex(0u) {
500 oapvdHandle = NULL;
501 oapvmHandle = NULL;
502 outputCsp = OUTPUT_CSP_NATIVE;
503}
504
505C2SoftApvDec::~C2SoftApvDec() {
506 onRelease();
507}
508
509c2_status_t C2SoftApvDec::onInit() {
510 ALOGV("%s", __FUNCTION__);
511 status_t err = initDecoder();
512 return err == OK ? C2_OK : C2_CORRUPTED;
513}
514
515c2_status_t C2SoftApvDec::onStop() {
516 ALOGV("%s", __FUNCTION__);
517 if (OK != resetDecoder()) return C2_CORRUPTED;
518 resetPlugin();
519 return C2_OK;
520}
521
522void C2SoftApvDec::onReset() {
523 ALOGV("%s", __FUNCTION__);
524 (void)onStop();
525}
526
527status_t C2SoftApvDec::deleteDecoder() {
528 ALOGV("%s", __FUNCTION__);
529 if (oapvdHandle) {
530 oapvd_delete(oapvdHandle);
531 oapvdHandle = NULL;
532 }
533 if (oapvmHandle) {
534 oapvm_delete(oapvmHandle);
535 oapvmHandle = NULL;
536 }
537 for (int i = 0; i < ofrms.num_frms; i++) {
538 if (ofrms.frm[i].imgb != NULL) {
539 ofrms.frm[i].imgb->release(ofrms.frm[i].imgb);
540 ofrms.frm[i].imgb = NULL;
541 }
542 }
543 return OK;
544}
545
546void C2SoftApvDec::onRelease() {
547 ALOGV("%s", __FUNCTION__);
548 (void)deleteDecoder();
549 if (mOutBufferFlush) {
550 ivd_aligned_free(nullptr, mOutBufferFlush);
551 mOutBufferFlush = nullptr;
552 }
553 if (mOutBlock) {
554 mOutBlock.reset();
555 }
556}
557
558c2_status_t C2SoftApvDec::onFlush_sm() {
559 ALOGV("%s", __FUNCTION__);
560 mSignalledError = false;
561 mSignalledOutputEos = false;
562 return C2_OK;
563}
564
565status_t C2SoftApvDec::createDecoder() {
566 ALOGV("%s", __FUNCTION__);
567 return OK;
568}
569
570status_t C2SoftApvDec::initDecoder() {
571 int ret;
572 mSignalledError = false;
573 mSignalledOutputEos = false;
574
575 mHalPixelFormat = HAL_PIXEL_FORMAT_YV12;
576 {
577 IntfImpl::Lock lock = mIntf->lock();
578 mPixelFormatInfo = mIntf->getPixelFormat_l();
579 ALOGW("Hal pixel format = %d", mPixelFormatInfo->value);
580 }
581 memset(&cdesc, 0, sizeof(oapvd_cdesc_t));
582
583 cdesc.threads = 1; // default
584 oapvdHandle = oapvd_create(&cdesc, &ret);
585 if (oapvdHandle == NULL) {
586 ALOGE("ERROR: cannot create APV decoder (err=%d)\n", ret);
587 return C2_NO_INIT;
588 }
589
590 memset(&ofrms, 0, sizeof(oapv_frms_t));
591
592 oapvmHandle = oapvm_create(&ret);
593 if (OAPV_FAILED(ret)) {
594 ALOGE("oapvm create failed");
595 oapvd_delete(oapvdHandle);
596 oapvdHandle = NULL;
597 return C2_NO_INIT;
598 }
599
600 ALOGV("oapvd init done");
601 return OK;
602}
603
604status_t C2SoftApvDec::setFlushMode() {
605 ALOGV("%s", __FUNCTION__);
606 return OK;
607}
608
609status_t C2SoftApvDec::resetDecoder() {
610 ALOGV("%s", __FUNCTION__);
611 return OK;
612}
613
614void C2SoftApvDec::resetPlugin() {
615 ALOGV("%s", __FUNCTION__);
616 mSignalledOutputEos = false;
617 if (mOutBlock) {
618 mOutBlock.reset();
619 }
620}
621
622void fillEmptyWork(const std::unique_ptr<C2Work>& work) {
623 uint32_t flags = 0;
624 if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
625 flags |= C2FrameData::FLAG_END_OF_STREAM;
626 ALOGV("signalling eos");
627 }
628 work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
629 work->worklets.front()->output.buffers.clear();
630 work->worklets.front()->output.ordinal = work->input.ordinal;
631 work->workletsProcessed = 1u;
632}
633
634void C2SoftApvDec::finishWork(uint64_t index, const std::unique_ptr<C2Work>& work,
635 const std::shared_ptr<C2GraphicBlock>& block) {
636 std::shared_ptr<C2Buffer> buffer = createGraphicBuffer(block, C2Rect(mWidth, mHeight));
637
638 {
639 IntfImpl::Lock lock = mIntf->lock();
640 buffer->setInfo(mIntf->getColorAspects_l());
641 }
642
643 class FillWork {
644 public:
645 FillWork(uint32_t flags, C2WorkOrdinalStruct ordinal,
646 const std::shared_ptr<C2Buffer>& buffer)
647 : mFlags(flags), mOrdinal(ordinal), mBuffer(buffer) {}
648 ~FillWork() = default;
649
650 void operator()(const std::unique_ptr<C2Work>& work) {
651 work->worklets.front()->output.flags = (C2FrameData::flags_t)mFlags;
652 work->worklets.front()->output.buffers.clear();
653 work->worklets.front()->output.ordinal = mOrdinal;
654 work->workletsProcessed = 1u;
655 work->result = C2_OK;
656 if (mBuffer) {
657 work->worklets.front()->output.buffers.push_back(mBuffer);
658 }
659 ALOGV("timestamp = %lld, index = %lld, w/%s buffer", mOrdinal.timestamp.peekll(),
660 mOrdinal.frameIndex.peekll(), mBuffer ? "" : "o");
661 }
662
663 private:
664 const uint32_t mFlags;
665 const C2WorkOrdinalStruct mOrdinal;
666 const std::shared_ptr<C2Buffer> mBuffer;
667 };
668
669 auto fillWork = [buffer](const std::unique_ptr<C2Work>& work) {
670 work->worklets.front()->output.flags = (C2FrameData::flags_t)0;
671 work->worklets.front()->output.buffers.clear();
672 work->worklets.front()->output.buffers.push_back(buffer);
673 work->worklets.front()->output.ordinal = work->input.ordinal;
674 work->workletsProcessed = 1u;
675 };
676
677 if (work && c2_cntr64_t(index) == work->input.ordinal.frameIndex) {
678 bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
679 // TODO: Check if cloneAndSend can be avoided by tracking number of frames remaining
680 if (eos) {
681 if (buffer) {
682 mOutIndex = index;
683 C2WorkOrdinalStruct outOrdinal = work->input.ordinal;
684 cloneAndSend(mOutIndex, work,
685 FillWork(C2FrameData::FLAG_INCOMPLETE, outOrdinal, buffer));
686 buffer.reset();
687 }
688 } else {
689 fillWork(work);
690 }
691 } else {
692 finish(index, fillWork);
693 }
694}
695
696static void copyBufferFromYUV420ToYV12(uint8_t* dstY, uint8_t* dstU, uint8_t* dstV,
697 const uint8_t* srcY, const uint8_t* srcU,
698 const uint8_t* srcV, size_t srcYStride, size_t srcUStride,
699 size_t srcVStride, size_t dstYStride, size_t dstUStride,
700 size_t dstVStride, uint32_t width, uint32_t height) {
701 for (size_t i = 0; i < height; ++i) {
702 memcpy(dstY, srcY, width);
703 srcY += srcYStride;
704 dstY += dstYStride;
705 }
706
707 for (size_t i = 0; i < height / 2; ++i) {
708 memcpy(dstU, srcU, width / 2);
709 memcpy(dstV, srcV, width / 2);
710 dstU += dstUStride;
711 srcU += srcUStride;
712 dstV += dstVStride;
713 srcV += srcVStride;
714 }
715}
716
717static void copyBufferFromYUV422ToYV12(uint8_t* dstY, uint8_t* dstU, uint8_t* dstV,
718 const uint8_t* srcY, const uint8_t* srcU,
719 const uint8_t* srcV, size_t srcYStride, size_t srcUStride,
720 size_t srcVStride, size_t dstYStride, size_t dstUStride,
721 size_t dstVStride, uint32_t width, uint32_t height) {
722 for (size_t i = 0; i < height; ++i) {
723 memcpy(dstY, srcY, width);
724 srcY += srcYStride;
725 dstY += dstYStride;
726 }
727
728 for (size_t i = 0; i < height / 2; ++i) {
729 memcpy(dstU, srcU, width / 2);
730 memcpy(dstV, srcV, width / 2);
731 dstU += dstUStride;
732 srcU += srcUStride * 2;
733 dstV += dstVStride;
734 srcV += srcVStride * 2;
735 }
736}
737
738static void copyBufferFromYUV42010bitToP010(uint16_t* dstY, uint16_t* dstUV, const uint16_t* srcY,
739 const uint16_t* srcU, const uint16_t* srcV,
740 size_t srcYStride, size_t srcUStride, size_t srcVStride,
741 size_t dstYStride, size_t dstUVStride, size_t width,
742 size_t height) {
743 for (size_t y = 0; y < height; ++y) {
744 for (size_t x = 0; x < width; ++x) {
745 dstY[x] = srcY[x] << 6;
746 }
747 srcY += srcYStride;
748 dstY += dstYStride;
749 }
750
751 for (size_t y = 0; y < height / 2; ++y) {
752 for (size_t x = 0; x < width / 2; ++x) {
753 dstUV[2 * x] = srcU[x] << 6;
754 dstUV[2 * x + 1] = srcV[x] << 6;
755 }
756 srcU += srcUStride;
757 srcV += srcVStride;
758 dstUV += dstUVStride;
759 }
760}
761
762static void copyBufferFromYUV42210bitToP010(uint16_t* dstY, uint16_t* dstUV, const uint16_t* srcY,
763 const uint16_t* srcU, const uint16_t* srcV,
764 size_t srcYStride, size_t srcUStride, size_t srcVStride,
765 size_t dstYStride, size_t dstUVStride, size_t width,
766 size_t height) {
767 for (size_t y = 0; y < height; ++y) {
768 for (size_t x = 0; x < width; ++x) {
769 dstY[x] = srcY[x] << 6;
770 }
771 srcY += srcYStride;
772 dstY += dstYStride;
773 }
774
775 for (size_t y = 0; y < height / 2; ++y) {
776 for (size_t x = 0; x < width / 2; ++x) {
777 dstUV[2 * x] = srcU[x] << 6;
778 dstUV[2 * x + 1] = srcV[x] << 6;
779 }
780 srcU += srcUStride * 2;
781 srcV += srcVStride * 2;
782 dstUV += dstUVStride;
783 }
784}
785
786static void copyBufferFromP210ToP010(uint16_t* dstY, uint16_t* dstUV, const uint16_t* srcY,
787 const uint16_t* srcUV, size_t srcYStride, size_t srcUVStride,
788 size_t dstYStride, size_t dstUVStride, size_t width,
789 size_t height) {
790 for (size_t y = 0; y < height; ++y) {
791 memcpy(dstY, srcY, width * sizeof(uint16_t));
792 srcY += srcYStride;
793 dstY += dstYStride;
794 }
795
796 for (size_t y = 0; y < height / 2; ++y) {
797 memcpy(dstUV, srcUV, width * 2);
798 srcUV += srcUVStride * 2;
799 dstUV += dstUVStride;
800 }
801}
802
803static void copyBufferFromYUV42010bitToYV12(uint8_t* dstY, uint8_t* dstU, uint8_t* dstV,
804 const uint16_t* srcY, const uint16_t* srcU,
805 const uint16_t* srcV, size_t srcYStride,
806 size_t srcUStride, size_t srcVStride, size_t dstYStride,
807 size_t dstUStride, size_t dstVStride, uint32_t width,
808 uint32_t height) {
809 for (size_t i = 0; i < height; ++i) {
810 for (size_t j = 0; j < width; ++j) {
811 dstY[i * dstYStride + j] = (srcY[i * srcYStride + j] >> 2) & 0xFF;
812 }
813 }
814
815 for (size_t i = 0; i < height / 2; ++i) {
816 for (size_t j = 0; j < width / 2; ++j) {
817 dstU[i * dstUStride + j] = (srcU[i * srcUStride + j] >> 2) & 0xFF;
818 }
819 }
820
821 for (size_t i = 0; i < height / 2; ++i) {
822 for (size_t j = 0; j < width / 2; ++j) {
823 dstV[i * dstVStride + j] = (srcV[i * srcVStride + j] >> 2) & 0xFF;
824 }
825 }
826}
827
828static void copyBufferFromYUV42210bitToYV12(uint8_t* dstY, uint8_t* dstU, uint8_t* dstV,
829 const uint16_t* srcY, const uint16_t* srcU,
830 const uint16_t* srcV, size_t srcYStride,
831 size_t srcUStride, size_t srcVStride, size_t dstYStride,
832 size_t dstUStride, size_t dstVStride, uint32_t width,
833 uint32_t height) {
834 for (size_t i = 0; i < height; ++i) {
835 for (size_t j = 0; j < width; ++j) {
836 dstY[i * dstYStride + j] = (srcY[i * srcYStride + j] >> 2) & 0xFF;
837 }
838 }
839
840 for (size_t i = 0; i < height / 2; ++i) {
841 for (size_t j = 0; j < width / 2; ++j) {
842 dstU[i * dstUStride + j] = (srcU[i * srcUStride * 2 + j] >> 2) & 0xFF;
843 }
844 }
845
846 for (size_t i = 0; i < height / 2; ++i) {
847 for (size_t j = 0; j < width / 2; ++j) {
848 dstV[i * dstVStride + j] = (srcV[i * srcVStride * 2 + j] >> 2) & 0xFF;
849 }
850 }
851}
852
853static void copyBufferFromP210ToYV12(uint8_t* dstY, uint8_t* dstU, uint8_t* dstV,
854 const uint16_t* srcY, const uint16_t* srcUV, size_t srcYStride,
855 size_t srcUVStride, size_t dstYStride, size_t dstUStride,
856 size_t dstVStride, size_t width, size_t height) {
857 for (size_t i = 0; i < height; ++i) {
858 for (size_t j = 0; j < width; ++j) {
859 dstY[i * dstYStride + j] = (srcY[i * srcYStride + j] >> 8) & 0xFF;
860 }
861 }
862
863 for (size_t i = 0; i < height / 2; ++i) {
864 for (size_t j = 0; j < width / 2; ++j) {
865 dstV[i * dstVStride + j] = (srcUV[i * srcUVStride * 2 + j * 2] >> 8) & 0xFF;
866 dstU[i * dstUStride + j] = (srcUV[i * srcUVStride * 2 + j * 2 + 1] >> 8) & 0xFF;
867 }
868 }
869}
870
871void C2SoftApvDec::process(const std::unique_ptr<C2Work>& work,
872 const std::shared_ptr<C2BlockPool>& pool) {
873 // Initialize output work
874 work->result = C2_OK;
875 work->workletsProcessed = 0u;
876 work->worklets.front()->output.configUpdate.clear();
877 work->worklets.front()->output.flags = work->input.flags;
878 if (mSignalledError || mSignalledOutputEos) {
879 work->result = C2_BAD_VALUE;
880 return;
881 }
882
883 int ret = 0;
884 size_t inOffset = 0u;
885 size_t inSize = 0u;
886 C2ReadView rView = mDummyReadView;
887 if (!work->input.buffers.empty()) {
888 rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
889 inSize = rView.capacity();
890 if (inSize && rView.error()) {
891 ALOGE("read view map failed %d", rView.error());
892 work->result = C2_CORRUPTED;
893 return;
894 }
895 }
896
897 bool codecConfig = ((work->input.flags & C2FrameData::FLAG_CODEC_CONFIG) != 0);
898 bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
899
900 ALOGV("in buffer attr. size %zu timestamp %llu frameindex %d, flags %x", inSize,
901 work->input.ordinal.timestamp.peekull(), (int)work->input.ordinal.frameIndex.peeku(),
902 work->input.flags);
903
904 if (codecConfig) {
905 fillEmptyWork(work);
906 return;
907 }
908
909 if (inSize > 0) {
910 uint8_t* bitstream = const_cast<uint8_t*>(rView.data() + inOffset);
911 oapv_au_info_t aui;
912 oapv_bitb_t bitb;
913 bitb.addr = bitstream + 4; // skip au
914 bitb.ssize = inSize - 4;
915
916 if (OAPV_FAILED(oapvd_info(bitb.addr, bitb.ssize, &aui))) {
917 ALOGE("cannot get information from bitstream");
918 return;
919 }
920
921 /* create decoding frame buffers */
922 ofrms.num_frms = aui.num_frms;
923 if (ofrms.num_frms <= 0) {
924 ALOGE("Parse error - no output frame(%d)", ofrms.num_frms);
925 fillEmptyWork(work);
926 return;
927 }
928 for (int i = 0; i < ofrms.num_frms; i++) {
929 oapv_frm_info_t* finfo = &aui.frm_info[FRM_IDX];
930 oapv_frm_t* frm = &ofrms.frm[i];
931
932 if (mWidth != finfo->w || mHeight != finfo->w) {
933 mWidth = finfo->w;
934 mHeight = finfo->h;
935 }
936
937 if (frm->imgb != NULL && (frm->imgb->w[0] != finfo->w || frm->imgb->h[0] != finfo->h)) {
938 frm->imgb->release(frm->imgb);
939 frm->imgb = NULL;
940 }
941
942 if (frm->imgb == NULL) {
943 if (outputCsp == OUTPUT_CSP_P210) {
944 frm->imgb = imgb_create(finfo->w, finfo->h, OAPV_CS_P210);
945 } else {
946 frm->imgb = imgb_create(finfo->w, finfo->h, finfo->cs);
947 }
948 if (frm->imgb == NULL) {
949 ALOGE("cannot allocate image buffer (w:%d, h:%d, cs:%d)", finfo->w, finfo->h,
950 finfo->cs);
951 fillEmptyWork(work);
952 return;
953 }
954 }
955 }
956
957 oapvd_stat_t stat;
958 ret = oapvd_decode(oapvdHandle, &bitb, &ofrms, oapvmHandle, &stat);
959 if (bitb.ssize != stat.read) {
960 ALOGW("decode done, input size: %d, processed size: %d", bitb.ssize, stat.read);
961 }
962
963 if (OAPV_FAILED(ret)) {
964 ALOGE("failed to decode bitstream\n");
965 fillEmptyWork(work);
966 return;
967 }
968
969 status_t err = outputBuffer(pool, work);
970 if (err == NOT_ENOUGH_DATA) {
971 if (inSize > 0) {
972 ALOGV("Maybe non-display frame at %lld.", work->input.ordinal.frameIndex.peekll());
973 // send the work back with empty buffer.
974 inSize = 0;
975 }
976 } else if (err != OK) {
977 ALOGD("Error while getting the output frame out");
978 // work->result would be already filled; do fillEmptyWork() below to
979 // send the work back.
980 inSize = 0;
981 }
982 }
983
984 if (eos) {
985 drainInternal(DRAIN_COMPONENT_WITH_EOS, pool, work);
986 mSignalledOutputEos = true;
987 } else if (!inSize) {
988 fillEmptyWork(work);
989 }
990}
991
992status_t C2SoftApvDec::outputBuffer(const std::shared_ptr<C2BlockPool>& pool,
993 const std::unique_ptr<C2Work>& work) {
994 if (!(work && pool)) return BAD_VALUE;
995
996 oapv_imgb_t* imgbOutput;
997 std::shared_ptr<C2GraphicBlock> block;
998
999 if (ofrms.num_frms > 0) {
1000 oapv_frm_t* frm = &ofrms.frm[0];
1001 imgbOutput = frm->imgb;
1002 } else {
1003 ALOGW("No output frames");
1004 return false;
1005 }
1006 bool isMonochrome = OAPV_CS_GET_FORMAT(imgbOutput->cs) == OAPV_CS_YCBCR400;
1007
1008 uint32_t format = HAL_PIXEL_FORMAT_YV12;
1009 std::shared_ptr<C2StreamColorAspectsInfo::output> codedColorAspects;
1010 if (OAPV_CS_GET_BIT_DEPTH(imgbOutput->cs) == 10 &&
1011 mPixelFormatInfo->value != HAL_PIXEL_FORMAT_YCBCR_420_888) {
1012 IntfImpl::Lock lock = mIntf->lock();
1013 codedColorAspects = mIntf->getColorAspects_l();
1014 bool allowRGBA1010102 = false;
1015 if (codedColorAspects->primaries == C2Color::PRIMARIES_BT2020 &&
1016 codedColorAspects->matrix == C2Color::MATRIX_BT2020 &&
1017 codedColorAspects->transfer == C2Color::TRANSFER_ST2084) {
1018 allowRGBA1010102 = true;
1019 }
1020 format = getHalPixelFormatForBitDepth10(allowRGBA1010102);
1021 }
1022
1023 if (mHalPixelFormat != format) {
1024 C2StreamPixelFormatInfo::output pixelFormat(0u, format);
1025 std::vector<std::unique_ptr<C2SettingResult>> failures;
1026 c2_status_t err = mIntf->config({&pixelFormat}, C2_MAY_BLOCK, &failures);
1027 if (err == C2_OK) {
1028 work->worklets.front()->output.configUpdate.push_back(C2Param::Copy(pixelFormat));
1029 } else {
1030 ALOGE("Config update pixelFormat failed");
1031 mSignalledError = true;
1032 work->workletsProcessed = 1u;
1033 work->result = C2_CORRUPTED;
1034 return UNKNOWN_ERROR;
1035 }
1036 mHalPixelFormat = format;
1037 }
1038 ALOGV("mHalPixelFormat: %u, format: %d", mHalPixelFormat, format);
1039
1040 C2MemoryUsage usage = {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE};
1041
1042 // check. align height to 2 times does not work.
1043 c2_status_t err =
1044 pool->fetchGraphicBlock(align(mWidth, 16), align(mHeight, 16), format, usage, &block);
1045
1046 if (err != C2_OK) {
1047 ALOGE("fetchGraphicBlock for Output failed with status %d", err);
1048 work->result = err;
1049 return false;
1050 }
1051
1052 C2GraphicView wView = block->map().get();
1053 if (wView.error()) {
1054 ALOGE("graphic view map failed %d", wView.error());
1055 work->result = C2_CORRUPTED;
1056 return false;
1057 }
1058
1059 ALOGV("provided (%dx%d) required (%dx%d)", block->width(), block->height(), mWidth, mHeight);
1060
1061 uint8_t* dstY = const_cast<uint8_t*>(wView.data()[C2PlanarLayout::PLANE_Y]);
1062 uint8_t* dstU = const_cast<uint8_t*>(wView.data()[C2PlanarLayout::PLANE_U]);
1063 uint8_t* dstV = const_cast<uint8_t*>(wView.data()[C2PlanarLayout::PLANE_V]);
1064
1065 C2PlanarLayout layout = wView.layout();
1066 size_t dstYStride = layout.planes[C2PlanarLayout::PLANE_Y].rowInc;
1067 size_t dstUStride = layout.planes[C2PlanarLayout::PLANE_U].rowInc;
1068 size_t dstVStride = layout.planes[C2PlanarLayout::PLANE_V].rowInc;
1069
1070 if (format == HAL_PIXEL_FORMAT_YCBCR_P010) {
1071 if (OAPV_CS_GET_BIT_DEPTH(imgbOutput->cs) == 10) {
1072 const uint16_t* srcY = (const uint16_t*)imgbOutput->a[0];
1073 const uint16_t* srcU = (const uint16_t*)imgbOutput->a[1];
1074 const uint16_t* srcV = (const uint16_t*)imgbOutput->a[2];
1075 size_t srcYStride = imgbOutput->s[0] / 2;
1076 size_t srcUStride = imgbOutput->s[1] / 2;
1077 size_t srcVStride = imgbOutput->s[2] / 2;
1078 dstYStride /= 2;
1079 dstUStride /= 2;
1080 dstVStride /= 2;
1081 if (OAPV_CS_GET_FORMAT(imgbOutput->cs) == OAPV_CF_YCBCR420) {
1082 ALOGV("OAPV_CS_YUV420 10bit to P010");
1083 copyBufferFromYUV42010bitToP010((uint16_t*)dstY, (uint16_t*)dstU, srcY, srcU, srcV,
1084 srcYStride, srcUStride, srcVStride, dstYStride,
1085 dstUStride, mWidth, mHeight);
1086 } else if (OAPV_CS_GET_FORMAT(imgbOutput->cs) == OAPV_CF_YCBCR422) {
1087 ALOGV("OAPV_CS_YUV422 10bit to P010");
1088 copyBufferFromYUV42210bitToP010((uint16_t*)dstY, (uint16_t*)dstU, srcY, srcU, srcV,
1089 srcYStride, srcUStride, srcVStride, dstYStride,
1090 dstUStride, mWidth, mHeight);
1091 } else if (OAPV_CS_GET_FORMAT(imgbOutput->cs) == OAPV_CF_PLANAR2) {
1092 ALOGV("OAPV_CS_P210 to P010");
1093 copyBufferFromP210ToP010((uint16_t*)dstY, (uint16_t*)dstU, srcY, srcU, srcYStride,
1094 srcUStride, dstYStride, dstUStride, mWidth, mHeight);
1095 } else {
1096 ALOGE("Not supported convert format : %d", OAPV_CS_GET_FORMAT(imgbOutput->cs));
1097 }
1098 } else {
1099 ALOGE("Not supported convder from bd:%d, format: %d(%s), to format: %d(%s)",
1100 OAPV_CS_GET_BIT_DEPTH(imgbOutput->cs), OAPV_CS_GET_FORMAT(imgbOutput->cs),
1101 OAPV_CS_GET_FORMAT(imgbOutput->cs) == OAPV_CF_YCBCR420
1102 ? "YUV420"
1103 : (OAPV_CS_GET_FORMAT(imgbOutput->cs) == OAPV_CF_YCBCR422 ? "YUV422"
1104 : "UNKNOWN"),
1105 format,
1106 format == HAL_PIXEL_FORMAT_YCBCR_P010
1107 ? "P010"
1108 : (format == HAL_PIXEL_FORMAT_YCBCR_420_888
1109 ? "YUV420"
1110 : (format == HAL_PIXEL_FORMAT_YV12 ? "YV12" : "UNKNOWN")));
1111 }
1112 } else { // HAL_PIXEL_FORMAT_YV12
1113 if (OAPV_CS_GET_BIT_DEPTH(imgbOutput->cs) == 10) {
1114 const uint16_t* srcY = (const uint16_t*)imgbOutput->a[0];
1115 const uint16_t* srcV = (const uint16_t*)imgbOutput->a[1];
1116 const uint16_t* srcU = (const uint16_t*)imgbOutput->a[2];
1117 size_t srcYStride = imgbOutput->s[0] / 2;
1118 size_t srcVStride = imgbOutput->s[1] / 2;
1119 size_t srcUStride = imgbOutput->s[2] / 2;
1120 if (OAPV_CS_GET_FORMAT(imgbOutput->cs) == OAPV_CF_YCBCR420) {
1121 ALOGV("OAPV_CS_YUV420 10bit to YV12");
1122 copyBufferFromYUV42010bitToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride,
1123 srcUStride, srcVStride, dstYStride, dstUStride,
1124 dstVStride, mWidth, mHeight);
1125 } else if (OAPV_CS_GET_FORMAT(imgbOutput->cs) == OAPV_CF_YCBCR422) {
1126 ALOGV("OAPV_CS_YUV422 10bit to YV12");
1127 copyBufferFromYUV42210bitToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride,
1128 srcUStride, srcVStride, dstYStride, dstUStride,
1129 dstVStride, mWidth, mHeight);
1130 } else if (OAPV_CS_GET_FORMAT(imgbOutput->cs) == OAPV_CF_PLANAR2) {
1131 ALOGV("OAPV_CS_P210 to YV12");
1132 copyBufferFromP210ToYV12(dstY, dstU, dstV, srcY, srcV, srcYStride, srcVStride,
1133 dstYStride, dstUStride, dstVStride, mWidth, mHeight);
1134 } else {
1135 ALOGE("Not supported convert format : %d", OAPV_CS_GET_FORMAT(imgbOutput->cs));
1136 }
1137 } else if (OAPV_CS_GET_BIT_DEPTH(imgbOutput->cs) == 8) {
1138 const uint8_t* srcY = (const uint8_t*)imgbOutput->a[0];
1139 const uint8_t* srcV = (const uint8_t*)imgbOutput->a[1];
1140 const uint8_t* srcU = (const uint8_t*)imgbOutput->a[2];
1141 size_t srcYStride = imgbOutput->s[0];
1142 size_t srcVStride = imgbOutput->s[1];
1143 size_t srcUStride = imgbOutput->s[2];
1144 if (OAPV_CS_GET_FORMAT(imgbOutput->cs) == OAPV_CF_YCBCR420) {
1145 ALOGV("OAPV_CS_YUV420 to YV12");
1146 copyBufferFromYUV420ToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride,
1147 srcUStride, srcVStride, dstYStride, dstUStride,
1148 dstVStride, mWidth, mHeight);
1149 } else if (OAPV_CS_GET_FORMAT(imgbOutput->cs) == OAPV_CF_YCBCR422) {
1150 ALOGV("OAPV_CS_YUV422 to YV12");
1151 copyBufferFromYUV422ToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride,
1152 srcUStride, srcVStride, dstYStride, dstUStride,
1153 dstVStride, mWidth, mHeight);
1154 } else {
1155 ALOGE("Not supported convert format : %d", OAPV_CS_GET_FORMAT(imgbOutput->cs));
1156 }
1157 } else {
1158 ALOGE("Not supported convert from bd:%d, format: %d(%s), to format: %d(%s)",
1159 OAPV_CS_GET_BIT_DEPTH(imgbOutput->cs), OAPV_CS_GET_FORMAT(imgbOutput->cs),
1160 OAPV_CS_GET_FORMAT(imgbOutput->cs) == OAPV_CF_YCBCR420
1161 ? "YUV420"
1162 : (OAPV_CS_GET_FORMAT(imgbOutput->cs) == OAPV_CF_YCBCR422 ? "YUV422"
1163 : "UNKNOWN"),
1164 format,
1165 format == HAL_PIXEL_FORMAT_YCBCR_P010
1166 ? "P010"
1167 : (format == HAL_PIXEL_FORMAT_YCBCR_420_888
1168 ? "YUV420"
1169 : (format == HAL_PIXEL_FORMAT_YV12 ? "YV12" : "UNKNOWN")));
1170 }
1171 }
1172
1173 finishWork(work->input.ordinal.frameIndex.peekll(), work, std::move(block));
1174 return OK;
1175}
1176
1177c2_status_t C2SoftApvDec::drainInternal(uint32_t drainMode,
1178 const std::shared_ptr<C2BlockPool>& pool,
1179 const std::unique_ptr<C2Work>& work) {
1180 if (drainMode == NO_DRAIN) {
1181 ALOGW("drain with NO_DRAIN: no-op");
1182 return C2_OK;
1183 }
1184 if (drainMode == DRAIN_CHAIN) {
1185 ALOGW("DRAIN_CHAIN not supported");
1186 return C2_OMITTED;
1187 }
1188
1189 if (drainMode == DRAIN_COMPONENT_WITH_EOS && work && work->workletsProcessed == 0u) {
1190 fillEmptyWork(work);
1191 }
1192 return C2_OK;
1193}
1194
1195c2_status_t C2SoftApvDec::drain(uint32_t drainMode, const std::shared_ptr<C2BlockPool>& pool) {
1196 return drainInternal(drainMode, pool, nullptr);
1197}
1198
1199class C2SoftApvDecFactory : public C2ComponentFactory {
1200 public:
1201 C2SoftApvDecFactory()
1202 : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
1203 GetCodec2PlatformComponentStore()->getParamReflector())) {}
1204
1205 virtual c2_status_t createComponent(c2_node_id_t id,
1206 std::shared_ptr<C2Component>* const component,
1207 std::function<void(C2Component*)> deleter) override {
1208 *component = std::shared_ptr<C2Component>(
1209 new C2SoftApvDec(COMPONENT_NAME, id,
1210 std::make_shared<C2SoftApvDec::IntfImpl>(mHelper)),
1211 deleter);
1212 return C2_OK;
1213 }
1214
1215 virtual c2_status_t createInterface(
1216 c2_node_id_t id, std::shared_ptr<C2ComponentInterface>* const interface,
1217 std::function<void(C2ComponentInterface*)> deleter) override {
1218 *interface = std::shared_ptr<C2ComponentInterface>(
1219 new SimpleInterface<C2SoftApvDec::IntfImpl>(
1220 COMPONENT_NAME, id, std::make_shared<C2SoftApvDec::IntfImpl>(mHelper)),
1221 deleter);
1222 return C2_OK;
1223 }
1224
1225 virtual ~C2SoftApvDecFactory() override = default;
1226
1227 private:
1228 std::shared_ptr<C2ReflectorHelper> mHelper;
1229};
1230
1231} // namespace android
1232
1233__attribute__((cfi_canonical_jump_table)) extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
1234 return new ::android::C2SoftApvDecFactory();
1235}
1236
1237__attribute__((cfi_canonical_jump_table)) extern "C" void DestroyCodec2Factory(
1238 ::C2ComponentFactory* factory) {
1239 delete factory;
1240}