/*
 * 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>

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_COLS,
    AMEDIAFORMAT_KEY_GRID_HEIGHT,
    AMEDIAFORMAT_KEY_GRID_ROWS,
    AMEDIAFORMAT_KEY_GRID_WIDTH,
    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,
};

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

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

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

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 == 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 {
    if (mAMediaFormat == NULL) {
        return NULL;
    }

    sp<AMessage> 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 : 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);
            }
        }
    }
    return msg;
}

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(sp<MetaData> meta) {
    if (meta == NULL) {
        ALOGE("Create: Unexpected. No meta data for sample.");
        return NULL;
    }

    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;
}

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));
}

size_t AMediaExtractorWrapper::getTrackCount() {
    if (mAMediaExtractor == NULL) {
        return 0;
    }
    return AMediaExtractor_getTrackCount(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));
}

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

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);
}

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

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

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));
}

}  // namespace android
