MediaCodecList.cpp revision 69829f3bd09ee4e6be49fee8795c5df24c4da70e
1afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber/*
2afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber * Copyright 2012, The Android Open Source Project
3afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber *
4afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber * you may not use this file except in compliance with the License.
6afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber * You may obtain a copy of the License at
7afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber *
8afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber *     http://www.apache.org/licenses/LICENSE-2.0
9afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber *
10afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber * Unless required by applicable law or agreed to in writing, software
11afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber * See the License for the specific language governing permissions and
14afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber * limitations under the License.
15afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber */
16afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
17afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber//#define LOG_NDEBUG 0
18afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#define LOG_TAG "MediaCodecList"
19afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <utils/Log.h>
20afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
21afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/MediaCodecList.h>
22afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
23afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/foundation/ADebug.h>
24afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/MediaErrors.h>
2569829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber#include <media/stagefright/OMXClient.h>
2669829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber#include <media/stagefright/OMXCodec.h>
27afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <utils/threads.h>
28afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
29afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <expat.h>
30afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
31afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubernamespace android {
32afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
33afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberstatic Mutex sInitMutex;
34afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
35afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber// static
36afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas HuberMediaCodecList *MediaCodecList::sCodecList;
37afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
38afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber// static
39afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberconst MediaCodecList *MediaCodecList::getInstance() {
40afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    Mutex::Autolock autoLock(sInitMutex);
41afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
42afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (sCodecList == NULL) {
43afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        sCodecList = new MediaCodecList;
44afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
45afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
46afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return sCodecList->initCheck() == OK ? sCodecList : NULL;
47afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
48afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
49afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas HuberMediaCodecList::MediaCodecList()
50afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mInitCheck(NO_INIT) {
51afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    FILE *file = fopen("/etc/media_codecs.xml", "r");
52afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
53afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (file == NULL) {
54afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        ALOGW("unable to open media codecs configuration xml file.");
55afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return;
56afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
57afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
58afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    parseXMLFile(file);
59afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
60afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (mInitCheck == OK) {
61afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        // These are currently still used by the video editing suite.
62afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
63afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        addMediaCodec(true /* encoder */, "AACEncoder", "audio/mp4a-latm");
64afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        addMediaCodec(true /* encoder */, "AVCEncoder", "video/avc");
65afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
66afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        addMediaCodec(true /* encoder */, "M4vH263Encoder");
67afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        addType("video/3gpp");
68afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        addType("video/mp4v-es");
69ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber
70ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        addMediaCodec(
71ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                false /* encoder */, "OMX.google.raw.decoder", "audio/raw");
72afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
73afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
74afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#if 0
75afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    for (size_t i = 0; i < mCodecInfos.size(); ++i) {
76afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        const CodecInfo &info = mCodecInfos.itemAt(i);
77afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
78afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        AString line = info.mName;
79afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        line.append(" supports ");
80afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        for (size_t j = 0; j < mTypes.size(); ++j) {
81afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            uint32_t value = mTypes.valueAt(j);
82afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
83afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (info.mTypes & (1ul << value)) {
84afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                line.append(mTypes.keyAt(j));
85afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                line.append(" ");
86afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
87afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
88afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
89afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        ALOGI("%s", line.c_str());
90afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
91afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#endif
92afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
93afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    fclose(file);
94afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    file = NULL;
95afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
96afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
97afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas HuberMediaCodecList::~MediaCodecList() {
98afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
99afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
100afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberstatus_t MediaCodecList::initCheck() const {
101afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return mInitCheck;
102afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
103afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
104afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubervoid MediaCodecList::parseXMLFile(FILE *file) {
105afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mInitCheck = OK;
106afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCurrentSection = SECTION_TOPLEVEL;
107afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mDepth = 0;
108afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
109afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    XML_Parser parser = ::XML_ParserCreate(NULL);
110afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    CHECK(parser != NULL);
111afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
112afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    ::XML_SetUserData(parser, this);
113afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    ::XML_SetElementHandler(
114afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            parser, StartElementHandlerWrapper, EndElementHandlerWrapper);
115afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
116afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    const int BUFF_SIZE = 512;
117afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    while (mInitCheck == OK) {
118afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        void *buff = ::XML_GetBuffer(parser, BUFF_SIZE);
119afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (buff == NULL) {
120afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            ALOGE("failed to in call to XML_GetBuffer()");
121afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            mInitCheck = UNKNOWN_ERROR;
122afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
123afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
124afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
125afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        int bytes_read = ::fread(buff, 1, BUFF_SIZE, file);
126afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (bytes_read < 0) {
127afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            ALOGE("failed in call to read");
128afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            mInitCheck = ERROR_IO;
129afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
130afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
131afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
132afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (::XML_ParseBuffer(parser, bytes_read, bytes_read == 0)
133afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                != XML_STATUS_OK) {
134afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            mInitCheck = ERROR_MALFORMED;
135afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
136afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
137afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
138afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (bytes_read == 0) {
139afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
140afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
141afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
142afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
143afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    ::XML_ParserFree(parser);
144afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
145afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (mInitCheck == OK) {
146afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        for (size_t i = mCodecInfos.size(); i-- > 0;) {
147afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            CodecInfo *info = &mCodecInfos.editItemAt(i);
148afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
149afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (info->mTypes == 0) {
150afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                // No types supported by this component???
151afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
152afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                ALOGW("Component %s does not support any type of media?",
153afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                      info->mName.c_str());
154afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
155afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mCodecInfos.removeAt(i);
156afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
157afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
158afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
159afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
160afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (mInitCheck != OK) {
161afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        mCodecInfos.clear();
162afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        mCodecQuirks.clear();
163afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
164afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
165afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
166afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber// static
167afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubervoid MediaCodecList::StartElementHandlerWrapper(
168afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        void *me, const char *name, const char **attrs) {
169afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    static_cast<MediaCodecList *>(me)->startElementHandler(name, attrs);
170afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
171afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
172afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber// static
173afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubervoid MediaCodecList::EndElementHandlerWrapper(void *me, const char *name) {
174afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    static_cast<MediaCodecList *>(me)->endElementHandler(name);
175afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
176afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
177afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubervoid MediaCodecList::startElementHandler(
178afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        const char *name, const char **attrs) {
179afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (mInitCheck != OK) {
180afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return;
181afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
182afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
183afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    switch (mCurrentSection) {
184afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        case SECTION_TOPLEVEL:
185afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        {
186afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (!strcmp(name, "Decoders")) {
187afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mCurrentSection = SECTION_DECODERS;
188afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            } else if (!strcmp(name, "Encoders")) {
189afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mCurrentSection = SECTION_ENCODERS;
190afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
191afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
192afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
193afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
194afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        case SECTION_DECODERS:
195afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        {
196afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (!strcmp(name, "MediaCodec")) {
197afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mInitCheck =
198afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    addMediaCodecFromAttributes(false /* encoder */, attrs);
199afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
200afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mCurrentSection = SECTION_DECODER;
201afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
202afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
203afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
204afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
205afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        case SECTION_ENCODERS:
206afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        {
207afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (!strcmp(name, "MediaCodec")) {
208afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mInitCheck =
209afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    addMediaCodecFromAttributes(true /* encoder */, attrs);
210afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
211afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mCurrentSection = SECTION_ENCODER;
212afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
213afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
214afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
215afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
216afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        case SECTION_DECODER:
217afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        case SECTION_ENCODER:
218afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        {
219afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (!strcmp(name, "Quirk")) {
220afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mInitCheck = addQuirk(attrs);
221afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            } else if (!strcmp(name, "Type")) {
222afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mInitCheck = addTypeFromAttributes(attrs);
223afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
224afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
225afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
226afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
227afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        default:
228afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
229afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
230afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
231afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    ++mDepth;
232afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
233afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
234afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubervoid MediaCodecList::endElementHandler(const char *name) {
235afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (mInitCheck != OK) {
236afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return;
237afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
238afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
239afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    switch (mCurrentSection) {
240afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        case SECTION_DECODERS:
241afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        {
242afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (!strcmp(name, "Decoders")) {
243afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mCurrentSection = SECTION_TOPLEVEL;
244afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
245afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
246afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
247afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
248afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        case SECTION_ENCODERS:
249afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        {
250afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (!strcmp(name, "Encoders")) {
251afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mCurrentSection = SECTION_TOPLEVEL;
252afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
253afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
254afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
255afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
256afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        case SECTION_DECODER:
257afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        {
258afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (!strcmp(name, "MediaCodec")) {
259afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mCurrentSection = SECTION_DECODERS;
260afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
261afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
262afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
263afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
264afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        case SECTION_ENCODER:
265afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        {
266afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (!strcmp(name, "MediaCodec")) {
267afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mCurrentSection = SECTION_ENCODERS;
268afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
269afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
270afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
271afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
272afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        default:
273afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
274afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
275afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
276afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    --mDepth;
277afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
278afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
279afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberstatus_t MediaCodecList::addMediaCodecFromAttributes(
280afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        bool encoder, const char **attrs) {
281afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    const char *name = NULL;
282afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    const char *type = NULL;
283afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
284afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    size_t i = 0;
285afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    while (attrs[i] != NULL) {
286afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (!strcmp(attrs[i], "name")) {
287afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (attrs[i + 1] == NULL) {
288afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                return -EINVAL;
289afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
290afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            name = attrs[i + 1];
291afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            ++i;
292afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        } else if (!strcmp(attrs[i], "type")) {
293afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (attrs[i + 1] == NULL) {
294afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                return -EINVAL;
295afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
296afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            type = attrs[i + 1];
297afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            ++i;
298afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        } else {
299afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            return -EINVAL;
300afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
301afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
302afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        ++i;
303afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
304afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
305afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (name == NULL) {
306afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return -EINVAL;
307afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
308afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
309afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    addMediaCodec(encoder, name, type);
310afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
311afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return OK;
312afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
313afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
314afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubervoid MediaCodecList::addMediaCodec(
315afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        bool encoder, const char *name, const char *type) {
316afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodecInfos.push();
317afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    CodecInfo *info = &mCodecInfos.editItemAt(mCodecInfos.size() - 1);
318afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    info->mName = name;
319afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    info->mIsEncoder = encoder;
320afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    info->mTypes = 0;
321afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    info->mQuirks = 0;
322afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
323afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (type != NULL) {
324afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        addType(type);
325afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
326afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
327afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
328afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberstatus_t MediaCodecList::addQuirk(const char **attrs) {
329afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    const char *name = NULL;
330afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
331afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    size_t i = 0;
332afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    while (attrs[i] != NULL) {
333afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (!strcmp(attrs[i], "name")) {
334afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (attrs[i + 1] == NULL) {
335afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                return -EINVAL;
336afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
337afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            name = attrs[i + 1];
338afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            ++i;
339afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        } else {
340afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            return -EINVAL;
341afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
342afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
343afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        ++i;
344afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
345afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
346afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (name == NULL) {
347afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return -EINVAL;
348afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
349afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
350afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    uint32_t bit;
351afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    ssize_t index = mCodecQuirks.indexOfKey(name);
352afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (index < 0) {
353afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        bit = mCodecQuirks.size();
354afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
355afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (bit == 32) {
356afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            ALOGW("Too many distinct quirk names in configuration.");
357afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            return OK;
358afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
359afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
360afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        mCodecQuirks.add(name, bit);
361afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    } else {
362afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        bit = mCodecQuirks.valueAt(index);
363afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
364afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
365afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    CodecInfo *info = &mCodecInfos.editItemAt(mCodecInfos.size() - 1);
366afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    info->mQuirks |= 1ul << bit;
367afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
368afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return OK;
369afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
370afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
371afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberstatus_t MediaCodecList::addTypeFromAttributes(const char **attrs) {
372afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    const char *name = NULL;
373afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
374afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    size_t i = 0;
375afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    while (attrs[i] != NULL) {
376afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (!strcmp(attrs[i], "name")) {
377afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (attrs[i + 1] == NULL) {
378afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                return -EINVAL;
379afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
380afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            name = attrs[i + 1];
381afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            ++i;
382afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        } else {
383afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            return -EINVAL;
384afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
385afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
386afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        ++i;
387afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
388afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
389afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (name == NULL) {
390afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return -EINVAL;
391afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
392afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
393afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    addType(name);
394afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
395afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return OK;
396afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
397afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
398afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubervoid MediaCodecList::addType(const char *name) {
399afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    uint32_t bit;
400afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    ssize_t index = mTypes.indexOfKey(name);
401afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (index < 0) {
402afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        bit = mTypes.size();
403afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
404afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (bit == 32) {
405afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            ALOGW("Too many distinct type names in configuration.");
406afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            return;
407afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
408afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
409afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        mTypes.add(name, bit);
410afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    } else {
411afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        bit = mTypes.valueAt(index);
412afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
413afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
414afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    CodecInfo *info = &mCodecInfos.editItemAt(mCodecInfos.size() - 1);
415afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    info->mTypes |= 1ul << bit;
416afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
417afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
418afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberssize_t MediaCodecList::findCodecByType(
419afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        const char *type, bool encoder, size_t startIndex) const {
420afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    ssize_t typeIndex = mTypes.indexOfKey(type);
421afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
422afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (typeIndex < 0) {
423afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return -ENOENT;
424afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
425afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
426afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    uint32_t typeMask = 1ul << mTypes.valueAt(typeIndex);
427afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
428afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    while (startIndex < mCodecInfos.size()) {
429afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        const CodecInfo &info = mCodecInfos.itemAt(startIndex);
430afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
431afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (info.mIsEncoder == encoder && (info.mTypes & typeMask)) {
432afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            return startIndex;
433afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
434afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
435afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        ++startIndex;
436afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
437afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
438afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return -ENOENT;
439afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
440afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
441afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberssize_t MediaCodecList::findCodecByName(const char *name) const {
442afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    for (size_t i = 0; i < mCodecInfos.size(); ++i) {
443afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        const CodecInfo &info = mCodecInfos.itemAt(i);
444afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
445afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (info.mName == name) {
446afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            return i;
447afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
448afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
449afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
450afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return -ENOENT;
451afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
452afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
45369829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Hubersize_t MediaCodecList::countCodecs() const {
45469829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    return mCodecInfos.size();
45569829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber}
45669829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
457afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberconst char *MediaCodecList::getCodecName(size_t index) const {
458afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (index >= mCodecInfos.size()) {
459afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return NULL;
460afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
461afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
462afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    const CodecInfo &info = mCodecInfos.itemAt(index);
463afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return info.mName.c_str();
464afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
465afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
46669829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huberbool MediaCodecList::isEncoder(size_t index) const {
46769829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    if (index >= mCodecInfos.size()) {
46869829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        return NULL;
46969829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    }
47069829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
47169829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    const CodecInfo &info = mCodecInfos.itemAt(index);
47269829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    return info.mIsEncoder;
47369829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber}
47469829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
475afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberbool MediaCodecList::codecHasQuirk(
476afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        size_t index, const char *quirkName) const {
477afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (index >= mCodecInfos.size()) {
478afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return NULL;
479afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
480afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
481afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    const CodecInfo &info = mCodecInfos.itemAt(index);
482afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
483afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (info.mQuirks != 0) {
484afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        ssize_t index = mCodecQuirks.indexOfKey(quirkName);
485afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (index >= 0 && info.mQuirks & (1ul << mCodecQuirks.valueAt(index))) {
486afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            return true;
487afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
488afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
489afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
490afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return false;
491afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
492afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
49369829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huberstatus_t MediaCodecList::getSupportedTypes(
49469829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        size_t index, Vector<AString> *types) const {
49569829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    types->clear();
49669829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
49769829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    if (index >= mCodecInfos.size()) {
49869829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        return -ERANGE;
49969829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    }
50069829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
50169829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    const CodecInfo &info = mCodecInfos.itemAt(index);
50269829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
50369829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    for (size_t i = 0; i < mTypes.size(); ++i) {
50469829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        uint32_t typeMask = 1ul << mTypes.valueAt(i);
50569829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
50669829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        if (info.mTypes & typeMask) {
50769829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber            types->push(mTypes.keyAt(i));
50869829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        }
50969829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    }
51069829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
51169829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    return OK;
51269829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber}
51369829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
51469829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huberstatus_t MediaCodecList::getCodecCapabilities(
51569829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        size_t index, const char *type,
51669829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        Vector<ProfileLevel> *profileLevels,
51769829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        Vector<uint32_t> *colorFormats) const {
51869829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    profileLevels->clear();
51969829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    colorFormats->clear();
52069829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
52169829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    if (index >= mCodecInfos.size()) {
52269829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        return -ERANGE;
52369829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    }
52469829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
52569829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    const CodecInfo &info = mCodecInfos.itemAt(index);
52669829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
52769829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    OMXClient client;
52869829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    status_t err = client.connect();
52969829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    if (err != OK) {
53069829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        return err;
53169829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    }
53269829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
53369829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    CodecCapabilities caps;
53469829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    err = QueryCodec(
53569829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber            client.interface(),
53669829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber            info.mName.c_str(), type, info.mIsEncoder, &caps);
53769829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
53869829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    if (err != OK) {
53969829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        return err;
54069829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    }
54169829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
54269829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    for (size_t i = 0; i < caps.mProfileLevels.size(); ++i) {
54369829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        const CodecProfileLevel &src = caps.mProfileLevels.itemAt(i);
54469829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
54569829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        ProfileLevel profileLevel;
54669829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        profileLevel.mProfile = src.mProfile;
54769829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        profileLevel.mLevel = src.mLevel;
54869829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        profileLevels->push(profileLevel);
54969829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    }
55069829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
55169829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    for (size_t i = 0; i < caps.mColorFormats.size(); ++i) {
55269829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        colorFormats->push(caps.mColorFormats.itemAt(i));
55369829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    }
55469829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
55569829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    return OK;
55669829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber}
55769829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
558afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}  // namespace android
559