/*
 * Copyright 2012, 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 "MediaCodecList"
#include <utils/Log.h>

#include <media/stagefright/MediaCodecList.h>

#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/OMXClient.h>
#include <media/stagefright/OMXCodec.h>
#include <utils/threads.h>

#include <libexpat/expat.h>

namespace android {

static Mutex sInitMutex;

// static
MediaCodecList *MediaCodecList::sCodecList;

// static
const MediaCodecList *MediaCodecList::getInstance() {
    Mutex::Autolock autoLock(sInitMutex);

    if (sCodecList == NULL) {
        sCodecList = new MediaCodecList;
    }

    return sCodecList->initCheck() == OK ? sCodecList : NULL;
}

MediaCodecList::MediaCodecList()
    : mInitCheck(NO_INIT) {
    FILE *file = fopen("/etc/media_codecs.xml", "r");

    if (file == NULL) {
        ALOGW("unable to open media codecs configuration xml file.");
        return;
    }

    parseXMLFile(file);

    if (mInitCheck == OK) {
        // These are currently still used by the video editing suite.

        addMediaCodec(true /* encoder */, "AACEncoder", "audio/mp4a-latm");

        addMediaCodec(
                false /* encoder */, "OMX.google.raw.decoder", "audio/raw");
    }

#if 0
    for (size_t i = 0; i < mCodecInfos.size(); ++i) {
        const CodecInfo &info = mCodecInfos.itemAt(i);

        AString line = info.mName;
        line.append(" supports ");
        for (size_t j = 0; j < mTypes.size(); ++j) {
            uint32_t value = mTypes.valueAt(j);

            if (info.mTypes & (1ul << value)) {
                line.append(mTypes.keyAt(j));
                line.append(" ");
            }
        }

        ALOGI("%s", line.c_str());
    }
#endif

    fclose(file);
    file = NULL;
}

MediaCodecList::~MediaCodecList() {
}

status_t MediaCodecList::initCheck() const {
    return mInitCheck;
}

void MediaCodecList::parseXMLFile(FILE *file) {
    mInitCheck = OK;
    mCurrentSection = SECTION_TOPLEVEL;
    mDepth = 0;

    XML_Parser parser = ::XML_ParserCreate(NULL);
    CHECK(parser != NULL);

    ::XML_SetUserData(parser, this);
    ::XML_SetElementHandler(
            parser, StartElementHandlerWrapper, EndElementHandlerWrapper);

    const int BUFF_SIZE = 512;
    while (mInitCheck == OK) {
        void *buff = ::XML_GetBuffer(parser, BUFF_SIZE);
        if (buff == NULL) {
            ALOGE("failed to in call to XML_GetBuffer()");
            mInitCheck = UNKNOWN_ERROR;
            break;
        }

        int bytes_read = ::fread(buff, 1, BUFF_SIZE, file);
        if (bytes_read < 0) {
            ALOGE("failed in call to read");
            mInitCheck = ERROR_IO;
            break;
        }

        if (::XML_ParseBuffer(parser, bytes_read, bytes_read == 0)
                != XML_STATUS_OK) {
            mInitCheck = ERROR_MALFORMED;
            break;
        }

        if (bytes_read == 0) {
            break;
        }
    }

    ::XML_ParserFree(parser);

    if (mInitCheck == OK) {
        for (size_t i = mCodecInfos.size(); i-- > 0;) {
            CodecInfo *info = &mCodecInfos.editItemAt(i);

            if (info->mTypes == 0) {
                // No types supported by this component???

                ALOGW("Component %s does not support any type of media?",
                      info->mName.c_str());

                mCodecInfos.removeAt(i);
            }
        }
    }

    if (mInitCheck != OK) {
        mCodecInfos.clear();
        mCodecQuirks.clear();
    }
}

// static
void MediaCodecList::StartElementHandlerWrapper(
        void *me, const char *name, const char **attrs) {
    static_cast<MediaCodecList *>(me)->startElementHandler(name, attrs);
}

// static
void MediaCodecList::EndElementHandlerWrapper(void *me, const char *name) {
    static_cast<MediaCodecList *>(me)->endElementHandler(name);
}

void MediaCodecList::startElementHandler(
        const char *name, const char **attrs) {
    if (mInitCheck != OK) {
        return;
    }

    switch (mCurrentSection) {
        case SECTION_TOPLEVEL:
        {
            if (!strcmp(name, "Decoders")) {
                mCurrentSection = SECTION_DECODERS;
            } else if (!strcmp(name, "Encoders")) {
                mCurrentSection = SECTION_ENCODERS;
            }
            break;
        }

        case SECTION_DECODERS:
        {
            if (!strcmp(name, "MediaCodec")) {
                mInitCheck =
                    addMediaCodecFromAttributes(false /* encoder */, attrs);

                mCurrentSection = SECTION_DECODER;
            }
            break;
        }

        case SECTION_ENCODERS:
        {
            if (!strcmp(name, "MediaCodec")) {
                mInitCheck =
                    addMediaCodecFromAttributes(true /* encoder */, attrs);

                mCurrentSection = SECTION_ENCODER;
            }
            break;
        }

        case SECTION_DECODER:
        case SECTION_ENCODER:
        {
            if (!strcmp(name, "Quirk")) {
                mInitCheck = addQuirk(attrs);
            } else if (!strcmp(name, "Type")) {
                mInitCheck = addTypeFromAttributes(attrs);
            }
            break;
        }

        default:
            break;
    }

    ++mDepth;
}

void MediaCodecList::endElementHandler(const char *name) {
    if (mInitCheck != OK) {
        return;
    }

    switch (mCurrentSection) {
        case SECTION_DECODERS:
        {
            if (!strcmp(name, "Decoders")) {
                mCurrentSection = SECTION_TOPLEVEL;
            }
            break;
        }

        case SECTION_ENCODERS:
        {
            if (!strcmp(name, "Encoders")) {
                mCurrentSection = SECTION_TOPLEVEL;
            }
            break;
        }

        case SECTION_DECODER:
        {
            if (!strcmp(name, "MediaCodec")) {
                mCurrentSection = SECTION_DECODERS;
            }
            break;
        }

        case SECTION_ENCODER:
        {
            if (!strcmp(name, "MediaCodec")) {
                mCurrentSection = SECTION_ENCODERS;
            }
            break;
        }

        default:
            break;
    }

    --mDepth;
}

status_t MediaCodecList::addMediaCodecFromAttributes(
        bool encoder, const char **attrs) {
    const char *name = NULL;
    const char *type = NULL;

    size_t i = 0;
    while (attrs[i] != NULL) {
        if (!strcmp(attrs[i], "name")) {
            if (attrs[i + 1] == NULL) {
                return -EINVAL;
            }
            name = attrs[i + 1];
            ++i;
        } else if (!strcmp(attrs[i], "type")) {
            if (attrs[i + 1] == NULL) {
                return -EINVAL;
            }
            type = attrs[i + 1];
            ++i;
        } else {
            return -EINVAL;
        }

        ++i;
    }

    if (name == NULL) {
        return -EINVAL;
    }

    addMediaCodec(encoder, name, type);

    return OK;
}

void MediaCodecList::addMediaCodec(
        bool encoder, const char *name, const char *type) {
    mCodecInfos.push();
    CodecInfo *info = &mCodecInfos.editItemAt(mCodecInfos.size() - 1);
    info->mName = name;
    info->mIsEncoder = encoder;
    info->mTypes = 0;
    info->mQuirks = 0;

    if (type != NULL) {
        addType(type);
    }
}

status_t MediaCodecList::addQuirk(const char **attrs) {
    const char *name = NULL;

    size_t i = 0;
    while (attrs[i] != NULL) {
        if (!strcmp(attrs[i], "name")) {
            if (attrs[i + 1] == NULL) {
                return -EINVAL;
            }
            name = attrs[i + 1];
            ++i;
        } else {
            return -EINVAL;
        }

        ++i;
    }

    if (name == NULL) {
        return -EINVAL;
    }

    uint32_t bit;
    ssize_t index = mCodecQuirks.indexOfKey(name);
    if (index < 0) {
        bit = mCodecQuirks.size();

        if (bit == 32) {
            ALOGW("Too many distinct quirk names in configuration.");
            return OK;
        }

        mCodecQuirks.add(name, bit);
    } else {
        bit = mCodecQuirks.valueAt(index);
    }

    CodecInfo *info = &mCodecInfos.editItemAt(mCodecInfos.size() - 1);
    info->mQuirks |= 1ul << bit;

    return OK;
}

status_t MediaCodecList::addTypeFromAttributes(const char **attrs) {
    const char *name = NULL;

    size_t i = 0;
    while (attrs[i] != NULL) {
        if (!strcmp(attrs[i], "name")) {
            if (attrs[i + 1] == NULL) {
                return -EINVAL;
            }
            name = attrs[i + 1];
            ++i;
        } else {
            return -EINVAL;
        }

        ++i;
    }

    if (name == NULL) {
        return -EINVAL;
    }

    addType(name);

    return OK;
}

void MediaCodecList::addType(const char *name) {
    uint32_t bit;
    ssize_t index = mTypes.indexOfKey(name);
    if (index < 0) {
        bit = mTypes.size();

        if (bit == 32) {
            ALOGW("Too many distinct type names in configuration.");
            return;
        }

        mTypes.add(name, bit);
    } else {
        bit = mTypes.valueAt(index);
    }

    CodecInfo *info = &mCodecInfos.editItemAt(mCodecInfos.size() - 1);
    info->mTypes |= 1ul << bit;
}

ssize_t MediaCodecList::findCodecByType(
        const char *type, bool encoder, size_t startIndex) const {
    ssize_t typeIndex = mTypes.indexOfKey(type);

    if (typeIndex < 0) {
        return -ENOENT;
    }

    uint32_t typeMask = 1ul << mTypes.valueAt(typeIndex);

    while (startIndex < mCodecInfos.size()) {
        const CodecInfo &info = mCodecInfos.itemAt(startIndex);

        if (info.mIsEncoder == encoder && (info.mTypes & typeMask)) {
            return startIndex;
        }

        ++startIndex;
    }

    return -ENOENT;
}

ssize_t MediaCodecList::findCodecByName(const char *name) const {
    for (size_t i = 0; i < mCodecInfos.size(); ++i) {
        const CodecInfo &info = mCodecInfos.itemAt(i);

        if (info.mName == name) {
            return i;
        }
    }

    return -ENOENT;
}

size_t MediaCodecList::countCodecs() const {
    return mCodecInfos.size();
}

const char *MediaCodecList::getCodecName(size_t index) const {
    if (index >= mCodecInfos.size()) {
        return NULL;
    }

    const CodecInfo &info = mCodecInfos.itemAt(index);
    return info.mName.c_str();
}

bool MediaCodecList::isEncoder(size_t index) const {
    if (index >= mCodecInfos.size()) {
        return NULL;
    }

    const CodecInfo &info = mCodecInfos.itemAt(index);
    return info.mIsEncoder;
}

bool MediaCodecList::codecHasQuirk(
        size_t index, const char *quirkName) const {
    if (index >= mCodecInfos.size()) {
        return NULL;
    }

    const CodecInfo &info = mCodecInfos.itemAt(index);

    if (info.mQuirks != 0) {
        ssize_t index = mCodecQuirks.indexOfKey(quirkName);
        if (index >= 0 && info.mQuirks & (1ul << mCodecQuirks.valueAt(index))) {
            return true;
        }
    }

    return false;
}

status_t MediaCodecList::getSupportedTypes(
        size_t index, Vector<AString> *types) const {
    types->clear();

    if (index >= mCodecInfos.size()) {
        return -ERANGE;
    }

    const CodecInfo &info = mCodecInfos.itemAt(index);

    for (size_t i = 0; i < mTypes.size(); ++i) {
        uint32_t typeMask = 1ul << mTypes.valueAt(i);

        if (info.mTypes & typeMask) {
            types->push(mTypes.keyAt(i));
        }
    }

    return OK;
}

status_t MediaCodecList::getCodecCapabilities(
        size_t index, const char *type,
        Vector<ProfileLevel> *profileLevels,
        Vector<uint32_t> *colorFormats,
        uint32_t *flags) const {
    profileLevels->clear();
    colorFormats->clear();

    if (index >= mCodecInfos.size()) {
        return -ERANGE;
    }

    const CodecInfo &info = mCodecInfos.itemAt(index);

    OMXClient client;
    status_t err = client.connect();
    if (err != OK) {
        return err;
    }

    CodecCapabilities caps;
    err = QueryCodec(
            client.interface(),
            info.mName.c_str(), type, info.mIsEncoder, &caps);

    if (err != OK) {
        return err;
    }

    for (size_t i = 0; i < caps.mProfileLevels.size(); ++i) {
        const CodecProfileLevel &src = caps.mProfileLevels.itemAt(i);

        ProfileLevel profileLevel;
        profileLevel.mProfile = src.mProfile;
        profileLevel.mLevel = src.mLevel;
        profileLevels->push(profileLevel);
    }

    for (size_t i = 0; i < caps.mColorFormats.size(); ++i) {
        colorFormats->push(caps.mColorFormats.itemAt(i));
    }

    *flags = caps.mFlags;

    return OK;
}

}  // namespace android
