blob: 82ceb61564305960672fa19720e4a45b00b3779e [file] [log] [blame]
Songyue Hanef3ee052024-10-29 23:31:27 +00001/*
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 "NdkMediaCodecInfo"
19
20#include "NdkMediaCodecInfoPriv.h"
21
22#include <media/NdkMediaFormatPriv.h>
23
24using namespace android;
25
26extern "C" {
27
28// Utils
29
30EXPORT
31void AIntRange_delete(AIntRange *range) {
32 free(range);
33}
34
35EXPORT
36void ADoubleRange_delete(ADoubleRange *range) {
37 free(range);
38}
39
40// AMediaCodecInfo
41
42EXPORT
43const char* AMediaCodecInfo_getCanonicalName(const AMediaCodecInfo *info) {
44 if (info == nullptr || info->mInfo == nullptr) {
45 return nullptr;
46 }
47
48 return info->mInfo->getCodecName();
49}
50
51EXPORT
52bool AMediaCodecInfo_isEncoder(const AMediaCodecInfo *info) {
53 return info->mInfo->isEncoder();
54}
55
56EXPORT
57bool AMediaCodecInfo_isVendor(const AMediaCodecInfo *info) {
58 int32_t attributes = info->mInfo->getAttributes();
59 return (attributes & android::MediaCodecInfo::kFlagIsVendor);
60}
61
62EXPORT
63AMediaCodecType AMediaCodecInfo_getMediaCodecInfoType(const AMediaCodecInfo *info) {
64 if (info == nullptr || info->mInfo == nullptr) {
65 return (AMediaCodecType)0;
66 }
67
68 int32_t attributes = info->mInfo->getAttributes();
69
70 if (attributes & android::MediaCodecInfo::kFlagIsSoftwareOnly) {
71 return SOFTWARE_ONLY;
72 }
73 if (attributes & android::MediaCodecInfo::kFlagIsHardwareAccelerated) {
74 return HARDWARE_ACCELERATED;
75 }
76 return SOFTWARE_WITH_DEVICE_ACCESS;
77}
78
79EXPORT
80const char* AMediaCodecInfo_getMediaType(const AMediaCodecInfo *info) {
81 if (info == nullptr || info->mInfo == nullptr) {
82 return nullptr;
83 }
84
85 return info->mMediaType.c_str();
86}
87
88EXPORT
89int32_t AMediaCodecInfo_getMaxSupportedInstances(const AMediaCodecInfo *info) {
90 if (info == nullptr) {
91 return -1;
92 }
93
94 return info->mCodecCaps->getMaxSupportedInstances();
95}
96
97EXPORT
98int32_t AMediaCodecInfo_isFeatureSupported(const AMediaCodecInfo *info, const char *featureName) {
99 if (featureName == nullptr) {
100 return -1;
101 }
102 return info->mCodecCaps->isFeatureSupported(std::string(featureName));
103}
104
105EXPORT
106int32_t AMediaCodecInfo_isFeatureRequired(const AMediaCodecInfo *info, const char *featureName) {
107 if (featureName == nullptr) {
108 return -1;
109 }
110 return info->mCodecCaps->isFeatureRequired(std::string(featureName));
111}
112
113EXPORT
114int32_t AMediaCodecInfo_isFormatSupported(const AMediaCodecInfo *info, const AMediaFormat *format) {
115 if (format == nullptr) {
116 return -1;
117 }
118
119 sp<AMessage> nativeFormat;
120 AMediaFormat_getFormat(format, &nativeFormat);
121
122 return info->mCodecCaps->isFormatSupported(nativeFormat);
123}
124
125EXPORT
126media_status_t AMediaCodecInfo_getAudioCapabilities(const AMediaCodecInfo *info,
127 const ACodecAudioCapabilities **outAudioCaps) {
128 if (info == nullptr || info->mInfo == nullptr) {
129 return AMEDIA_ERROR_INVALID_PARAMETER;
130 }
131
132 *outAudioCaps = info->mAAudioCaps.get();
133
134 if ((*outAudioCaps) == nullptr) {
135 return AMEDIA_ERROR_UNSUPPORTED;
136 }
137
138 return AMEDIA_OK;
139}
140
141EXPORT
142media_status_t AMediaCodecInfo_getVideoCapabilities(const AMediaCodecInfo *info,
143 const ACodecVideoCapabilities **outVideoCaps) {
144 if (info == nullptr || info->mInfo == nullptr) {
145 return AMEDIA_ERROR_INVALID_PARAMETER;
146 }
147
148 *outVideoCaps = info->mAVideoCaps.get();
149
150 if ((*outVideoCaps) == nullptr) {
151 return AMEDIA_ERROR_UNSUPPORTED;
152 }
153
154 return AMEDIA_OK;
155}
156
157EXPORT
158media_status_t AMediaCodecInfo_getEncoderCapabilities(const AMediaCodecInfo *info,
159 const ACodecEncoderCapabilities **outEncoderCaps) {
160 if (info == nullptr || info->mInfo == nullptr) {
161 return AMEDIA_ERROR_INVALID_PARAMETER;
162 }
163
164 *outEncoderCaps = info->mAEncoderCaps.get();
165
166 if ((*outEncoderCaps) == nullptr) {
167 return AMEDIA_ERROR_UNSUPPORTED;
168 }
169
170 return AMEDIA_OK;
171}
172
173// ACodecAudioCapabilities
174
175EXPORT
176media_status_t ACodecAudioCapabilities_getBitrateRange(const ACodecAudioCapabilities *audioCaps,
177 AIntRange *outRange) {
178 if (audioCaps == nullptr || outRange == nullptr) {
179 return AMEDIA_ERROR_INVALID_PARAMETER;
180 }
181
182 const Range<int32_t>& bitrateRange = audioCaps->mAudioCaps->getBitrateRange();
183 outRange->mLower = bitrateRange.lower();
184 outRange->mUpper = bitrateRange.upper();
185
186 return AMEDIA_OK;
187}
188
189EXPORT
190media_status_t ACodecAudioCapabilities_getSupportedSampleRates(
191 const ACodecAudioCapabilities *audioCaps, const int **outArrayPtr, size_t *outCount) {
192 if (audioCaps == nullptr || outArrayPtr == nullptr || outCount == nullptr) {
193 return AMEDIA_ERROR_INVALID_PARAMETER;
194 }
195
196 if (audioCaps->mSampleRates.empty()) {
197 return AMEDIA_ERROR_UNSUPPORTED;
198 }
199
200 *outArrayPtr = audioCaps->mSampleRates.data();
201 *outCount = audioCaps->mSampleRates.size();
202
203 return AMEDIA_OK;
204}
205
206EXPORT
207media_status_t ACodecAudioCapabilities_getSupportedSampleRateRanges(
208 const ACodecAudioCapabilities *audioCaps, const AIntRange **outArrayPtr, size_t *outCount) {
209 if (audioCaps == nullptr || outArrayPtr == nullptr || outCount == nullptr) {
210 return AMEDIA_ERROR_INVALID_PARAMETER;
211 }
212
213 *outArrayPtr = audioCaps->mSampleRateRanges.data();
214 *outCount = audioCaps->mSampleRateRanges.size();
215
216 return AMEDIA_OK;
217}
218
219EXPORT
220int32_t ACodecAudioCapabilities_getMaxInputChannelCount(const ACodecAudioCapabilities *audioCaps) {
221 if (audioCaps == nullptr) {
222 return -1;
223 }
224 return audioCaps->mAudioCaps->getMaxInputChannelCount();
225}
226
227EXPORT
228int32_t ACodecAudioCapabilities_getMinInputChannelCount(const ACodecAudioCapabilities *audioCaps) {
229 if (audioCaps == nullptr) {
230 return -1;
231 }
232 return audioCaps->mAudioCaps->getMinInputChannelCount();
233}
234
235EXPORT
236media_status_t ACodecAudioCapabilities_getInputChannelCountRanges(
237 const ACodecAudioCapabilities *audioCaps, const AIntRange **outArrayPtr, size_t *outCount) {
238 if (audioCaps == nullptr || outArrayPtr == nullptr || outCount == nullptr) {
239 return AMEDIA_ERROR_INVALID_PARAMETER;
240 }
241
242 *outArrayPtr = audioCaps->mInputChannelCountRanges.data();
243 *outCount = audioCaps->mInputChannelCountRanges.size();
244
245 return AMEDIA_OK;
246}
247
248EXPORT
249int32_t ACodecAudioCapabilities_isSampleRateSupported(const ACodecAudioCapabilities *audioCaps,
250 int32_t sampleRate) {
251 if (audioCaps == nullptr) {
252 return -1;
253 }
254 return audioCaps->mAudioCaps->isSampleRateSupported(sampleRate);
255}
256
257// ACodecPerformancePoint
258
259EXPORT
260ACodecPerformancePoint* ACodecPerformancePoint_create(int32_t width, int32_t height,
261 int32_t frameRate) {
262 return new ACodecPerformancePoint(
263 std::make_shared<VideoCapabilities::PerformancePoint>(width, height, frameRate));
264}
265
266EXPORT
267media_status_t ACodecPerformancePoint_delete(ACodecPerformancePoint *performancePoint) {
268 if (performancePoint == nullptr) {
269 return AMEDIA_ERROR_INVALID_PARAMETER;
270 }
271
272 delete performancePoint;
273
274 return AMEDIA_OK;
275}
276
277EXPORT
278bool ACodecPerformancePoint_coversFormat(const ACodecPerformancePoint *performancePoint,
279 const AMediaFormat *format) {
280 sp<AMessage> nativeFormat;
281 AMediaFormat_getFormat(format, &nativeFormat);
282
283 return performancePoint->mPerformancePoint->covers(nativeFormat);
284}
285
286EXPORT
287bool ACodecPerformancePoint_covers(const ACodecPerformancePoint *one,
288 const ACodecPerformancePoint *another) {
289 return one->mPerformancePoint->covers(*(another->mPerformancePoint));
290}
291
292EXPORT
293bool ACodecPerformancePoint_equals(const ACodecPerformancePoint *one,
294 const ACodecPerformancePoint *another) {
295 return one->mPerformancePoint->equals(*(another->mPerformancePoint));
296}
297
298// ACodecVideoCapabilities
299
300EXPORT
301media_status_t ACodecVideoCapabilities_getBitrateRange(const ACodecVideoCapabilities *videoCaps,
302 AIntRange *outRange) {
303 if (videoCaps == nullptr || outRange == nullptr) {
304 return AMEDIA_ERROR_INVALID_PARAMETER;
305 }
306
307 const Range<int32_t>& bitrateRange = videoCaps->mVideoCaps->getBitrateRange();
308 outRange->mLower = bitrateRange.lower();
309 outRange->mUpper = bitrateRange.upper();
310
311 return AMEDIA_OK;
312}
313
314EXPORT
315media_status_t ACodecVideoCapabilities_getSupportedWidths(const ACodecVideoCapabilities *videoCaps,
316 AIntRange *outRange) {
317 if (videoCaps == nullptr || outRange == nullptr) {
318 return AMEDIA_ERROR_INVALID_PARAMETER;
319 }
320
321 const Range<int32_t>& supportedWidths = videoCaps->mVideoCaps->getSupportedWidths();
322 outRange->mLower = supportedWidths.lower();
323 outRange->mUpper = supportedWidths.upper();
324
325 return AMEDIA_OK;
326}
327
328EXPORT
329media_status_t ACodecVideoCapabilities_getSupportedHeights(const ACodecVideoCapabilities *videoCaps,
330 AIntRange *outRange) {
331 if (videoCaps == nullptr || outRange == nullptr) {
332 return AMEDIA_ERROR_INVALID_PARAMETER;
333 }
334
335 const Range<int32_t>& supportedHeights = videoCaps->mVideoCaps->getSupportedHeights();
336 outRange->mLower = supportedHeights.lower();
337 outRange->mUpper = supportedHeights.upper();
338
339 return AMEDIA_OK;
340}
341
342EXPORT
343int32_t ACodecVideoCapabilities_getWidthAlignment(const ACodecVideoCapabilities *videoCaps) {
344 if (videoCaps == nullptr) {
345 return -1;
346 }
347 return videoCaps->mVideoCaps->getWidthAlignment();
348}
349
350EXPORT
351int32_t ACodecVideoCapabilities_getHeightAlignment(const ACodecVideoCapabilities *videoCaps) {
352 if (videoCaps == nullptr) {
353 return -1;
354 }
355 return videoCaps->mVideoCaps->getHeightAlignment();
356}
357
358EXPORT
359media_status_t ACodecVideoCapabilities_getSupportedFrameRates(
360 const ACodecVideoCapabilities *videoCaps, AIntRange *outRange) {
361 if (videoCaps == nullptr || outRange == nullptr) {
362 return AMEDIA_ERROR_INVALID_PARAMETER;
363 }
364
365 const Range<int32_t>& frameRateRange = videoCaps->mVideoCaps->getSupportedFrameRates();
366 outRange->mLower = frameRateRange.lower();
367 outRange->mUpper = frameRateRange.upper();
368
369 return AMEDIA_OK;
370}
371
372EXPORT
373media_status_t ACodecVideoCapabilities_getSupportedWidthsFor(
374 const ACodecVideoCapabilities *videoCaps, int32_t height, AIntRange *outRange) {
375 if (videoCaps == nullptr || outRange == nullptr) {
376 return AMEDIA_ERROR_INVALID_PARAMETER;
377 }
378
379 std::optional<Range<int32_t>> widthRange = videoCaps->mVideoCaps->getSupportedWidthsFor(height);
380 if (!widthRange) {
381 return AMEDIA_ERROR_UNSUPPORTED;
382 }
383
384 outRange->mLower = widthRange.value().lower();
385 outRange->mUpper = widthRange.value().upper();
386
387 return AMEDIA_OK;
388}
389
390EXPORT
391media_status_t ACodecVideoCapabilities_getSupportedHeightsFor(
392 const ACodecVideoCapabilities *videoCaps, int32_t width, AIntRange *outRange) {
393 if (videoCaps == nullptr || outRange == nullptr) {
394 return AMEDIA_ERROR_INVALID_PARAMETER;
395 }
396
397 std::optional<Range<int32_t>> heightRange
398 = videoCaps->mVideoCaps->getSupportedHeightsFor(width);
399 if (!heightRange) {
400 return AMEDIA_ERROR_UNSUPPORTED;
401 }
402
403 outRange->mLower = heightRange.value().lower();
404 outRange->mUpper = heightRange.value().upper();
405
406 return AMEDIA_OK;
407}
408
409EXPORT
410media_status_t ACodecVideoCapabilities_getSupportedFrameRatesFor(
411 const ACodecVideoCapabilities *videoCaps, int32_t width, int32_t height,
412 ADoubleRange *outRange) {
413 if (videoCaps == nullptr || outRange == nullptr) {
414 return AMEDIA_ERROR_INVALID_PARAMETER;
415 }
416
417 std::optional<Range<double>> frameRates
418 = videoCaps->mVideoCaps->getSupportedFrameRatesFor(width, height);
419 if (!frameRates) {
420 return AMEDIA_ERROR_UNSUPPORTED;
421 }
422
423 outRange->mLower = frameRates.value().lower();
424 outRange->mUpper = frameRates.value().upper();
425
426 return AMEDIA_OK;
427}
428
429EXPORT
430media_status_t ACodecVideoCapabilities_getAchievableFrameRatesFor(
431 const ACodecVideoCapabilities *videoCaps, int32_t width, int32_t height,
432 ADoubleRange *outRange) {
433 if (videoCaps == nullptr || outRange == nullptr) {
434 return AMEDIA_ERROR_INVALID_PARAMETER;
435 }
436
437 std::optional<Range<double>> frameRates
438 = videoCaps->mVideoCaps->getAchievableFrameRatesFor(width, height);
439 if (!frameRates) {
440 return AMEDIA_ERROR_UNSUPPORTED;
441 }
442
443 outRange->mLower = frameRates.value().lower();
444 outRange->mUpper = frameRates.value().upper();
445
446 return AMEDIA_OK;
447}
448
449EXPORT
450media_status_t ACodecVideoCapabilities_getSupportedPerformancePoints(
451 const ACodecVideoCapabilities *videoCaps,
452 const ACodecPerformancePoint **outPerformancePointArray, size_t *outCount) {
453 if (videoCaps == nullptr) {
454 return AMEDIA_ERROR_INVALID_PARAMETER;
455 }
456
457 *outPerformancePointArray = videoCaps->mPerformancePoints.data();
458 *outCount = videoCaps->mPerformancePoints.size();
459
460 return AMEDIA_OK;
461}
462
463EXPORT
464int32_t ACodecVideoCapabilities_areSizeAndRateSupported(const ACodecVideoCapabilities *videoCaps,
465 int32_t width, int32_t height, double frameRate) {
466 if (videoCaps == nullptr) {
467 return -1;
468 }
469 return videoCaps->mVideoCaps->areSizeAndRateSupported(width, height, frameRate);
470}
471
472EXPORT
473int32_t ACodecVideoCapabilities_isSizeSupported(const ACodecVideoCapabilities *videoCaps,
474 int32_t width, int32_t height) {
475 if (videoCaps == nullptr) {
476 return -1;
477 }
478 return videoCaps->mVideoCaps->isSizeSupported(width, height);
479}
480
481// ACodecEncoderCapabilities
482
483EXPORT
484media_status_t ACodecEncoderCapabilities_getQualityRange(
485 const ACodecEncoderCapabilities *encoderCaps, AIntRange *outRange) {
486 if (encoderCaps == nullptr || outRange == nullptr) {
487 return AMEDIA_ERROR_INVALID_PARAMETER;
488 }
489
490 const Range<int32_t>& qualityRange = encoderCaps->mEncoderCaps->getQualityRange();
491 outRange->mLower = qualityRange.lower();
492 outRange->mUpper = qualityRange.upper();
493
494 return AMEDIA_OK;
495}
496
497EXPORT
498media_status_t ACodecEncoderCapabilities_getComplexityRange(
499 const ACodecEncoderCapabilities *encoderCaps, AIntRange *outRange) {
500 if (encoderCaps == nullptr || outRange == nullptr) {
501 return AMEDIA_ERROR_INVALID_PARAMETER;
502 }
503
504 const Range<int32_t>& complexityRange = encoderCaps->mEncoderCaps->getComplexityRange();
505 outRange->mLower = complexityRange.lower();
506 outRange->mUpper = complexityRange.upper();
507
508 return AMEDIA_OK;
509}
510
511int32_t ACodecEncoderCapabilities_isBitrateModeSupported(
512 const ACodecEncoderCapabilities *encoderCaps, ABiterateMode mode) {
513 if (encoderCaps == nullptr) {
514 return -1;
515 }
516 return encoderCaps->mEncoderCaps->isBitrateModeSupported(mode);
517}
518
519
520}