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