160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar/*
260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar * Copyright 2014, The Android Open Source Project
360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar *
460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar * Licensed under the Apache License, Version 2.0 (the "License");
560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar * you may not use this file except in compliance with the License.
660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar * You may obtain a copy of the License at
760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar *
860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar *     http://www.apache.org/licenses/LICENSE-2.0
960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar *
1060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar * Unless required by applicable law or agreed to in writing, software
1160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar * distributed under the License is distributed on an "AS IS" BASIS,
1260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar * See the License for the specific language governing permissions and
1460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar * limitations under the License.
1560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar */
1660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
1760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar//#define LOG_NDEBUG 0
1860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar#define LOG_TAG "MediaCodecInfo"
1960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar#include <utils/Log.h>
2060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
2160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar#include <media/IOMX.h>
2260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
2360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar#include <media/MediaCodecInfo.h>
2460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
2560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar#include <media/stagefright/foundation/ADebug.h>
2660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar#include <media/stagefright/foundation/AMessage.h>
2760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar#include <binder/Parcel.h>
2860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
2960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnarnamespace android {
3060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
3160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnarvoid MediaCodecInfo::Capabilities::getSupportedProfileLevels(
3260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        Vector<ProfileLevel> *profileLevels) const {
3360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    profileLevels->clear();
3460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    profileLevels->appendVector(mProfileLevels);
3560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar}
3660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
3760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnarvoid MediaCodecInfo::Capabilities::getSupportedColorFormats(
3860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        Vector<uint32_t> *colorFormats) const {
3960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    colorFormats->clear();
4060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    colorFormats->appendVector(mColorFormats);
4160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar}
4260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
4360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnaruint32_t MediaCodecInfo::Capabilities::getFlags() const {
4460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    return mFlags;
4560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar}
4660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
472461e0cf6ae3fe5c9b52ce9e3ac764f4aff5e5ebLajos Molnarconst sp<AMessage> MediaCodecInfo::Capabilities::getDetails() const {
4860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    return mDetails;
4960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar}
5060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
5160b1c0e79d12a1c70758bc8d060156924635f8baLajos MolnarMediaCodecInfo::Capabilities::Capabilities()
5260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar  : mFlags(0) {
5360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    mDetails = new AMessage;
5460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar}
5560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
5660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar// static
5760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnarsp<MediaCodecInfo::Capabilities> MediaCodecInfo::Capabilities::FromParcel(
5860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        const Parcel &parcel) {
5960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    sp<MediaCodecInfo::Capabilities> caps = new Capabilities();
6060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    size_t size = static_cast<size_t>(parcel.readInt32());
6160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    for (size_t i = 0; i < size; i++) {
6260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        ProfileLevel profileLevel;
6360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        profileLevel.mProfile = static_cast<uint32_t>(parcel.readInt32());
6460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        profileLevel.mLevel = static_cast<uint32_t>(parcel.readInt32());
6560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        if (caps != NULL) {
6660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            caps->mProfileLevels.push_back(profileLevel);
6760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        }
6860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    }
6960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    size = static_cast<size_t>(parcel.readInt32());
7060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    for (size_t i = 0; i < size; i++) {
7160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        uint32_t color = static_cast<uint32_t>(parcel.readInt32());
7260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        if (caps != NULL) {
7360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            caps->mColorFormats.push_back(color);
7460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        }
7560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    }
7660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    uint32_t flags = static_cast<uint32_t>(parcel.readInt32());
7760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    sp<AMessage> details = AMessage::FromParcel(parcel);
788dab17305ff72298e2b4874592ac72c004c392d8Pawin Vongmasa    if (details == NULL)
798dab17305ff72298e2b4874592ac72c004c392d8Pawin Vongmasa        return NULL;
8060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    if (caps != NULL) {
8160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        caps->mFlags = flags;
8260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        caps->mDetails = details;
8360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    }
8460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    return caps;
8560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar}
8660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
8760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnarstatus_t MediaCodecInfo::Capabilities::writeToParcel(Parcel *parcel) const {
8860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    CHECK_LE(mProfileLevels.size(), INT32_MAX);
8960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    parcel->writeInt32(mProfileLevels.size());
9060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    for (size_t i = 0; i < mProfileLevels.size(); i++) {
9160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        parcel->writeInt32(mProfileLevels.itemAt(i).mProfile);
9260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        parcel->writeInt32(mProfileLevels.itemAt(i).mLevel);
9360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    }
9460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    CHECK_LE(mColorFormats.size(), INT32_MAX);
9560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    parcel->writeInt32(mColorFormats.size());
9660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    for (size_t i = 0; i < mColorFormats.size(); i++) {
9760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        parcel->writeInt32(mColorFormats.itemAt(i));
9860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    }
9960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    parcel->writeInt32(mFlags);
10060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    mDetails->writeToParcel(parcel);
10160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    return OK;
10260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar}
10360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
1045b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnarvoid MediaCodecInfo::CapabilitiesBuilder::addProfileLevel(uint32_t profile, uint32_t level) {
1055b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    ProfileLevel profileLevel;
1065b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    profileLevel.mProfile = profile;
1075b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    profileLevel.mLevel = level;
1085b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    mProfileLevels.push_back(profileLevel);
1095b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar}
1105b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
1115b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnarvoid MediaCodecInfo::CapabilitiesBuilder::addColorFormat(uint32_t format) {
1125b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    mColorFormats.push(format);
1135b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar}
1145b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
1155b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnarvoid MediaCodecInfo::CapabilitiesBuilder::addFlags(uint32_t flags) {
1165b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    mFlags |= flags;
1175b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar}
1185b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
11960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnarbool MediaCodecInfo::isEncoder() const {
12060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    return mIsEncoder;
12160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar}
12260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
12360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnarbool MediaCodecInfo::hasQuirk(const char *name) const {
12489b2a0ad367cdff5ff4e70036311ecf82921a829Marco Nelissen    if (name) {
12589b2a0ad367cdff5ff4e70036311ecf82921a829Marco Nelissen        for (size_t ix = 0; ix < mQuirks.size(); ix++) {
12689b2a0ad367cdff5ff4e70036311ecf82921a829Marco Nelissen            if (mQuirks.itemAt(ix).equalsIgnoreCase(name)) {
12789b2a0ad367cdff5ff4e70036311ecf82921a829Marco Nelissen                return true;
12889b2a0ad367cdff5ff4e70036311ecf82921a829Marco Nelissen            }
12960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        }
13060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    }
13160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    return false;
13260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar}
13360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
13460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnarvoid MediaCodecInfo::getSupportedMimes(Vector<AString> *mimes) const {
13560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    mimes->clear();
13660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    for (size_t ix = 0; ix < mCaps.size(); ix++) {
13760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        mimes->push_back(mCaps.keyAt(ix));
13860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    }
13960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar}
14060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
1412461e0cf6ae3fe5c9b52ce9e3ac764f4aff5e5ebLajos Molnarconst sp<MediaCodecInfo::Capabilities>
14260b1c0e79d12a1c70758bc8d060156924635f8baLajos MolnarMediaCodecInfo::getCapabilitiesFor(const char *mime) const {
14360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    ssize_t ix = getCapabilityIndex(mime);
14460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    if (ix >= 0) {
14560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        return mCaps.valueAt(ix);
14660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    }
14760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    return NULL;
14860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar}
14960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
15060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnarconst char *MediaCodecInfo::getCodecName() const {
15160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    return mName.c_str();
15260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar}
15360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
15460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar// static
15560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnarsp<MediaCodecInfo> MediaCodecInfo::FromParcel(const Parcel &parcel) {
15660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    AString name = AString::FromParcel(parcel);
15760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    bool isEncoder = static_cast<bool>(parcel.readInt32());
15860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    sp<MediaCodecInfo> info = new MediaCodecInfo(name, isEncoder, NULL);
15960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    size_t size = static_cast<size_t>(parcel.readInt32());
16060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    for (size_t i = 0; i < size; i++) {
16160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        AString quirk = AString::FromParcel(parcel);
16260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        if (info != NULL) {
16360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            info->mQuirks.push_back(quirk);
16460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        }
16560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    }
16660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    size = static_cast<size_t>(parcel.readInt32());
16760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    for (size_t i = 0; i < size; i++) {
16860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        AString mime = AString::FromParcel(parcel);
16960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        sp<Capabilities> caps = Capabilities::FromParcel(parcel);
1708dab17305ff72298e2b4874592ac72c004c392d8Pawin Vongmasa        if (caps == NULL)
1718dab17305ff72298e2b4874592ac72c004c392d8Pawin Vongmasa            return NULL;
17260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        if (info != NULL) {
17360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            info->mCaps.add(mime, caps);
17460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        }
17560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    }
17660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    return info;
17760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar}
17860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
17960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnarstatus_t MediaCodecInfo::writeToParcel(Parcel *parcel) const {
18060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    mName.writeToParcel(parcel);
18160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    parcel->writeInt32(mIsEncoder);
18260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    parcel->writeInt32(mQuirks.size());
18360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    for (size_t i = 0; i < mQuirks.size(); i++) {
18460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        mQuirks.itemAt(i).writeToParcel(parcel);
18560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    }
18660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    parcel->writeInt32(mCaps.size());
18760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    for (size_t i = 0; i < mCaps.size(); i++) {
18860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        mCaps.keyAt(i).writeToParcel(parcel);
18960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        mCaps.valueAt(i)->writeToParcel(parcel);
19060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    }
19160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    return OK;
19260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar}
19360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
19460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnarssize_t MediaCodecInfo::getCapabilityIndex(const char *mime) const {
19589b2a0ad367cdff5ff4e70036311ecf82921a829Marco Nelissen    if (mime) {
19689b2a0ad367cdff5ff4e70036311ecf82921a829Marco Nelissen        for (size_t ix = 0; ix < mCaps.size(); ix++) {
19789b2a0ad367cdff5ff4e70036311ecf82921a829Marco Nelissen            if (mCaps.keyAt(ix).equalsIgnoreCase(mime)) {
19889b2a0ad367cdff5ff4e70036311ecf82921a829Marco Nelissen                return ix;
19989b2a0ad367cdff5ff4e70036311ecf82921a829Marco Nelissen            }
20060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        }
20160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    }
20260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    return -1;
20360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar}
20460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
20560b1c0e79d12a1c70758bc8d060156924635f8baLajos MolnarMediaCodecInfo::MediaCodecInfo(AString name, bool encoder, const char *mime)
20660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    : mName(name),
20760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar      mIsEncoder(encoder),
20860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar      mHasSoleMime(false) {
20960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    if (mime != NULL) {
21060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        addMime(mime);
21160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        mHasSoleMime = true;
21260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    }
21360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar}
21460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
21560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnarstatus_t MediaCodecInfo::addMime(const char *mime) {
21660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    if (mHasSoleMime) {
21760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        ALOGE("Codec '%s' already had its type specified", mName.c_str());
21860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        return -EINVAL;
21960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    }
22060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    ssize_t ix = getCapabilityIndex(mime);
22160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    if (ix >= 0) {
22260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        mCurrentCaps = mCaps.valueAt(ix);
22360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    } else {
22460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        mCurrentCaps = new Capabilities();
22560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        mCaps.add(AString(mime), mCurrentCaps);
22660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    }
22760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    return OK;
22860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar}
22960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
2309e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wustatus_t MediaCodecInfo::updateMime(const char *mime) {
2319e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    ssize_t ix = getCapabilityIndex(mime);
2329e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    if (ix < 0) {
2339e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        ALOGE("updateMime mime not found %s", mime);
2349e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        return -EINVAL;
2359e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    }
2369e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
2379e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    mCurrentCaps = mCaps.valueAt(ix);
2389e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    return OK;
2399e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu}
2409e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
2416ff58f04f78886b07c72c0118eb71a78d08f5651Lajos Molnarvoid MediaCodecInfo::removeMime(const char *mime) {
2426ff58f04f78886b07c72c0118eb71a78d08f5651Lajos Molnar    ssize_t ix = getCapabilityIndex(mime);
2436ff58f04f78886b07c72c0118eb71a78d08f5651Lajos Molnar    if (ix >= 0) {
2446ff58f04f78886b07c72c0118eb71a78d08f5651Lajos Molnar        mCaps.removeItemsAt(ix);
2456ff58f04f78886b07c72c0118eb71a78d08f5651Lajos Molnar        // mCurrentCaps will be removed when completed
2466ff58f04f78886b07c72c0118eb71a78d08f5651Lajos Molnar    }
2476ff58f04f78886b07c72c0118eb71a78d08f5651Lajos Molnar}
2486ff58f04f78886b07c72c0118eb71a78d08f5651Lajos Molnar
2490a4427bb91e72a4dfece276521d7f21fbb6c7846Lajos Molnarstatus_t MediaCodecInfo::initializeCapabilities(const sp<Capabilities> &caps) {
2500a4427bb91e72a4dfece276521d7f21fbb6c7846Lajos Molnar    // TRICKY: copy data to mCurrentCaps as it is a reference to
2510a4427bb91e72a4dfece276521d7f21fbb6c7846Lajos Molnar    // an element of the capabilites map.
2527f2262fc7d038a0d42def7d769bb9e816e292785Lajos Molnar    mCurrentCaps->mColorFormats.clear();
2530a4427bb91e72a4dfece276521d7f21fbb6c7846Lajos Molnar    mCurrentCaps->mColorFormats.appendVector(caps->mColorFormats);
2540a4427bb91e72a4dfece276521d7f21fbb6c7846Lajos Molnar    mCurrentCaps->mProfileLevels.clear();
2550a4427bb91e72a4dfece276521d7f21fbb6c7846Lajos Molnar    mCurrentCaps->mProfileLevels.appendVector(caps->mProfileLevels);
2560a4427bb91e72a4dfece276521d7f21fbb6c7846Lajos Molnar    mCurrentCaps->mFlags = caps->mFlags;
2570a4427bb91e72a4dfece276521d7f21fbb6c7846Lajos Molnar    mCurrentCaps->mDetails = caps->mDetails;
25860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    return OK;
25960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar}
26060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
26160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnarvoid MediaCodecInfo::addQuirk(const char *name) {
26260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    if (!hasQuirk(name)) {
26360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        mQuirks.push(name);
26460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    }
26560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar}
26660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
26760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnarvoid MediaCodecInfo::complete() {
26860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    mCurrentCaps = NULL;
26960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar}
27060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
27160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnarvoid MediaCodecInfo::addDetail(const AString &key, const AString &value) {
27260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    mCurrentCaps->mDetails->setString(key.c_str(), value.c_str());
27360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar}
27460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
27560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnarvoid MediaCodecInfo::addFeature(const AString &key, int32_t value) {
27660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    AString tag = "feature-";
27760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    tag.append(key);
27860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    mCurrentCaps->mDetails->setInt32(tag.c_str(), value);
27960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar}
28060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
281732c6d955524ead6c31e6e1bafbd41ea4cee525dLajos Molnarvoid MediaCodecInfo::addFeature(const AString &key, const char *value) {
282732c6d955524ead6c31e6e1bafbd41ea4cee525dLajos Molnar    AString tag = "feature-";
283732c6d955524ead6c31e6e1bafbd41ea4cee525dLajos Molnar    tag.append(key);
284732c6d955524ead6c31e6e1bafbd41ea4cee525dLajos Molnar    mCurrentCaps->mDetails->setString(tag.c_str(), value);
285732c6d955524ead6c31e6e1bafbd41ea4cee525dLajos Molnar}
286732c6d955524ead6c31e6e1bafbd41ea4cee525dLajos Molnar
28760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar}  // namespace android
288