blob: 3c55c565213a22fe96987d70375d5e8f07c4fd7e [file] [log] [blame]
Wei Jia53692fa2017-12-11 10:33:46 -08001/*
2 * Copyright 2017, 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 "NdkWrapper"
19
20#include "NdkWrapper.h"
21
22#include <gui/Surface.h>
23#include <log/log.h>
24#include <media/NdkMediaCodec.h>
25#include <media/NdkMediaCrypto.h>
26#include <media/NdkMediaDrm.h>
27#include <media/NdkMediaFormat.h>
28#include <media/stagefright/MetaData.h>
29#include <media/stagefright/foundation/ABuffer.h>
30#include <media/stagefright/foundation/AMessage.h>
31#include <utils/Errors.h>
32
33namespace android {
34
35static const size_t kAESBlockSize = 16; // AES_BLOCK_SIZE
36
37static const char *AMediaFormatKeyGroupInt32[] = {
38 AMEDIAFORMAT_KEY_AAC_DRC_ATTENUATION_FACTOR,
39 AMEDIAFORMAT_KEY_AAC_DRC_BOOST_FACTOR,
40 AMEDIAFORMAT_KEY_AAC_DRC_HEAVY_COMPRESSION,
41 AMEDIAFORMAT_KEY_AAC_DRC_TARGET_REFERENCE_LEVEL,
42 AMEDIAFORMAT_KEY_AAC_ENCODED_TARGET_LEVEL,
43 AMEDIAFORMAT_KEY_AAC_MAX_OUTPUT_CHANNEL_COUNT,
44 AMEDIAFORMAT_KEY_AAC_PROFILE,
45 AMEDIAFORMAT_KEY_AAC_SBR_MODE,
46 AMEDIAFORMAT_KEY_AUDIO_SESSION_ID,
47 AMEDIAFORMAT_KEY_BITRATE_MODE,
48 AMEDIAFORMAT_KEY_BIT_RATE,
49 AMEDIAFORMAT_KEY_CAPTURE_RATE,
50 AMEDIAFORMAT_KEY_CHANNEL_COUNT,
51 AMEDIAFORMAT_KEY_CHANNEL_MASK,
52 AMEDIAFORMAT_KEY_COLOR_FORMAT,
53 AMEDIAFORMAT_KEY_COLOR_RANGE,
54 AMEDIAFORMAT_KEY_COLOR_STANDARD,
55 AMEDIAFORMAT_KEY_COLOR_TRANSFER,
56 AMEDIAFORMAT_KEY_COMPLEXITY,
57 AMEDIAFORMAT_KEY_FLAC_COMPRESSION_LEVEL,
58 AMEDIAFORMAT_KEY_GRID_COLS,
59 AMEDIAFORMAT_KEY_GRID_HEIGHT,
60 AMEDIAFORMAT_KEY_GRID_ROWS,
61 AMEDIAFORMAT_KEY_GRID_WIDTH,
62 AMEDIAFORMAT_KEY_HEIGHT,
63 AMEDIAFORMAT_KEY_INTRA_REFRESH_PERIOD,
64 AMEDIAFORMAT_KEY_IS_ADTS,
65 AMEDIAFORMAT_KEY_IS_AUTOSELECT,
66 AMEDIAFORMAT_KEY_IS_DEFAULT,
67 AMEDIAFORMAT_KEY_IS_FORCED_SUBTITLE,
68 AMEDIAFORMAT_KEY_LATENCY,
69 AMEDIAFORMAT_KEY_LEVEL,
70 AMEDIAFORMAT_KEY_MAX_HEIGHT,
71 AMEDIAFORMAT_KEY_MAX_INPUT_SIZE,
72 AMEDIAFORMAT_KEY_MAX_WIDTH,
73 AMEDIAFORMAT_KEY_PCM_ENCODING,
74 AMEDIAFORMAT_KEY_PRIORITY,
75 AMEDIAFORMAT_KEY_PROFILE,
76 AMEDIAFORMAT_KEY_PUSH_BLANK_BUFFERS_ON_STOP,
77 AMEDIAFORMAT_KEY_ROTATION,
78 AMEDIAFORMAT_KEY_SAMPLE_RATE,
79 AMEDIAFORMAT_KEY_SLICE_HEIGHT,
80 AMEDIAFORMAT_KEY_STRIDE,
81 AMEDIAFORMAT_KEY_TRACK_ID,
82 AMEDIAFORMAT_KEY_WIDTH,
83};
84
85static const char *AMediaFormatKeyGroupInt64[] = {
86 AMEDIAFORMAT_KEY_DURATION,
87 AMEDIAFORMAT_KEY_REPEAT_PREVIOUS_FRAME_AFTER,
88};
89
90static const char *AMediaFormatKeyGroupString[] = {
91 AMEDIAFORMAT_KEY_LANGUAGE,
92 AMEDIAFORMAT_KEY_MIME,
93 AMEDIAFORMAT_KEY_TEMPORAL_LAYERING,
94};
95
96static const char *AMediaFormatKeyGroupBuffer[] = {
97 AMEDIAFORMAT_KEY_HDR_STATIC_INFO,
98};
99
100static const char *AMediaFormatKeyGroupRect[] = {
101 AMEDIAFORMAT_KEY_DISPLAY_CROP,
102};
103
104static const char *AMediaFormatKeyGroupFloatInt32[] = {
105 AMEDIAFORMAT_KEY_FRAME_RATE,
106 AMEDIAFORMAT_KEY_I_FRAME_INTERVAL,
107 AMEDIAFORMAT_KEY_OPERATING_RATE,
108};
109
110static status_t translateErrorCode(media_status_t err) {
111 if (err == AMEDIA_OK) {
112 return OK;
113 } else if (err == AMEDIACODEC_INFO_TRY_AGAIN_LATER) {
114 return -EAGAIN;
115 }
116
117 ALOGE("ndk error code: %d", err);
118 return UNKNOWN_ERROR;
119}
120
121static int32_t translateActionCode(int32_t actionCode) {
122 if (AMediaCodecActionCode_isTransient(actionCode)) {
123 return ACTION_CODE_TRANSIENT;
124 } else if (AMediaCodecActionCode_isRecoverable(actionCode)) {
125 return ACTION_CODE_RECOVERABLE;
126 }
127 return ACTION_CODE_FATAL;
128}
129
130static CryptoPlugin::Mode translateToCryptoPluginMode(cryptoinfo_mode_t mode) {
131 CryptoPlugin::Mode ret = CryptoPlugin::kMode_Unencrypted;
132 switch (mode) {
133 case AMEDIACODECRYPTOINFO_MODE_AES_CTR: {
134 ret = CryptoPlugin::kMode_AES_CTR;
135 break;
136 }
137
138 case AMEDIACODECRYPTOINFO_MODE_AES_WV: {
139 ret = CryptoPlugin::kMode_AES_WV;
140 break;
141 }
142
143 case AMEDIACODECRYPTOINFO_MODE_AES_CBC: {
144 ret = CryptoPlugin::kMode_AES_CBC;
145 break;
146 }
147
148 default:
149 break;
150 }
151
152 return ret;
153}
154
155static cryptoinfo_mode_t translateToCryptoInfoMode(CryptoPlugin::Mode mode) {
156 cryptoinfo_mode_t ret = AMEDIACODECRYPTOINFO_MODE_CLEAR;
157 switch (mode) {
158 case CryptoPlugin::kMode_AES_CTR: {
159 ret = AMEDIACODECRYPTOINFO_MODE_AES_CTR;
160 break;
161 }
162
163 case CryptoPlugin::kMode_AES_WV: {
164 ret = AMEDIACODECRYPTOINFO_MODE_AES_WV;
165 break;
166 }
167
168 case CryptoPlugin::kMode_AES_CBC: {
169 ret = AMEDIACODECRYPTOINFO_MODE_AES_CBC;
170 break;
171 }
172
173 default:
174 break;
175 }
176
177 return ret;
178}
179
180
181//////////// AMediaFormatWrapper
182// static
183sp<AMediaFormatWrapper> AMediaFormatWrapper::Create(const sp<AMessage> &message) {
184 sp<AMediaFormatWrapper> aMediaFormat = new AMediaFormatWrapper();
185
186 for (size_t i = 0; i < message->countEntries(); ++i) {
187 AMessage::Type valueType;
188 const char *key = message->getEntryNameAt(i, &valueType);
189
190 switch (valueType) {
191 case AMessage::kTypeInt32: {
192 int32_t val;
193 if (!message->findInt32(key, &val)) {
194 ALOGE("AMediaFormatWrapper::Create: error at item %zu", i);
195 continue;
196 }
197 aMediaFormat->setInt32(key, val);
198 break;
199 }
200
201 case AMessage::kTypeInt64: {
202 int64_t val;
203 if (!message->findInt64(key, &val)) {
204 ALOGE("AMediaFormatWrapper::Create: error at item %zu", i);
205 continue;
206 }
207 aMediaFormat->setInt64(key, val);
208 break;
209 }
210
211 case AMessage::kTypeFloat: {
212 float val;
213 if (!message->findFloat(key, &val)) {
214 ALOGE("AMediaFormatWrapper::Create: error at item %zu", i);
215 continue;
216 }
217 aMediaFormat->setFloat(key, val);
218 break;
219 }
220
221 case AMessage::kTypeDouble: {
222 double val;
223 if (!message->findDouble(key, &val)) {
224 ALOGE("AMediaFormatWrapper::Create: error at item %zu", i);
225 continue;
226 }
227 aMediaFormat->setDouble(key, val);
228 break;
229 }
230
231 case AMessage::kTypeSize: {
232 size_t val;
233 if (!message->findSize(key, &val)) {
234 ALOGE("AMediaFormatWrapper::Create: error at item %zu", i);
235 continue;
236 }
237 aMediaFormat->setSize(key, val);
238 break;
239 }
240
241 case AMessage::kTypeRect: {
242 int32_t left, top, right, bottom;
243 if (!message->findRect(key, &left, &top, &right, &bottom)) {
244 ALOGE("AMediaFormatWrapper::Create: error at item %zu", i);
245 continue;
246 }
247 aMediaFormat->setRect(key, left, top, right, bottom);
248 break;
249 }
250
251 case AMessage::kTypeString: {
252 AString val;
253 if (!message->findString(key, &val)) {
254 ALOGE("AMediaFormatWrapper::Create: error at item %zu", i);
255 continue;
256 }
257 aMediaFormat->setString(key, val);
258 break;
259 }
260
261 case AMessage::kTypeBuffer: {
262 sp<ABuffer> val;
263 if (!message->findBuffer(key, &val)) {
264 ALOGE("AMediaFormatWrapper::Create: error at item %zu", i);
265 continue;
266 }
267 aMediaFormat->setBuffer(key, val->data(), val->size());
268 break;
269 }
270
271 default: {
272 break;
273 }
274 }
275 }
276
277 return aMediaFormat;
278}
279
280AMediaFormatWrapper::AMediaFormatWrapper() {
281 mAMediaFormat = AMediaFormat_new();
282}
283
284AMediaFormatWrapper::AMediaFormatWrapper(AMediaFormat *aMediaFormat)
285 : mAMediaFormat(aMediaFormat) {
286}
287
288AMediaFormatWrapper::~AMediaFormatWrapper() {
289 release();
290}
291
292status_t AMediaFormatWrapper::release() {
293 if (mAMediaFormat != NULL) {
294 media_status_t err = AMediaFormat_delete(mAMediaFormat);
295 mAMediaFormat = NULL;
296 return translateErrorCode(err);
297 }
298 return OK;
299}
300
301AMediaFormat *AMediaFormatWrapper::getAMediaFormat() const {
302 return mAMediaFormat;
303}
304
305sp<AMessage> AMediaFormatWrapper::toAMessage() const {
306 if (mAMediaFormat == NULL) {
307 return NULL;
308 }
309
310 sp<AMessage> msg = new AMessage;
311 for (auto& key : AMediaFormatKeyGroupInt32) {
312 int32_t val;
313 if (getInt32(key, &val)) {
314 msg->setInt32(key, val);
315 }
316 }
317 for (auto& key : AMediaFormatKeyGroupInt64) {
318 int64_t val;
319 if (getInt64(key, &val)) {
320 msg->setInt64(key, val);
321 }
322 }
323 for (auto& key : AMediaFormatKeyGroupString) {
324 AString val;
325 if (getString(key, &val)) {
326 msg->setString(key, val);
327 }
328 }
329 for (auto& key : AMediaFormatKeyGroupBuffer) {
330 void *data;
331 size_t size;
332 if (getBuffer(key, &data, &size)) {
333 sp<ABuffer> buffer = ABuffer::CreateAsCopy(data, size);
334 msg->setBuffer(key, buffer);
335 }
336 }
337 for (auto& key : AMediaFormatKeyGroupRect) {
338 int32_t left, top, right, bottom;
339 if (getRect(key, &left, &top, &right, &bottom)) {
340 msg->setRect(key, left, top, right, bottom);
341 }
342 }
343 for (auto& key : AMediaFormatKeyGroupFloatInt32) {
344 float valFloat;
345 if (getFloat(key, &valFloat)) {
346 msg->setFloat(key, valFloat);
347 } else {
348 int32_t valInt32;
349 if (getInt32(key, &valInt32)) {
350 msg->setFloat(key, (float)valInt32);
351 }
352 }
353 }
354 return msg;
355}
356
357const char* AMediaFormatWrapper::toString() const {
358 if (mAMediaFormat == NULL) {
359 return NULL;
360 }
361 return AMediaFormat_toString(mAMediaFormat);
362}
363
364bool AMediaFormatWrapper::getInt32(const char *name, int32_t *out) const {
365 if (mAMediaFormat == NULL) {
366 return false;
367 }
368 return AMediaFormat_getInt32(mAMediaFormat, name, out);
369}
370
371bool AMediaFormatWrapper::getInt64(const char *name, int64_t *out) const {
372 if (mAMediaFormat == NULL) {
373 return false;
374 }
375 return AMediaFormat_getInt64(mAMediaFormat, name, out);
376}
377
378bool AMediaFormatWrapper::getFloat(const char *name, float *out) const {
379 if (mAMediaFormat == NULL) {
380 return false;
381 }
382 return AMediaFormat_getFloat(mAMediaFormat, name, out);
383}
384
385bool AMediaFormatWrapper::getDouble(const char *name, double *out) const {
386 if (mAMediaFormat == NULL) {
387 return false;
388 }
389 return AMediaFormat_getDouble(mAMediaFormat, name, out);
390}
391
392bool AMediaFormatWrapper::getSize(const char *name, size_t *out) const {
393 if (mAMediaFormat == NULL) {
394 return false;
395 }
396 return AMediaFormat_getSize(mAMediaFormat, name, out);
397}
398
399bool AMediaFormatWrapper::getRect(
400 const char *name, int32_t *left, int32_t *top, int32_t *right, int32_t *bottom) const {
401 if (mAMediaFormat == NULL) {
402 return false;
403 }
404 return AMediaFormat_getRect(mAMediaFormat, name, left, top, right, bottom);
405}
406
407bool AMediaFormatWrapper::getBuffer(const char *name, void** data, size_t *outSize) const {
408 if (mAMediaFormat == NULL) {
409 return false;
410 }
411 return AMediaFormat_getBuffer(mAMediaFormat, name, data, outSize);
412}
413
414bool AMediaFormatWrapper::getString(const char *name, AString *out) const {
415 if (mAMediaFormat == NULL) {
416 return false;
417 }
418 const char *outChar = NULL;
419 bool ret = AMediaFormat_getString(mAMediaFormat, name, &outChar);
420 if (ret) {
421 *out = AString(outChar);
422 }
423 return ret;
424}
425
426void AMediaFormatWrapper::setInt32(const char* name, int32_t value) {
427 if (mAMediaFormat != NULL) {
428 AMediaFormat_setInt32(mAMediaFormat, name, value);
429 }
430}
431
432void AMediaFormatWrapper::setInt64(const char* name, int64_t value) {
433 if (mAMediaFormat != NULL) {
434 AMediaFormat_setInt64(mAMediaFormat, name, value);
435 }
436}
437
438void AMediaFormatWrapper::setFloat(const char* name, float value) {
439 if (mAMediaFormat != NULL) {
440 AMediaFormat_setFloat(mAMediaFormat, name, value);
441 }
442}
443
444void AMediaFormatWrapper::setDouble(const char* name, double value) {
445 if (mAMediaFormat != NULL) {
446 AMediaFormat_setDouble(mAMediaFormat, name, value);
447 }
448}
449
450void AMediaFormatWrapper::setSize(const char* name, size_t value) {
451 if (mAMediaFormat != NULL) {
452 AMediaFormat_setSize(mAMediaFormat, name, value);
453 }
454}
455
456void AMediaFormatWrapper::setRect(
457 const char* name, int32_t left, int32_t top, int32_t right, int32_t bottom) {
458 if (mAMediaFormat != NULL) {
459 AMediaFormat_setRect(mAMediaFormat, name, left, top, right, bottom);
460 }
461}
462
463void AMediaFormatWrapper::setString(const char* name, const AString &value) {
464 if (mAMediaFormat != NULL) {
465 AMediaFormat_setString(mAMediaFormat, name, value.c_str());
466 }
467}
468
469void AMediaFormatWrapper::setBuffer(const char* name, void* data, size_t size) {
470 if (mAMediaFormat != NULL) {
471 AMediaFormat_setBuffer(mAMediaFormat, name, data, size);
472 }
473}
474
475
476//////////// AMediaDrmWrapper
477AMediaDrmWrapper::AMediaDrmWrapper(const uint8_t uuid[16]) {
478 mAMediaDrm = AMediaDrm_createByUUID(uuid);
479}
480
481AMediaDrmWrapper::AMediaDrmWrapper(AMediaDrm *aMediaDrm)
482 : mAMediaDrm(aMediaDrm) {
483}
484
485AMediaDrmWrapper::~AMediaDrmWrapper() {
486 release();
487}
488
489status_t AMediaDrmWrapper::release() {
490 if (mAMediaDrm != NULL) {
491 AMediaDrm_release(mAMediaDrm);
492 mAMediaDrm = NULL;
493 }
494 return OK;
495}
496
497AMediaDrm *AMediaDrmWrapper::getAMediaDrm() const {
498 return mAMediaDrm;
499}
500
501// static
502bool AMediaDrmWrapper::isCryptoSchemeSupported(
503 const uint8_t uuid[16],
504 const char *mimeType) {
505 return AMediaDrm_isCryptoSchemeSupported(uuid, mimeType);
506}
507
508
509//////////// AMediaCryptoWrapper
510AMediaCryptoWrapper::AMediaCryptoWrapper(
511 const uint8_t uuid[16], const void *initData, size_t initDataSize) {
512 mAMediaCrypto = AMediaCrypto_new(uuid, initData, initDataSize);
513}
514
515AMediaCryptoWrapper::AMediaCryptoWrapper(AMediaCrypto *aMediaCrypto)
516 : mAMediaCrypto(aMediaCrypto) {
517}
518
519AMediaCryptoWrapper::~AMediaCryptoWrapper() {
520 release();
521}
522
523status_t AMediaCryptoWrapper::release() {
524 if (mAMediaCrypto != NULL) {
525 AMediaCrypto_delete(mAMediaCrypto);
526 mAMediaCrypto = NULL;
527 }
528 return OK;
529}
530
531AMediaCrypto *AMediaCryptoWrapper::getAMediaCrypto() const {
532 return mAMediaCrypto;
533}
534
535bool AMediaCryptoWrapper::isCryptoSchemeSupported(const uint8_t uuid[16]) {
536 if (mAMediaCrypto == NULL) {
537 return false;
538 }
539 return AMediaCrypto_isCryptoSchemeSupported(uuid);
540}
541
542bool AMediaCryptoWrapper::requiresSecureDecoderComponent(const char *mime) {
543 if (mAMediaCrypto == NULL) {
544 return false;
545 }
546 return AMediaCrypto_requiresSecureDecoderComponent(mime);
547}
548
549
550//////////// AMediaCodecCryptoInfoWrapper
551// static
552sp<AMediaCodecCryptoInfoWrapper> AMediaCodecCryptoInfoWrapper::Create(sp<MetaData> meta) {
553 if (meta == NULL) {
554 ALOGE("Create: Unexpected. No meta data for sample.");
555 return NULL;
556 }
557
558 uint32_t type;
559 const void *crypteddata;
560 size_t cryptedsize;
561
562 if (!meta->findData(kKeyEncryptedSizes, &type, &crypteddata, &cryptedsize)) {
563 return NULL;
564 }
565
566 int numSubSamples = cryptedsize / sizeof(size_t);
567
568 if (numSubSamples <= 0) {
569 ALOGE("Create: INVALID numSubSamples: %d", numSubSamples);
570 return NULL;
571 }
572
573 const void *cleardata;
574 size_t clearsize;
575 if (meta->findData(kKeyPlainSizes, &type, &cleardata, &clearsize)) {
576 if (clearsize != cryptedsize) {
577 // The two must be of the same length.
578 ALOGE("Create: mismatch cryptedsize: %zu != clearsize: %zu", cryptedsize, clearsize);
579 return NULL;
580 }
581 }
582
583 const void *key;
584 size_t keysize;
585 if (meta->findData(kKeyCryptoKey, &type, &key, &keysize)) {
586 if (keysize != kAESBlockSize) {
587 // Keys must be 16 bytes in length.
588 ALOGE("Create: Keys must be %zu bytes in length: %zu", kAESBlockSize, keysize);
589 return NULL;
590 }
591 }
592
593 const void *iv;
594 size_t ivsize;
595 if (meta->findData(kKeyCryptoIV, &type, &iv, &ivsize)) {
596 if (ivsize != kAESBlockSize) {
597 // IVs must be 16 bytes in length.
598 ALOGE("Create: IV must be %zu bytes in length: %zu", kAESBlockSize, ivsize);
599 return NULL;
600 }
601 }
602
603 int32_t mode;
604 if (!meta->findInt32(kKeyCryptoMode, &mode)) {
605 mode = CryptoPlugin::kMode_AES_CTR;
606 }
607
608 return new AMediaCodecCryptoInfoWrapper(
609 numSubSamples,
610 (uint8_t*) key,
611 (uint8_t*) iv,
612 (CryptoPlugin::Mode)mode,
613 (size_t*) cleardata,
614 (size_t*) crypteddata);
615}
616
617AMediaCodecCryptoInfoWrapper::AMediaCodecCryptoInfoWrapper(
618 int numsubsamples,
619 uint8_t key[16],
620 uint8_t iv[16],
621 CryptoPlugin::Mode mode,
622 size_t *clearbytes,
623 size_t *encryptedbytes) {
624 mAMediaCodecCryptoInfo =
625 AMediaCodecCryptoInfo_new(numsubsamples,
626 key,
627 iv,
628 translateToCryptoInfoMode(mode),
629 clearbytes,
630 encryptedbytes);
631}
632
633AMediaCodecCryptoInfoWrapper::AMediaCodecCryptoInfoWrapper(
634 AMediaCodecCryptoInfo *aMediaCodecCryptoInfo)
635 : mAMediaCodecCryptoInfo(aMediaCodecCryptoInfo) {
636}
637
638AMediaCodecCryptoInfoWrapper::~AMediaCodecCryptoInfoWrapper() {
639 release();
640}
641
642status_t AMediaCodecCryptoInfoWrapper::release() {
643 if (mAMediaCodecCryptoInfo != NULL) {
644 media_status_t err = AMediaCodecCryptoInfo_delete(mAMediaCodecCryptoInfo);
645 mAMediaCodecCryptoInfo = NULL;
646 return translateErrorCode(err);
647 }
648 return OK;
649}
650
651AMediaCodecCryptoInfo *AMediaCodecCryptoInfoWrapper::getAMediaCodecCryptoInfo() const {
652 return mAMediaCodecCryptoInfo;
653}
654
655void AMediaCodecCryptoInfoWrapper::setPattern(CryptoPlugin::Pattern *pattern) {
656 if (mAMediaCodecCryptoInfo == NULL || pattern == NULL) {
657 return;
658 }
659 cryptoinfo_pattern_t ndkPattern = {(int32_t)pattern->mEncryptBlocks,
660 (int32_t)pattern->mSkipBlocks };
661 return AMediaCodecCryptoInfo_setPattern(mAMediaCodecCryptoInfo, &ndkPattern);
662}
663
664size_t AMediaCodecCryptoInfoWrapper::getNumSubSamples() {
665 if (mAMediaCodecCryptoInfo == NULL) {
666 return 0;
667 }
668 return AMediaCodecCryptoInfo_getNumSubSamples(mAMediaCodecCryptoInfo);
669}
670
671status_t AMediaCodecCryptoInfoWrapper::getKey(uint8_t *dst) {
672 if (mAMediaCodecCryptoInfo == NULL) {
673 return DEAD_OBJECT;
674 }
675 if (dst == NULL) {
676 return BAD_VALUE;
677 }
678 return translateErrorCode(
679 AMediaCodecCryptoInfo_getKey(mAMediaCodecCryptoInfo, dst));
680}
681
682status_t AMediaCodecCryptoInfoWrapper::getIV(uint8_t *dst) {
683 if (mAMediaCodecCryptoInfo == NULL) {
684 return DEAD_OBJECT;
685 }
686 if (dst == NULL) {
687 return BAD_VALUE;
688 }
689 return translateErrorCode(
690 AMediaCodecCryptoInfo_getIV(mAMediaCodecCryptoInfo, dst));
691}
692
693CryptoPlugin::Mode AMediaCodecCryptoInfoWrapper::getMode() {
694 if (mAMediaCodecCryptoInfo == NULL) {
695 return CryptoPlugin::kMode_Unencrypted;
696 }
697 return translateToCryptoPluginMode(
698 AMediaCodecCryptoInfo_getMode(mAMediaCodecCryptoInfo));
699}
700
701status_t AMediaCodecCryptoInfoWrapper::getClearBytes(size_t *dst) {
702 if (mAMediaCodecCryptoInfo == NULL) {
703 return DEAD_OBJECT;
704 }
705 if (dst == NULL) {
706 return BAD_VALUE;
707 }
708 return translateErrorCode(
709 AMediaCodecCryptoInfo_getClearBytes(mAMediaCodecCryptoInfo, dst));
710}
711
712status_t AMediaCodecCryptoInfoWrapper::getEncryptedBytes(size_t *dst) {
713 if (mAMediaCodecCryptoInfo == NULL) {
714 return DEAD_OBJECT;
715 }
716 if (dst == NULL) {
717 return BAD_VALUE;
718 }
719 return translateErrorCode(
720 AMediaCodecCryptoInfo_getEncryptedBytes(mAMediaCodecCryptoInfo, dst));
721}
722
723
724//////////// AMediaCodecWrapper
725// static
726sp<AMediaCodecWrapper> AMediaCodecWrapper::CreateCodecByName(const AString &name) {
727 AMediaCodec *aMediaCodec = AMediaCodec_createCodecByName(name.c_str());
728 return new AMediaCodecWrapper(aMediaCodec);
729}
730
731// static
732sp<AMediaCodecWrapper> AMediaCodecWrapper::CreateDecoderByType(const AString &mimeType) {
733 AMediaCodec *aMediaCodec = AMediaCodec_createDecoderByType(mimeType.c_str());
734 return new AMediaCodecWrapper(aMediaCodec);
735}
736
737// static
738void AMediaCodecWrapper::OnInputAvailableCB(
739 AMediaCodec * /* aMediaCodec */,
740 void *userdata,
741 int32_t index) {
742 ALOGV("OnInputAvailableCB: index(%d)", index);
743 sp<AMessage> msg = sp<AMessage>((AMessage *)userdata)->dup();
744 msg->setInt32("callbackID", CB_INPUT_AVAILABLE);
745 msg->setInt32("index", index);
746 msg->post();
747}
748
749// static
750void AMediaCodecWrapper::OnOutputAvailableCB(
751 AMediaCodec * /* aMediaCodec */,
752 void *userdata,
753 int32_t index,
754 AMediaCodecBufferInfo *bufferInfo) {
755 ALOGV("OnOutputAvailableCB: index(%d), (%d, %d, %lld, 0x%x)",
756 index, bufferInfo->offset, bufferInfo->size,
757 (long long)bufferInfo->presentationTimeUs, bufferInfo->flags);
758 sp<AMessage> msg = sp<AMessage>((AMessage *)userdata)->dup();
759 msg->setInt32("callbackID", CB_OUTPUT_AVAILABLE);
760 msg->setInt32("index", index);
761 msg->setSize("offset", (size_t)(bufferInfo->offset));
762 msg->setSize("size", (size_t)(bufferInfo->size));
763 msg->setInt64("timeUs", bufferInfo->presentationTimeUs);
764 msg->setInt32("flags", (int32_t)(bufferInfo->flags));
765 msg->post();
766}
767
768// static
769void AMediaCodecWrapper::OnFormatChangedCB(
770 AMediaCodec * /* aMediaCodec */,
771 void *userdata,
772 AMediaFormat *format) {
773 sp<AMediaFormatWrapper> formatWrapper = new AMediaFormatWrapper(format);
774 sp<AMessage> outputFormat = formatWrapper->toAMessage();
775 ALOGV("OnFormatChangedCB: format(%s)", outputFormat->debugString().c_str());
776
777 sp<AMessage> msg = sp<AMessage>((AMessage *)userdata)->dup();
778 msg->setInt32("callbackID", CB_OUTPUT_FORMAT_CHANGED);
779 msg->setMessage("format", outputFormat);
780 msg->post();
781}
782
783// static
784void AMediaCodecWrapper::OnErrorCB(
785 AMediaCodec * /* aMediaCodec */,
786 void *userdata,
787 media_status_t err,
788 int32_t actionCode,
789 const char *detail) {
790 ALOGV("OnErrorCB: err(%d), actionCode(%d), detail(%s)", err, actionCode, detail);
791 sp<AMessage> msg = sp<AMessage>((AMessage *)userdata)->dup();
792 msg->setInt32("callbackID", CB_ERROR);
793 msg->setInt32("err", translateErrorCode(err));
794 msg->setInt32("actionCode", translateActionCode(actionCode));
795 msg->setString("detail", detail);
796 msg->post();
797}
798
799AMediaCodecWrapper::AMediaCodecWrapper(AMediaCodec *aMediaCodec)
800 : mAMediaCodec(aMediaCodec) {
801}
802
803AMediaCodecWrapper::~AMediaCodecWrapper() {
804 release();
805}
806
807status_t AMediaCodecWrapper::release() {
808 if (mAMediaCodec != NULL) {
809 AMediaCodecOnAsyncNotifyCallback aCB = {};
810 AMediaCodec_setAsyncNotifyCallback(mAMediaCodec, aCB, NULL);
811 mCallback = NULL;
812
813 media_status_t err = AMediaCodec_delete(mAMediaCodec);
814 mAMediaCodec = NULL;
815 return translateErrorCode(err);
816 }
817 return OK;
818}
819
820AMediaCodec *AMediaCodecWrapper::getAMediaCodec() const {
821 return mAMediaCodec;
822}
823
824status_t AMediaCodecWrapper::getName(AString *outComponentName) const {
825 if (mAMediaCodec == NULL) {
826 return DEAD_OBJECT;
827 }
828 char *name = NULL;
829 media_status_t err = AMediaCodec_getName(mAMediaCodec, &name);
830 if (err != AMEDIA_OK) {
831 return translateErrorCode(err);
832 }
833
834 *outComponentName = AString(name);
835 AMediaCodec_releaseName(mAMediaCodec, name);
836 return OK;
837}
838
839status_t AMediaCodecWrapper::configure(
840 const sp<AMediaFormatWrapper> &format,
841 const sp<Surface> &surface,
842 const sp<AMediaCryptoWrapper> &crypto,
843 uint32_t flags) {
844 if (mAMediaCodec == NULL) {
845 return DEAD_OBJECT;
846 }
847
848 media_status_t err = AMediaCodec_configure(
849 mAMediaCodec,
850 format->getAMediaFormat(),
851 surface.get(),
852 crypto == NULL ? NULL : crypto->getAMediaCrypto(),
853 flags);
854
855 return translateErrorCode(err);
856}
857
858status_t AMediaCodecWrapper::setCallback(const sp<AMessage> &callback) {
859 if (mAMediaCodec == NULL) {
860 return DEAD_OBJECT;
861 }
862
863 mCallback = callback;
864
865 AMediaCodecOnAsyncNotifyCallback aCB = {
866 OnInputAvailableCB,
867 OnOutputAvailableCB,
868 OnFormatChangedCB,
869 OnErrorCB
870 };
871
872 return translateErrorCode(
873 AMediaCodec_setAsyncNotifyCallback(mAMediaCodec, aCB, callback.get()));
874}
875
876status_t AMediaCodecWrapper::releaseCrypto() {
877 if (mAMediaCodec == NULL) {
878 return DEAD_OBJECT;
879 }
880 return translateErrorCode(AMediaCodec_releaseCrypto(mAMediaCodec));
881}
882
883status_t AMediaCodecWrapper::start() {
884 if (mAMediaCodec == NULL) {
885 return DEAD_OBJECT;
886 }
887 return translateErrorCode(AMediaCodec_start(mAMediaCodec));
888}
889
890status_t AMediaCodecWrapper::stop() {
891 if (mAMediaCodec == NULL) {
892 return DEAD_OBJECT;
893 }
894 return translateErrorCode(AMediaCodec_stop(mAMediaCodec));
895}
896
897status_t AMediaCodecWrapper::flush() {
898 if (mAMediaCodec == NULL) {
899 return DEAD_OBJECT;
900 }
901 return translateErrorCode(AMediaCodec_flush(mAMediaCodec));
902}
903
904uint8_t* AMediaCodecWrapper::getInputBuffer(size_t idx, size_t *out_size) {
905 if (mAMediaCodec == NULL) {
906 return NULL;
907 }
908 return AMediaCodec_getInputBuffer(mAMediaCodec, idx, out_size);
909}
910
911uint8_t* AMediaCodecWrapper::getOutputBuffer(size_t idx, size_t *out_size) {
912 if (mAMediaCodec == NULL) {
913 return NULL;
914 }
915 return AMediaCodec_getOutputBuffer(mAMediaCodec, idx, out_size);
916}
917
918status_t AMediaCodecWrapper::queueInputBuffer(
919 size_t idx,
920 size_t offset,
921 size_t size,
922 uint64_t time,
923 uint32_t flags) {
924 if (mAMediaCodec == NULL) {
925 return DEAD_OBJECT;
926 }
927 return translateErrorCode(
928 AMediaCodec_queueInputBuffer(mAMediaCodec, idx, offset, size, time, flags));
929}
930
931status_t AMediaCodecWrapper::queueSecureInputBuffer(
932 size_t idx,
933 size_t offset,
934 sp<AMediaCodecCryptoInfoWrapper> &codecCryptoInfo,
935 uint64_t time,
936 uint32_t flags) {
937 if (mAMediaCodec == NULL) {
938 return DEAD_OBJECT;
939 }
940 return translateErrorCode(
941 AMediaCodec_queueSecureInputBuffer(
942 mAMediaCodec,
943 idx,
944 offset,
945 codecCryptoInfo->getAMediaCodecCryptoInfo(),
946 time,
947 flags));
948}
949
950sp<AMediaFormatWrapper> AMediaCodecWrapper::getOutputFormat() {
951 if (mAMediaCodec == NULL) {
952 return NULL;
953 }
954 return new AMediaFormatWrapper(AMediaCodec_getOutputFormat(mAMediaCodec));
955}
956
957sp<AMediaFormatWrapper> AMediaCodecWrapper::getInputFormat() {
958 if (mAMediaCodec == NULL) {
959 return NULL;
960 }
961 return new AMediaFormatWrapper(AMediaCodec_getInputFormat(mAMediaCodec));
962}
963
964status_t AMediaCodecWrapper::releaseOutputBuffer(size_t idx, bool render) {
965 if (mAMediaCodec == NULL) {
966 return DEAD_OBJECT;
967 }
968 return translateErrorCode(
969 AMediaCodec_releaseOutputBuffer(mAMediaCodec, idx, render));
970}
971
972status_t AMediaCodecWrapper::setOutputSurface(const sp<Surface> &surface) {
973 if (mAMediaCodec == NULL) {
974 return DEAD_OBJECT;
975 }
976 return translateErrorCode(
977 AMediaCodec_setOutputSurface(mAMediaCodec, surface.get()));
978}
979
980status_t AMediaCodecWrapper::releaseOutputBufferAtTime(size_t idx, int64_t timestampNs) {
981 if (mAMediaCodec == NULL) {
982 return DEAD_OBJECT;
983 }
984 return translateErrorCode(
985 AMediaCodec_releaseOutputBufferAtTime(mAMediaCodec, idx, timestampNs));
986}
987
988status_t AMediaCodecWrapper::setParameters(const sp<AMediaFormatWrapper> &params) {
989 if (mAMediaCodec == NULL) {
990 return DEAD_OBJECT;
991 }
992 return translateErrorCode(
993 AMediaCodec_setParameters(mAMediaCodec, params->getAMediaFormat()));
994}
995
996} // namespace android