/*
 * Copyright 2017, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//#define LOG_NDEBUG 0
#define LOG_TAG "NdkWrapper"

#include <media/NdkWrapper.h>

#include <android/native_window.h>
#include <log/log.h>
#include <media/NdkMediaCodec.h>
#include <media/NdkMediaCrypto.h>
#include <media/NdkMediaDrm.h>
#include <media/NdkMediaFormat.h>
#include <media/NdkMediaExtractor.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/AMessage.h>
#include <utils/Errors.h>

// TODO: remove forward declaration when AMediaExtractor_disconnect is offcially added to NDK

#ifdef __cplusplus
extern "C" {
#endif

media_status_t AMediaExtractor_disconnect(AMediaExtractor *);

#ifdef __cplusplus
} // extern "C"
#endif

namespace android {

static const size_t kAESBlockSize = 16;  // AES_BLOCK_SIZE

static const char *AMediaFormatKeyGroupInt32[] = {
    AMEDIAFORMAT_KEY_AAC_DRC_ATTENUATION_FACTOR,
    AMEDIAFORMAT_KEY_AAC_DRC_BOOST_FACTOR,
    AMEDIAFORMAT_KEY_AAC_DRC_HEAVY_COMPRESSION,
    AMEDIAFORMAT_KEY_AAC_DRC_TARGET_REFERENCE_LEVEL,
    AMEDIAFORMAT_KEY_AAC_ENCODED_TARGET_LEVEL,
    AMEDIAFORMAT_KEY_AAC_MAX_OUTPUT_CHANNEL_COUNT,
    AMEDIAFORMAT_KEY_AAC_PROFILE,
    AMEDIAFORMAT_KEY_AAC_SBR_MODE,
    AMEDIAFORMAT_KEY_AUDIO_SESSION_ID,
    AMEDIAFORMAT_KEY_BITRATE_MODE,
    AMEDIAFORMAT_KEY_BIT_RATE,
    AMEDIAFORMAT_KEY_CAPTURE_RATE,
    AMEDIAFORMAT_KEY_CHANNEL_COUNT,
    AMEDIAFORMAT_KEY_CHANNEL_MASK,
    AMEDIAFORMAT_KEY_COLOR_FORMAT,
    AMEDIAFORMAT_KEY_COLOR_RANGE,
    AMEDIAFORMAT_KEY_COLOR_STANDARD,
    AMEDIAFORMAT_KEY_COLOR_TRANSFER,
    AMEDIAFORMAT_KEY_COMPLEXITY,
    AMEDIAFORMAT_KEY_FLAC_COMPRESSION_LEVEL,
    AMEDIAFORMAT_KEY_GRID_COLUMNS,
    AMEDIAFORMAT_KEY_GRID_ROWS,
    AMEDIAFORMAT_KEY_HEIGHT,
    AMEDIAFORMAT_KEY_INTRA_REFRESH_PERIOD,
    AMEDIAFORMAT_KEY_IS_ADTS,
    AMEDIAFORMAT_KEY_IS_AUTOSELECT,
    AMEDIAFORMAT_KEY_IS_DEFAULT,
    AMEDIAFORMAT_KEY_IS_FORCED_SUBTITLE,
    AMEDIAFORMAT_KEY_LATENCY,
    AMEDIAFORMAT_KEY_LEVEL,
    AMEDIAFORMAT_KEY_MAX_HEIGHT,
    AMEDIAFORMAT_KEY_MAX_INPUT_SIZE,
    AMEDIAFORMAT_KEY_MAX_WIDTH,
    AMEDIAFORMAT_KEY_PCM_ENCODING,
    AMEDIAFORMAT_KEY_PRIORITY,
    AMEDIAFORMAT_KEY_PROFILE,
    AMEDIAFORMAT_KEY_PUSH_BLANK_BUFFERS_ON_STOP,
    AMEDIAFORMAT_KEY_ROTATION,
    AMEDIAFORMAT_KEY_SAMPLE_RATE,
    AMEDIAFORMAT_KEY_SLICE_HEIGHT,
    AMEDIAFORMAT_KEY_STRIDE,
    AMEDIAFORMAT_KEY_TRACK_ID,
    AMEDIAFORMAT_KEY_WIDTH,
    AMEDIAFORMAT_KEY_DISPLAY_HEIGHT,
    AMEDIAFORMAT_KEY_DISPLAY_WIDTH,
    AMEDIAFORMAT_KEY_TEMPORAL_LAYER_ID,
    AMEDIAFORMAT_KEY_TILE_HEIGHT,
    AMEDIAFORMAT_KEY_TILE_WIDTH,
    AMEDIAFORMAT_KEY_TRACK_INDEX,
};

static const char *AMediaFormatKeyGroupInt64[] = {
    AMEDIAFORMAT_KEY_DURATION,
    AMEDIAFORMAT_KEY_REPEAT_PREVIOUS_FRAME_AFTER,
    AMEDIAFORMAT_KEY_TIME_US,
};

static const char *AMediaFormatKeyGroupString[] = {
    AMEDIAFORMAT_KEY_LANGUAGE,
    AMEDIAFORMAT_KEY_MIME,
    AMEDIAFORMAT_KEY_TEMPORAL_LAYERING,
};

static const char *AMediaFormatKeyGroupBuffer[] = {
    AMEDIAFORMAT_KEY_HDR_STATIC_INFO,
    AMEDIAFORMAT_KEY_SEI,
    AMEDIAFORMAT_KEY_MPEG_USER_DATA,
};

static const char *AMediaFormatKeyGroupCsd[] = {
    AMEDIAFORMAT_KEY_CSD_0,
    AMEDIAFORMAT_KEY_CSD_1,
    AMEDIAFORMAT_KEY_CSD_2,
};

static const char *AMediaFormatKeyGroupRect[] = {
    AMEDIAFORMAT_KEY_DISPLAY_CROP,
};

static const char *AMediaFormatKeyGroupFloatInt32[] = {
    AMEDIAFORMAT_KEY_FRAME_RATE,
    AMEDIAFORMAT_KEY_I_FRAME_INTERVAL,
    AMEDIAFORMAT_KEY_OPERATING_RATE,
};

static status_t translateErrorCode(media_status_t err) {
    if (err == AMEDIA_OK) {
        return OK;
    } else if (err == AMEDIA_ERROR_END_OF_STREAM) {
        return ERROR_END_OF_STREAM;
    } else if (err == AMEDIA_ERROR_IO) {
        return ERROR_IO;
    } else if (err == AMEDIACODEC_INFO_TRY_AGAIN_LATER) {
        return -EAGAIN;
    }

    ALOGE("ndk error code: %d", err);
    return UNKNOWN_ERROR;
}

static int32_t translateActionCode(int32_t actionCode) {
    if (AMediaCodecActionCode_isTransient(actionCode)) {
        return ACTION_CODE_TRANSIENT;
    } else if (AMediaCodecActionCode_isRecoverable(actionCode)) {
        return ACTION_CODE_RECOVERABLE;
    }
    return ACTION_CODE_FATAL;
}

static CryptoPlugin::Mode translateToCryptoPluginMode(cryptoinfo_mode_t mode) {
    CryptoPlugin::Mode ret = CryptoPlugin::kMode_Unencrypted;
    switch (mode) {
        case AMEDIACODECRYPTOINFO_MODE_AES_CTR: {
            ret = CryptoPlugin::kMode_AES_CTR;
            break;
        }

        case AMEDIACODECRYPTOINFO_MODE_AES_WV: {
            ret = CryptoPlugin::kMode_AES_WV;
            break;
        }

        case AMEDIACODECRYPTOINFO_MODE_AES_CBC: {
            ret = CryptoPlugin::kMode_AES_CBC;
            break;
        }

        default:
            break;
    }

    return ret;
}

static cryptoinfo_mode_t translateToCryptoInfoMode(CryptoPlugin::Mode mode) {
    cryptoinfo_mode_t ret = AMEDIACODECRYPTOINFO_MODE_CLEAR;
    switch (mode) {
        case CryptoPlugin::kMode_AES_CTR: {
            ret = AMEDIACODECRYPTOINFO_MODE_AES_CTR;
            break;
        }

        case CryptoPlugin::kMode_AES_WV: {
            ret = AMEDIACODECRYPTOINFO_MODE_AES_WV;
            break;
        }

        case CryptoPlugin::kMode_AES_CBC: {
            ret = AMEDIACODECRYPTOINFO_MODE_AES_CBC;
            break;
        }

        default:
            break;
    }

    return ret;
}

//////////// AMediaFormatWrapper
// static
sp<AMediaFormatWrapper> AMediaFormatWrapper::Create(const sp<AMessage> &message) {
    sp<AMediaFormatWrapper> aMediaFormat = new AMediaFormatWrapper();

    for (size_t i = 0; i < message->countEntries(); ++i) {
        AMessage::Type valueType;
        const char *key = message->getEntryNameAt(i, &valueType);

        switch (valueType) {
            case AMessage::kTypeInt32: {
                int32_t val;
                if (!message->findInt32(key, &val)) {
                    ALOGE("AMediaFormatWrapper::Create: error at item %zu", i);
                    continue;
                }
                aMediaFormat->setInt32(key, val);
                break;
            }

            case AMessage::kTypeInt64: {
                int64_t val;
                if (!message->findInt64(key, &val)) {
                    ALOGE("AMediaFormatWrapper::Create: error at item %zu", i);
                    continue;
                }
                aMediaFormat->setInt64(key, val);
                break;
            }

            case AMessage::kTypeFloat: {
                float val;
                if (!message->findFloat(key, &val)) {
                    ALOGE("AMediaFormatWrapper::Create: error at item %zu", i);
                    continue;
                }
                aMediaFormat->setFloat(key, val);
                break;
            }

            case AMessage::kTypeDouble: {
                double val;
                if (!message->findDouble(key, &val)) {
                    ALOGE("AMediaFormatWrapper::Create: error at item %zu", i);
                    continue;
                }
                aMediaFormat->setDouble(key, val);
                break;
            }

            case AMessage::kTypeSize: {
                size_t val;
                if (!message->findSize(key, &val)) {
                    ALOGE("AMediaFormatWrapper::Create: error at item %zu", i);
                    continue;
                }
                aMediaFormat->setSize(key, val);
                break;
            }

            case AMessage::kTypeRect: {
                int32_t left, top, right, bottom;
                if (!message->findRect(key, &left, &top, &right, &bottom)) {
                    ALOGE("AMediaFormatWrapper::Create: error at item %zu", i);
                    continue;
                }
                aMediaFormat->setRect(key, left, top, right, bottom);
                break;
            }

            case AMessage::kTypeString: {
                AString val;
                if (!message->findString(key, &val)) {
                    ALOGE("AMediaFormatWrapper::Create: error at item %zu", i);
                    continue;
                }
                aMediaFormat->setString(key, val);
                break;
            }

            case AMessage::kTypeBuffer: {
                sp<ABuffer> val;
                if (!message->findBuffer(key, &val)) {
                    ALOGE("AMediaFormatWrapper::Create: error at item %zu", i);
                    continue;
                }
                aMediaFormat->setBuffer(key, val->data(), val->size());
                break;
            }

            default: {
                break;
            }
        }
    }

    return aMediaFormat;
}

AMediaFormatWrapper::AMediaFormatWrapper() {
    mAMediaFormat = AMediaFormat_new();
}

AMediaFormatWrapper::AMediaFormatWrapper(AMediaFormat *aMediaFormat)
    : mAMediaFormat(aMediaFormat) {
}

AMediaFormatWrapper::~AMediaFormatWrapper() {
    release();
}

status_t AMediaFormatWrapper::release() {
    if (mAMediaFormat != NULL) {
        media_status_t err = AMediaFormat_delete(mAMediaFormat);
        mAMediaFormat = NULL;
        return translateErrorCode(err);
    }
    return OK;
}

AMediaFormat *AMediaFormatWrapper::getAMediaFormat() const {
    return mAMediaFormat;
}

sp<AMessage> AMediaFormatWrapper::toAMessage() const {
  sp<AMessage> msg;
  writeToAMessage(msg);
  return msg;
}

void AMediaFormatWrapper::writeToAMessage(sp<AMessage> &msg) const {
    if (mAMediaFormat == NULL) {
        msg = NULL;
    }

    if (msg == NULL) {
        msg = new AMessage;
    }
    for (auto& key : AMediaFormatKeyGroupInt32) {
        int32_t val;
        if (getInt32(key, &val)) {
            msg->setInt32(key, val);
        }
    }
    for (auto& key : AMediaFormatKeyGroupInt64) {
        int64_t val;
        if (getInt64(key, &val)) {
            msg->setInt64(key, val);
        }
    }
    for (auto& key : AMediaFormatKeyGroupString) {
        AString val;
        if (getString(key, &val)) {
            msg->setString(key, val);
        }
    }
    for (auto& key : AMediaFormatKeyGroupBuffer) {
        void *data;
        size_t size;
        if (getBuffer(key, &data, &size)) {
            sp<ABuffer> buffer = ABuffer::CreateAsCopy(data, size);
            msg->setBuffer(key, buffer);
        }
    }
    for (auto& key : AMediaFormatKeyGroupCsd) {
        void *data;
        size_t size;
        if (getBuffer(key, &data, &size)) {
            sp<ABuffer> buffer = ABuffer::CreateAsCopy(data, size);
            buffer->meta()->setInt32(AMEDIAFORMAT_KEY_CSD, 1);
            buffer->meta()->setInt64(AMEDIAFORMAT_KEY_TIME_US, 0);
            msg->setBuffer(key, buffer);
        }
    }
    for (auto& key : AMediaFormatKeyGroupRect) {
        int32_t left, top, right, bottom;
        if (getRect(key, &left, &top, &right, &bottom)) {
            msg->setRect(key, left, top, right, bottom);
        }
    }
    for (auto& key : AMediaFormatKeyGroupFloatInt32) {
        float valFloat;
        if (getFloat(key, &valFloat)) {
            msg->setFloat(key, valFloat);
        } else {
            int32_t valInt32;
            if (getInt32(key, &valInt32)) {
                msg->setFloat(key, (float)valInt32);
            }
        }
    }
}

const char* AMediaFormatWrapper::toString() const {
    if (mAMediaFormat == NULL) {
        return NULL;
    }
    return AMediaFormat_toString(mAMediaFormat);
}

bool AMediaFormatWrapper::getInt32(const char *name, int32_t *out) const {
    if (mAMediaFormat == NULL) {
        return false;
    }
    return AMediaFormat_getInt32(mAMediaFormat, name, out);
}

bool AMediaFormatWrapper::getInt64(const char *name, int64_t *out) const {
    if (mAMediaFormat == NULL) {
        return false;
    }
    return AMediaFormat_getInt64(mAMediaFormat, name, out);
}

bool AMediaFormatWrapper::getFloat(const char *name, float *out) const {
    if (mAMediaFormat == NULL) {
        return false;
    }
    return AMediaFormat_getFloat(mAMediaFormat, name, out);
}

bool AMediaFormatWrapper::getDouble(const char *name, double *out) const {
    if (mAMediaFormat == NULL) {
        return false;
    }
    return AMediaFormat_getDouble(mAMediaFormat, name, out);
}

bool AMediaFormatWrapper::getSize(const char *name, size_t *out) const {
    if (mAMediaFormat == NULL) {
        return false;
    }
    return AMediaFormat_getSize(mAMediaFormat, name, out);
}

bool AMediaFormatWrapper::getRect(
        const char *name, int32_t *left, int32_t *top, int32_t *right, int32_t *bottom) const {
    if (mAMediaFormat == NULL) {
        return false;
    }
    return AMediaFormat_getRect(mAMediaFormat, name, left, top, right, bottom);
}

bool AMediaFormatWrapper::getBuffer(const char *name, void** data, size_t *outSize) const {
    if (mAMediaFormat == NULL) {
        return false;
    }
    return AMediaFormat_getBuffer(mAMediaFormat, name, data, outSize);
}

bool AMediaFormatWrapper::getString(const char *name, AString *out) const {
    if (mAMediaFormat == NULL) {
        return false;
    }
    const char *outChar = NULL;
    bool ret = AMediaFormat_getString(mAMediaFormat, name, &outChar);
    if (ret) {
        *out = AString(outChar);
    }
    return ret;
}

void AMediaFormatWrapper::setInt32(const char* name, int32_t value) {
    if (mAMediaFormat != NULL) {
        AMediaFormat_setInt32(mAMediaFormat, name, value);
    }
}

void AMediaFormatWrapper::setInt64(const char* name, int64_t value) {
    if (mAMediaFormat != NULL) {
        AMediaFormat_setInt64(mAMediaFormat, name, value);
    }
}

void AMediaFormatWrapper::setFloat(const char* name, float value) {
    if (mAMediaFormat != NULL) {
        AMediaFormat_setFloat(mAMediaFormat, name, value);
    }
}

void AMediaFormatWrapper::setDouble(const char* name, double value) {
    if (mAMediaFormat != NULL) {
        AMediaFormat_setDouble(mAMediaFormat, name, value);
    }
}

void AMediaFormatWrapper::setSize(const char* name, size_t value) {
    if (mAMediaFormat != NULL) {
        AMediaFormat_setSize(mAMediaFormat, name, value);
    }
}

void AMediaFormatWrapper::setRect(
        const char* name, int32_t left, int32_t top, int32_t right, int32_t bottom) {
    if (mAMediaFormat != NULL) {
        AMediaFormat_setRect(mAMediaFormat, name, left, top, right, bottom);
    }
}

void AMediaFormatWrapper::setString(const char* name, const AString &value) {
    if (mAMediaFormat != NULL) {
        AMediaFormat_setString(mAMediaFormat, name, value.c_str());
    }
}

void AMediaFormatWrapper::setBuffer(const char* name, void* data, size_t size) {
    if (mAMediaFormat != NULL) {
        AMediaFormat_setBuffer(mAMediaFormat, name, data, size);
    }
}


//////////// ANativeWindowWrapper
ANativeWindowWrapper::ANativeWindowWrapper(ANativeWindow *aNativeWindow)
    : mANativeWindow(aNativeWindow) {
    if (aNativeWindow != NULL) {
        ANativeWindow_acquire(aNativeWindow);
    }
}

ANativeWindowWrapper::~ANativeWindowWrapper() {
    release();
}

status_t ANativeWindowWrapper::release() {
    if (mANativeWindow != NULL) {
        ANativeWindow_release(mANativeWindow);
        mANativeWindow = NULL;
    }
    return OK;
}

ANativeWindow *ANativeWindowWrapper::getANativeWindow() const {
    return mANativeWindow;
}


//////////// AMediaDrmWrapper
AMediaDrmWrapper::AMediaDrmWrapper(const uint8_t uuid[16]) {
    mAMediaDrm = AMediaDrm_createByUUID(uuid);
}

AMediaDrmWrapper::AMediaDrmWrapper(AMediaDrm *aMediaDrm)
    : mAMediaDrm(aMediaDrm) {
}

AMediaDrmWrapper::~AMediaDrmWrapper() {
    release();
}

status_t AMediaDrmWrapper::release() {
    if (mAMediaDrm != NULL) {
        AMediaDrm_release(mAMediaDrm);
        mAMediaDrm = NULL;
    }
    return OK;
}

AMediaDrm *AMediaDrmWrapper::getAMediaDrm() const {
    return mAMediaDrm;
}

// static
bool AMediaDrmWrapper::isCryptoSchemeSupported(
        const uint8_t uuid[16],
        const char *mimeType) {
    return AMediaDrm_isCryptoSchemeSupported(uuid, mimeType);
}


//////////// AMediaCryptoWrapper
AMediaCryptoWrapper::AMediaCryptoWrapper(
        const uint8_t uuid[16], const void *initData, size_t initDataSize) {
    mAMediaCrypto = AMediaCrypto_new(uuid, initData, initDataSize);
}

AMediaCryptoWrapper::AMediaCryptoWrapper(AMediaCrypto *aMediaCrypto)
    : mAMediaCrypto(aMediaCrypto) {
}

AMediaCryptoWrapper::~AMediaCryptoWrapper() {
    release();
}

status_t AMediaCryptoWrapper::release() {
    if (mAMediaCrypto != NULL) {
        AMediaCrypto_delete(mAMediaCrypto);
        mAMediaCrypto = NULL;
    }
    return OK;
}

AMediaCrypto *AMediaCryptoWrapper::getAMediaCrypto() const {
    return mAMediaCrypto;
}

bool AMediaCryptoWrapper::isCryptoSchemeSupported(const uint8_t uuid[16]) {
    if (mAMediaCrypto == NULL) {
        return false;
    }
    return AMediaCrypto_isCryptoSchemeSupported(uuid);
}

bool AMediaCryptoWrapper::requiresSecureDecoderComponent(const char *mime) {
    if (mAMediaCrypto == NULL) {
        return false;
    }
    return AMediaCrypto_requiresSecureDecoderComponent(mime);
}


//////////// AMediaCodecCryptoInfoWrapper
// static
sp<AMediaCodecCryptoInfoWrapper> AMediaCodecCryptoInfoWrapper::Create(MetaDataBase &meta) {

    uint32_t type;
    const void *crypteddata;
    size_t cryptedsize;

    if (!meta.findData(kKeyEncryptedSizes, &type, &crypteddata, &cryptedsize)) {
        return NULL;
    }

    int numSubSamples = cryptedsize / sizeof(size_t);

    if (numSubSamples <= 0) {
        ALOGE("Create: INVALID numSubSamples: %d", numSubSamples);
        return NULL;
    }

    const void *cleardata;
    size_t clearsize;
    if (meta.findData(kKeyPlainSizes, &type, &cleardata, &clearsize)) {
        if (clearsize != cryptedsize) {
            // The two must be of the same length.
            ALOGE("Create: mismatch cryptedsize: %zu != clearsize: %zu", cryptedsize, clearsize);
            return NULL;
        }
    }

    const void *key;
    size_t keysize;
    if (meta.findData(kKeyCryptoKey, &type, &key, &keysize)) {
        if (keysize != kAESBlockSize) {
            // Keys must be 16 bytes in length.
            ALOGE("Create: Keys must be %zu bytes in length: %zu", kAESBlockSize, keysize);
            return NULL;
        }
    }

    const void *iv;
    size_t ivsize;
    if (meta.findData(kKeyCryptoIV, &type, &iv, &ivsize)) {
        if (ivsize != kAESBlockSize) {
            // IVs must be 16 bytes in length.
            ALOGE("Create: IV must be %zu bytes in length: %zu", kAESBlockSize, ivsize);
            return NULL;
        }
    }

    int32_t mode;
    if (!meta.findInt32(kKeyCryptoMode, &mode)) {
        mode = CryptoPlugin::kMode_AES_CTR;
    }

    return new AMediaCodecCryptoInfoWrapper(
            numSubSamples,
            (uint8_t*) key,
            (uint8_t*) iv,
            (CryptoPlugin::Mode)mode,
            (size_t*) cleardata,
            (size_t*) crypteddata);
}

AMediaCodecCryptoInfoWrapper::AMediaCodecCryptoInfoWrapper(
        int numsubsamples,
        uint8_t key[16],
        uint8_t iv[16],
        CryptoPlugin::Mode mode,
        size_t *clearbytes,
        size_t *encryptedbytes) {
    mAMediaCodecCryptoInfo =
        AMediaCodecCryptoInfo_new(numsubsamples,
                                  key,
                                  iv,
                                  translateToCryptoInfoMode(mode),
                                  clearbytes,
                                  encryptedbytes);
}

AMediaCodecCryptoInfoWrapper::AMediaCodecCryptoInfoWrapper(
        AMediaCodecCryptoInfo *aMediaCodecCryptoInfo)
    : mAMediaCodecCryptoInfo(aMediaCodecCryptoInfo) {
}

AMediaCodecCryptoInfoWrapper::~AMediaCodecCryptoInfoWrapper() {
    release();
}

status_t AMediaCodecCryptoInfoWrapper::release() {
    if (mAMediaCodecCryptoInfo != NULL) {
        media_status_t err = AMediaCodecCryptoInfo_delete(mAMediaCodecCryptoInfo);
        mAMediaCodecCryptoInfo = NULL;
        return translateErrorCode(err);
    }
    return OK;
}

AMediaCodecCryptoInfo *AMediaCodecCryptoInfoWrapper::getAMediaCodecCryptoInfo() const {
    return mAMediaCodecCryptoInfo;
}

void AMediaCodecCryptoInfoWrapper::setPattern(CryptoPlugin::Pattern *pattern) {
    if (mAMediaCodecCryptoInfo == NULL || pattern == NULL) {
        return;
    }
    cryptoinfo_pattern_t ndkPattern = {(int32_t)pattern->mEncryptBlocks,
                                       (int32_t)pattern->mSkipBlocks };
    return AMediaCodecCryptoInfo_setPattern(mAMediaCodecCryptoInfo, &ndkPattern);
}

size_t AMediaCodecCryptoInfoWrapper::getNumSubSamples() {
    if (mAMediaCodecCryptoInfo == NULL) {
        return 0;
    }
    return AMediaCodecCryptoInfo_getNumSubSamples(mAMediaCodecCryptoInfo);
}

status_t AMediaCodecCryptoInfoWrapper::getKey(uint8_t *dst) {
    if (mAMediaCodecCryptoInfo == NULL) {
        return DEAD_OBJECT;
    }
    if (dst == NULL) {
        return BAD_VALUE;
    }
    return translateErrorCode(
        AMediaCodecCryptoInfo_getKey(mAMediaCodecCryptoInfo, dst));
}

status_t AMediaCodecCryptoInfoWrapper::getIV(uint8_t *dst) {
    if (mAMediaCodecCryptoInfo == NULL) {
        return DEAD_OBJECT;
    }
    if (dst == NULL) {
        return BAD_VALUE;
    }
    return translateErrorCode(
        AMediaCodecCryptoInfo_getIV(mAMediaCodecCryptoInfo, dst));
}

CryptoPlugin::Mode AMediaCodecCryptoInfoWrapper::getMode() {
    if (mAMediaCodecCryptoInfo == NULL) {
        return CryptoPlugin::kMode_Unencrypted;
    }
    return translateToCryptoPluginMode(
        AMediaCodecCryptoInfo_getMode(mAMediaCodecCryptoInfo));
}

status_t AMediaCodecCryptoInfoWrapper::getClearBytes(size_t *dst) {
    if (mAMediaCodecCryptoInfo == NULL) {
        return DEAD_OBJECT;
    }
    if (dst == NULL) {
        return BAD_VALUE;
    }
    return translateErrorCode(
        AMediaCodecCryptoInfo_getClearBytes(mAMediaCodecCryptoInfo, dst));
}

status_t AMediaCodecCryptoInfoWrapper::getEncryptedBytes(size_t *dst) {
    if (mAMediaCodecCryptoInfo == NULL) {
        return DEAD_OBJECT;
    }
    if (dst == NULL) {
        return BAD_VALUE;
    }
    return translateErrorCode(
        AMediaCodecCryptoInfo_getEncryptedBytes(mAMediaCodecCryptoInfo, dst));
}


//////////// AMediaCodecWrapper
// static
sp<AMediaCodecWrapper> AMediaCodecWrapper::CreateCodecByName(const AString &name) {
    AMediaCodec *aMediaCodec = AMediaCodec_createCodecByName(name.c_str());
    return new AMediaCodecWrapper(aMediaCodec);
}

// static
sp<AMediaCodecWrapper> AMediaCodecWrapper::CreateDecoderByType(const AString &mimeType) {
    AMediaCodec *aMediaCodec = AMediaCodec_createDecoderByType(mimeType.c_str());
    return new AMediaCodecWrapper(aMediaCodec);
}

// static
void AMediaCodecWrapper::OnInputAvailableCB(
        AMediaCodec * /* aMediaCodec */,
        void *userdata,
        int32_t index) {
    ALOGV("OnInputAvailableCB: index(%d)", index);
    sp<AMessage> msg = sp<AMessage>((AMessage *)userdata)->dup();
    msg->setInt32("callbackID", CB_INPUT_AVAILABLE);
    msg->setInt32("index", index);
    msg->post();
}

// static
void AMediaCodecWrapper::OnOutputAvailableCB(
        AMediaCodec * /* aMediaCodec */,
        void *userdata,
        int32_t index,
        AMediaCodecBufferInfo *bufferInfo) {
    ALOGV("OnOutputAvailableCB: index(%d), (%d, %d, %lld, 0x%x)",
          index, bufferInfo->offset, bufferInfo->size,
          (long long)bufferInfo->presentationTimeUs, bufferInfo->flags);
    sp<AMessage> msg = sp<AMessage>((AMessage *)userdata)->dup();
    msg->setInt32("callbackID", CB_OUTPUT_AVAILABLE);
    msg->setInt32("index", index);
    msg->setSize("offset", (size_t)(bufferInfo->offset));
    msg->setSize("size", (size_t)(bufferInfo->size));
    msg->setInt64("timeUs", bufferInfo->presentationTimeUs);
    msg->setInt32("flags", (int32_t)(bufferInfo->flags));
    msg->post();
}

// static
void AMediaCodecWrapper::OnFormatChangedCB(
        AMediaCodec * /* aMediaCodec */,
        void *userdata,
        AMediaFormat *format) {
    sp<AMediaFormatWrapper> formatWrapper = new AMediaFormatWrapper(format);
    sp<AMessage> outputFormat = formatWrapper->toAMessage();
    ALOGV("OnFormatChangedCB: format(%s)", outputFormat->debugString().c_str());

    sp<AMessage> msg = sp<AMessage>((AMessage *)userdata)->dup();
    msg->setInt32("callbackID", CB_OUTPUT_FORMAT_CHANGED);
    msg->setMessage("format", outputFormat);
    msg->post();
}

// static
void AMediaCodecWrapper::OnErrorCB(
        AMediaCodec * /* aMediaCodec */,
        void *userdata,
        media_status_t err,
        int32_t actionCode,
        const char *detail) {
    ALOGV("OnErrorCB: err(%d), actionCode(%d), detail(%s)", err, actionCode, detail);
    sp<AMessage> msg = sp<AMessage>((AMessage *)userdata)->dup();
    msg->setInt32("callbackID", CB_ERROR);
    msg->setInt32("err", translateErrorCode(err));
    msg->setInt32("actionCode", translateActionCode(actionCode));
    msg->setString("detail", detail);
    msg->post();
}

AMediaCodecWrapper::AMediaCodecWrapper(AMediaCodec *aMediaCodec)
    : mAMediaCodec(aMediaCodec) {
}

AMediaCodecWrapper::~AMediaCodecWrapper() {
    release();
}

status_t AMediaCodecWrapper::release() {
    if (mAMediaCodec != NULL) {
        AMediaCodecOnAsyncNotifyCallback aCB = {};
        AMediaCodec_setAsyncNotifyCallback(mAMediaCodec, aCB, NULL);
        mCallback = NULL;

        media_status_t err = AMediaCodec_delete(mAMediaCodec);
        mAMediaCodec = NULL;
        return translateErrorCode(err);
    }
    return OK;
}

AMediaCodec *AMediaCodecWrapper::getAMediaCodec() const {
    return mAMediaCodec;
}

status_t AMediaCodecWrapper::getName(AString *outComponentName) const {
    if (mAMediaCodec == NULL) {
        return DEAD_OBJECT;
    }
    char *name = NULL;
    media_status_t err = AMediaCodec_getName(mAMediaCodec, &name);
    if (err != AMEDIA_OK) {
        return translateErrorCode(err);
    }

    *outComponentName = AString(name);
    AMediaCodec_releaseName(mAMediaCodec, name);
    return OK;
}

status_t AMediaCodecWrapper::configure(
    const sp<AMediaFormatWrapper> &format,
    const sp<ANativeWindowWrapper> &nww,
    const sp<AMediaCryptoWrapper> &crypto,
    uint32_t flags) {
    if (mAMediaCodec == NULL) {
        return DEAD_OBJECT;
    }

    media_status_t err = AMediaCodec_configure(
            mAMediaCodec,
            format->getAMediaFormat(),
            (nww == NULL ? NULL : nww->getANativeWindow()),
            crypto == NULL ? NULL : crypto->getAMediaCrypto(),
            flags);

    return translateErrorCode(err);
}

status_t AMediaCodecWrapper::setCallback(const sp<AMessage> &callback) {
    if (mAMediaCodec == NULL) {
        return DEAD_OBJECT;
    }

    mCallback = callback;

    AMediaCodecOnAsyncNotifyCallback aCB = {
        OnInputAvailableCB,
        OnOutputAvailableCB,
        OnFormatChangedCB,
        OnErrorCB
    };

    return translateErrorCode(
            AMediaCodec_setAsyncNotifyCallback(mAMediaCodec, aCB, callback.get()));
}

status_t AMediaCodecWrapper::releaseCrypto() {
    if (mAMediaCodec == NULL) {
        return DEAD_OBJECT;
    }
    return translateErrorCode(AMediaCodec_releaseCrypto(mAMediaCodec));
}

status_t AMediaCodecWrapper::start() {
    if (mAMediaCodec == NULL) {
        return DEAD_OBJECT;
    }
    return translateErrorCode(AMediaCodec_start(mAMediaCodec));
}

status_t AMediaCodecWrapper::stop() {
    if (mAMediaCodec == NULL) {
        return DEAD_OBJECT;
    }
    return translateErrorCode(AMediaCodec_stop(mAMediaCodec));
}

status_t AMediaCodecWrapper::flush() {
    if (mAMediaCodec == NULL) {
        return DEAD_OBJECT;
    }
    return translateErrorCode(AMediaCodec_flush(mAMediaCodec));
}

uint8_t* AMediaCodecWrapper::getInputBuffer(size_t idx, size_t *out_size) {
    if (mAMediaCodec == NULL) {
        return NULL;
    }
    return AMediaCodec_getInputBuffer(mAMediaCodec, idx, out_size);
}

uint8_t* AMediaCodecWrapper::getOutputBuffer(size_t idx, size_t *out_size) {
    if (mAMediaCodec == NULL) {
        return NULL;
    }
    return AMediaCodec_getOutputBuffer(mAMediaCodec, idx, out_size);
}

status_t AMediaCodecWrapper::queueInputBuffer(
        size_t idx,
        size_t offset,
        size_t size,
        uint64_t time,
        uint32_t flags) {
    if (mAMediaCodec == NULL) {
        return DEAD_OBJECT;
    }
    return translateErrorCode(
        AMediaCodec_queueInputBuffer(mAMediaCodec, idx, offset, size, time, flags));
}

status_t AMediaCodecWrapper::queueSecureInputBuffer(
        size_t idx,
        size_t offset,
        sp<AMediaCodecCryptoInfoWrapper> &codecCryptoInfo,
        uint64_t time,
        uint32_t flags) {
    if (mAMediaCodec == NULL) {
        return DEAD_OBJECT;
    }
    return translateErrorCode(
        AMediaCodec_queueSecureInputBuffer(
            mAMediaCodec,
            idx,
            offset,
            codecCryptoInfo->getAMediaCodecCryptoInfo(),
            time,
            flags));
}

sp<AMediaFormatWrapper> AMediaCodecWrapper::getOutputFormat() {
    if (mAMediaCodec == NULL) {
        return NULL;
    }
    return new AMediaFormatWrapper(AMediaCodec_getOutputFormat(mAMediaCodec));
}

sp<AMediaFormatWrapper> AMediaCodecWrapper::getInputFormat() {
    if (mAMediaCodec == NULL) {
        return NULL;
    }
    return new AMediaFormatWrapper(AMediaCodec_getInputFormat(mAMediaCodec));
}

status_t AMediaCodecWrapper::releaseOutputBuffer(size_t idx, bool render) {
    if (mAMediaCodec == NULL) {
        return DEAD_OBJECT;
    }
    return translateErrorCode(
        AMediaCodec_releaseOutputBuffer(mAMediaCodec, idx, render));
}

status_t AMediaCodecWrapper::setOutputSurface(const sp<ANativeWindowWrapper> &nww) {
    if (mAMediaCodec == NULL) {
        return DEAD_OBJECT;
    }
    return translateErrorCode(
        AMediaCodec_setOutputSurface(mAMediaCodec,
                                     (nww == NULL ? NULL : nww->getANativeWindow())));
}

status_t AMediaCodecWrapper::releaseOutputBufferAtTime(size_t idx, int64_t timestampNs) {
    if (mAMediaCodec == NULL) {
        return DEAD_OBJECT;
    }
    return translateErrorCode(
        AMediaCodec_releaseOutputBufferAtTime(mAMediaCodec, idx, timestampNs));
}

status_t AMediaCodecWrapper::setParameters(const sp<AMediaFormatWrapper> &params) {
    if (mAMediaCodec == NULL) {
        return DEAD_OBJECT;
    }
    return translateErrorCode(
        AMediaCodec_setParameters(mAMediaCodec, params->getAMediaFormat()));
}

//////////// AMediaExtractorWrapper

AMediaExtractorWrapper::AMediaExtractorWrapper(AMediaExtractor *aMediaExtractor)
    : mAMediaExtractor(aMediaExtractor) {
}

AMediaExtractorWrapper::~AMediaExtractorWrapper() {
    release();
}

status_t AMediaExtractorWrapper::release() {
    if (mAMediaExtractor != NULL) {
        media_status_t err = AMediaExtractor_delete(mAMediaExtractor);
        mAMediaExtractor = NULL;
        return translateErrorCode(err);
    }
    return OK;
}

status_t AMediaExtractorWrapper::disconnect() {
    if (mAMediaExtractor != NULL) {
        media_status_t err = AMediaExtractor_disconnect(mAMediaExtractor);
        return translateErrorCode(err);
    }
    return DEAD_OBJECT;
}

AMediaExtractor *AMediaExtractorWrapper::getAMediaExtractor() const {
    return mAMediaExtractor;
}

status_t AMediaExtractorWrapper::setDataSource(int fd, off64_t offset, off64_t length) {
    if (mAMediaExtractor == NULL) {
        return DEAD_OBJECT;
    }
    return translateErrorCode(AMediaExtractor_setDataSourceFd(
            mAMediaExtractor, fd, offset, length));
}

status_t AMediaExtractorWrapper::setDataSource(const char *location) {
    if (mAMediaExtractor == NULL) {
        return DEAD_OBJECT;
    }
    return translateErrorCode(AMediaExtractor_setDataSource(mAMediaExtractor, location));
}

status_t AMediaExtractorWrapper::setDataSource(AMediaDataSource *source) {
    if (mAMediaExtractor == NULL) {
        return DEAD_OBJECT;
    }
    return translateErrorCode(AMediaExtractor_setDataSourceCustom(mAMediaExtractor, source));
}

size_t AMediaExtractorWrapper::getTrackCount() {
    if (mAMediaExtractor == NULL) {
        return 0;
    }
    return AMediaExtractor_getTrackCount(mAMediaExtractor);
}

sp<AMediaFormatWrapper> AMediaExtractorWrapper::getFormat() {
    if (mAMediaExtractor == NULL) {
        return NULL;
    }
    return new AMediaFormatWrapper(AMediaExtractor_getFileFormat(mAMediaExtractor));
}

sp<AMediaFormatWrapper> AMediaExtractorWrapper::getTrackFormat(size_t idx) {
    if (mAMediaExtractor == NULL) {
        return NULL;
    }
    return new AMediaFormatWrapper(AMediaExtractor_getTrackFormat(mAMediaExtractor, idx));
}

status_t AMediaExtractorWrapper::selectTrack(size_t idx) {
    if (mAMediaExtractor == NULL) {
        return DEAD_OBJECT;
    }
    return translateErrorCode(AMediaExtractor_selectTrack(mAMediaExtractor, idx));
}

status_t AMediaExtractorWrapper::unselectTrack(size_t idx) {
    if (mAMediaExtractor == NULL) {
        return DEAD_OBJECT;
    }
    return translateErrorCode(AMediaExtractor_unselectTrack(mAMediaExtractor, idx));
}

status_t AMediaExtractorWrapper::selectSingleTrack(size_t idx) {
    if (mAMediaExtractor == NULL) {
        return DEAD_OBJECT;
    }
    for (size_t i = 0; i < AMediaExtractor_getTrackCount(mAMediaExtractor); ++i) {
        if (i == idx) {
            media_status_t err = AMediaExtractor_selectTrack(mAMediaExtractor, i);
            if (err != AMEDIA_OK) {
                return translateErrorCode(err);
            }
        } else {
            media_status_t err = AMediaExtractor_unselectTrack(mAMediaExtractor, i);
            if (err != AMEDIA_OK) {
                return translateErrorCode(err);
            }
        }
    }
    return OK;
}

ssize_t AMediaExtractorWrapper::readSampleData(const sp<ABuffer> &buffer) {
    if (mAMediaExtractor == NULL) {
        return -1;
    }
    return AMediaExtractor_readSampleData(mAMediaExtractor, buffer->data(), buffer->capacity());
}

ssize_t AMediaExtractorWrapper::getSampleSize() {
    if (mAMediaExtractor == NULL) {
        return 0;
    }
    return AMediaExtractor_getSampleSize(mAMediaExtractor);
}

uint32_t AMediaExtractorWrapper::getSampleFlags() {
    if (mAMediaExtractor == NULL) {
        return 0;
    }
    return AMediaExtractor_getSampleFlags(mAMediaExtractor);
}

int AMediaExtractorWrapper::getSampleTrackIndex() {
    if (mAMediaExtractor == NULL) {
        return -1;
    }
    return AMediaExtractor_getSampleTrackIndex(mAMediaExtractor);
}

int64_t AMediaExtractorWrapper::getSampleTime() {
    if (mAMediaExtractor == NULL) {
        return -1;
    }
    return AMediaExtractor_getSampleTime(mAMediaExtractor);
}

status_t AMediaExtractorWrapper::getSampleFormat(sp<AMediaFormatWrapper> &formatWrapper) {
    if (mAMediaExtractor == NULL) {
        return DEAD_OBJECT;
    }
    AMediaFormat *format = AMediaFormat_new();
    formatWrapper = new AMediaFormatWrapper(format);
    return translateErrorCode(AMediaExtractor_getSampleFormat(mAMediaExtractor, format));
}

int64_t AMediaExtractorWrapper::getCachedDuration() {
    if (mAMediaExtractor == NULL) {
        return -1;
    }
    return AMediaExtractor_getCachedDuration(mAMediaExtractor);
}

bool AMediaExtractorWrapper::advance() {
    if (mAMediaExtractor == NULL) {
        return false;
    }
    return AMediaExtractor_advance(mAMediaExtractor);
}

status_t AMediaExtractorWrapper::seekTo(int64_t seekPosUs, MediaSource::ReadOptions::SeekMode mode) {
    if (mAMediaExtractor == NULL) {
        return DEAD_OBJECT;
    }

    SeekMode aMode;
    switch (mode) {
        case MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC: {
            aMode = AMEDIAEXTRACTOR_SEEK_PREVIOUS_SYNC;
            break;
        }
        case MediaSource::ReadOptions::SEEK_NEXT_SYNC: {
            aMode = AMEDIAEXTRACTOR_SEEK_NEXT_SYNC;
            break;
        }
        default: {
            aMode = AMEDIAEXTRACTOR_SEEK_CLOSEST_SYNC;
            break;
        }
    }
    return AMediaExtractor_seekTo(mAMediaExtractor, seekPosUs, aMode);
}

PsshInfo* AMediaExtractorWrapper::getPsshInfo() {
    if (mAMediaExtractor == NULL) {
        return NULL;
    }
    return AMediaExtractor_getPsshInfo(mAMediaExtractor);
}

sp<AMediaCodecCryptoInfoWrapper> AMediaExtractorWrapper::getSampleCryptoInfo() {
    if (mAMediaExtractor == NULL) {
        return NULL;
    }
    return new AMediaCodecCryptoInfoWrapper(AMediaExtractor_getSampleCryptoInfo(mAMediaExtractor));
}

ssize_t AMediaDataSourceWrapper::AMediaDataSourceWrapper_getSize(void *userdata) {
    DataSource *source = static_cast<DataSource *>(userdata);
    off64_t size = -1;
    source->getSize(&size);
    return size;
}

ssize_t AMediaDataSourceWrapper::AMediaDataSourceWrapper_readAt(void *userdata, off64_t offset, void * buf, size_t size) {
    DataSource *source = static_cast<DataSource *>(userdata);
    return source->readAt(offset, buf, size);
}

void AMediaDataSourceWrapper::AMediaDataSourceWrapper_close(void *userdata) {
    DataSource *source = static_cast<DataSource *>(userdata);
    source->close();
}

AMediaDataSourceWrapper::AMediaDataSourceWrapper(const sp<DataSource> &dataSource)
    : mDataSource(dataSource),
      mAMediaDataSource(AMediaDataSource_new()) {
    ALOGV("setDataSource (source: %p)", dataSource.get());
    AMediaDataSource_setUserdata(mAMediaDataSource, dataSource.get());
    AMediaDataSource_setReadAt(mAMediaDataSource, AMediaDataSourceWrapper_readAt);
    AMediaDataSource_setGetSize(mAMediaDataSource, AMediaDataSourceWrapper_getSize);
    AMediaDataSource_setClose(mAMediaDataSource, AMediaDataSourceWrapper_close);
}

AMediaDataSourceWrapper::~AMediaDataSourceWrapper() {
    if (mAMediaDataSource == NULL) {
        return;
    }
    AMediaDataSource_delete(mAMediaDataSource);
    mAMediaDataSource = NULL;
}

AMediaDataSource* AMediaDataSourceWrapper::getAMediaDataSource() {
    return mAMediaDataSource;
}

}  // namespace android
