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_TAG "ApexCodecs"
18 // #define LOG_NDEBUG 0
19 #include <android-base/logging.h>
20
21 #include <new>
22 #include <map>
23 #include <vector>
24
25 #include <C2ParamInternal.h>
26 #include <android_media_swcodec_flags.h>
27
28 #include <android-base/no_destructor.h>
29 #include <apex/ApexCodecs.h>
30 #include <apex/ApexCodecsImpl.h>
31 #include <apex/ApexCodecsParam.h>
32
33 // TODO: remove when we have real implementations
34 #pragma clang diagnostic push
35 #pragma clang diagnostic ignored "-Wunused-parameter"
36
37 using ::android::apexcodecs::ApexComponentIntf;
38 using ::android::apexcodecs::ApexComponentStoreIntf;
39 using ::android::base::ERROR;
40
41 struct ApexCodec_Component {
ApexCodec_ComponentApexCodec_Component42 explicit ApexCodec_Component(std::unique_ptr<ApexComponentIntf> &&comp)
43 : mComponent(std::move(comp)) {
44 }
45
startApexCodec_Component46 ApexCodec_Status start() {
47 return mComponent->start();
48 }
49
flushApexCodec_Component50 ApexCodec_Status flush() {
51 return mComponent->flush();
52 }
53
resetApexCodec_Component54 ApexCodec_Status reset() {
55 return mComponent->reset();
56 }
57
58 private:
59 std::unique_ptr<ApexComponentIntf> mComponent;
60 };
61
62 struct ApexCodec_ComponentStore {
ApexCodec_ComponentStoreApexCodec_ComponentStore63 ApexCodec_ComponentStore() : mStore((ApexComponentStoreIntf *)GetApexComponentStore()) {
64 if (mStore == nullptr) {
65 return;
66 }
67 mC2Traits = mStore->listComponents();
68 mTraits.reserve(mC2Traits.size());
69 for (const std::shared_ptr<const C2Component::Traits> &trait : mC2Traits) {
70 mTraits.push_back(ApexCodec_ComponentTraits{
71 trait->name.c_str(), // name
72 trait->mediaType.c_str(), // mediaType
73 (ApexCodec_Kind)trait->kind, // kind
74 (ApexCodec_Domain)trait->domain, // domain
75 });
76 }
77 }
78
getTraitsApexCodec_ComponentStore79 ApexCodec_ComponentTraits *getTraits(size_t index) {
80 if (mStore == nullptr) {
81 return nullptr;
82 }
83 if (index < mTraits.size()) {
84 return mTraits.data() + index;
85 } else {
86 return nullptr;
87 }
88 }
89
createComponentApexCodec_ComponentStore90 std::unique_ptr<ApexComponentIntf> createComponent(const char *name) {
91 if (mStore == nullptr) {
92 return nullptr;
93 }
94 return mStore->createComponent(name);
95 }
96 private:
97 ApexComponentStoreIntf *mStore;
98 std::vector<std::shared_ptr<const C2Component::Traits>> mC2Traits;
99 std::vector<ApexCodec_ComponentTraits> mTraits;
100 };
101
ApexCodec_GetComponentStore()102 ApexCodec_ComponentStore *ApexCodec_GetComponentStore() {
103 ::android::base::NoDestructor<ApexCodec_ComponentStore> store;
104 return store.get();
105 }
106
ApexCodec_Traits_get(ApexCodec_ComponentStore * store,size_t index)107 ApexCodec_ComponentTraits *ApexCodec_Traits_get(
108 ApexCodec_ComponentStore *store, size_t index) {
109 if (!android::media::swcodec::flags::apexcodecs_base()) {
110 return nullptr;
111 }
112 return store->getTraits(index);
113 }
114
ApexCodec_Component_create(ApexCodec_ComponentStore * store,const char * name,ApexCodec_Component ** comp)115 ApexCodec_Status ApexCodec_Component_create(
116 ApexCodec_ComponentStore *store, const char *name, ApexCodec_Component **comp) {
117 if (!android::media::swcodec::flags::apexcodecs_base()) {
118 return APEXCODEC_STATUS_NOT_FOUND;
119 }
120 if (store == nullptr) {
121 LOG(ERROR) << "ApexCodec_Component_create: store is nullptr";
122 return APEXCODEC_STATUS_BAD_VALUE;
123 }
124 if (name == nullptr) {
125 LOG(ERROR) << "ApexCodec_Component_create: name is nullptr";
126 return APEXCODEC_STATUS_BAD_VALUE;
127 }
128 if (comp == nullptr) {
129 LOG(ERROR) << "ApexCodec_Component_create: comp is nullptr";
130 return APEXCODEC_STATUS_BAD_VALUE;
131 }
132 *comp = nullptr;
133 std::unique_ptr<ApexComponentIntf> compIntf = store->createComponent(name);
134 if (compIntf == nullptr) {
135 return APEXCODEC_STATUS_NOT_FOUND;
136 }
137 *comp = new ApexCodec_Component(std::move(compIntf));
138 return APEXCODEC_STATUS_OK;
139 }
140
ApexCodec_Component_destroy(ApexCodec_Component * comp)141 void ApexCodec_Component_destroy(ApexCodec_Component *comp) {
142 delete comp;
143 }
144
ApexCodec_Component_start(ApexCodec_Component * comp)145 ApexCodec_Status ApexCodec_Component_start(ApexCodec_Component *comp) {
146 if (comp == nullptr) {
147 return APEXCODEC_STATUS_BAD_VALUE;
148 }
149 return comp->start();
150 }
151
ApexCodec_Component_flush(ApexCodec_Component * comp)152 ApexCodec_Status ApexCodec_Component_flush(ApexCodec_Component *comp) {
153 if (comp == nullptr) {
154 return APEXCODEC_STATUS_BAD_VALUE;
155 }
156 return comp->flush();
157 }
158
ApexCodec_Component_reset(ApexCodec_Component * comp)159 ApexCodec_Status ApexCodec_Component_reset(ApexCodec_Component *comp) {
160 if (comp == nullptr) {
161 return APEXCODEC_STATUS_BAD_VALUE;
162 }
163 return comp->reset();
164 }
165
ApexCodec_Component_getConfigurable(ApexCodec_Component * comp)166 ApexCodec_Configurable *ApexCodec_Component_getConfigurable(
167 ApexCodec_Component *comp) {
168 return nullptr;
169 }
170
171 struct ApexCodec_Buffer {
172 public:
ApexCodec_BufferApexCodec_Buffer173 ApexCodec_Buffer()
174 : mType(APEXCODEC_BUFFER_TYPE_EMPTY) {
175 }
176
~ApexCodec_BufferApexCodec_Buffer177 ~ApexCodec_Buffer() {
178 }
179
clearApexCodec_Buffer180 void clear() {
181 mType = APEXCODEC_BUFFER_TYPE_EMPTY;
182 mBufferInfo.reset();
183 mLinearBuffer = {};
184 mGraphicBuffer = nullptr;
185 mConfigUpdates.reset();
186 mOwnedConfigUpdates.reset();
187 }
188
getTypeApexCodec_Buffer189 ApexCodec_BufferType getType() const {
190 return mType;
191 }
192
setBufferInfoApexCodec_Buffer193 void setBufferInfo(ApexCodec_BufferFlags flags, uint64_t frameIndex, uint64_t timestampUs) {
194 mBufferInfo.emplace(BufferInfo{flags, frameIndex, timestampUs});
195 }
196
setLinearBufferApexCodec_Buffer197 ApexCodec_Status setLinearBuffer(const ApexCodec_LinearBuffer *linearBuffer) {
198 if (mType != APEXCODEC_BUFFER_TYPE_EMPTY) {
199 return APEXCODEC_STATUS_BAD_STATE;
200 }
201 mType = APEXCODEC_BUFFER_TYPE_LINEAR;
202 if (linearBuffer == nullptr) {
203 mLinearBuffer.data = nullptr;
204 mLinearBuffer.size = 0;
205 } else {
206 mLinearBuffer = *linearBuffer;
207 }
208 return APEXCODEC_STATUS_OK;
209 }
210
setGraphicBufferApexCodec_Buffer211 ApexCodec_Status setGraphicBuffer(AHardwareBuffer *graphicBuffer) {
212 if (mType != APEXCODEC_BUFFER_TYPE_EMPTY) {
213 return APEXCODEC_STATUS_BAD_STATE;
214 }
215 mType = APEXCODEC_BUFFER_TYPE_GRAPHIC;
216 mGraphicBuffer = graphicBuffer;
217 return APEXCODEC_STATUS_OK;
218 }
219
setConfigUpdatesApexCodec_Buffer220 ApexCodec_Status setConfigUpdates(const ApexCodec_LinearBuffer *configUpdates) {
221 if (configUpdates == nullptr) {
222 return APEXCODEC_STATUS_BAD_VALUE;
223 }
224 if (mConfigUpdates.has_value()) {
225 return APEXCODEC_STATUS_BAD_STATE;
226 }
227 mOwnedConfigUpdates.reset();
228 mConfigUpdates.emplace(*configUpdates);
229 return APEXCODEC_STATUS_OK;
230 }
231
getBufferInfoApexCodec_Buffer232 ApexCodec_Status getBufferInfo(
233 ApexCodec_BufferFlags *outFlags,
234 uint64_t *outFrameIndex,
235 uint64_t *outTimestampUs) const {
236 if (!mBufferInfo.has_value()) {
237 return APEXCODEC_STATUS_BAD_STATE;
238 }
239 *outFlags = mBufferInfo->flags;
240 *outFrameIndex = mBufferInfo->frameIndex;
241 *outTimestampUs = mBufferInfo->timestampUs;
242 return APEXCODEC_STATUS_OK;
243 }
244
getLinearBufferApexCodec_Buffer245 ApexCodec_Status getLinearBuffer(ApexCodec_LinearBuffer *outLinearBuffer) const {
246 if (mType != APEXCODEC_BUFFER_TYPE_LINEAR) {
247 return APEXCODEC_STATUS_BAD_STATE;
248 }
249 *outLinearBuffer = mLinearBuffer;
250 return APEXCODEC_STATUS_OK;
251 }
252
getGraphicBufferApexCodec_Buffer253 ApexCodec_Status getGraphicBuffer(AHardwareBuffer **outGraphicBuffer) const {
254 if (mType != APEXCODEC_BUFFER_TYPE_GRAPHIC) {
255 return APEXCODEC_STATUS_BAD_STATE;
256 }
257 *outGraphicBuffer = mGraphicBuffer;
258 return APEXCODEC_STATUS_OK;
259 }
260
getConfigUpdatesApexCodec_Buffer261 ApexCodec_Status getConfigUpdates(
262 ApexCodec_LinearBuffer *outConfigUpdates,
263 bool *outOwnedByClient) const {
264 if (!mConfigUpdates.has_value()) {
265 return APEXCODEC_STATUS_NOT_FOUND;
266 }
267 *outConfigUpdates = mConfigUpdates.value();
268 *outOwnedByClient = mOwnedConfigUpdates.has_value();
269 return APEXCODEC_STATUS_OK;
270 }
271
setOwnedConfigUpdatesApexCodec_Buffer272 void setOwnedConfigUpdates(std::vector<uint8_t> &&configUpdates) {
273 mOwnedConfigUpdates = std::move(configUpdates);
274 mConfigUpdates.emplace(
275 ApexCodec_LinearBuffer{ configUpdates.data(), configUpdates.size() });
276 }
277
278 private:
279 struct BufferInfo {
280 ApexCodec_BufferFlags flags;
281 uint64_t frameIndex;
282 uint64_t timestampUs;
283 };
284
285 ApexCodec_BufferType mType;
286 std::optional<BufferInfo> mBufferInfo;
287 ApexCodec_LinearBuffer mLinearBuffer;
288 AHardwareBuffer *mGraphicBuffer;
289 std::optional<ApexCodec_LinearBuffer> mConfigUpdates;
290 std::optional<std::vector<uint8_t>> mOwnedConfigUpdates;
291 };
292
ApexCodec_Buffer_create()293 ApexCodec_Buffer *ApexCodec_Buffer_create() {
294 return new ApexCodec_Buffer;
295 }
296
ApexCodec_Buffer_destroy(ApexCodec_Buffer * buffer)297 void ApexCodec_Buffer_destroy(ApexCodec_Buffer *buffer) {
298 delete buffer;
299 }
300
ApexCodec_Buffer_clear(ApexCodec_Buffer * buffer)301 void ApexCodec_Buffer_clear(ApexCodec_Buffer *buffer) {
302 if (buffer == nullptr) {
303 return;
304 }
305 buffer->clear();
306 }
307
ApexCodec_Buffer_getType(ApexCodec_Buffer * buffer)308 ApexCodec_BufferType ApexCodec_Buffer_getType(ApexCodec_Buffer *buffer) {
309 if (buffer == nullptr) {
310 return APEXCODEC_BUFFER_TYPE_EMPTY;
311 }
312 return buffer->getType();
313 }
314
ApexCodec_Buffer_setBufferInfo(ApexCodec_Buffer * buffer,ApexCodec_BufferFlags flags,uint64_t frameIndex,uint64_t timestampUs)315 void ApexCodec_Buffer_setBufferInfo(
316 ApexCodec_Buffer *buffer,
317 ApexCodec_BufferFlags flags,
318 uint64_t frameIndex,
319 uint64_t timestampUs) {
320 if (buffer == nullptr) {
321 return;
322 }
323 buffer->setBufferInfo(flags, frameIndex, timestampUs);
324 }
325
ApexCodec_Buffer_setLinearBuffer(ApexCodec_Buffer * buffer,const ApexCodec_LinearBuffer * linearBuffer)326 ApexCodec_Status ApexCodec_Buffer_setLinearBuffer(
327 ApexCodec_Buffer *buffer,
328 const ApexCodec_LinearBuffer *linearBuffer) {
329 if (buffer == nullptr) {
330 return APEXCODEC_STATUS_BAD_VALUE;
331 }
332 return buffer->setLinearBuffer(linearBuffer);
333 }
334
ApexCodec_Buffer_setGraphicBuffer(ApexCodec_Buffer * buffer,AHardwareBuffer * graphicBuffer)335 ApexCodec_Status ApexCodec_Buffer_setGraphicBuffer(
336 ApexCodec_Buffer *buffer,
337 AHardwareBuffer *graphicBuffer) {
338 if (buffer == nullptr) {
339 return APEXCODEC_STATUS_BAD_VALUE;
340 }
341 return buffer->setGraphicBuffer(graphicBuffer);
342 }
343
ApexCodec_Buffer_setConfigUpdates(ApexCodec_Buffer * buffer,const ApexCodec_LinearBuffer * configUpdates)344 ApexCodec_Status ApexCodec_Buffer_setConfigUpdates(
345 ApexCodec_Buffer *buffer,
346 const ApexCodec_LinearBuffer *configUpdates) {
347 if (buffer == nullptr) {
348 return APEXCODEC_STATUS_BAD_VALUE;
349 }
350 return buffer->setConfigUpdates(configUpdates);
351 }
352
ApexCodec_Buffer_getBufferInfo(ApexCodec_Buffer * buffer,ApexCodec_BufferFlags * outFlags,uint64_t * outFrameIndex,uint64_t * outTimestampUs)353 ApexCodec_Status ApexCodec_Buffer_getBufferInfo(
354 ApexCodec_Buffer *buffer,
355 ApexCodec_BufferFlags *outFlags,
356 uint64_t *outFrameIndex,
357 uint64_t *outTimestampUs) {
358 if (buffer == nullptr) {
359 return APEXCODEC_STATUS_BAD_VALUE;
360 }
361 return buffer->getBufferInfo(outFlags, outFrameIndex, outTimestampUs);
362 }
363
ApexCodec_Buffer_getLinearBuffer(ApexCodec_Buffer * buffer,ApexCodec_LinearBuffer * outLinearBuffer)364 ApexCodec_Status ApexCodec_Buffer_getLinearBuffer(
365 ApexCodec_Buffer *buffer,
366 ApexCodec_LinearBuffer *outLinearBuffer) {
367 if (buffer == nullptr) {
368 return APEXCODEC_STATUS_BAD_VALUE;
369 }
370 return buffer->getLinearBuffer(outLinearBuffer);
371 }
372
ApexCodec_Buffer_getGraphicBuffer(ApexCodec_Buffer * buffer,AHardwareBuffer ** outGraphicBuffer)373 ApexCodec_Status ApexCodec_Buffer_getGraphicBuffer(
374 ApexCodec_Buffer *buffer,
375 AHardwareBuffer **outGraphicBuffer) {
376 if (buffer == nullptr) {
377 return APEXCODEC_STATUS_BAD_VALUE;
378 }
379 return buffer->getGraphicBuffer(outGraphicBuffer);
380 }
381
ApexCodec_Buffer_getConfigUpdates(ApexCodec_Buffer * buffer,ApexCodec_LinearBuffer * outConfigUpdates,bool * outOwnedByClient)382 ApexCodec_Status ApexCodec_Buffer_getConfigUpdates(
383 ApexCodec_Buffer *buffer,
384 ApexCodec_LinearBuffer *outConfigUpdates,
385 bool *outOwnedByClient) {
386 if (buffer == nullptr) {
387 return APEXCODEC_STATUS_BAD_VALUE;
388 }
389 return buffer->getConfigUpdates(outConfigUpdates, outOwnedByClient);
390 }
391
392 struct ApexCodec_SupportedValues {
393 public:
ApexCodec_SupportedValuesApexCodec_SupportedValues394 ApexCodec_SupportedValues(
395 const C2FieldSupportedValues &supportedValues,
396 const C2Value::type_t &numberType) {
397 mType = (ApexCodec_SupportedValuesType)supportedValues.type;
398 mNumberType = (ApexCodec_SupportedValuesNumberType)numberType;
399 switch (supportedValues.type) {
400 case C2FieldSupportedValues::RANGE: {
401 mValues.insert(mValues.end(), 5, ApexCodec_Value{});
402 ToApexCodecValue(supportedValues.range.min, numberType, &mValues[0]);
403 ToApexCodecValue(supportedValues.range.max, numberType, &mValues[1]);
404 ToApexCodecValue(supportedValues.range.step, numberType, &mValues[2]);
405 ToApexCodecValue(supportedValues.range.num, numberType, &mValues[3]);
406 ToApexCodecValue(supportedValues.range.denom, numberType, &mValues[4]);
407 break;
408 }
409 case C2FieldSupportedValues::VALUES:
410 case C2FieldSupportedValues::FLAGS: {
411 for (size_t i = 0; i < supportedValues.values.size(); ++i) {
412 mValues.emplace_back();
413 ToApexCodecValue(supportedValues.values[i], numberType, &mValues[i]);
414 }
415 break;
416 }
417 default:
418 // Unrecognized type; initialize as empty.
419 mType = APEXCODEC_SUPPORTED_VALUES_EMPTY;
420 break;
421 }
422 }
423
~ApexCodec_SupportedValuesApexCodec_SupportedValues424 ~ApexCodec_SupportedValues() {
425 }
426
getTypeAndValuesApexCodec_SupportedValues427 ApexCodec_Status getTypeAndValues(
428 ApexCodec_SupportedValuesType *type,
429 ApexCodec_SupportedValuesNumberType *numberType,
430 ApexCodec_Value **values,
431 uint32_t *numValues) {
432 if (type == nullptr) {
433 return APEXCODEC_STATUS_BAD_VALUE;
434 }
435 if (numberType == nullptr) {
436 return APEXCODEC_STATUS_BAD_VALUE;
437 }
438 if (values == nullptr) {
439 return APEXCODEC_STATUS_BAD_VALUE;
440 }
441 if (numValues == nullptr) {
442 return APEXCODEC_STATUS_BAD_VALUE;
443 }
444 *type = mType;
445 *numberType = mNumberType;
446 switch (mType) {
447 case APEXCODEC_SUPPORTED_VALUES_EMPTY: {
448 *values = nullptr;
449 *numValues = 0;
450 break;
451 }
452 case APEXCODEC_SUPPORTED_VALUES_RANGE:
453 case APEXCODEC_SUPPORTED_VALUES_VALUES:
454 case APEXCODEC_SUPPORTED_VALUES_FLAGS: {
455 if (mValues.empty()) {
456 return APEXCODEC_STATUS_BAD_STATE;
457 }
458 *values = mValues.data();
459 *numValues = mValues.size();
460 break;
461 }
462 default:
463 return APEXCODEC_STATUS_BAD_STATE;
464 }
465 return APEXCODEC_STATUS_OK;
466 }
467
ToApexCodecValueApexCodec_SupportedValues468 static bool ToApexCodecValue(
469 const C2Value::Primitive &value,
470 const C2Value::type_t &type,
471 ApexCodec_Value *outValue) {
472 switch (type) {
473 case C2Value::NO_INIT:
474 return false;
475 case C2Value::INT32:
476 outValue->i32 = value.i32;
477 return true;
478 case C2Value::UINT32:
479 outValue->u32 = value.u32;
480 return true;
481 case C2Value::INT64:
482 outValue->i64 = value.i64;
483 return true;
484 case C2Value::UINT64:
485 outValue->u64 = value.u64;
486 return true;
487 case C2Value::FLOAT:
488 outValue->f = value.fp;
489 return true;
490 default:
491 return false;
492 }
493 }
494
GetFieldTypeApexCodec_SupportedValues495 static C2Value::type_t GetFieldType(
496 const std::shared_ptr<C2ParamReflector> &reflector,
497 const C2ParamField& field) {
498 std::unique_ptr<C2StructDescriptor> desc = reflector->describe(
499 _C2ParamInspector::GetIndex(field));
500
501 for (const C2FieldDescriptor &fieldDesc : *desc) {
502 if (_C2ParamInspector::GetOffset(fieldDesc) == _C2ParamInspector::GetOffset(field)) {
503 if (_C2ParamInspector::GetSize(fieldDesc) != _C2ParamInspector::GetSize(field)) {
504 // Size doesn't match.
505 return C2Value::NO_INIT;
506 }
507 switch (fieldDesc.type()) {
508 case C2FieldDescriptor::INT32:
509 case C2FieldDescriptor::UINT32:
510 case C2FieldDescriptor::INT64:
511 case C2FieldDescriptor::UINT64:
512 case C2FieldDescriptor::FLOAT:
513 return (C2Value::type_t)fieldDesc.type();
514 default:
515 // Unrecognized type.
516 return C2Value::NO_INIT;
517 }
518 }
519 }
520 return C2Value::NO_INIT;
521 }
522
523 private:
524 ApexCodec_SupportedValuesType mType;
525 ApexCodec_SupportedValuesNumberType mNumberType;
526 std::vector<ApexCodec_Value> mValues;
527 };
528
ApexCodec_SupportedValues_getTypeAndValues(ApexCodec_SupportedValues * supportedValues,ApexCodec_SupportedValuesType * type,ApexCodec_SupportedValuesNumberType * numberType,ApexCodec_Value ** values,uint32_t * numValues)529 ApexCodec_Status ApexCodec_SupportedValues_getTypeAndValues(
530 ApexCodec_SupportedValues *supportedValues,
531 ApexCodec_SupportedValuesType *type,
532 ApexCodec_SupportedValuesNumberType *numberType,
533 ApexCodec_Value **values,
534 uint32_t *numValues) {
535 if (supportedValues == nullptr) {
536 return APEXCODEC_STATUS_BAD_VALUE;
537 }
538 return supportedValues->getTypeAndValues(type, numberType, values, numValues);
539 }
540
ApexCodec_SupportedValues_destroy(ApexCodec_SupportedValues * values)541 void ApexCodec_SupportedValues_destroy(ApexCodec_SupportedValues *values) {
542 delete values;
543 }
544
545 struct ApexCodec_SettingResults {
546 public:
ApexCodec_SettingResultsApexCodec_SettingResults547 explicit ApexCodec_SettingResults(
548 const std::shared_ptr<C2ParamReflector> &reflector,
549 const std::vector<C2SettingResult> &results) : mReflector(reflector) {
550 for (const C2SettingResult &c2Result : results) {
551 mResults.emplace_back();
552 Entry &entry = mResults.back();
553 entry.failure = (ApexCodec_SettingResultFailure)c2Result.failure;
554 entry.field.index = _C2ParamInspector::GetIndex(c2Result.field.paramOrField);
555 entry.field.offset = _C2ParamInspector::GetOffset(c2Result.field.paramOrField);
556 entry.field.size = _C2ParamInspector::GetSize(c2Result.field.paramOrField);
557 if (c2Result.field.values) {
558 entry.fieldValues = std::make_unique<ApexCodec_SupportedValues>(
559 *c2Result.field.values,
560 ApexCodec_SupportedValues::GetFieldType(mReflector,
561 c2Result.field.paramOrField));
562 entry.field.values = entry.fieldValues.get();
563 } else {
564 entry.field.values = nullptr;
565 }
566 for (const C2ParamFieldValues &c2Conflict : c2Result.conflicts) {
567 entry.conflicts.emplace_back();
568 ApexCodec_ParamFieldValues &conflict = entry.conflicts.back();
569 conflict.index = _C2ParamInspector::GetIndex(c2Conflict.paramOrField);
570 conflict.offset = _C2ParamInspector::GetOffset(c2Conflict.paramOrField);
571 conflict.size = _C2ParamInspector::GetSize(c2Conflict.paramOrField);
572 if (c2Conflict.values) {
573 entry.conflictValues.emplace_back(std::make_unique<ApexCodec_SupportedValues>(
574 *c2Conflict.values,
575 ApexCodec_SupportedValues::GetFieldType(mReflector,
576 c2Conflict.paramOrField)));
577 conflict.values = entry.conflictValues.back().get();
578 } else {
579 conflict.values = nullptr;
580 }
581 }
582 }
583 }
584
~ApexCodec_SettingResultsApexCodec_SettingResults585 ~ApexCodec_SettingResults() {
586 }
587
getResultAtIndexApexCodec_SettingResults588 ApexCodec_Status getResultAtIndex(
589 size_t index,
590 ApexCodec_SettingResultFailure *failure,
591 ApexCodec_ParamFieldValues *field,
592 ApexCodec_ParamFieldValues **conflicts,
593 size_t *numConflicts) {
594 if (failure == nullptr) {
595 return APEXCODEC_STATUS_BAD_VALUE;
596 }
597 if (field == nullptr) {
598 return APEXCODEC_STATUS_BAD_VALUE;
599 }
600 if (conflicts == nullptr) {
601 return APEXCODEC_STATUS_BAD_VALUE;
602 }
603 if (numConflicts == nullptr) {
604 return APEXCODEC_STATUS_BAD_VALUE;
605 }
606 if (index >= mResults.size()) {
607 return APEXCODEC_STATUS_NOT_FOUND;
608 }
609 *failure = mResults[index].failure;
610 *field = mResults[index].field;
611 *conflicts = mResults[index].conflicts.data();
612 *numConflicts = mResults[index].conflicts.size();
613 return APEXCODEC_STATUS_OK;
614 }
615 private:
616 std::shared_ptr<C2ParamReflector> mReflector;
617 struct Entry {
618 ApexCodec_SettingResultFailure failure;
619 ApexCodec_ParamFieldValues field;
620 std::vector<ApexCodec_ParamFieldValues> conflicts;
621 std::unique_ptr<ApexCodec_SupportedValues> fieldValues;
622 std::vector<std::unique_ptr<ApexCodec_SupportedValues>> conflictValues;
623 };
624 std::vector<Entry> mResults;
625 };
626
ApexCodec_SettingResults_getResultAtIndex(ApexCodec_SettingResults * results,size_t index,ApexCodec_SettingResultFailure * failure,ApexCodec_ParamFieldValues * field,ApexCodec_ParamFieldValues ** conflicts,size_t * numConflicts)627 ApexCodec_Status ApexCodec_SettingResults_getResultAtIndex(
628 ApexCodec_SettingResults *results,
629 size_t index,
630 ApexCodec_SettingResultFailure *failure,
631 ApexCodec_ParamFieldValues *field,
632 ApexCodec_ParamFieldValues **conflicts,
633 size_t *numConflicts) {
634 if (results == nullptr) {
635 return APEXCODEC_STATUS_BAD_VALUE;
636 }
637 return results->getResultAtIndex(index, failure, field, conflicts, numConflicts);
638 }
639
ApexCodec_SettingResults_destroy(ApexCodec_SettingResults * results)640 void ApexCodec_SettingResults_destroy(ApexCodec_SettingResults *results) {
641 delete results;
642 }
643
ApexCodec_Component_process(ApexCodec_Component * comp,const ApexCodec_Buffer * input,ApexCodec_Buffer * output,size_t * consumed,size_t * produced)644 ApexCodec_Status ApexCodec_Component_process(
645 ApexCodec_Component *comp,
646 const ApexCodec_Buffer *input,
647 ApexCodec_Buffer *output,
648 size_t *consumed,
649 size_t *produced) {
650 return APEXCODEC_STATUS_OMITTED;
651 }
652
ApexCodec_Configurable_config(ApexCodec_Configurable * comp,ApexCodec_LinearBuffer * config,ApexCodec_SettingResults ** results)653 ApexCodec_Status ApexCodec_Configurable_config(
654 ApexCodec_Configurable *comp,
655 ApexCodec_LinearBuffer *config,
656 ApexCodec_SettingResults **results) {
657 return APEXCODEC_STATUS_OMITTED;
658 }
659
ApexCodec_Configurable_query(ApexCodec_Configurable * comp,uint32_t indices[],size_t numIndices,ApexCodec_LinearBuffer * config,size_t * writtenOrRequired)660 ApexCodec_Status ApexCodec_Configurable_query(
661 ApexCodec_Configurable *comp,
662 uint32_t indices[],
663 size_t numIndices,
664 ApexCodec_LinearBuffer *config,
665 size_t *writtenOrRequired) {
666 return APEXCODEC_STATUS_OMITTED;
667 }
668
669 struct ApexCodec_ParamDescriptors {
670 public:
ApexCodec_ParamDescriptorsApexCodec_ParamDescriptors671 explicit ApexCodec_ParamDescriptors(
672 const std::vector<std::shared_ptr<C2ParamDescriptor>> ¶mDescriptors) {
673 for (const std::shared_ptr<C2ParamDescriptor> &c2Descriptor : paramDescriptors) {
674 if (!c2Descriptor) {
675 continue;
676 }
677 uint32_t index = c2Descriptor->index();
678 Entry &entry = mDescriptors[index];
679 entry.index = index;
680 entry.attr = (ApexCodec_ParamAttribute)_C2ParamInspector::GetAttrib(*c2Descriptor);
681 entry.name = c2Descriptor->name();
682 for (const C2Param::Index &dependency : c2Descriptor->dependencies()) {
683 entry.dependencies.emplace_back((uint32_t)dependency);
684 }
685 mIndices.push_back(entry.index);
686 }
687 }
688
~ApexCodec_ParamDescriptorsApexCodec_ParamDescriptors689 ~ApexCodec_ParamDescriptors() {
690 }
691
getIndicesApexCodec_ParamDescriptors692 ApexCodec_Status getIndices(uint32_t **indices, size_t *numIndices) {
693 if (indices == nullptr) {
694 return APEXCODEC_STATUS_BAD_VALUE;
695 }
696 if (numIndices == nullptr) {
697 return APEXCODEC_STATUS_BAD_VALUE;
698 }
699 *indices = mIndices.data();
700 *numIndices = mIndices.size();
701 return APEXCODEC_STATUS_OK;
702 }
703
getDescriptorApexCodec_ParamDescriptors704 ApexCodec_Status getDescriptor(
705 uint32_t index,
706 ApexCodec_ParamAttribute *attr,
707 const char **name,
708 uint32_t **dependencies,
709 size_t *numDependencies) {
710 if (attr == nullptr) {
711 return APEXCODEC_STATUS_BAD_VALUE;
712 }
713 if (name == nullptr) {
714 return APEXCODEC_STATUS_BAD_VALUE;
715 }
716 if (dependencies == nullptr) {
717 return APEXCODEC_STATUS_BAD_VALUE;
718 }
719 if (numDependencies == nullptr) {
720 return APEXCODEC_STATUS_BAD_VALUE;
721 }
722 auto it = mDescriptors.find(index);
723 if (it == mDescriptors.end()) {
724 return APEXCODEC_STATUS_BAD_VALUE;
725 }
726 const Entry &entry = it->second;
727 *attr = entry.attr;
728 *name = entry.name.c_str();
729 *dependencies = const_cast<uint32_t *>(entry.dependencies.data());
730 *numDependencies = entry.dependencies.size();
731 return APEXCODEC_STATUS_OK;
732 }
733
734 private:
735 struct Entry {
736 uint32_t index;
737 ApexCodec_ParamAttribute attr;
738 C2String name;
739 std::vector<uint32_t> dependencies;
740 };
741 std::map<uint32_t, Entry> mDescriptors;
742 std::vector<uint32_t> mIndices;
743 };
744
ApexCodec_ParamDescriptors_getIndices(ApexCodec_ParamDescriptors * descriptors,uint32_t ** indices,size_t * numIndices)745 ApexCodec_Status ApexCodec_ParamDescriptors_getIndices(
746 ApexCodec_ParamDescriptors *descriptors,
747 uint32_t **indices,
748 size_t *numIndices) {
749 if (descriptors == nullptr) {
750 return APEXCODEC_STATUS_BAD_VALUE;
751 }
752 return descriptors->getIndices(indices, numIndices);
753 }
754
ApexCodec_ParamDescriptors_getDescriptor(ApexCodec_ParamDescriptors * descriptors,uint32_t index,ApexCodec_ParamAttribute * attr,const char ** name,uint32_t ** dependencies,size_t * numDependencies)755 ApexCodec_Status ApexCodec_ParamDescriptors_getDescriptor(
756 ApexCodec_ParamDescriptors *descriptors,
757 uint32_t index,
758 ApexCodec_ParamAttribute *attr,
759 const char **name,
760 uint32_t **dependencies,
761 size_t *numDependencies) {
762 if (descriptors == nullptr) {
763 return APEXCODEC_STATUS_BAD_VALUE;
764 }
765 return descriptors->getDescriptor(index, attr, name, dependencies, numDependencies);
766 }
767
ApexCodec_ParamDescriptors_destroy(ApexCodec_ParamDescriptors * descriptors)768 void ApexCodec_ParamDescriptors_destroy(ApexCodec_ParamDescriptors *descriptors) {
769 delete descriptors;
770 }
771
ApexCodec_Configurable_querySupportedParams(ApexCodec_Configurable * comp,ApexCodec_ParamDescriptors ** descriptors)772 ApexCodec_Status ApexCodec_Configurable_querySupportedParams(
773 ApexCodec_Configurable *comp,
774 ApexCodec_ParamDescriptors **descriptors) {
775 return APEXCODEC_STATUS_OMITTED;
776 }
777
ApexCodec_Configurable_querySupportedValues(ApexCodec_Configurable * comp,ApexCodec_SupportedValuesQuery * queries,size_t numQueries)778 ApexCodec_Status ApexCodec_Configurable_querySupportedValues(
779 ApexCodec_Configurable *comp,
780 ApexCodec_SupportedValuesQuery *queries,
781 size_t numQueries) {
782 return APEXCODEC_STATUS_OMITTED;
783 }
784
785 #pragma clang diagnostic pop