• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 "C2SoftApvEnc"
19 #include <log/log.h>
20 
21 #include <android_media_swcodec_flags.h>
22 
23 #include <media/hardware/VideoAPI.h>
24 #include <media/stagefright/MediaDefs.h>
25 #include <media/stagefright/MediaErrors.h>
26 #include <media/stagefright/MetaData.h>
27 #include <media/stagefright/foundation/AUtils.h>
28 
29 #include <C2Debug.h>
30 #include <C2PlatformSupport.h>
31 #include <Codec2BufferUtils.h>
32 #include <Codec2CommonUtils.h>
33 #include <Codec2Mapper.h>
34 #include <SimpleC2Interface.h>
35 #include <media/stagefright/foundation/ABitReader.h>
36 #include <util/C2InterfaceHelper.h>
37 #include <cmath>
38 #include "C2SoftApvEnc.h"
39 #include "isAtLeastRelease.h"
40 
41 namespace android {
42 
43 namespace {
44 
45 constexpr char COMPONENT_NAME[] = "c2.android.apv.encoder";
46 constexpr uint32_t kMinOutBufferSize = 524288;
47 constexpr uint32_t kMaxBitstreamBufSize = 16 * 1024 * 1024;
48 constexpr int32_t kApvQpMin = 0;
49 constexpr int32_t kApvQpMax = 51;
50 constexpr int32_t kApvDefaultQP = 32;
51 
52 #define PROFILE_APV_DEFAULT 0
53 #define LEVEL_APV_DEFAULT 0
54 #define MAX_NUM_FRMS (1)  // supports only 1-frame input
55 
56 }  // namespace
57 
58 class C2SoftApvEnc::IntfImpl : public SimpleInterface<void>::BaseParams {
59   public:
IntfImpl(const std::shared_ptr<C2ReflectorHelper> & helper)60     explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper>& helper)
61         : SimpleInterface<void>::BaseParams(helper, COMPONENT_NAME, C2Component::KIND_ENCODER,
62                                             C2Component::DOMAIN_VIDEO, MEDIA_MIMETYPE_VIDEO_APV) {
63         noPrivateBuffers();
64         noInputReferences();
65         noOutputReferences();
66         noTimeStretch();
67         setDerivedInstance(this);
68 
69         addParameter(DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
70                              .withConstValue(new C2ComponentAttributesSetting(
71                                      C2Component::ATTRIB_IS_TEMPORAL))
72                              .build());
73 
74         addParameter(DefineParam(mUsage, C2_PARAMKEY_INPUT_STREAM_USAGE)
75                              .withConstValue(new C2StreamUsageTuning::input(
76                                      0u, (uint64_t)C2MemoryUsage::CPU_READ))
77                              .build());
78 
79         // matches size limits in codec library
80         addParameter(DefineParam(mSize, C2_PARAMKEY_PICTURE_SIZE)
81                              .withDefault(new C2StreamPictureSizeInfo::input(0u, 320, 240))
82                              .withFields({
83                                      C2F(mSize, width).inRange(2, 4096, 2),
84                                      C2F(mSize, height).inRange(2, 4096, 2),
85                              })
86                              .withSetter(SizeSetter)
87                              .build());
88 
89         addParameter(DefineParam(mBitrate, C2_PARAMKEY_BITRATE)
90                              .withDefault(new C2StreamBitrateInfo::output(0u, 512000))
91                              .withFields({C2F(mBitrate, value).inRange(512000, 240000000)})
92                              .withSetter(BitrateSetter)
93                              .build());
94 
95         addParameter(DefineParam(mFrameRate, C2_PARAMKEY_FRAME_RATE)
96                              .withDefault(new C2StreamFrameRateInfo::output(0u, 15.))
97                              .withFields({C2F(mFrameRate, value).greaterThan(0.)})
98                              .withSetter(Setter<decltype(*mFrameRate)>::StrictValueWithNoDeps)
99                              .build());
100 
101         addParameter(DefineParam(mQuality, C2_PARAMKEY_QUALITY)
102                              .withDefault(new C2StreamQualityTuning::output(0u, 40))
103                              .withFields({C2F(mQuality, value).inRange(0, 100)})
104                              .withSetter(Setter<decltype(*mQuality)>::NonStrictValueWithNoDeps)
105                              .build());
106 
107         addParameter(
108                 DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
109                         .withDefault(new C2StreamProfileLevelInfo::output(
110                                 0u, C2Config::PROFILE_APV_422_10, LEVEL_APV_1_BAND_0))
111                         .withFields({
112                                 C2F(mProfileLevel, profile).oneOf({C2Config::PROFILE_APV_422_10}),
113                                 C2F(mProfileLevel, level)
114                                         .oneOf({
115                                                 C2Config::LEVEL_APV_1_BAND_0,
116                                                 C2Config::LEVEL_APV_1_1_BAND_0,
117                                                 C2Config::LEVEL_APV_2_BAND_0,
118                                                 C2Config::LEVEL_APV_2_1_BAND_0,
119                                                 C2Config::LEVEL_APV_3_BAND_0,
120                                                 C2Config::LEVEL_APV_3_1_BAND_0,
121                                                 C2Config::LEVEL_APV_4_BAND_0,
122                                                 C2Config::LEVEL_APV_4_1_BAND_0,
123                                                 C2Config::LEVEL_APV_5_BAND_0,
124                                                 C2Config::LEVEL_APV_5_1_BAND_0,
125                                                 C2Config::LEVEL_APV_6_BAND_0,
126                                                 C2Config::LEVEL_APV_6_1_BAND_0,
127                                                 C2Config::LEVEL_APV_7_BAND_0,
128                                                 C2Config::LEVEL_APV_7_1_BAND_0,
129                                                 C2Config::LEVEL_APV_1_BAND_1,
130                                                 C2Config::LEVEL_APV_1_1_BAND_1,
131                                                 C2Config::LEVEL_APV_2_BAND_1,
132                                                 C2Config::LEVEL_APV_2_1_BAND_1,
133                                                 C2Config::LEVEL_APV_3_BAND_1,
134                                                 C2Config::LEVEL_APV_3_1_BAND_1,
135                                                 C2Config::LEVEL_APV_4_BAND_1,
136                                                 C2Config::LEVEL_APV_4_1_BAND_1,
137                                                 C2Config::LEVEL_APV_5_BAND_1,
138                                                 C2Config::LEVEL_APV_5_1_BAND_1,
139                                                 C2Config::LEVEL_APV_6_BAND_1,
140                                                 C2Config::LEVEL_APV_6_1_BAND_1,
141                                                 C2Config::LEVEL_APV_7_BAND_1,
142                                                 C2Config::LEVEL_APV_7_1_BAND_1,
143                                                 C2Config::LEVEL_APV_1_BAND_2,
144                                                 C2Config::LEVEL_APV_1_1_BAND_2,
145                                                 C2Config::LEVEL_APV_2_BAND_2,
146                                                 C2Config::LEVEL_APV_2_1_BAND_2,
147                                                 C2Config::LEVEL_APV_3_BAND_2,
148                                                 C2Config::LEVEL_APV_3_1_BAND_2,
149                                                 C2Config::LEVEL_APV_4_BAND_2,
150                                                 C2Config::LEVEL_APV_4_1_BAND_2,
151                                                 C2Config::LEVEL_APV_5_BAND_2,
152                                                 C2Config::LEVEL_APV_5_1_BAND_2,
153                                                 C2Config::LEVEL_APV_6_BAND_2,
154                                                 C2Config::LEVEL_APV_6_1_BAND_2,
155                                                 C2Config::LEVEL_APV_7_BAND_2,
156                                                 C2Config::LEVEL_APV_7_1_BAND_2,
157                                                 C2Config::LEVEL_APV_1_BAND_3,
158                                                 C2Config::LEVEL_APV_1_1_BAND_3,
159                                                 C2Config::LEVEL_APV_2_BAND_3,
160                                                 C2Config::LEVEL_APV_2_1_BAND_3,
161                                                 C2Config::LEVEL_APV_3_BAND_3,
162                                                 C2Config::LEVEL_APV_3_1_BAND_3,
163                                                 C2Config::LEVEL_APV_4_BAND_3,
164                                                 C2Config::LEVEL_APV_4_1_BAND_3,
165                                                 C2Config::LEVEL_APV_5_BAND_3,
166                                                 C2Config::LEVEL_APV_5_1_BAND_3,
167                                                 C2Config::LEVEL_APV_6_BAND_3,
168                                                 C2Config::LEVEL_APV_6_1_BAND_3,
169                                                 C2Config::LEVEL_APV_7_BAND_3,
170                                                 C2Config::LEVEL_APV_7_1_BAND_3,
171                                         }),
172                         })
173                         .withSetter(ProfileLevelSetter, mSize, mFrameRate, mBitrate)
174                         .build());
175 
176         addParameter(DefineParam(mColorAspects, C2_PARAMKEY_COLOR_ASPECTS)
177                              .withDefault(new C2StreamColorAspectsInfo::input(
178                                      0u, C2Color::RANGE_UNSPECIFIED, C2Color::PRIMARIES_UNSPECIFIED,
179                                      C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
180                              .withFields({C2F(mColorAspects, range)
181                                                   .inRange(C2Color::RANGE_UNSPECIFIED,
182                                                            C2Color::RANGE_OTHER),
183                                           C2F(mColorAspects, primaries)
184                                                   .inRange(C2Color::PRIMARIES_UNSPECIFIED,
185                                                            C2Color::PRIMARIES_OTHER),
186                                           C2F(mColorAspects, transfer)
187                                                   .inRange(C2Color::TRANSFER_UNSPECIFIED,
188                                                            C2Color::TRANSFER_OTHER),
189                                           C2F(mColorAspects, matrix)
190                                                   .inRange(C2Color::MATRIX_UNSPECIFIED,
191                                                            C2Color::MATRIX_OTHER)})
192                              .withSetter(ColorAspectsSetter)
193                              .build());
194 
195         addParameter(DefineParam(mCodedColorAspects, C2_PARAMKEY_VUI_COLOR_ASPECTS)
196                              .withDefault(new C2StreamColorAspectsInfo::output(
197                                      0u, C2Color::RANGE_LIMITED, C2Color::PRIMARIES_UNSPECIFIED,
198                                      C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
199                              .withFields({C2F(mCodedColorAspects, range)
200                                                   .inRange(C2Color::RANGE_UNSPECIFIED,
201                                                            C2Color::RANGE_OTHER),
202                                           C2F(mCodedColorAspects, primaries)
203                                                   .inRange(C2Color::PRIMARIES_UNSPECIFIED,
204                                                            C2Color::PRIMARIES_OTHER),
205                                           C2F(mCodedColorAspects, transfer)
206                                                   .inRange(C2Color::TRANSFER_UNSPECIFIED,
207                                                            C2Color::TRANSFER_OTHER),
208                                           C2F(mCodedColorAspects, matrix)
209                                                   .inRange(C2Color::MATRIX_UNSPECIFIED,
210                                                            C2Color::MATRIX_OTHER)})
211                              .withSetter(CodedColorAspectsSetter, mColorAspects)
212                              .build());
213         std::vector<uint32_t> pixelFormats = {
214             HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
215             HAL_PIXEL_FORMAT_YCBCR_420_888,
216         };
217         if (isHalPixelFormatSupported((AHardwareBuffer_Format)HAL_PIXEL_FORMAT_YCBCR_P010)) {
218             pixelFormats.push_back(HAL_PIXEL_FORMAT_YCBCR_P010);
219         }
220         if (isHalPixelFormatSupported((AHardwareBuffer_Format)AHARDWAREBUFFER_FORMAT_YCbCr_P210)) {
221             pixelFormats.push_back(AHARDWAREBUFFER_FORMAT_YCbCr_P210);
222         }
223         addParameter(DefineParam(mPixelFormat, C2_PARAMKEY_PIXEL_FORMAT)
224                              .withDefault(new C2StreamPixelFormatInfo::input(
225                                      0u, HAL_PIXEL_FORMAT_YCBCR_420_888))
226                              .withFields({C2F(mPixelFormat, value).oneOf({pixelFormats})})
227                              .withSetter((Setter<decltype(*mPixelFormat)>::StrictValueWithNoDeps))
228                              .build());
229     }
230 
BitrateSetter(bool mayBlock,C2P<C2StreamBitrateInfo::output> & me)231     static C2R BitrateSetter(bool mayBlock, C2P<C2StreamBitrateInfo::output>& me) {
232         (void)mayBlock;
233         C2R res = C2R::Ok();
234         if (me.v.value < 1000000) {
235             me.set().value = 1000000;
236         }
237         return res;
238     }
239 
SizeSetter(bool mayBlock,const C2P<C2StreamPictureSizeInfo::input> & oldMe,C2P<C2StreamPictureSizeInfo::input> & me)240     static C2R SizeSetter(bool mayBlock, const C2P<C2StreamPictureSizeInfo::input>& oldMe,
241                           C2P<C2StreamPictureSizeInfo::input>& me) {
242         (void)mayBlock;
243         C2R res = C2R::Ok();
244         if (!me.F(me.v.width).supportsAtAll(me.v.width)) {
245             res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.width)));
246             me.set().width = oldMe.v.width;
247         }
248         if (!me.F(me.v.height).supportsAtAll(me.v.height)) {
249             res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.height)));
250             me.set().height = oldMe.v.height;
251         }
252         return res;
253     }
254 
ProfileLevelSetter(bool mayBlock,C2P<C2StreamProfileLevelInfo::output> & me,const C2P<C2StreamPictureSizeInfo::input> & size,const C2P<C2StreamFrameRateInfo::output> & frameRate,const C2P<C2StreamBitrateInfo::output> & bitrate)255     static C2R ProfileLevelSetter(bool mayBlock, C2P<C2StreamProfileLevelInfo::output>& me,
256                                   const C2P<C2StreamPictureSizeInfo::input>& size,
257                                   const C2P<C2StreamFrameRateInfo::output>& frameRate,
258                                   const C2P<C2StreamBitrateInfo::output>& bitrate) {
259         (void)mayBlock;
260         if (!me.F(me.v.profile).supportsAtAll(me.v.profile)) {
261             me.set().profile = C2Config::PROFILE_APV_422_10;
262         }
263         if (!me.F(me.v.level).supportsAtAll(me.v.level)) {
264             me.set().level = LEVEL_APV_1_BAND_0;
265         }
266 
267         int32_t bandIdc = me.v.level <= LEVEL_APV_7_1_BAND_0 ? 0 :
268                           me.v.level <= LEVEL_APV_7_1_BAND_1 ? 1 :
269                           me.v.level <= LEVEL_APV_7_1_BAND_2 ? 2 : 3;
270 
271         me.set().level = decisionApvLevel(size.v.width, size.v.height, frameRate.v.value,
272                                             (uint64_t)bitrate.v.value, bandIdc);
273         return C2R::Ok();
274     }
275 
ColorAspectsSetter(bool mayBlock,C2P<C2StreamColorAspectsInfo::input> & me)276     static C2R ColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::input>& me) {
277         (void)mayBlock;
278         if (me.v.range > C2Color::RANGE_OTHER) {
279             me.set().range = C2Color::RANGE_OTHER;
280         }
281         if (me.v.primaries > C2Color::PRIMARIES_OTHER) {
282             me.set().primaries = C2Color::PRIMARIES_OTHER;
283         }
284         if (me.v.transfer > C2Color::TRANSFER_OTHER) {
285             me.set().transfer = C2Color::TRANSFER_OTHER;
286         }
287         if (me.v.matrix > C2Color::MATRIX_OTHER) {
288             me.set().matrix = C2Color::MATRIX_OTHER;
289         }
290         return C2R::Ok();
291     }
292 
CodedColorAspectsSetter(bool mayBlock,C2P<C2StreamColorAspectsInfo::output> & me,const C2P<C2StreamColorAspectsInfo::input> & coded)293     static C2R CodedColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::output>& me,
294                                        const C2P<C2StreamColorAspectsInfo::input>& coded) {
295         (void)mayBlock;
296         me.set().range = coded.v.range;
297         me.set().primaries = coded.v.primaries;
298         me.set().transfer = coded.v.transfer;
299         me.set().matrix = coded.v.matrix;
300         return C2R::Ok();
301     }
302 
decisionApvLevel(int32_t width,int32_t height,int32_t fps,uint64_t bitrate,int32_t band)303     static C2Config::level_t decisionApvLevel(int32_t width, int32_t height, int32_t fps,
304                                                     uint64_t bitrate, int32_t band) {
305         C2Config::level_t level = C2Config::LEVEL_APV_1_BAND_0;
306         struct LevelLimits {
307             C2Config::level_t level;
308             uint64_t samplesPerSec;
309             uint64_t kbpsOfBand;
310         };
311 
312         constexpr LevelLimits kLimitsBand0[] = {
313                 {LEVEL_APV_1_BAND_0, 3'041'280, 7'000},
314                 {LEVEL_APV_1_1_BAND_0, 6'082'560, 14'000},
315                 {LEVEL_APV_2_BAND_0, 15'667'200, 36'000},
316                 {LEVEL_APV_2_1_BAND_0, 31'334'400, 71'000},
317                 {LEVEL_APV_3_BAND_0, 66'846'720, 101'000},
318                 {LEVEL_APV_3_1_BAND_0, 133'693'440, 201'000},
319                 {LEVEL_APV_4_BAND_0, 265'420'800, 401'000},
320                 {LEVEL_APV_4_1_BAND_0, 530'841'600, 780'000},
321                 {LEVEL_APV_5_BAND_0, 1'061'683'200, 1'560'000},
322                 {LEVEL_APV_5_1_BAND_0, 2'123'366'400, 3'324'000},
323                 {LEVEL_APV_6_BAND_0, 4'777'574'400, 6'648'000},
324                 {LEVEL_APV_6_1_BAND_0, 8'493'465'600, 13'296'000},
325                 {LEVEL_APV_7_BAND_0, 16'986'931'200, 26'592'000},
326                 {LEVEL_APV_7_1_BAND_0, 33'973'862'400, 53'184'000},
327         };
328 
329         constexpr LevelLimits kLimitsBand1[] = {
330                 {LEVEL_APV_1_BAND_1, 3'041'280, 11'000},
331                 {LEVEL_APV_1_1_BAND_1, 6'082'560, 21'000},
332                 {LEVEL_APV_2_BAND_1, 15'667'200, 53'000},
333                 {LEVEL_APV_2_1_BAND_1, 31'334'400, 106'00},
334                 {LEVEL_APV_3_BAND_1, 66'846'720, 151'000},
335                 {LEVEL_APV_3_1_BAND_1, 133'693'440, 301'000},
336                 {LEVEL_APV_4_BAND_1, 265'420'800, 602'000},
337                 {LEVEL_APV_4_1_BAND_1, 530'841'600, 1'170'000},
338                 {LEVEL_APV_5_BAND_1, 1'061'683'200, 2'340'000},
339                 {LEVEL_APV_5_1_BAND_1, 2'123'366'400, 4'986'000},
340                 {LEVEL_APV_6_BAND_1, 4'777'574'400, 9'972'000},
341                 {LEVEL_APV_6_1_BAND_1, 8'493'465'600, 19'944'000},
342                 {LEVEL_APV_7_BAND_1, 16'986'931'200, 39'888'000},
343                 {LEVEL_APV_7_1_BAND_1, 33'973'862'400, 79'776'000},
344         };
345 
346         constexpr LevelLimits kLimitsBand2[] = {
347                 {LEVEL_APV_1_BAND_2, 3'041'280, 14'000},
348                 {LEVEL_APV_1_1_BAND_2, 6'082'560, 28'000},
349                 {LEVEL_APV_2_BAND_2, 15'667'200, 71'000},
350                 {LEVEL_APV_2_1_BAND_2, 31'334'400, 141'000},
351                 {LEVEL_APV_3_BAND_2, 66'846'720, 201'000},
352                 {LEVEL_APV_3_1_BAND_2, 133'693'440, 401'000},
353                 {LEVEL_APV_4_BAND_2, 265'420'800, 780'000},
354                 {LEVEL_APV_4_1_BAND_2, 530'841'600, 1'560'000},
355                 {LEVEL_APV_5_BAND_2, 1'061'683'200, 3'324'000},
356                 {LEVEL_APV_5_1_BAND_2, 2'123'366'400, 6'648'000},
357                 {LEVEL_APV_6_BAND_2, 4'777'574'400, 13'296'000},
358                 {LEVEL_APV_6_1_BAND_2, 8'493'465'600, 26'592'000},
359                 {LEVEL_APV_7_BAND_2, 16'986'931'200, 53'184'000},
360                 {LEVEL_APV_7_1_BAND_2, 33'973'862'400, 106'368'000},
361         };
362 
363         constexpr LevelLimits kLimitsBand3[] = {
364                 {LEVEL_APV_1_BAND_3, 3'041'280, 21'000},
365                 {LEVEL_APV_1_1_BAND_3, 6'082'560, 42'000},
366                 {LEVEL_APV_2_BAND_3, 15'667'200, 106'000},
367                 {LEVEL_APV_2_1_BAND_3, 31'334'400, 212'000},
368                 {LEVEL_APV_3_BAND_3, 66'846'720, 301'000},
369                 {LEVEL_APV_3_1_BAND_3, 133'693'440, 602'000},
370                 {LEVEL_APV_4_BAND_3, 265'420'800, 1'170'000},
371                 {LEVEL_APV_4_1_BAND_3, 530'841'600, 2'340'000},
372                 {LEVEL_APV_5_BAND_3, 1'061'683'200, 4'986'000},
373                 {LEVEL_APV_5_1_BAND_3, 2'123'366'400, 9'972'000},
374                 {LEVEL_APV_6_BAND_3, 4'777'574'400, 19'944'000},
375                 {LEVEL_APV_6_1_BAND_3, 8'493'465'600, 39'888'000},
376                 {LEVEL_APV_7_BAND_3, 16'986'931'200, 79'776'000},
377                 {LEVEL_APV_7_1_BAND_3, 33'973'862'400, 159'552'000},
378         };
379 
380         uint64_t samplesPerSec = width * height * fps;
381         if (band == 0) {
382             for (const LevelLimits& limit : kLimitsBand0) {
383                 if (samplesPerSec <= limit.samplesPerSec && bitrate <= limit.kbpsOfBand * 1000) {
384                     level = limit.level;
385                     break;
386                 }
387             }
388         } else if (band == 1) {
389             for (const LevelLimits& limit : kLimitsBand1) {
390                 if (samplesPerSec <= limit.samplesPerSec && bitrate <= limit.kbpsOfBand * 1000) {
391                     level = limit.level;
392                     break;
393                 }
394             }
395         } else if (band == 2) {
396             for (const LevelLimits& limit : kLimitsBand2) {
397                 if (samplesPerSec <= limit.samplesPerSec && bitrate <= limit.kbpsOfBand * 1000) {
398                     level = limit.level;
399                     break;
400                 }
401             }
402         } else if (band == 3) {
403             for (const LevelLimits& limit : kLimitsBand3) {
404                 if (samplesPerSec <= limit.samplesPerSec && bitrate <= limit.kbpsOfBand * 1000) {
405                     level = limit.level;
406                     break;
407                 }
408             }
409         } else {
410             ALOGE("Invalid band_idc on calculte level");
411         }
412 
413         return level;
414     }
415 
getProfile_l() const416     uint32_t getProfile_l() const {
417         int32_t profile = PROFILE_UNUSED;
418 
419         switch (mProfileLevel->profile) {
420             case C2Config::PROFILE_APV_422_10:
421                 profile = 33;
422                 break;
423             case C2Config::PROFILE_APV_422_12:
424                 profile = 44;
425                 break;
426             case C2Config::PROFILE_APV_444_10:
427                 profile = 55;
428                 break;
429             case C2Config::PROFILE_APV_444_12:
430                 profile = 66;
431                 break;
432             case C2Config::PROFILE_APV_4444_10:
433                 profile = 77;
434                 break;
435             case C2Config::PROFILE_APV_4444_12:
436                 profile = 88;
437                 break;
438             case C2Config::PROFILE_APV_400_10:
439                 profile = 99;
440                 break;
441             default:
442                 ALOGW("Unrecognized profile: %x", mProfileLevel->profile);
443         }
444         return profile;
445     }
446 
getLevel_l() const447     uint32_t getLevel_l() const {
448         int32_t level = LEVEL_UNUSED;
449 
450         // TODO: Add Band settings
451         switch (mProfileLevel->level) {
452             case C2Config::LEVEL_APV_1_BAND_0:
453                 [[fallthrough]];
454             case C2Config::LEVEL_APV_1_BAND_1:
455                 [[fallthrough]];
456             case C2Config::LEVEL_APV_1_BAND_2:
457                 [[fallthrough]];
458             case C2Config::LEVEL_APV_1_BAND_3:
459                 level = 10;
460                 break;
461             case C2Config::LEVEL_APV_1_1_BAND_0:
462                 [[fallthrough]];
463             case C2Config::LEVEL_APV_1_1_BAND_1:
464                 [[fallthrough]];
465             case C2Config::LEVEL_APV_1_1_BAND_2:
466                 [[fallthrough]];
467             case C2Config::LEVEL_APV_1_1_BAND_3:
468                 level = 11;
469                 break;
470             case C2Config::LEVEL_APV_2_BAND_0:
471                 [[fallthrough]];
472             case C2Config::LEVEL_APV_2_BAND_1:
473                 [[fallthrough]];
474             case C2Config::LEVEL_APV_2_BAND_2:
475                 [[fallthrough]];
476             case C2Config::LEVEL_APV_2_BAND_3:
477                 level = 20;
478                 break;
479             case C2Config::LEVEL_APV_2_1_BAND_0:
480                 [[fallthrough]];
481             case C2Config::LEVEL_APV_2_1_BAND_1:
482                 [[fallthrough]];
483             case C2Config::LEVEL_APV_2_1_BAND_2:
484                 [[fallthrough]];
485             case C2Config::LEVEL_APV_2_1_BAND_3:
486                 level = 21;
487                 break;
488             case C2Config::LEVEL_APV_3_BAND_0:
489                 [[fallthrough]];
490             case C2Config::LEVEL_APV_3_BAND_1:
491                 [[fallthrough]];
492             case C2Config::LEVEL_APV_3_BAND_2:
493                 [[fallthrough]];
494             case C2Config::LEVEL_APV_3_BAND_3:
495                 level = 30;
496                 break;
497             case C2Config::LEVEL_APV_3_1_BAND_0:
498                 [[fallthrough]];
499             case C2Config::LEVEL_APV_3_1_BAND_1:
500                 [[fallthrough]];
501             case C2Config::LEVEL_APV_3_1_BAND_2:
502                 [[fallthrough]];
503             case C2Config::LEVEL_APV_3_1_BAND_3:
504                 level = 31;
505                 break;
506             case C2Config::LEVEL_APV_4_BAND_0:
507                 [[fallthrough]];
508             case C2Config::LEVEL_APV_4_BAND_1:
509                 [[fallthrough]];
510             case C2Config::LEVEL_APV_4_BAND_2:
511                 [[fallthrough]];
512             case C2Config::LEVEL_APV_4_BAND_3:
513                 level = 40;
514                 break;
515             case C2Config::LEVEL_APV_4_1_BAND_0:
516                 [[fallthrough]];
517             case C2Config::LEVEL_APV_4_1_BAND_1:
518                 [[fallthrough]];
519             case C2Config::LEVEL_APV_4_1_BAND_2:
520                 [[fallthrough]];
521             case C2Config::LEVEL_APV_4_1_BAND_3:
522                 level = 41;
523                 break;
524             case C2Config::LEVEL_APV_5_BAND_0:
525                 [[fallthrough]];
526             case C2Config::LEVEL_APV_5_BAND_1:
527                 [[fallthrough]];
528             case C2Config::LEVEL_APV_5_BAND_2:
529                 [[fallthrough]];
530             case C2Config::LEVEL_APV_5_BAND_3:
531                 level = 50;
532                 break;
533             case C2Config::LEVEL_APV_5_1_BAND_0:
534                 [[fallthrough]];
535             case C2Config::LEVEL_APV_5_1_BAND_1:
536                 [[fallthrough]];
537             case C2Config::LEVEL_APV_5_1_BAND_2:
538                 [[fallthrough]];
539             case C2Config::LEVEL_APV_5_1_BAND_3:
540                 level = 51;
541                 break;
542             case C2Config::LEVEL_APV_6_BAND_0:
543                 [[fallthrough]];
544             case C2Config::LEVEL_APV_6_BAND_1:
545                 [[fallthrough]];
546             case C2Config::LEVEL_APV_6_BAND_2:
547                 [[fallthrough]];
548             case C2Config::LEVEL_APV_6_BAND_3:
549                 level = 60;
550                 break;
551             case C2Config::LEVEL_APV_6_1_BAND_0:
552                 [[fallthrough]];
553             case C2Config::LEVEL_APV_6_1_BAND_1:
554                 [[fallthrough]];
555             case C2Config::LEVEL_APV_6_1_BAND_2:
556                 [[fallthrough]];
557             case C2Config::LEVEL_APV_6_1_BAND_3:
558                 level = 61;
559                 break;
560             case C2Config::LEVEL_APV_7_BAND_0:
561                 [[fallthrough]];
562             case C2Config::LEVEL_APV_7_BAND_1:
563                 [[fallthrough]];
564             case C2Config::LEVEL_APV_7_BAND_2:
565                 [[fallthrough]];
566             case C2Config::LEVEL_APV_7_BAND_3:
567                 level = 70;
568                 break;
569             case C2Config::LEVEL_APV_7_1_BAND_0:
570                 [[fallthrough]];
571             case C2Config::LEVEL_APV_7_1_BAND_1:
572                 [[fallthrough]];
573             case C2Config::LEVEL_APV_7_1_BAND_2:
574                 [[fallthrough]];
575             case C2Config::LEVEL_APV_7_1_BAND_3:
576                 level = 71;
577                 break;
578             default:
579                 ALOGW("Unrecognized level: %x", mProfileLevel->level);
580         }
581         // Convert to APV level_idc according to APV spec
582         return level * 3;
583     }
584 
getBandIdc_l() const585     uint32_t getBandIdc_l() const {
586         uint32_t bandIdc = 0;
587 
588         switch (mProfileLevel->level) {
589             case C2Config::LEVEL_APV_1_BAND_0:
590                 [[fallthrough]];
591             case C2Config::LEVEL_APV_1_1_BAND_0:
592                 [[fallthrough]];
593             case C2Config::LEVEL_APV_2_BAND_0:
594                 [[fallthrough]];
595             case C2Config::LEVEL_APV_2_1_BAND_0:
596                 [[fallthrough]];
597             case C2Config::LEVEL_APV_3_BAND_0:
598                 [[fallthrough]];
599             case C2Config::LEVEL_APV_3_1_BAND_0:
600                 [[fallthrough]];
601             case C2Config::LEVEL_APV_4_BAND_0:
602                 [[fallthrough]];
603             case C2Config::LEVEL_APV_4_1_BAND_0:
604                 [[fallthrough]];
605             case C2Config::LEVEL_APV_5_BAND_0:
606                 [[fallthrough]];
607             case C2Config::LEVEL_APV_5_1_BAND_0:
608                 [[fallthrough]];
609             case C2Config::LEVEL_APV_6_BAND_0:
610                 [[fallthrough]];
611             case C2Config::LEVEL_APV_6_1_BAND_0:
612                 [[fallthrough]];
613             case C2Config::LEVEL_APV_7_BAND_0:
614                 [[fallthrough]];
615             case C2Config::LEVEL_APV_7_1_BAND_0:
616                 bandIdc = 0;
617                 break;
618             case C2Config::LEVEL_APV_1_BAND_1:
619                 [[fallthrough]];
620             case C2Config::LEVEL_APV_1_1_BAND_1:
621                 [[fallthrough]];
622             case C2Config::LEVEL_APV_2_BAND_1:
623                 [[fallthrough]];
624             case C2Config::LEVEL_APV_2_1_BAND_1:
625                 [[fallthrough]];
626             case C2Config::LEVEL_APV_3_BAND_1:
627                 [[fallthrough]];
628             case C2Config::LEVEL_APV_3_1_BAND_1:
629                 [[fallthrough]];
630             case C2Config::LEVEL_APV_4_BAND_1:
631                 [[fallthrough]];
632             case C2Config::LEVEL_APV_4_1_BAND_1:
633                 [[fallthrough]];
634             case C2Config::LEVEL_APV_5_BAND_1:
635                 [[fallthrough]];
636             case C2Config::LEVEL_APV_5_1_BAND_1:
637                 [[fallthrough]];
638             case C2Config::LEVEL_APV_6_BAND_1:
639                 [[fallthrough]];
640             case C2Config::LEVEL_APV_6_1_BAND_1:
641                 [[fallthrough]];
642             case C2Config::LEVEL_APV_7_BAND_1:
643                 [[fallthrough]];
644             case C2Config::LEVEL_APV_7_1_BAND_1:
645                 bandIdc = 1;
646                 break;
647             case C2Config::LEVEL_APV_1_BAND_2:
648                 [[fallthrough]];
649             case C2Config::LEVEL_APV_1_1_BAND_2:
650                 [[fallthrough]];
651             case C2Config::LEVEL_APV_2_BAND_2:
652                 [[fallthrough]];
653             case C2Config::LEVEL_APV_2_1_BAND_2:
654                 [[fallthrough]];
655             case C2Config::LEVEL_APV_3_BAND_2:
656                 [[fallthrough]];
657             case C2Config::LEVEL_APV_3_1_BAND_2:
658                 [[fallthrough]];
659             case C2Config::LEVEL_APV_4_BAND_2:
660                 [[fallthrough]];
661             case C2Config::LEVEL_APV_4_1_BAND_2:
662                 [[fallthrough]];
663             case C2Config::LEVEL_APV_5_BAND_2:
664                 [[fallthrough]];
665             case C2Config::LEVEL_APV_5_1_BAND_2:
666                 [[fallthrough]];
667             case C2Config::LEVEL_APV_6_BAND_2:
668                 [[fallthrough]];
669             case C2Config::LEVEL_APV_6_1_BAND_2:
670                 [[fallthrough]];
671             case C2Config::LEVEL_APV_7_BAND_2:
672                 [[fallthrough]];
673             case C2Config::LEVEL_APV_7_1_BAND_2:
674                 bandIdc = 2;
675                 break;
676             case C2Config::LEVEL_APV_1_BAND_3:
677                 [[fallthrough]];
678             case C2Config::LEVEL_APV_1_1_BAND_3:
679                 [[fallthrough]];
680             case C2Config::LEVEL_APV_2_BAND_3:
681                 [[fallthrough]];
682             case C2Config::LEVEL_APV_2_1_BAND_3:
683                 [[fallthrough]];
684             case C2Config::LEVEL_APV_3_BAND_3:
685                 [[fallthrough]];
686             case C2Config::LEVEL_APV_3_1_BAND_3:
687                 [[fallthrough]];
688             case C2Config::LEVEL_APV_4_BAND_3:
689                 [[fallthrough]];
690             case C2Config::LEVEL_APV_4_1_BAND_3:
691                 [[fallthrough]];
692             case C2Config::LEVEL_APV_5_BAND_3:
693                 [[fallthrough]];
694             case C2Config::LEVEL_APV_5_1_BAND_3:
695                 [[fallthrough]];
696             case C2Config::LEVEL_APV_6_BAND_3:
697                 [[fallthrough]];
698             case C2Config::LEVEL_APV_6_1_BAND_3:
699                 [[fallthrough]];
700             case C2Config::LEVEL_APV_7_BAND_3:
701                 [[fallthrough]];
702             case C2Config::LEVEL_APV_7_1_BAND_3:
703                 bandIdc = 3;
704                 break;
705             default:
706                 ALOGW("Unrecognized bandIdc through level: %x", mProfileLevel->level);
707         }
708         return bandIdc;
709     }
710 
getSize_l() const711     std::shared_ptr<C2StreamPictureSizeInfo::input> getSize_l() const { return mSize; }
getFrameRate_l() const712     std::shared_ptr<C2StreamFrameRateInfo::output> getFrameRate_l() const { return mFrameRate; }
getBitrate_l() const713     std::shared_ptr<C2StreamBitrateInfo::output> getBitrate_l() const { return mBitrate; }
getQuality_l() const714     std::shared_ptr<C2StreamQualityTuning::output> getQuality_l() const { return mQuality; }
getColorAspects_l() const715     std::shared_ptr<C2StreamColorAspectsInfo::input> getColorAspects_l() const {
716         return mColorAspects;
717     }
getCodedColorAspects_l() const718     std::shared_ptr<C2StreamColorAspectsInfo::output> getCodedColorAspects_l() const {
719         return mCodedColorAspects;
720     }
getPictureQuantization_l() const721     std::shared_ptr<C2StreamPictureQuantizationTuning::output> getPictureQuantization_l() const {
722         return mPictureQuantization;
723     }
getProfileLevel_l() const724     std::shared_ptr<C2StreamProfileLevelInfo::output> getProfileLevel_l() const {
725         return mProfileLevel;
726     }
getPixelFormat_l() const727     std::shared_ptr<C2StreamPixelFormatInfo::input> getPixelFormat_l() const {
728         return mPixelFormat;
729     }
730 
731   private:
732     std::shared_ptr<C2StreamProfileLevelInfo::output> mProfileLevel;
733     std::shared_ptr<C2StreamUsageTuning::input> mUsage;
734     std::shared_ptr<C2StreamPictureSizeInfo::input> mSize;
735     std::shared_ptr<C2StreamFrameRateInfo::output> mFrameRate;
736     std::shared_ptr<C2StreamBitrateInfo::output> mBitrate;
737     std::shared_ptr<C2StreamQualityTuning::output> mQuality;
738     std::shared_ptr<C2StreamColorAspectsInfo::input> mColorAspects;
739     std::shared_ptr<C2StreamColorAspectsInfo::output> mCodedColorAspects;
740     std::shared_ptr<C2StreamPictureQuantizationTuning::output> mPictureQuantization;
741     std::shared_ptr<C2StreamColorInfo::input> mColorFormat;
742     std::shared_ptr<C2StreamPixelFormatInfo::input> mPixelFormat;
743 };
744 
C2SoftApvEnc(const char * name,c2_node_id_t id,const std::shared_ptr<IntfImpl> & intfImpl)745 C2SoftApvEnc::C2SoftApvEnc(const char* name, c2_node_id_t id,
746                            const std::shared_ptr<IntfImpl>& intfImpl)
747     : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
748       mIntf(intfImpl),
749       mColorFormat(OAPV_CF_PLANAR2),
750       mStarted(false),
751       mSignalledEos(false),
752       mSignalledError(false),
753       mOutBlock(nullptr) {
754     resetEncoder();
755 }
756 
C2SoftApvEnc(const char * name,c2_node_id_t id,const std::shared_ptr<C2ReflectorHelper> & helper)757 C2SoftApvEnc::C2SoftApvEnc(const char* name, c2_node_id_t id,
758                            const std::shared_ptr<C2ReflectorHelper>& helper)
759     : C2SoftApvEnc(name, id, std::make_shared<IntfImpl>(helper)) {
760 }
761 
~C2SoftApvEnc()762 C2SoftApvEnc::~C2SoftApvEnc() {
763     onRelease();
764 }
765 
onInit()766 c2_status_t C2SoftApvEnc::onInit() {
767     return C2_OK;
768 }
769 
onStop()770 c2_status_t C2SoftApvEnc::onStop() {
771     return C2_OK;
772 }
773 
onReset()774 void C2SoftApvEnc::onReset() {
775     releaseEncoder();
776     resetEncoder();
777 }
778 
onRelease()779 void C2SoftApvEnc::onRelease() {
780     releaseEncoder();
781 }
782 
onFlush_sm()783 c2_status_t C2SoftApvEnc::onFlush_sm() {
784     return C2_OK;
785 }
786 
fillEmptyWork(const std::unique_ptr<C2Work> & work)787 static void fillEmptyWork(const std::unique_ptr<C2Work>& work) {
788     uint32_t flags = 0;
789     if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
790         flags |= C2FrameData::FLAG_END_OF_STREAM;
791         ALOGV("Signalling EOS");
792     }
793     work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
794     work->worklets.front()->output.buffers.clear();
795     work->worklets.front()->output.ordinal = work->input.ordinal;
796     work->workletsProcessed = 1u;
797 }
798 
getQpFromQuality(int32_t quality)799 int32_t C2SoftApvEnc::getQpFromQuality(int32_t quality) {
800     int32_t qp = ((kApvQpMin - kApvQpMax) * quality / 100) + kApvQpMax;
801     qp = std::min(qp, (int)kApvQpMax);
802     qp = std::max(qp, (int)kApvQpMin);
803     return qp;
804 }
805 
resetEncoder()806 c2_status_t C2SoftApvEnc::resetEncoder() {
807     ALOGV("reset");
808     mInitEncoder = false;
809     mStarted = false;
810     mSignalledEos = false;
811     mSignalledError = false;
812     mBitDepth = 10;
813     mMaxFrames = MAX_NUM_FRMS;
814     mReceivedFrames = 0;
815     mReceivedFirstFrame = false;
816     mColorFormat = OAPV_CF_PLANAR2;
817     memset(&mInputFrames, 0, sizeof(mInputFrames));
818     memset(&mReconFrames, 0, sizeof(mReconFrames));
819     return C2_OK;
820 }
821 
releaseEncoder()822 c2_status_t C2SoftApvEnc::releaseEncoder() {
823     for (int32_t i = 0; i < MAX_NUM_FRMS; i++) {
824         if (mInputFrames.frm[i].imgb != nullptr) {
825             imgb_release(mInputFrames.frm[i].imgb);
826             mInputFrames.frm[i].imgb = nullptr;
827         }
828     }
829 
830     if (mBitstreamBuf) {
831         std::free(mBitstreamBuf);
832         mBitstreamBuf = nullptr;
833     }
834     return C2_OK;
835 }
836 
drain(uint32_t drainMode,const std::shared_ptr<C2BlockPool> & pool)837 c2_status_t C2SoftApvEnc::drain(uint32_t drainMode, const std::shared_ptr<C2BlockPool>& pool) {
838     return drainInternal(drainMode, pool, nullptr);
839 }
840 
showEncoderParams(oapve_cdesc_t * cdsc)841 void C2SoftApvEnc::showEncoderParams(oapve_cdesc_t* cdsc) {
842     std::string title = "APV encoder params:";
843     ALOGD("%s width = %d, height = %d", title.c_str(), cdsc->param[0].w, cdsc->param[0].h);
844     ALOGD("%s FrameRate = %f", title.c_str(),
845           (double)cdsc->param[0].fps_num / cdsc->param[0].fps_den);
846     ALOGD("%s BitRate = %d Kbps", title.c_str(), cdsc->param[0].bitrate);
847     ALOGD("%s QP = %d", title.c_str(), cdsc->param[0].qp);
848     ALOGD("%s profile_idc = %d, level_idc = %d, band_idc = %d", title.c_str(),
849           cdsc->param[0].profile_idc, cdsc->param[0].level_idc / 3, cdsc->param[0].band_idc);
850     ALOGD("%s Bitrate Mode: %d", title.c_str(), cdsc->param[0].rc_type);
851     ALOGD("%s mColorAspects primaries: %d, transfer: %d, matrix: %d, range: %d", title.c_str(),
852           mColorAspects->primaries, mColorAspects->transfer, mColorAspects->matrix,
853           mColorAspects->range);
854     ALOGD("%s mCodedColorAspects primaries: %d, transfer: %d, matrix: %d, range: %d", title.c_str(),
855           mCodedColorAspects->primaries, mCodedColorAspects->transfer, mCodedColorAspects->matrix,
856           mCodedColorAspects->range);
857     ALOGD("%s Input color format: %s", title.c_str(),
858           mColorFormat == OAPV_CF_YCBCR422 ? "YUV422P10LE" : "P210");
859     ALOGD("%s max_num_frms: %d", title.c_str(), cdsc->max_num_frms);
860 }
861 
initEncoder()862 c2_status_t C2SoftApvEnc::initEncoder() {
863     if (mInitEncoder) {
864         return C2_OK;
865     }
866     ALOGV("initEncoder");
867 
868     mSize = mIntf->getSize_l();
869     mFrameRate = mIntf->getFrameRate_l();
870     mBitrate = mIntf->getBitrate_l();
871     mQuality = mIntf->getQuality_l();
872     mColorAspects = mIntf->getColorAspects_l();
873     mCodedColorAspects = mIntf->getCodedColorAspects_l();
874     mProfileLevel = mIntf->getProfileLevel_l();
875     mPixelFormat = mIntf->getPixelFormat_l();
876 
877     mCodecDesc = std::make_unique<oapve_cdesc_t>();
878     if (mCodecDesc == nullptr) {
879         ALOGE("Allocate ctx failed");
880         return C2_NO_INIT;
881     }
882     mCodecDesc->max_bs_buf_size = kMaxBitstreamBufSize;
883     mCodecDesc->max_num_frms = MAX_NUM_FRMS;
884     // TODO: Bound parameters to CPU count
885     mCodecDesc->threads = 4;
886 
887     int32_t ret = C2_OK;
888     /* set params */
889     for (int32_t i = 0; i < mMaxFrames; i++) {
890         oapve_param_t* param = &mCodecDesc->param[i];
891         ret = oapve_param_default(param);
892         if (OAPV_FAILED(ret)) {
893             ALOGE("cannot set default parameter");
894             return C2_NO_INIT;
895         }
896         setParams(*param);
897     }
898 
899     showEncoderParams(mCodecDesc.get());
900 
901     /* create encoder */
902     mEncoderId = oapve_create(mCodecDesc.get(), NULL);
903     if (mEncoderId == NULL) {
904         ALOGE("cannot create APV encoder");
905         return C2_CORRUPTED;
906     }
907 
908     /* create metadata */
909     mMetaId = oapvm_create(&ret);
910     if (mMetaId == NULL) {
911         ALOGE("cannot create APV encoder");
912         return C2_NO_MEMORY;
913     }
914 
915     /* create image buffers */
916     for (int32_t i = 0; i < mMaxFrames; i++) {
917         if (mBitDepth == 10) {
918             mInputFrames.frm[i].imgb = imgb_create(mCodecDesc->param[0].w, mCodecDesc->param[0].h,
919                                                   OAPV_CS_SET(mColorFormat, mBitDepth, 0));
920             mReconFrames.frm[i].imgb = nullptr;
921         } else {
922             mInputFrames.frm[i].imgb = imgb_create(mCodecDesc->param[0].w, mCodecDesc->param[0].h,
923                                                   OAPV_CS_SET(mColorFormat, 10, 0));
924             mReconFrames.frm[i].imgb = nullptr;
925         }
926     }
927 
928     /* allocate bitstream buffer */
929     mBitstreamBuf = new unsigned char[kMaxBitstreamBufSize];
930     if (mBitstreamBuf == nullptr) {
931         ALOGE("cannot allocate bitstream buffer, size= %d", kMaxBitstreamBufSize);
932         return C2_NO_MEMORY;
933     }
934 
935     mStarted = true;
936     mInitEncoder = true;
937     return C2_OK;
938 }
939 
setParams(oapve_param_t & param)940 void C2SoftApvEnc::setParams(oapve_param_t& param) {
941     param.w = mSize->width;
942     param.h = mSize->height;
943     param.fps_num = (int)(mFrameRate->value * 100);
944     param.fps_den = 100;
945     param.bitrate = (int)(mBitrate->value / 1000);
946     param.rc_type = OAPV_RC_ABR;
947 
948     param.qp = kApvDefaultQP;
949     param.band_idc = mIntf->getBandIdc_l();
950     param.profile_idc = mIntf->getProfile_l();
951     param.level_idc = mIntf->getLevel_l();
952     mColorAspects = mIntf->getColorAspects_l();
953     ColorAspects sfAspects;
954     if (!C2Mapper::map(mColorAspects->primaries, &sfAspects.mPrimaries)) {
955         sfAspects.mPrimaries = android::ColorAspects::PrimariesUnspecified;
956     }
957     if (!C2Mapper::map(mColorAspects->range, &sfAspects.mRange)) {
958         sfAspects.mRange = android::ColorAspects::RangeUnspecified;
959     }
960     if (!C2Mapper::map(mColorAspects->matrix, &sfAspects.mMatrixCoeffs)) {
961         sfAspects.mMatrixCoeffs = android::ColorAspects::MatrixUnspecified;
962     }
963     if (!C2Mapper::map(mColorAspects->transfer, &sfAspects.mTransfer)) {
964         sfAspects.mTransfer = android::ColorAspects::TransferUnspecified;
965     }
966 
967     int32_t isoPrimaries, isoTransfer, isoMatrix;
968     bool isoFullRange;
969     ColorUtils::convertCodecColorAspectsToIsoAspects(sfAspects,
970         &isoPrimaries, &isoTransfer, &isoMatrix, &isoFullRange);
971     param.color_primaries = isoPrimaries;
972     param.transfer_characteristics = isoTransfer;
973     param.matrix_coefficients = isoMatrix;
974     param.full_range_flag = isoFullRange;
975 
976     if (mColorAspects->primaries != C2Color::PRIMARIES_UNSPECIFIED ||
977             mColorAspects->transfer != C2Color::TRANSFER_UNSPECIFIED ||
978             mColorAspects->matrix != C2Color::MATRIX_UNSPECIFIED ||
979             mColorAspects->range != C2Color::RANGE_UNSPECIFIED) {
980         param.color_description_present_flag = 1;
981     }
982 }
983 
setEncodeArgs(oapv_frms_t * inputFrames,const C2GraphicView * const input,uint64_t workIndex)984 c2_status_t C2SoftApvEnc::setEncodeArgs(oapv_frms_t* inputFrames, const C2GraphicView* const input,
985                                         uint64_t workIndex) {
986     if (input->width() < mSize->width || input->height() < mSize->height) {
987         /* Expect width height to be configured */
988         ALOGW("unexpected Capacity Aspect %d(%d) x %d(%d)", input->width(), mSize->width,
989               input->height(), mSize->height);
990         return C2_BAD_VALUE;
991     }
992     const C2PlanarLayout& layout = input->layout();
993     uint8_t* yPlane = const_cast<uint8_t*>(input->data()[C2PlanarLayout::PLANE_Y]);
994     uint8_t* uPlane = const_cast<uint8_t*>(input->data()[C2PlanarLayout::PLANE_U]);
995     uint8_t* vPlane = const_cast<uint8_t*>(input->data()[C2PlanarLayout::PLANE_V]);
996 
997     uint32_t width = mSize->width;
998     uint32_t height = mSize->height;
999 
1000     /* width and height must be even */
1001     if (width & 1u || height & 1u) {
1002         ALOGW("height(%u) and width(%u) must both be even", height, width);
1003         return C2_BAD_VALUE;
1004     }
1005 
1006     /* Set num frames */
1007     inputFrames->num_frms = MAX_NUM_FRMS;
1008     inputFrames->frm[mReceivedFrames].group_id = 1;
1009     inputFrames->frm[mReceivedFrames].pbu_type = OAPV_PBU_TYPE_PRIMARY_FRAME;
1010 
1011     switch (layout.type) {
1012         case C2PlanarLayout::TYPE_RGB: {
1013             uint16_t *dstY  = (uint16_t*)inputFrames->frm[0].imgb->a[0];
1014             uint16_t *dstUV = (uint16_t*)inputFrames->frm[0].imgb->a[1];
1015             size_t dstYStride = inputFrames->frm[0].imgb->s[0] / 2;
1016             size_t dstUVStride = inputFrames->frm[0].imgb->s[1] / 2;
1017             convertRGBToP210(dstY, dstUV, (uint32_t*)(input->data()[0]),
1018                                         layout.planes[layout.PLANE_Y].rowInc / 4,
1019                                         dstYStride, dstUVStride, width, height,
1020                                         mColorAspects->matrix, mColorAspects->range);
1021             break;
1022         }
1023         case C2PlanarLayout::TYPE_RGBA: {
1024             [[fallthrough]];
1025         }
1026         case C2PlanarLayout::TYPE_YUVA: {
1027             ALOGV("Convert from ABGR2101010 to P210");
1028             if (mColorFormat == OAPV_CF_PLANAR2) {
1029                 uint16_t *dstY, *dstUV;
1030                 dstY = (uint16_t*)inputFrames->frm[0].imgb->a[0];
1031                 dstUV = (uint16_t*)inputFrames->frm[0].imgb->a[1];
1032                 size_t dstYStride = inputFrames->frm[0].imgb->s[0] / 2;
1033                 size_t dstUVStride = inputFrames->frm[0].imgb->s[1] / 2;
1034                 convertRGBA1010102ToP210(dstY, dstUV, (uint32_t*)(input->data()[0]),
1035                                                 layout.planes[layout.PLANE_Y].rowInc / 4,
1036                                                 dstYStride, dstUVStride, width, height,
1037                                                 mColorAspects->matrix, mColorAspects->range);
1038                 break;
1039             } else {
1040                 ALOGE("Not supported color format. %d", mColorFormat);
1041                 return C2_BAD_VALUE;
1042             }
1043         }
1044         case C2PlanarLayout::TYPE_YUV: {
1045             if (IsP010(*input)) {
1046                 ALOGV("Convert from P010 to P210");
1047                 if (mColorFormat == OAPV_CF_PLANAR2) {
1048                     uint16_t *srcY  = (uint16_t*)(input->data()[0]);
1049                     uint16_t *srcUV = (uint16_t*)(input->data()[1]);
1050                     uint16_t *dstY  = (uint16_t*)inputFrames->frm[0].imgb->a[0];
1051                     uint16_t *dstUV = (uint16_t*)inputFrames->frm[0].imgb->a[1];
1052                     size_t dstYStride = inputFrames->frm[0].imgb->s[0] / 2;
1053                     size_t dstUVStride = inputFrames->frm[0].imgb->s[1] / 2;
1054                     convertP010ToP210(dstY, dstUV, srcY, srcUV,
1055                                       layout.planes[layout.PLANE_Y].rowInc / 2,
1056                                       layout.planes[layout.PLANE_U].rowInc / 2,
1057                                       dstYStride, dstUVStride, width, height);
1058                 } else {
1059                     ALOGE("Not supported color format. %d", mColorFormat);
1060                     return C2_BAD_VALUE;
1061                 }
1062             } else if (IsP210(*input)) {
1063                 ALOGV("Convert from P210 to P210");
1064                 if (mColorFormat == OAPV_CF_PLANAR2) {
1065                     uint16_t *srcY  = (uint16_t*)(input->data()[0]);
1066                     uint16_t *srcUV = (uint16_t*)(input->data()[1]);
1067                     uint16_t *dstY  = (uint16_t*)inputFrames->frm[0].imgb->a[0];
1068                     uint16_t *dstUV = (uint16_t*)inputFrames->frm[0].imgb->a[1];
1069                     size_t srcYStride = layout.planes[layout.PLANE_Y].rowInc / 2;
1070                     size_t srcUVStride = layout.planes[layout.PLANE_U].rowInc / 2;
1071                     size_t dstYStride = inputFrames->frm[0].imgb->s[0] / 2;
1072                     size_t dstUVStride = inputFrames->frm[0].imgb->s[1] / 2;
1073 
1074                     for (size_t y = 0; y < height; ++y) {
1075                         std::memcpy(dstY, srcY, width * sizeof(uint16_t));
1076                         dstY += dstYStride;
1077                         srcY += srcYStride;
1078                     }
1079 
1080                     for (size_t y = 0; y < height; ++y) {
1081                         std::memcpy(dstUV, srcUV, width * sizeof(uint16_t));
1082                         srcUV += srcUVStride;
1083                         dstUV += dstUVStride;
1084                     }
1085                 } else {
1086                     ALOGE("Not supported color format. %d", mColorFormat);
1087                     return C2_BAD_VALUE;
1088                 }
1089             } else if (IsNV12(*input) || IsNV21(*input)) {
1090                 ALOGV("Convert from NV12 to P210");
1091                 uint8_t  *srcY  = (uint8_t*)input->data()[0];
1092                 uint8_t  *srcUV = (uint8_t*)input->data()[1];
1093                 uint16_t *dstY  = (uint16_t*)inputFrames->frm[0].imgb->a[0];
1094                 uint16_t *dstUV = (uint16_t*)inputFrames->frm[0].imgb->a[1];
1095                 size_t dstYStride = inputFrames->frm[0].imgb->s[0] / 2;
1096                 size_t dstUVStride = inputFrames->frm[0].imgb->s[1] / 2;
1097                 convertSemiPlanar8ToP210(dstY, dstUV, srcY, srcUV,
1098                                          layout.planes[layout.PLANE_Y].rowInc,
1099                                          layout.planes[layout.PLANE_U].rowInc,
1100                                          dstYStride, dstUVStride,
1101                                          width, height, CONV_FORMAT_I420, IsNV12(*input));
1102             } else if (IsI420(*input)) {
1103                 ALOGV("Convert from I420 to P210");
1104                 uint8_t  *srcY  = (uint8_t*)input->data()[0];
1105                 uint8_t  *srcU  = (uint8_t*)input->data()[1];
1106                 uint8_t  *srcV  = (uint8_t*)input->data()[2];
1107                 uint16_t *dstY  = (uint16_t*)inputFrames->frm[0].imgb->a[0];
1108                 uint16_t *dstUV = (uint16_t*)inputFrames->frm[0].imgb->a[1];
1109                 size_t dstYStride = inputFrames->frm[0].imgb->s[0] / 2;
1110                 size_t dstUVStride = inputFrames->frm[0].imgb->s[1] / 2;
1111                 convertPlanar8ToP210(dstY, dstUV, srcY, srcU, srcV,
1112                                         layout.planes[C2PlanarLayout::PLANE_Y].rowInc,
1113                                         layout.planes[C2PlanarLayout::PLANE_U].rowInc,
1114                                         layout.planes[C2PlanarLayout::PLANE_V].rowInc,
1115                                         dstYStride, dstUVStride,
1116                                         width, height,
1117                                         CONV_FORMAT_I420);
1118 
1119             } else {
1120                 ALOGE("Not supported color format. %d", mColorFormat);
1121                 return C2_BAD_VALUE;
1122             }
1123             break;
1124         }
1125 
1126         default:
1127             ALOGE("Unrecognized plane type: %d", layout.type);
1128             return C2_BAD_VALUE;
1129     }
1130 
1131     return C2_OK;
1132 }
1133 
finishWork(uint64_t workIndex,const std::unique_ptr<C2Work> & work,const std::shared_ptr<C2BlockPool> & pool,oapv_bitb_t * bitb,oapve_stat_t * stat)1134 void C2SoftApvEnc::finishWork(uint64_t workIndex, const std::unique_ptr<C2Work>& work,
1135                               const std::shared_ptr<C2BlockPool>& pool, oapv_bitb_t* bitb,
1136                               oapve_stat_t* stat) {
1137     std::shared_ptr<C2LinearBlock> block;
1138     C2MemoryUsage usage = {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE};
1139     c2_status_t status = pool->fetchLinearBlock(stat->write, usage, &block);
1140     if (C2_OK != status) {
1141         ALOGE("fetchLinearBlock for Output failed with status 0x%x", status);
1142         mSignalledError = true;
1143         work->result = status;
1144         work->workletsProcessed = 1u;
1145         return;
1146     }
1147 
1148     C2WriteView wView = block->map().get();
1149     if (C2_OK != wView.error()) {
1150         ALOGE("write view map failed with status 0x%x", wView.error());
1151         mSignalledError = true;
1152         work->result = wView.error();
1153         work->workletsProcessed = 1u;
1154         return;
1155     }
1156     if ((!mReceivedFirstFrame)) {
1157         createCsdData(work, bitb, stat->write);
1158         mReceivedFirstFrame = true;
1159     }
1160 
1161     memcpy(wView.data(), bitb->addr, stat->write);
1162     std::shared_ptr<C2Buffer> buffer = createLinearBuffer(block, 0, stat->write);
1163 
1164     /* All frames are SYNC FRAME */
1165     buffer->setInfo(std::make_shared<C2StreamPictureTypeMaskInfo::output>(0u /* stream id */,
1166                                                                           C2Config::SYNC_FRAME));
1167 
1168     auto fillWork = [buffer](const std::unique_ptr<C2Work>& work) {
1169         work->worklets.front()->output.flags = (C2FrameData::flags_t)0;
1170         work->worklets.front()->output.buffers.clear();
1171         work->worklets.front()->output.buffers.push_back(buffer);
1172         work->worklets.front()->output.ordinal = work->input.ordinal;
1173         work->workletsProcessed = 1u;
1174     };
1175     if (work && c2_cntr64_t(workIndex) == work->input.ordinal.frameIndex) {
1176         fillWork(work);
1177         if (mSignalledEos) {
1178             work->worklets.front()->output.flags = C2FrameData::FLAG_END_OF_STREAM;
1179         }
1180     } else {
1181         finish(workIndex, fillWork);
1182     }
1183 }
1184 
createCsdData(const std::unique_ptr<C2Work> & work,oapv_bitb_t * bitb,uint32_t encodedSize)1185 void C2SoftApvEnc::createCsdData(const std::unique_ptr<C2Work>& work,
1186                                  oapv_bitb_t* bitb,
1187                                  uint32_t encodedSize) {
1188     if (encodedSize < 35) {
1189         ALOGE("the first frame size is too small, so no csd data will be created.");
1190         return;
1191     }
1192     ABitReader reader((uint8_t*)bitb->addr, encodedSize);
1193 
1194     uint8_t number_of_configuration_entry = 0;
1195     uint8_t pbu_type = 0;
1196     uint8_t number_of_frame_info = 0;
1197     bool color_description_present_flag = false;
1198     bool capture_time_distance_ignored = false;
1199     uint8_t profile_idc = 0;
1200     uint8_t level_idc = 0;
1201     uint8_t band_idc = 0;
1202     uint32_t frame_width = 0;
1203     uint32_t frame_height = 0;
1204     uint8_t chroma_format_idc = 0;
1205     uint8_t bit_depth_minus8 = 0;
1206     uint8_t capture_time_distance = 0;
1207     uint8_t color_primaries = 0;
1208     uint8_t transfer_characteristics = 0;
1209     uint8_t full_range_flag = 0;
1210     uint8_t matrix_coefficients = 0;
1211 
1212     /* pbu_header() */
1213     reader.skipBits(32);           // pbu_size
1214     reader.skipBits(32);           // signature
1215     reader.skipBits(32);           // currReadSize
1216     pbu_type = reader.getBits(8);  // pbu_type
1217     reader.skipBits(16);           // group_id
1218     reader.skipBits(8);            // reserved_zero_8bits
1219 
1220     /* frame info() */
1221     profile_idc = reader.getBits(8);            // profile_idc
1222     level_idc = reader.getBits(8);              // level_idc
1223     band_idc = reader.getBits(3);               // band_idc
1224     reader.skipBits(5);                         // reserved_zero_5bits
1225     frame_width = reader.getBits(24);           // width
1226     frame_height = reader.getBits(24);          // height
1227     chroma_format_idc = reader.getBits(4);      // chroma_format_idc
1228     bit_depth_minus8 = reader.getBits(4);       // bit_depth
1229     capture_time_distance = reader.getBits(8);  // capture_time_distance
1230     reader.skipBits(8);                         // reserved_zero_8bits
1231 
1232     /* frame header() */
1233     reader.skipBits(8);  // reserved_zero_8bit
1234     color_description_present_flag = reader.getBits(1);  // color_description_present_flag
1235     if (color_description_present_flag) {
1236         color_primaries = reader.getBits(8);           // color_primaries
1237         transfer_characteristics = reader.getBits(8);  // transfer_characteristics
1238         matrix_coefficients = reader.getBits(8);       // matrix_coefficients
1239         full_range_flag = reader.getBits(1);           // full_range_flag
1240         reader.skipBits(7);                            // reserved_zero_7bits
1241     }
1242 
1243     number_of_configuration_entry = 1;  // The real-time encoding on the device is assumed to be 1.
1244     number_of_frame_info = 1;  // The real-time encoding on the device is assumed to be 1.
1245 
1246     std::vector<uint8_t> csdData;
1247 
1248     csdData.push_back((uint8_t)0x1);
1249     csdData.push_back(number_of_configuration_entry);
1250 
1251     for (uint8_t i = 0; i < number_of_configuration_entry; i++) {
1252         csdData.push_back(pbu_type);
1253         csdData.push_back(number_of_frame_info);
1254         for (uint8_t j = 0; j < number_of_frame_info; j++) {
1255             csdData.push_back((uint8_t)((color_description_present_flag << 1) |
1256                                       capture_time_distance_ignored));
1257             csdData.push_back(profile_idc);
1258             csdData.push_back(level_idc);
1259             csdData.push_back(band_idc);
1260             csdData.push_back((uint8_t)((frame_width >> 24) & 0xff));
1261             csdData.push_back((uint8_t)((frame_width >> 16) & 0xff));
1262             csdData.push_back((uint8_t)((frame_width >> 8) & 0xff));
1263             csdData.push_back((uint8_t)(frame_width & 0xff));
1264             csdData.push_back((uint8_t)((frame_height >> 24) & 0xff));
1265             csdData.push_back((uint8_t)((frame_height >> 16) & 0xff));
1266             csdData.push_back((uint8_t)((frame_height >> 8) & 0xff));
1267             csdData.push_back((uint8_t)(frame_height & 0xff));
1268             csdData.push_back((uint8_t)(((chroma_format_idc << 4) & 0xf0) |
1269                                       (bit_depth_minus8 & 0xf)));
1270             csdData.push_back((uint8_t)(capture_time_distance));
1271             if (color_description_present_flag) {
1272                 csdData.push_back(color_primaries);
1273                 csdData.push_back(transfer_characteristics);
1274                 csdData.push_back(matrix_coefficients);
1275                 csdData.push_back(full_range_flag << 7);
1276             }
1277         }
1278     }
1279 
1280     std::unique_ptr<C2StreamInitDataInfo::output> csd =
1281         C2StreamInitDataInfo::output::AllocUnique(csdData.size(), 0u);
1282     if (!csd) {
1283         ALOGE("CSD allocation failed");
1284         mSignalledError = true;
1285         work->result = C2_NO_MEMORY;
1286         work->workletsProcessed = 1u;
1287         return;
1288     }
1289 
1290     memcpy(csd->m.value, csdData.data(), csdData.size());
1291     work->worklets.front()->output.configUpdate.push_back(std::move(csd));
1292 }
1293 
drainInternal(uint32_t drainMode,const std::shared_ptr<C2BlockPool> & pool,const std::unique_ptr<C2Work> & work)1294 c2_status_t C2SoftApvEnc::drainInternal(uint32_t drainMode,
1295                                         const std::shared_ptr<C2BlockPool>& pool,
1296                                         const std::unique_ptr<C2Work>& work) {
1297     fillEmptyWork(work);
1298     return C2_OK;
1299 }
1300 
process(const std::unique_ptr<C2Work> & work,const std::shared_ptr<C2BlockPool> & pool)1301 void C2SoftApvEnc::process(const std::unique_ptr<C2Work>& work,
1302                            const std::shared_ptr<C2BlockPool>& pool) {
1303     c2_status_t error;
1304     work->result = C2_OK;
1305     work->workletsProcessed = 0u;
1306     work->worklets.front()->output.flags = work->input.flags;
1307 
1308     nsecs_t timeDelay = 0;
1309     uint64_t workIndex = work->input.ordinal.frameIndex.peekull();
1310 
1311     mSignalledEos = false;
1312     mOutBlock = nullptr;
1313 
1314     if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
1315         ALOGV("Got FLAG_END_OF_STREAM");
1316         mSignalledEos = true;
1317     }
1318 
1319     /* Initialize encoder if not already initialized */
1320     if (initEncoder() != C2_OK) {
1321         ALOGE("Failed to initialize encoder");
1322         mSignalledError = true;
1323         work->result = C2_CORRUPTED;
1324         work->workletsProcessed = 1u;
1325         ALOGE("[%s] Failed to make Codec context", __func__);
1326         return;
1327     }
1328     if (mSignalledError) {
1329         ALOGE("[%s] Received signalled error", __func__);
1330         return;
1331     }
1332 
1333     if (mSignalledEos) {
1334         drainInternal(DRAIN_COMPONENT_WITH_EOS, pool, work);
1335         return;
1336     }
1337 
1338     std::shared_ptr<C2GraphicView> view;
1339     std::shared_ptr<C2Buffer> inputBuffer = nullptr;
1340     if (!work->input.buffers.empty()) {
1341         inputBuffer = work->input.buffers[0];
1342         view = std::make_shared<C2GraphicView>(
1343                 inputBuffer->data().graphicBlocks().front().map().get());
1344         if (view->error() != C2_OK) {
1345             ALOGE("graphic view map err = %d", view->error());
1346             work->workletsProcessed = 1u;
1347             return;
1348         }
1349     } else {
1350         ALOGV("Empty input Buffer");
1351         uint32_t flags = 0;
1352         if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
1353             flags |= C2FrameData::FLAG_END_OF_STREAM;
1354         }
1355         work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
1356         work->worklets.front()->output.buffers.clear();
1357         work->worklets.front()->output.ordinal = work->input.ordinal;
1358         work->workletsProcessed = 1u;
1359         return;
1360     }
1361 
1362     if (!inputBuffer) {
1363         fillEmptyWork(work);
1364         return;
1365     }
1366 
1367     oapve_stat_t stat;
1368     auto outBufferSize =
1369             mCodecDesc->param[mReceivedFrames].w * mCodecDesc->param[mReceivedFrames].h * 4;
1370     if (!mOutBlock) {
1371         C2MemoryUsage usage = {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE};
1372         c2_status_t err = pool->fetchLinearBlock(outBufferSize, usage, &mOutBlock);
1373         if (err != C2_OK) {
1374             work->result = err;
1375             work->workletsProcessed = 1u;
1376             ALOGE("fetchLinearBlock has failed. err = %d", err);
1377             return;
1378         }
1379     }
1380 
1381     C2WriteView wView = mOutBlock->map().get();
1382     if (wView.error() != C2_OK) {
1383         work->result = wView.error();
1384         work->workletsProcessed = 1u;
1385         return;
1386     }
1387 
1388     view->setCrop_be(C2Rect(mSize->width, mSize->height));
1389 
1390     error = setEncodeArgs(&mInputFrames, view.get(), workIndex);
1391     if (error != C2_OK) {
1392         ALOGE("setEncodeArgs has failed. err = %d", error);
1393         mSignalledError = true;
1394         work->result = error;
1395         work->workletsProcessed = 1u;
1396         return;
1397     }
1398 
1399     if (++mReceivedFrames < mMaxFrames) {
1400         return;
1401     }
1402     mReceivedFrames = 0;
1403 
1404     std::shared_ptr<oapv_bitb_t> bits = std::make_shared<oapv_bitb_t>();
1405     std::memset(mBitstreamBuf, 0, kMaxBitstreamBufSize);
1406     bits->addr = mBitstreamBuf;
1407     bits->bsize = kMaxBitstreamBufSize;
1408     bits->err = C2_OK;
1409 
1410     if (mInputFrames.frm[0].imgb) {
1411         int32_t status =
1412                 oapve_encode(mEncoderId, &mInputFrames, mMetaId, bits.get(), &stat, &mReconFrames);
1413         if (status != C2_OK) {
1414             ALOGE("oapve_encode has failed. err = %d", status);
1415             mSignalledError = true;
1416             work->result = C2_CORRUPTED;
1417             work->workletsProcessed = 1u;
1418             return;
1419         }
1420     } else if (!mSignalledEos) {
1421         fillEmptyWork(work);
1422     }
1423     finishWork(workIndex, work, pool, bits.get(), &stat);
1424 }
1425 
1426 class C2SoftApvEncFactory : public C2ComponentFactory {
1427   public:
C2SoftApvEncFactory()1428     C2SoftApvEncFactory()
1429         : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
1430                   GetCodec2PlatformComponentStore()->getParamReflector())) {}
1431 
createComponent(c2_node_id_t id,std::shared_ptr<C2Component> * const component,std::function<void (C2Component *)> deleter)1432     virtual c2_status_t createComponent(c2_node_id_t id,
1433                                         std::shared_ptr<C2Component>* const component,
1434                                         std::function<void(C2Component*)> deleter) override {
1435         *component = std::shared_ptr<C2Component>(
1436                 new C2SoftApvEnc(COMPONENT_NAME, id,
1437                                  std::make_shared<C2SoftApvEnc::IntfImpl>(mHelper)),
1438                 deleter);
1439         return C2_OK;
1440     }
1441 
createInterface(c2_node_id_t id,std::shared_ptr<C2ComponentInterface> * const interface,std::function<void (C2ComponentInterface *)> deleter)1442     c2_status_t createInterface(c2_node_id_t id,
1443                                 std::shared_ptr<C2ComponentInterface>* const interface,
1444                                 std::function<void(C2ComponentInterface*)> deleter) override {
1445         *interface = std::shared_ptr<C2ComponentInterface>(
1446                 new SimpleInterface<C2SoftApvEnc::IntfImpl>(
1447                         COMPONENT_NAME, id, std::make_shared<C2SoftApvEnc::IntfImpl>(mHelper)),
1448                 deleter);
1449         return C2_OK;
1450     }
1451 
1452     ~C2SoftApvEncFactory() override = default;
1453 
1454   private:
1455     std::shared_ptr<C2ReflectorHelper> mHelper;
1456 };
1457 
1458 }  // namespace android
1459 
CreateCodec2Factory()1460 __attribute__((cfi_canonical_jump_table)) extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
1461     if (!android::media::swcodec::flags::apv_software_codec()) {
1462         ALOGV("APV SW Codec is not enabled");
1463         return nullptr;
1464     }
1465 
1466     bool enabled = isAtLeastRelease(36, "Baklava");
1467     ALOGD("isAtLeastRelease(36, Baklava) says enable: %s", enabled ? "yes" : "no");
1468     if (!enabled) {
1469         return nullptr;
1470     }
1471 
1472     return new ::android::C2SoftApvEncFactory();
1473 }
1474 
DestroyCodec2Factory(::C2ComponentFactory * factory)1475 __attribute__((cfi_canonical_jump_table)) extern "C" void DestroyCodec2Factory(
1476         ::C2ComponentFactory* factory) {
1477     delete factory;
1478 }
1479