blob: 936e92f0bb2c903aec7ab49bbf790c5d6b8535f8 [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
Wei Jia28288fb2017-12-15 13:45:29 -080020#include <media/NdkWrapper.h>
Wei Jia53692fa2017-12-11 10:33:46 -080021
Wei Jia28288fb2017-12-15 13:45:29 -080022#include <android/native_window.h>
Wei Jia53692fa2017-12-11 10:33:46 -080023#include <log/log.h>
24#include <media/NdkMediaCodec.h>
25#include <media/NdkMediaCrypto.h>
26#include <media/NdkMediaDrm.h>
27#include <media/NdkMediaFormat.h>
Robert Shihff282cb2017-12-18 14:10:56 -080028#include <media/NdkMediaExtractor.h>
Wei Jia53692fa2017-12-11 10:33:46 -080029#include <media/stagefright/MetaData.h>
30#include <media/stagefright/foundation/ABuffer.h>
31#include <media/stagefright/foundation/AMessage.h>
32#include <utils/Errors.h>
33
34namespace android {
35
36static const size_t kAESBlockSize = 16; // AES_BLOCK_SIZE
37
38static const char *AMediaFormatKeyGroupInt32[] = {
39 AMEDIAFORMAT_KEY_AAC_DRC_ATTENUATION_FACTOR,
40 AMEDIAFORMAT_KEY_AAC_DRC_BOOST_FACTOR,
41 AMEDIAFORMAT_KEY_AAC_DRC_HEAVY_COMPRESSION,
42 AMEDIAFORMAT_KEY_AAC_DRC_TARGET_REFERENCE_LEVEL,
43 AMEDIAFORMAT_KEY_AAC_ENCODED_TARGET_LEVEL,
44 AMEDIAFORMAT_KEY_AAC_MAX_OUTPUT_CHANNEL_COUNT,
45 AMEDIAFORMAT_KEY_AAC_PROFILE,
46 AMEDIAFORMAT_KEY_AAC_SBR_MODE,
47 AMEDIAFORMAT_KEY_AUDIO_SESSION_ID,
48 AMEDIAFORMAT_KEY_BITRATE_MODE,
49 AMEDIAFORMAT_KEY_BIT_RATE,
50 AMEDIAFORMAT_KEY_CAPTURE_RATE,
51 AMEDIAFORMAT_KEY_CHANNEL_COUNT,
52 AMEDIAFORMAT_KEY_CHANNEL_MASK,
53 AMEDIAFORMAT_KEY_COLOR_FORMAT,
54 AMEDIAFORMAT_KEY_COLOR_RANGE,
55 AMEDIAFORMAT_KEY_COLOR_STANDARD,
56 AMEDIAFORMAT_KEY_COLOR_TRANSFER,
57 AMEDIAFORMAT_KEY_COMPLEXITY,
58 AMEDIAFORMAT_KEY_FLAC_COMPRESSION_LEVEL,
59 AMEDIAFORMAT_KEY_GRID_COLS,
60 AMEDIAFORMAT_KEY_GRID_HEIGHT,
61 AMEDIAFORMAT_KEY_GRID_ROWS,
62 AMEDIAFORMAT_KEY_GRID_WIDTH,
63 AMEDIAFORMAT_KEY_HEIGHT,
64 AMEDIAFORMAT_KEY_INTRA_REFRESH_PERIOD,
65 AMEDIAFORMAT_KEY_IS_ADTS,
66 AMEDIAFORMAT_KEY_IS_AUTOSELECT,
67 AMEDIAFORMAT_KEY_IS_DEFAULT,
68 AMEDIAFORMAT_KEY_IS_FORCED_SUBTITLE,
69 AMEDIAFORMAT_KEY_LATENCY,
70 AMEDIAFORMAT_KEY_LEVEL,
71 AMEDIAFORMAT_KEY_MAX_HEIGHT,
72 AMEDIAFORMAT_KEY_MAX_INPUT_SIZE,
73 AMEDIAFORMAT_KEY_MAX_WIDTH,
74 AMEDIAFORMAT_KEY_PCM_ENCODING,
75 AMEDIAFORMAT_KEY_PRIORITY,
76 AMEDIAFORMAT_KEY_PROFILE,
77 AMEDIAFORMAT_KEY_PUSH_BLANK_BUFFERS_ON_STOP,
78 AMEDIAFORMAT_KEY_ROTATION,
79 AMEDIAFORMAT_KEY_SAMPLE_RATE,
80 AMEDIAFORMAT_KEY_SLICE_HEIGHT,
81 AMEDIAFORMAT_KEY_STRIDE,
82 AMEDIAFORMAT_KEY_TRACK_ID,
83 AMEDIAFORMAT_KEY_WIDTH,
84};
85
86static const char *AMediaFormatKeyGroupInt64[] = {
87 AMEDIAFORMAT_KEY_DURATION,
88 AMEDIAFORMAT_KEY_REPEAT_PREVIOUS_FRAME_AFTER,
89};
90
91static const char *AMediaFormatKeyGroupString[] = {
92 AMEDIAFORMAT_KEY_LANGUAGE,
93 AMEDIAFORMAT_KEY_MIME,
94 AMEDIAFORMAT_KEY_TEMPORAL_LAYERING,
95};
96
97static const char *AMediaFormatKeyGroupBuffer[] = {
98 AMEDIAFORMAT_KEY_HDR_STATIC_INFO,
99};
100
101static const char *AMediaFormatKeyGroupRect[] = {
102 AMEDIAFORMAT_KEY_DISPLAY_CROP,
103};
104
105static const char *AMediaFormatKeyGroupFloatInt32[] = {
106 AMEDIAFORMAT_KEY_FRAME_RATE,
107 AMEDIAFORMAT_KEY_I_FRAME_INTERVAL,
108 AMEDIAFORMAT_KEY_OPERATING_RATE,
109};
110
111static status_t translateErrorCode(media_status_t err) {
112 if (err == AMEDIA_OK) {
113 return OK;
114 } else if (err == AMEDIACODEC_INFO_TRY_AGAIN_LATER) {
115 return -EAGAIN;
116 }
117
118 ALOGE("ndk error code: %d", err);
119 return UNKNOWN_ERROR;
120}
121
122static int32_t translateActionCode(int32_t actionCode) {
123 if (AMediaCodecActionCode_isTransient(actionCode)) {
124 return ACTION_CODE_TRANSIENT;
125 } else if (AMediaCodecActionCode_isRecoverable(actionCode)) {
126 return ACTION_CODE_RECOVERABLE;
127 }
128 return ACTION_CODE_FATAL;
129}
130
131static CryptoPlugin::Mode translateToCryptoPluginMode(cryptoinfo_mode_t mode) {
132 CryptoPlugin::Mode ret = CryptoPlugin::kMode_Unencrypted;
133 switch (mode) {
134 case AMEDIACODECRYPTOINFO_MODE_AES_CTR: {
135 ret = CryptoPlugin::kMode_AES_CTR;
136 break;
137 }
138
139 case AMEDIACODECRYPTOINFO_MODE_AES_WV: {
140 ret = CryptoPlugin::kMode_AES_WV;
141 break;
142 }
143
144 case AMEDIACODECRYPTOINFO_MODE_AES_CBC: {
145 ret = CryptoPlugin::kMode_AES_CBC;
146 break;
147 }
148
149 default:
150 break;
151 }
152
153 return ret;
154}
155
156static cryptoinfo_mode_t translateToCryptoInfoMode(CryptoPlugin::Mode mode) {
157 cryptoinfo_mode_t ret = AMEDIACODECRYPTOINFO_MODE_CLEAR;
158 switch (mode) {
159 case CryptoPlugin::kMode_AES_CTR: {
160 ret = AMEDIACODECRYPTOINFO_MODE_AES_CTR;
161 break;
162 }
163
164 case CryptoPlugin::kMode_AES_WV: {
165 ret = AMEDIACODECRYPTOINFO_MODE_AES_WV;
166 break;
167 }
168
169 case CryptoPlugin::kMode_AES_CBC: {
170 ret = AMEDIACODECRYPTOINFO_MODE_AES_CBC;
171 break;
172 }
173
174 default:
175 break;
176 }
177
178 return ret;
179}
180
Wei Jia53692fa2017-12-11 10:33:46 -0800181//////////// 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
Wei Jia28288fb2017-12-15 13:45:29 -0800476//////////// ANativeWindowWrapper
477ANativeWindowWrapper::ANativeWindowWrapper(ANativeWindow *aNativeWindow)
478 : mANativeWindow(aNativeWindow) {
479 if (aNativeWindow != NULL) {
480 ANativeWindow_acquire(aNativeWindow);
481 }
482}
483
484ANativeWindowWrapper::~ANativeWindowWrapper() {
485 release();
486}
487
488status_t ANativeWindowWrapper::release() {
489 if (mANativeWindow != NULL) {
490 ANativeWindow_release(mANativeWindow);
491 mANativeWindow = NULL;
492 }
493 return OK;
494}
495
496ANativeWindow *ANativeWindowWrapper::getANativeWindow() const {
497 return mANativeWindow;
498}
499
500
Wei Jia53692fa2017-12-11 10:33:46 -0800501//////////// AMediaDrmWrapper
502AMediaDrmWrapper::AMediaDrmWrapper(const uint8_t uuid[16]) {
503 mAMediaDrm = AMediaDrm_createByUUID(uuid);
504}
505
506AMediaDrmWrapper::AMediaDrmWrapper(AMediaDrm *aMediaDrm)
507 : mAMediaDrm(aMediaDrm) {
508}
509
510AMediaDrmWrapper::~AMediaDrmWrapper() {
511 release();
512}
513
514status_t AMediaDrmWrapper::release() {
515 if (mAMediaDrm != NULL) {
516 AMediaDrm_release(mAMediaDrm);
517 mAMediaDrm = NULL;
518 }
519 return OK;
520}
521
522AMediaDrm *AMediaDrmWrapper::getAMediaDrm() const {
523 return mAMediaDrm;
524}
525
526// static
527bool AMediaDrmWrapper::isCryptoSchemeSupported(
528 const uint8_t uuid[16],
529 const char *mimeType) {
530 return AMediaDrm_isCryptoSchemeSupported(uuid, mimeType);
531}
532
533
534//////////// AMediaCryptoWrapper
535AMediaCryptoWrapper::AMediaCryptoWrapper(
536 const uint8_t uuid[16], const void *initData, size_t initDataSize) {
537 mAMediaCrypto = AMediaCrypto_new(uuid, initData, initDataSize);
538}
539
540AMediaCryptoWrapper::AMediaCryptoWrapper(AMediaCrypto *aMediaCrypto)
541 : mAMediaCrypto(aMediaCrypto) {
542}
543
544AMediaCryptoWrapper::~AMediaCryptoWrapper() {
545 release();
546}
547
548status_t AMediaCryptoWrapper::release() {
549 if (mAMediaCrypto != NULL) {
550 AMediaCrypto_delete(mAMediaCrypto);
551 mAMediaCrypto = NULL;
552 }
553 return OK;
554}
555
556AMediaCrypto *AMediaCryptoWrapper::getAMediaCrypto() const {
557 return mAMediaCrypto;
558}
559
560bool AMediaCryptoWrapper::isCryptoSchemeSupported(const uint8_t uuid[16]) {
561 if (mAMediaCrypto == NULL) {
562 return false;
563 }
564 return AMediaCrypto_isCryptoSchemeSupported(uuid);
565}
566
567bool AMediaCryptoWrapper::requiresSecureDecoderComponent(const char *mime) {
568 if (mAMediaCrypto == NULL) {
569 return false;
570 }
571 return AMediaCrypto_requiresSecureDecoderComponent(mime);
572}
573
574
575//////////// AMediaCodecCryptoInfoWrapper
576// static
577sp<AMediaCodecCryptoInfoWrapper> AMediaCodecCryptoInfoWrapper::Create(sp<MetaData> meta) {
578 if (meta == NULL) {
579 ALOGE("Create: Unexpected. No meta data for sample.");
580 return NULL;
581 }
582
583 uint32_t type;
584 const void *crypteddata;
585 size_t cryptedsize;
586
587 if (!meta->findData(kKeyEncryptedSizes, &type, &crypteddata, &cryptedsize)) {
588 return NULL;
589 }
590
591 int numSubSamples = cryptedsize / sizeof(size_t);
592
593 if (numSubSamples <= 0) {
594 ALOGE("Create: INVALID numSubSamples: %d", numSubSamples);
595 return NULL;
596 }
597
598 const void *cleardata;
599 size_t clearsize;
600 if (meta->findData(kKeyPlainSizes, &type, &cleardata, &clearsize)) {
601 if (clearsize != cryptedsize) {
602 // The two must be of the same length.
603 ALOGE("Create: mismatch cryptedsize: %zu != clearsize: %zu", cryptedsize, clearsize);
604 return NULL;
605 }
606 }
607
608 const void *key;
609 size_t keysize;
610 if (meta->findData(kKeyCryptoKey, &type, &key, &keysize)) {
611 if (keysize != kAESBlockSize) {
612 // Keys must be 16 bytes in length.
613 ALOGE("Create: Keys must be %zu bytes in length: %zu", kAESBlockSize, keysize);
614 return NULL;
615 }
616 }
617
618 const void *iv;
619 size_t ivsize;
620 if (meta->findData(kKeyCryptoIV, &type, &iv, &ivsize)) {
621 if (ivsize != kAESBlockSize) {
622 // IVs must be 16 bytes in length.
623 ALOGE("Create: IV must be %zu bytes in length: %zu", kAESBlockSize, ivsize);
624 return NULL;
625 }
626 }
627
628 int32_t mode;
629 if (!meta->findInt32(kKeyCryptoMode, &mode)) {
630 mode = CryptoPlugin::kMode_AES_CTR;
631 }
632
633 return new AMediaCodecCryptoInfoWrapper(
634 numSubSamples,
635 (uint8_t*) key,
636 (uint8_t*) iv,
637 (CryptoPlugin::Mode)mode,
638 (size_t*) cleardata,
639 (size_t*) crypteddata);
640}
641
642AMediaCodecCryptoInfoWrapper::AMediaCodecCryptoInfoWrapper(
643 int numsubsamples,
644 uint8_t key[16],
645 uint8_t iv[16],
646 CryptoPlugin::Mode mode,
647 size_t *clearbytes,
648 size_t *encryptedbytes) {
649 mAMediaCodecCryptoInfo =
650 AMediaCodecCryptoInfo_new(numsubsamples,
651 key,
652 iv,
653 translateToCryptoInfoMode(mode),
654 clearbytes,
655 encryptedbytes);
656}
657
658AMediaCodecCryptoInfoWrapper::AMediaCodecCryptoInfoWrapper(
659 AMediaCodecCryptoInfo *aMediaCodecCryptoInfo)
660 : mAMediaCodecCryptoInfo(aMediaCodecCryptoInfo) {
661}
662
663AMediaCodecCryptoInfoWrapper::~AMediaCodecCryptoInfoWrapper() {
664 release();
665}
666
667status_t AMediaCodecCryptoInfoWrapper::release() {
668 if (mAMediaCodecCryptoInfo != NULL) {
669 media_status_t err = AMediaCodecCryptoInfo_delete(mAMediaCodecCryptoInfo);
670 mAMediaCodecCryptoInfo = NULL;
671 return translateErrorCode(err);
672 }
673 return OK;
674}
675
676AMediaCodecCryptoInfo *AMediaCodecCryptoInfoWrapper::getAMediaCodecCryptoInfo() const {
677 return mAMediaCodecCryptoInfo;
678}
679
680void AMediaCodecCryptoInfoWrapper::setPattern(CryptoPlugin::Pattern *pattern) {
681 if (mAMediaCodecCryptoInfo == NULL || pattern == NULL) {
682 return;
683 }
684 cryptoinfo_pattern_t ndkPattern = {(int32_t)pattern->mEncryptBlocks,
685 (int32_t)pattern->mSkipBlocks };
686 return AMediaCodecCryptoInfo_setPattern(mAMediaCodecCryptoInfo, &ndkPattern);
687}
688
689size_t AMediaCodecCryptoInfoWrapper::getNumSubSamples() {
690 if (mAMediaCodecCryptoInfo == NULL) {
691 return 0;
692 }
693 return AMediaCodecCryptoInfo_getNumSubSamples(mAMediaCodecCryptoInfo);
694}
695
696status_t AMediaCodecCryptoInfoWrapper::getKey(uint8_t *dst) {
697 if (mAMediaCodecCryptoInfo == NULL) {
698 return DEAD_OBJECT;
699 }
700 if (dst == NULL) {
701 return BAD_VALUE;
702 }
703 return translateErrorCode(
704 AMediaCodecCryptoInfo_getKey(mAMediaCodecCryptoInfo, dst));
705}
706
707status_t AMediaCodecCryptoInfoWrapper::getIV(uint8_t *dst) {
708 if (mAMediaCodecCryptoInfo == NULL) {
709 return DEAD_OBJECT;
710 }
711 if (dst == NULL) {
712 return BAD_VALUE;
713 }
714 return translateErrorCode(
715 AMediaCodecCryptoInfo_getIV(mAMediaCodecCryptoInfo, dst));
716}
717
718CryptoPlugin::Mode AMediaCodecCryptoInfoWrapper::getMode() {
719 if (mAMediaCodecCryptoInfo == NULL) {
720 return CryptoPlugin::kMode_Unencrypted;
721 }
722 return translateToCryptoPluginMode(
723 AMediaCodecCryptoInfo_getMode(mAMediaCodecCryptoInfo));
724}
725
726status_t AMediaCodecCryptoInfoWrapper::getClearBytes(size_t *dst) {
727 if (mAMediaCodecCryptoInfo == NULL) {
728 return DEAD_OBJECT;
729 }
730 if (dst == NULL) {
731 return BAD_VALUE;
732 }
733 return translateErrorCode(
734 AMediaCodecCryptoInfo_getClearBytes(mAMediaCodecCryptoInfo, dst));
735}
736
737status_t AMediaCodecCryptoInfoWrapper::getEncryptedBytes(size_t *dst) {
738 if (mAMediaCodecCryptoInfo == NULL) {
739 return DEAD_OBJECT;
740 }
741 if (dst == NULL) {
742 return BAD_VALUE;
743 }
744 return translateErrorCode(
745 AMediaCodecCryptoInfo_getEncryptedBytes(mAMediaCodecCryptoInfo, dst));
746}
747
748
749//////////// AMediaCodecWrapper
750// static
751sp<AMediaCodecWrapper> AMediaCodecWrapper::CreateCodecByName(const AString &name) {
752 AMediaCodec *aMediaCodec = AMediaCodec_createCodecByName(name.c_str());
753 return new AMediaCodecWrapper(aMediaCodec);
754}
755
756// static
757sp<AMediaCodecWrapper> AMediaCodecWrapper::CreateDecoderByType(const AString &mimeType) {
758 AMediaCodec *aMediaCodec = AMediaCodec_createDecoderByType(mimeType.c_str());
759 return new AMediaCodecWrapper(aMediaCodec);
760}
761
762// static
763void AMediaCodecWrapper::OnInputAvailableCB(
764 AMediaCodec * /* aMediaCodec */,
765 void *userdata,
766 int32_t index) {
767 ALOGV("OnInputAvailableCB: index(%d)", index);
768 sp<AMessage> msg = sp<AMessage>((AMessage *)userdata)->dup();
769 msg->setInt32("callbackID", CB_INPUT_AVAILABLE);
770 msg->setInt32("index", index);
771 msg->post();
772}
773
774// static
775void AMediaCodecWrapper::OnOutputAvailableCB(
776 AMediaCodec * /* aMediaCodec */,
777 void *userdata,
778 int32_t index,
779 AMediaCodecBufferInfo *bufferInfo) {
780 ALOGV("OnOutputAvailableCB: index(%d), (%d, %d, %lld, 0x%x)",
781 index, bufferInfo->offset, bufferInfo->size,
782 (long long)bufferInfo->presentationTimeUs, bufferInfo->flags);
783 sp<AMessage> msg = sp<AMessage>((AMessage *)userdata)->dup();
784 msg->setInt32("callbackID", CB_OUTPUT_AVAILABLE);
785 msg->setInt32("index", index);
786 msg->setSize("offset", (size_t)(bufferInfo->offset));
787 msg->setSize("size", (size_t)(bufferInfo->size));
788 msg->setInt64("timeUs", bufferInfo->presentationTimeUs);
789 msg->setInt32("flags", (int32_t)(bufferInfo->flags));
790 msg->post();
791}
792
793// static
794void AMediaCodecWrapper::OnFormatChangedCB(
795 AMediaCodec * /* aMediaCodec */,
796 void *userdata,
797 AMediaFormat *format) {
798 sp<AMediaFormatWrapper> formatWrapper = new AMediaFormatWrapper(format);
799 sp<AMessage> outputFormat = formatWrapper->toAMessage();
800 ALOGV("OnFormatChangedCB: format(%s)", outputFormat->debugString().c_str());
801
802 sp<AMessage> msg = sp<AMessage>((AMessage *)userdata)->dup();
803 msg->setInt32("callbackID", CB_OUTPUT_FORMAT_CHANGED);
804 msg->setMessage("format", outputFormat);
805 msg->post();
806}
807
808// static
809void AMediaCodecWrapper::OnErrorCB(
810 AMediaCodec * /* aMediaCodec */,
811 void *userdata,
812 media_status_t err,
813 int32_t actionCode,
814 const char *detail) {
815 ALOGV("OnErrorCB: err(%d), actionCode(%d), detail(%s)", err, actionCode, detail);
816 sp<AMessage> msg = sp<AMessage>((AMessage *)userdata)->dup();
817 msg->setInt32("callbackID", CB_ERROR);
818 msg->setInt32("err", translateErrorCode(err));
819 msg->setInt32("actionCode", translateActionCode(actionCode));
820 msg->setString("detail", detail);
821 msg->post();
822}
823
824AMediaCodecWrapper::AMediaCodecWrapper(AMediaCodec *aMediaCodec)
825 : mAMediaCodec(aMediaCodec) {
826}
827
828AMediaCodecWrapper::~AMediaCodecWrapper() {
829 release();
830}
831
832status_t AMediaCodecWrapper::release() {
833 if (mAMediaCodec != NULL) {
834 AMediaCodecOnAsyncNotifyCallback aCB = {};
835 AMediaCodec_setAsyncNotifyCallback(mAMediaCodec, aCB, NULL);
836 mCallback = NULL;
837
838 media_status_t err = AMediaCodec_delete(mAMediaCodec);
839 mAMediaCodec = NULL;
840 return translateErrorCode(err);
841 }
842 return OK;
843}
844
845AMediaCodec *AMediaCodecWrapper::getAMediaCodec() const {
846 return mAMediaCodec;
847}
848
849status_t AMediaCodecWrapper::getName(AString *outComponentName) const {
850 if (mAMediaCodec == NULL) {
851 return DEAD_OBJECT;
852 }
853 char *name = NULL;
854 media_status_t err = AMediaCodec_getName(mAMediaCodec, &name);
855 if (err != AMEDIA_OK) {
856 return translateErrorCode(err);
857 }
858
859 *outComponentName = AString(name);
860 AMediaCodec_releaseName(mAMediaCodec, name);
861 return OK;
862}
863
864status_t AMediaCodecWrapper::configure(
865 const sp<AMediaFormatWrapper> &format,
Wei Jia28288fb2017-12-15 13:45:29 -0800866 const sp<ANativeWindowWrapper> &nww,
Wei Jia53692fa2017-12-11 10:33:46 -0800867 const sp<AMediaCryptoWrapper> &crypto,
868 uint32_t flags) {
869 if (mAMediaCodec == NULL) {
870 return DEAD_OBJECT;
871 }
872
873 media_status_t err = AMediaCodec_configure(
874 mAMediaCodec,
875 format->getAMediaFormat(),
Wei Jia28288fb2017-12-15 13:45:29 -0800876 (nww == NULL ? NULL : nww->getANativeWindow()),
Wei Jia53692fa2017-12-11 10:33:46 -0800877 crypto == NULL ? NULL : crypto->getAMediaCrypto(),
878 flags);
879
880 return translateErrorCode(err);
881}
882
883status_t AMediaCodecWrapper::setCallback(const sp<AMessage> &callback) {
884 if (mAMediaCodec == NULL) {
885 return DEAD_OBJECT;
886 }
887
888 mCallback = callback;
889
890 AMediaCodecOnAsyncNotifyCallback aCB = {
891 OnInputAvailableCB,
892 OnOutputAvailableCB,
893 OnFormatChangedCB,
894 OnErrorCB
895 };
896
897 return translateErrorCode(
898 AMediaCodec_setAsyncNotifyCallback(mAMediaCodec, aCB, callback.get()));
899}
900
901status_t AMediaCodecWrapper::releaseCrypto() {
902 if (mAMediaCodec == NULL) {
903 return DEAD_OBJECT;
904 }
905 return translateErrorCode(AMediaCodec_releaseCrypto(mAMediaCodec));
906}
907
908status_t AMediaCodecWrapper::start() {
909 if (mAMediaCodec == NULL) {
910 return DEAD_OBJECT;
911 }
912 return translateErrorCode(AMediaCodec_start(mAMediaCodec));
913}
914
915status_t AMediaCodecWrapper::stop() {
916 if (mAMediaCodec == NULL) {
917 return DEAD_OBJECT;
918 }
919 return translateErrorCode(AMediaCodec_stop(mAMediaCodec));
920}
921
922status_t AMediaCodecWrapper::flush() {
923 if (mAMediaCodec == NULL) {
924 return DEAD_OBJECT;
925 }
926 return translateErrorCode(AMediaCodec_flush(mAMediaCodec));
927}
928
929uint8_t* AMediaCodecWrapper::getInputBuffer(size_t idx, size_t *out_size) {
930 if (mAMediaCodec == NULL) {
931 return NULL;
932 }
933 return AMediaCodec_getInputBuffer(mAMediaCodec, idx, out_size);
934}
935
936uint8_t* AMediaCodecWrapper::getOutputBuffer(size_t idx, size_t *out_size) {
937 if (mAMediaCodec == NULL) {
938 return NULL;
939 }
940 return AMediaCodec_getOutputBuffer(mAMediaCodec, idx, out_size);
941}
942
943status_t AMediaCodecWrapper::queueInputBuffer(
944 size_t idx,
945 size_t offset,
946 size_t size,
947 uint64_t time,
948 uint32_t flags) {
949 if (mAMediaCodec == NULL) {
950 return DEAD_OBJECT;
951 }
952 return translateErrorCode(
953 AMediaCodec_queueInputBuffer(mAMediaCodec, idx, offset, size, time, flags));
954}
955
956status_t AMediaCodecWrapper::queueSecureInputBuffer(
957 size_t idx,
958 size_t offset,
959 sp<AMediaCodecCryptoInfoWrapper> &codecCryptoInfo,
960 uint64_t time,
961 uint32_t flags) {
962 if (mAMediaCodec == NULL) {
963 return DEAD_OBJECT;
964 }
965 return translateErrorCode(
966 AMediaCodec_queueSecureInputBuffer(
967 mAMediaCodec,
968 idx,
969 offset,
970 codecCryptoInfo->getAMediaCodecCryptoInfo(),
971 time,
972 flags));
973}
974
975sp<AMediaFormatWrapper> AMediaCodecWrapper::getOutputFormat() {
976 if (mAMediaCodec == NULL) {
977 return NULL;
978 }
979 return new AMediaFormatWrapper(AMediaCodec_getOutputFormat(mAMediaCodec));
980}
981
982sp<AMediaFormatWrapper> AMediaCodecWrapper::getInputFormat() {
983 if (mAMediaCodec == NULL) {
984 return NULL;
985 }
986 return new AMediaFormatWrapper(AMediaCodec_getInputFormat(mAMediaCodec));
987}
988
989status_t AMediaCodecWrapper::releaseOutputBuffer(size_t idx, bool render) {
990 if (mAMediaCodec == NULL) {
991 return DEAD_OBJECT;
992 }
993 return translateErrorCode(
994 AMediaCodec_releaseOutputBuffer(mAMediaCodec, idx, render));
995}
996
Wei Jia28288fb2017-12-15 13:45:29 -0800997status_t AMediaCodecWrapper::setOutputSurface(const sp<ANativeWindowWrapper> &nww) {
Wei Jia53692fa2017-12-11 10:33:46 -0800998 if (mAMediaCodec == NULL) {
999 return DEAD_OBJECT;
1000 }
1001 return translateErrorCode(
Wei Jia28288fb2017-12-15 13:45:29 -08001002 AMediaCodec_setOutputSurface(mAMediaCodec,
1003 (nww == NULL ? NULL : nww->getANativeWindow())));
Wei Jia53692fa2017-12-11 10:33:46 -08001004}
1005
1006status_t AMediaCodecWrapper::releaseOutputBufferAtTime(size_t idx, int64_t timestampNs) {
1007 if (mAMediaCodec == NULL) {
1008 return DEAD_OBJECT;
1009 }
1010 return translateErrorCode(
1011 AMediaCodec_releaseOutputBufferAtTime(mAMediaCodec, idx, timestampNs));
1012}
1013
1014status_t AMediaCodecWrapper::setParameters(const sp<AMediaFormatWrapper> &params) {
1015 if (mAMediaCodec == NULL) {
1016 return DEAD_OBJECT;
1017 }
1018 return translateErrorCode(
1019 AMediaCodec_setParameters(mAMediaCodec, params->getAMediaFormat()));
1020}
1021
Robert Shihff282cb2017-12-18 14:10:56 -08001022//////////// AMediaExtractorWrapper
1023
1024AMediaExtractorWrapper::AMediaExtractorWrapper(AMediaExtractor *aMediaExtractor)
1025 : mAMediaExtractor(aMediaExtractor) {
1026}
1027
1028AMediaExtractorWrapper::~AMediaExtractorWrapper() {
1029 release();
1030}
1031
1032status_t AMediaExtractorWrapper::release() {
1033 if (mAMediaExtractor != NULL) {
1034 media_status_t err = AMediaExtractor_delete(mAMediaExtractor);
1035 mAMediaExtractor = NULL;
1036 return translateErrorCode(err);
1037 }
1038 return OK;
1039}
1040
1041AMediaExtractor *AMediaExtractorWrapper::getAMediaExtractor() const {
1042 return mAMediaExtractor;
1043}
1044
1045status_t AMediaExtractorWrapper::setDataSource(int fd, off64_t offset, off64_t length) {
1046 if (mAMediaExtractor == NULL) {
1047 return DEAD_OBJECT;
1048 }
1049 return translateErrorCode(AMediaExtractor_setDataSourceFd(
1050 mAMediaExtractor, fd, offset, length));
1051}
1052
1053status_t AMediaExtractorWrapper::setDataSource(const char *location) {
1054 if (mAMediaExtractor == NULL) {
1055 return DEAD_OBJECT;
1056 }
1057 return translateErrorCode(AMediaExtractor_setDataSource(mAMediaExtractor, location));
1058}
1059
Robert Shihd4faf9e2018-01-21 17:52:25 -08001060status_t AMediaExtractorWrapper::setDataSource(AMediaDataSource *source) {
1061 if (mAMediaExtractor == NULL) {
1062 return DEAD_OBJECT;
1063 }
1064 return translateErrorCode(AMediaExtractor_setDataSourceCustom(mAMediaExtractor, source));
1065}
1066
Robert Shihff282cb2017-12-18 14:10:56 -08001067size_t AMediaExtractorWrapper::getTrackCount() {
1068 if (mAMediaExtractor == NULL) {
1069 return 0;
1070 }
1071 return AMediaExtractor_getTrackCount(mAMediaExtractor);
1072}
1073
Robert Shihd4faf9e2018-01-21 17:52:25 -08001074sp<AMediaFormatWrapper> AMediaExtractorWrapper::getFormat() {
1075 if (mAMediaExtractor == NULL) {
1076 return NULL;
1077 }
1078 return new AMediaFormatWrapper(AMediaExtractor_getFileFormat(mAMediaExtractor));
1079}
1080
Robert Shihff282cb2017-12-18 14:10:56 -08001081sp<AMediaFormatWrapper> AMediaExtractorWrapper::getTrackFormat(size_t idx) {
1082 if (mAMediaExtractor == NULL) {
1083 return NULL;
1084 }
1085 return new AMediaFormatWrapper(AMediaExtractor_getTrackFormat(mAMediaExtractor, idx));
1086}
1087
1088status_t AMediaExtractorWrapper::selectTrack(size_t idx) {
1089 if (mAMediaExtractor == NULL) {
1090 return DEAD_OBJECT;
1091 }
1092 return translateErrorCode(AMediaExtractor_selectTrack(mAMediaExtractor, idx));
1093}
1094
1095status_t AMediaExtractorWrapper::unselectTrack(size_t idx) {
1096 if (mAMediaExtractor == NULL) {
1097 return DEAD_OBJECT;
1098 }
1099 return translateErrorCode(AMediaExtractor_unselectTrack(mAMediaExtractor, idx));
1100}
1101
Robert Shihd4faf9e2018-01-21 17:52:25 -08001102status_t AMediaExtractorWrapper::selectSingleTrack(size_t idx) {
1103 if (mAMediaExtractor == NULL) {
1104 return DEAD_OBJECT;
1105 }
1106 for (size_t i = 0; i < AMediaExtractor_getTrackCount(mAMediaExtractor); ++i) {
1107 if (i == idx) {
1108 media_status_t err = AMediaExtractor_selectTrack(mAMediaExtractor, i);
1109 if (err != AMEDIA_OK) {
1110 return translateErrorCode(err);
1111 }
1112 } else {
1113 media_status_t err = AMediaExtractor_unselectTrack(mAMediaExtractor, i);
1114 if (err != AMEDIA_OK) {
1115 return translateErrorCode(err);
1116 }
1117 }
1118 }
1119 return OK;
1120}
1121
Robert Shihff282cb2017-12-18 14:10:56 -08001122ssize_t AMediaExtractorWrapper::readSampleData(const sp<ABuffer> &buffer) {
1123 if (mAMediaExtractor == NULL) {
1124 return -1;
1125 }
1126 return AMediaExtractor_readSampleData(mAMediaExtractor, buffer->data(), buffer->capacity());
1127}
1128
Robert Shihd4faf9e2018-01-21 17:52:25 -08001129ssize_t AMediaExtractorWrapper::getSampleSize() {
1130 if (mAMediaExtractor == NULL) {
1131 return 0;
1132 }
1133 return AMediaExtractor_getSampleSize(mAMediaExtractor);
1134}
1135
Robert Shihff282cb2017-12-18 14:10:56 -08001136uint32_t AMediaExtractorWrapper::getSampleFlags() {
1137 if (mAMediaExtractor == NULL) {
1138 return 0;
1139 }
1140 return AMediaExtractor_getSampleFlags(mAMediaExtractor);
1141}
1142
1143int AMediaExtractorWrapper::getSampleTrackIndex() {
1144 if (mAMediaExtractor == NULL) {
1145 return -1;
1146 }
1147 return AMediaExtractor_getSampleTrackIndex(mAMediaExtractor);
1148}
1149
1150int64_t AMediaExtractorWrapper::getSampleTime() {
1151 if (mAMediaExtractor == NULL) {
1152 return -1;
1153 }
1154 return AMediaExtractor_getSampleTime(mAMediaExtractor);
1155}
1156
Robert Shihd4faf9e2018-01-21 17:52:25 -08001157int64_t AMediaExtractorWrapper::getCachedDuration() {
1158 if (mAMediaExtractor == NULL) {
1159 return -1;
1160 }
1161 return AMediaExtractor_getCachedDuration(mAMediaExtractor);
1162}
1163
Robert Shihff282cb2017-12-18 14:10:56 -08001164bool AMediaExtractorWrapper::advance() {
1165 if (mAMediaExtractor == NULL) {
1166 return false;
1167 }
1168 return AMediaExtractor_advance(mAMediaExtractor);
1169}
1170
Robert Shihd4faf9e2018-01-21 17:52:25 -08001171status_t AMediaExtractorWrapper::seekTo(int64_t seekPosUs, MediaSource::ReadOptions::SeekMode mode) {
Robert Shihff282cb2017-12-18 14:10:56 -08001172 if (mAMediaExtractor == NULL) {
1173 return DEAD_OBJECT;
1174 }
Robert Shihd4faf9e2018-01-21 17:52:25 -08001175
1176 SeekMode aMode;
1177 switch (mode) {
1178 case MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC: {
1179 aMode = AMEDIAEXTRACTOR_SEEK_PREVIOUS_SYNC;
1180 break;
1181 }
1182 case MediaSource::ReadOptions::SEEK_NEXT_SYNC: {
1183 aMode = AMEDIAEXTRACTOR_SEEK_NEXT_SYNC;
1184 break;
1185 }
1186 default: {
1187 aMode = AMEDIAEXTRACTOR_SEEK_CLOSEST_SYNC;
1188 break;
1189 }
1190 }
1191 return AMediaExtractor_seekTo(mAMediaExtractor, seekPosUs, aMode);
Robert Shihff282cb2017-12-18 14:10:56 -08001192}
1193
1194PsshInfo* AMediaExtractorWrapper::getPsshInfo() {
1195 if (mAMediaExtractor == NULL) {
1196 return NULL;
1197 }
1198 return AMediaExtractor_getPsshInfo(mAMediaExtractor);
1199}
1200
1201sp<AMediaCodecCryptoInfoWrapper> AMediaExtractorWrapper::getSampleCryptoInfo() {
1202 if (mAMediaExtractor == NULL) {
1203 return NULL;
1204 }
1205 return new AMediaCodecCryptoInfoWrapper(AMediaExtractor_getSampleCryptoInfo(mAMediaExtractor));
1206}
1207
Robert Shihd4faf9e2018-01-21 17:52:25 -08001208ssize_t AMediaDataSourceWrapper::AMediaDataSourceWrapper_getSize(void *userdata) {
1209 DataSource *source = static_cast<DataSource *>(userdata);
1210 off64_t size = -1;
1211 source->getSize(&size);
1212 return size;
1213}
1214
1215ssize_t AMediaDataSourceWrapper::AMediaDataSourceWrapper_readAt(void *userdata, off64_t offset, void * buf, size_t size) {
1216 DataSource *source = static_cast<DataSource *>(userdata);
1217 return source->readAt(offset, buf, size);
1218}
1219
1220void AMediaDataSourceWrapper::AMediaDataSourceWrapper_close(void *userdata) {
1221 DataSource *source = static_cast<DataSource *>(userdata);
1222 source->close();
1223}
1224
1225AMediaDataSourceWrapper::AMediaDataSourceWrapper(const sp<DataSource> &dataSource)
1226 : mDataSource(dataSource),
1227 mAMediaDataSource(AMediaDataSource_new()) {
1228 ALOGV("setDataSource (source: %p)", dataSource.get());
1229 AMediaDataSource_setUserdata(mAMediaDataSource, dataSource.get());
1230 AMediaDataSource_setReadAt(mAMediaDataSource, AMediaDataSourceWrapper_readAt);
1231 AMediaDataSource_setGetSize(mAMediaDataSource, AMediaDataSourceWrapper_getSize);
1232 AMediaDataSource_setClose(mAMediaDataSource, AMediaDataSourceWrapper_close);
1233}
1234
1235AMediaDataSourceWrapper::~AMediaDataSourceWrapper() {
1236 if (mAMediaDataSource == NULL) {
1237 return;
1238 }
1239 AMediaDataSource_delete(mAMediaDataSource);
1240 mAMediaDataSource = NULL;
1241}
1242
1243AMediaDataSource* AMediaDataSourceWrapper::getAMediaDataSource() {
1244 return mAMediaDataSource;
1245}
1246
Wei Jia53692fa2017-12-11 10:33:46 -08001247} // namespace android