MediaCodecList.cpp revision e8057dd8208f0a185109992339a995c518b12780
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
29e8057dd8208f0a185109992339a995c518b12780Elliott Hughes#include <libexpat/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");
64ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber
65ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        addMediaCodec(
66ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                false /* encoder */, "OMX.google.raw.decoder", "audio/raw");
67afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
68afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
69afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#if 0
70afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    for (size_t i = 0; i < mCodecInfos.size(); ++i) {
71afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        const CodecInfo &info = mCodecInfos.itemAt(i);
72afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
73afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        AString line = info.mName;
74afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        line.append(" supports ");
75afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        for (size_t j = 0; j < mTypes.size(); ++j) {
76afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            uint32_t value = mTypes.valueAt(j);
77afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
78afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (info.mTypes & (1ul << value)) {
79afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                line.append(mTypes.keyAt(j));
80afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                line.append(" ");
81afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
82afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
83afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
84afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        ALOGI("%s", line.c_str());
85afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
86afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#endif
87afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
88afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    fclose(file);
89afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    file = NULL;
90afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
91afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
92afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas HuberMediaCodecList::~MediaCodecList() {
93afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
94afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
95afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberstatus_t MediaCodecList::initCheck() const {
96afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return mInitCheck;
97afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
98afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
99afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubervoid MediaCodecList::parseXMLFile(FILE *file) {
100afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mInitCheck = OK;
101afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCurrentSection = SECTION_TOPLEVEL;
102afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mDepth = 0;
103afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
104afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    XML_Parser parser = ::XML_ParserCreate(NULL);
105afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    CHECK(parser != NULL);
106afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
107afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    ::XML_SetUserData(parser, this);
108afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    ::XML_SetElementHandler(
109afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            parser, StartElementHandlerWrapper, EndElementHandlerWrapper);
110afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
111afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    const int BUFF_SIZE = 512;
112afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    while (mInitCheck == OK) {
113afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        void *buff = ::XML_GetBuffer(parser, BUFF_SIZE);
114afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (buff == NULL) {
115afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            ALOGE("failed to in call to XML_GetBuffer()");
116afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            mInitCheck = UNKNOWN_ERROR;
117afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
118afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
119afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
120afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        int bytes_read = ::fread(buff, 1, BUFF_SIZE, file);
121afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (bytes_read < 0) {
122afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            ALOGE("failed in call to read");
123afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            mInitCheck = ERROR_IO;
124afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
125afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
126afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
127afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (::XML_ParseBuffer(parser, bytes_read, bytes_read == 0)
128afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                != XML_STATUS_OK) {
129afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            mInitCheck = ERROR_MALFORMED;
130afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
131afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
132afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
133afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (bytes_read == 0) {
134afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
135afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
136afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
137afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
138afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    ::XML_ParserFree(parser);
139afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
140afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (mInitCheck == OK) {
141afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        for (size_t i = mCodecInfos.size(); i-- > 0;) {
142afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            CodecInfo *info = &mCodecInfos.editItemAt(i);
143afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
144afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (info->mTypes == 0) {
145afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                // No types supported by this component???
146afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
147afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                ALOGW("Component %s does not support any type of media?",
148afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                      info->mName.c_str());
149afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
150afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mCodecInfos.removeAt(i);
151afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
152afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
153afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
154afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
155afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (mInitCheck != OK) {
156afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        mCodecInfos.clear();
157afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        mCodecQuirks.clear();
158afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
159afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
160afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
161afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber// static
162afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubervoid MediaCodecList::StartElementHandlerWrapper(
163afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        void *me, const char *name, const char **attrs) {
164afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    static_cast<MediaCodecList *>(me)->startElementHandler(name, attrs);
165afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
166afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
167afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber// static
168afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubervoid MediaCodecList::EndElementHandlerWrapper(void *me, const char *name) {
169afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    static_cast<MediaCodecList *>(me)->endElementHandler(name);
170afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
171afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
172afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubervoid MediaCodecList::startElementHandler(
173afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        const char *name, const char **attrs) {
174afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (mInitCheck != OK) {
175afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return;
176afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
177afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
178afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    switch (mCurrentSection) {
179afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        case SECTION_TOPLEVEL:
180afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        {
181afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (!strcmp(name, "Decoders")) {
182afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mCurrentSection = SECTION_DECODERS;
183afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            } else if (!strcmp(name, "Encoders")) {
184afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mCurrentSection = SECTION_ENCODERS;
185afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
186afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
187afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
188afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
189afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        case SECTION_DECODERS:
190afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        {
191afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (!strcmp(name, "MediaCodec")) {
192afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mInitCheck =
193afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    addMediaCodecFromAttributes(false /* encoder */, attrs);
194afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
195afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mCurrentSection = SECTION_DECODER;
196afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
197afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
198afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
199afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
200afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        case SECTION_ENCODERS:
201afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        {
202afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (!strcmp(name, "MediaCodec")) {
203afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mInitCheck =
204afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    addMediaCodecFromAttributes(true /* encoder */, attrs);
205afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
206afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mCurrentSection = SECTION_ENCODER;
207afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
208afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
209afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
210afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
211afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        case SECTION_DECODER:
212afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        case SECTION_ENCODER:
213afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        {
214afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (!strcmp(name, "Quirk")) {
215afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mInitCheck = addQuirk(attrs);
216afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            } else if (!strcmp(name, "Type")) {
217afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mInitCheck = addTypeFromAttributes(attrs);
218afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
219afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
220afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
221afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
222afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        default:
223afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
224afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
225afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
226afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    ++mDepth;
227afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
228afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
229afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubervoid MediaCodecList::endElementHandler(const char *name) {
230afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (mInitCheck != OK) {
231afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return;
232afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
233afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
234afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    switch (mCurrentSection) {
235afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        case SECTION_DECODERS:
236afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        {
237afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (!strcmp(name, "Decoders")) {
238afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mCurrentSection = SECTION_TOPLEVEL;
239afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
240afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
241afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
242afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
243afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        case SECTION_ENCODERS:
244afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        {
245afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (!strcmp(name, "Encoders")) {
246afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mCurrentSection = SECTION_TOPLEVEL;
247afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
248afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
249afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
250afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
251afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        case SECTION_DECODER:
252afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        {
253afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (!strcmp(name, "MediaCodec")) {
254afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mCurrentSection = SECTION_DECODERS;
255afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
256afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
257afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
258afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
259afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        case SECTION_ENCODER:
260afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        {
261afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (!strcmp(name, "MediaCodec")) {
262afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mCurrentSection = SECTION_ENCODERS;
263afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
264afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
265afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
266afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
267afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        default:
268afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
269afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
270afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
271afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    --mDepth;
272afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
273afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
274afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberstatus_t MediaCodecList::addMediaCodecFromAttributes(
275afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        bool encoder, const char **attrs) {
276afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    const char *name = NULL;
277afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    const char *type = NULL;
278afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
279afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    size_t i = 0;
280afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    while (attrs[i] != NULL) {
281afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (!strcmp(attrs[i], "name")) {
282afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (attrs[i + 1] == NULL) {
283afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                return -EINVAL;
284afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
285afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            name = attrs[i + 1];
286afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            ++i;
287afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        } else if (!strcmp(attrs[i], "type")) {
288afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (attrs[i + 1] == NULL) {
289afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                return -EINVAL;
290afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
291afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            type = attrs[i + 1];
292afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            ++i;
293afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        } else {
294afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            return -EINVAL;
295afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
296afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
297afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        ++i;
298afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
299afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
300afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (name == NULL) {
301afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return -EINVAL;
302afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
303afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
304afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    addMediaCodec(encoder, name, type);
305afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
306afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return OK;
307afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
308afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
309afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubervoid MediaCodecList::addMediaCodec(
310afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        bool encoder, const char *name, const char *type) {
311afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodecInfos.push();
312afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    CodecInfo *info = &mCodecInfos.editItemAt(mCodecInfos.size() - 1);
313afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    info->mName = name;
314afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    info->mIsEncoder = encoder;
315afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    info->mTypes = 0;
316afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    info->mQuirks = 0;
317afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
318afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (type != NULL) {
319afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        addType(type);
320afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
321afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
322afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
323afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberstatus_t MediaCodecList::addQuirk(const char **attrs) {
324afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    const char *name = NULL;
325afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
326afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    size_t i = 0;
327afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    while (attrs[i] != NULL) {
328afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (!strcmp(attrs[i], "name")) {
329afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (attrs[i + 1] == NULL) {
330afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                return -EINVAL;
331afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
332afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            name = attrs[i + 1];
333afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            ++i;
334afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        } else {
335afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            return -EINVAL;
336afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
337afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
338afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        ++i;
339afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
340afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
341afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (name == NULL) {
342afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return -EINVAL;
343afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
344afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
345afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    uint32_t bit;
346afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    ssize_t index = mCodecQuirks.indexOfKey(name);
347afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (index < 0) {
348afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        bit = mCodecQuirks.size();
349afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
350afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (bit == 32) {
351afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            ALOGW("Too many distinct quirk names in configuration.");
352afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            return OK;
353afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
354afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
355afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        mCodecQuirks.add(name, bit);
356afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    } else {
357afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        bit = mCodecQuirks.valueAt(index);
358afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
359afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
360afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    CodecInfo *info = &mCodecInfos.editItemAt(mCodecInfos.size() - 1);
361afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    info->mQuirks |= 1ul << bit;
362afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
363afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return OK;
364afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
365afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
366afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberstatus_t MediaCodecList::addTypeFromAttributes(const char **attrs) {
367afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    const char *name = NULL;
368afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
369afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    size_t i = 0;
370afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    while (attrs[i] != NULL) {
371afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (!strcmp(attrs[i], "name")) {
372afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (attrs[i + 1] == NULL) {
373afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                return -EINVAL;
374afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
375afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            name = attrs[i + 1];
376afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            ++i;
377afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        } else {
378afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            return -EINVAL;
379afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
380afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
381afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        ++i;
382afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
383afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
384afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (name == NULL) {
385afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return -EINVAL;
386afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
387afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
388afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    addType(name);
389afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
390afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return OK;
391afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
392afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
393afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubervoid MediaCodecList::addType(const char *name) {
394afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    uint32_t bit;
395afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    ssize_t index = mTypes.indexOfKey(name);
396afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (index < 0) {
397afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        bit = mTypes.size();
398afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
399afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (bit == 32) {
400afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            ALOGW("Too many distinct type names in configuration.");
401afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            return;
402afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
403afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
404afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        mTypes.add(name, bit);
405afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    } else {
406afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        bit = mTypes.valueAt(index);
407afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
408afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
409afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    CodecInfo *info = &mCodecInfos.editItemAt(mCodecInfos.size() - 1);
410afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    info->mTypes |= 1ul << bit;
411afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
412afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
413afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberssize_t MediaCodecList::findCodecByType(
414afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        const char *type, bool encoder, size_t startIndex) const {
415afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    ssize_t typeIndex = mTypes.indexOfKey(type);
416afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
417afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (typeIndex < 0) {
418afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return -ENOENT;
419afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
420afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
421afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    uint32_t typeMask = 1ul << mTypes.valueAt(typeIndex);
422afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
423afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    while (startIndex < mCodecInfos.size()) {
424afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        const CodecInfo &info = mCodecInfos.itemAt(startIndex);
425afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
426afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (info.mIsEncoder == encoder && (info.mTypes & typeMask)) {
427afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            return startIndex;
428afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
429afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
430afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        ++startIndex;
431afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
432afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
433afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return -ENOENT;
434afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
435afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
436afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberssize_t MediaCodecList::findCodecByName(const char *name) const {
437afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    for (size_t i = 0; i < mCodecInfos.size(); ++i) {
438afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        const CodecInfo &info = mCodecInfos.itemAt(i);
439afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
440afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (info.mName == name) {
441afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            return i;
442afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
443afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
444afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
445afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return -ENOENT;
446afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
447afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
44869829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Hubersize_t MediaCodecList::countCodecs() const {
44969829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    return mCodecInfos.size();
45069829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber}
45169829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
452afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberconst char *MediaCodecList::getCodecName(size_t index) const {
453afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (index >= mCodecInfos.size()) {
454afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return NULL;
455afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
456afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
457afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    const CodecInfo &info = mCodecInfos.itemAt(index);
458afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return info.mName.c_str();
459afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
460afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
46169829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huberbool MediaCodecList::isEncoder(size_t index) const {
46269829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    if (index >= mCodecInfos.size()) {
46369829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        return NULL;
46469829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    }
46569829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
46669829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    const CodecInfo &info = mCodecInfos.itemAt(index);
46769829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    return info.mIsEncoder;
46869829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber}
46969829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
470afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberbool MediaCodecList::codecHasQuirk(
471afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        size_t index, const char *quirkName) const {
472afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (index >= mCodecInfos.size()) {
473afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return NULL;
474afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
475afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
476afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    const CodecInfo &info = mCodecInfos.itemAt(index);
477afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
478afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (info.mQuirks != 0) {
479afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        ssize_t index = mCodecQuirks.indexOfKey(quirkName);
480afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (index >= 0 && info.mQuirks & (1ul << mCodecQuirks.valueAt(index))) {
481afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            return true;
482afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
483afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
484afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
485afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return false;
486afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
487afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
48869829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huberstatus_t MediaCodecList::getSupportedTypes(
48969829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        size_t index, Vector<AString> *types) const {
49069829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    types->clear();
49169829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
49269829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    if (index >= mCodecInfos.size()) {
49369829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        return -ERANGE;
49469829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    }
49569829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
49669829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    const CodecInfo &info = mCodecInfos.itemAt(index);
49769829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
49869829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    for (size_t i = 0; i < mTypes.size(); ++i) {
49969829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        uint32_t typeMask = 1ul << mTypes.valueAt(i);
50069829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
50169829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        if (info.mTypes & typeMask) {
50269829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber            types->push(mTypes.keyAt(i));
50369829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        }
50469829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    }
50569829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
50669829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    return OK;
50769829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber}
50869829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
50969829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huberstatus_t MediaCodecList::getCodecCapabilities(
51069829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        size_t index, const char *type,
51169829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        Vector<ProfileLevel> *profileLevels,
51269829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        Vector<uint32_t> *colorFormats) const {
51369829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    profileLevels->clear();
51469829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    colorFormats->clear();
51569829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
51669829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    if (index >= mCodecInfos.size()) {
51769829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        return -ERANGE;
51869829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    }
51969829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
52069829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    const CodecInfo &info = mCodecInfos.itemAt(index);
52169829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
52269829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    OMXClient client;
52369829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    status_t err = client.connect();
52469829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    if (err != OK) {
52569829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        return err;
52669829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    }
52769829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
52869829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    CodecCapabilities caps;
52969829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    err = QueryCodec(
53069829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber            client.interface(),
53169829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber            info.mName.c_str(), type, info.mIsEncoder, &caps);
53269829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
53369829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    if (err != OK) {
53469829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        return err;
53569829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    }
53669829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
53769829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    for (size_t i = 0; i < caps.mProfileLevels.size(); ++i) {
53869829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        const CodecProfileLevel &src = caps.mProfileLevels.itemAt(i);
53969829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
54069829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        ProfileLevel profileLevel;
54169829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        profileLevel.mProfile = src.mProfile;
54269829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        profileLevel.mLevel = src.mLevel;
54369829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        profileLevels->push(profileLevel);
54469829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    }
54569829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
54669829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    for (size_t i = 0; i < caps.mColorFormats.size(); ++i) {
54769829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        colorFormats->push(caps.mColorFormats.itemAt(i));
54869829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    }
54969829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
55069829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    return OK;
55169829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber}
55269829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
553afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}  // namespace android
554