MediaCodecList.cpp revision ecdd39c5af016e2fa57cbfd837aa670b706dabd3
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>
25afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <utils/threads.h>
26afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
27afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <expat.h>
28afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
29afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubernamespace android {
30afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
31afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberstatic Mutex sInitMutex;
32afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
33afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber// static
34afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas HuberMediaCodecList *MediaCodecList::sCodecList;
35afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
36afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber// static
37afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberconst MediaCodecList *MediaCodecList::getInstance() {
38afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    Mutex::Autolock autoLock(sInitMutex);
39afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
40afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (sCodecList == NULL) {
41afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        sCodecList = new MediaCodecList;
42afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
43afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
44afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return sCodecList->initCheck() == OK ? sCodecList : NULL;
45afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
46afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
47afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas HuberMediaCodecList::MediaCodecList()
48afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mInitCheck(NO_INIT) {
49afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    FILE *file = fopen("/etc/media_codecs.xml", "r");
50afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
51afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (file == NULL) {
52afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        ALOGW("unable to open media codecs configuration xml file.");
53afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return;
54afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
55afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
56afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    parseXMLFile(file);
57afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
58afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (mInitCheck == OK) {
59afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        // These are currently still used by the video editing suite.
60afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
61afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        addMediaCodec(true /* encoder */, "AACEncoder", "audio/mp4a-latm");
62afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        addMediaCodec(true /* encoder */, "AVCEncoder", "video/avc");
63afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
64afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        addMediaCodec(true /* encoder */, "M4vH263Encoder");
65afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        addType("video/3gpp");
66afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        addType("video/mp4v-es");
67ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber
68ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        addMediaCodec(
69ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                false /* encoder */, "OMX.google.raw.decoder", "audio/raw");
70afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
71afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
72afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#if 0
73afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    for (size_t i = 0; i < mCodecInfos.size(); ++i) {
74afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        const CodecInfo &info = mCodecInfos.itemAt(i);
75afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
76afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        AString line = info.mName;
77afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        line.append(" supports ");
78afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        for (size_t j = 0; j < mTypes.size(); ++j) {
79afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            uint32_t value = mTypes.valueAt(j);
80afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
81afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (info.mTypes & (1ul << value)) {
82afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                line.append(mTypes.keyAt(j));
83afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                line.append(" ");
84afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
85afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
86afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
87afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        ALOGI("%s", line.c_str());
88afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
89afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#endif
90afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
91afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    fclose(file);
92afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    file = NULL;
93afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
94afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
95afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas HuberMediaCodecList::~MediaCodecList() {
96afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
97afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
98afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberstatus_t MediaCodecList::initCheck() const {
99afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return mInitCheck;
100afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
101afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
102afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubervoid MediaCodecList::parseXMLFile(FILE *file) {
103afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mInitCheck = OK;
104afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCurrentSection = SECTION_TOPLEVEL;
105afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mDepth = 0;
106afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
107afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    XML_Parser parser = ::XML_ParserCreate(NULL);
108afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    CHECK(parser != NULL);
109afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
110afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    ::XML_SetUserData(parser, this);
111afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    ::XML_SetElementHandler(
112afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            parser, StartElementHandlerWrapper, EndElementHandlerWrapper);
113afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
114afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    const int BUFF_SIZE = 512;
115afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    while (mInitCheck == OK) {
116afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        void *buff = ::XML_GetBuffer(parser, BUFF_SIZE);
117afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (buff == NULL) {
118afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            ALOGE("failed to in call to XML_GetBuffer()");
119afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            mInitCheck = UNKNOWN_ERROR;
120afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
121afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
122afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
123afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        int bytes_read = ::fread(buff, 1, BUFF_SIZE, file);
124afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (bytes_read < 0) {
125afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            ALOGE("failed in call to read");
126afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            mInitCheck = ERROR_IO;
127afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
128afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
129afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
130afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (::XML_ParseBuffer(parser, bytes_read, bytes_read == 0)
131afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                != XML_STATUS_OK) {
132afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            mInitCheck = ERROR_MALFORMED;
133afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
134afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
135afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
136afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (bytes_read == 0) {
137afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
138afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
139afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
140afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
141afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    ::XML_ParserFree(parser);
142afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
143afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (mInitCheck == OK) {
144afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        for (size_t i = mCodecInfos.size(); i-- > 0;) {
145afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            CodecInfo *info = &mCodecInfos.editItemAt(i);
146afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
147afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (info->mTypes == 0) {
148afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                // No types supported by this component???
149afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
150afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                ALOGW("Component %s does not support any type of media?",
151afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                      info->mName.c_str());
152afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
153afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mCodecInfos.removeAt(i);
154afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
155afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
156afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
157afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
158afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (mInitCheck != OK) {
159afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        mCodecInfos.clear();
160afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        mCodecQuirks.clear();
161afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
162afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
163afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
164afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber// static
165afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubervoid MediaCodecList::StartElementHandlerWrapper(
166afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        void *me, const char *name, const char **attrs) {
167afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    static_cast<MediaCodecList *>(me)->startElementHandler(name, attrs);
168afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
169afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
170afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber// static
171afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubervoid MediaCodecList::EndElementHandlerWrapper(void *me, const char *name) {
172afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    static_cast<MediaCodecList *>(me)->endElementHandler(name);
173afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
174afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
175afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubervoid MediaCodecList::startElementHandler(
176afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        const char *name, const char **attrs) {
177afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (mInitCheck != OK) {
178afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return;
179afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
180afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
181afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    switch (mCurrentSection) {
182afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        case SECTION_TOPLEVEL:
183afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        {
184afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (!strcmp(name, "Decoders")) {
185afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mCurrentSection = SECTION_DECODERS;
186afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            } else if (!strcmp(name, "Encoders")) {
187afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mCurrentSection = SECTION_ENCODERS;
188afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
189afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
190afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
191afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
192afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        case SECTION_DECODERS:
193afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        {
194afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (!strcmp(name, "MediaCodec")) {
195afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mInitCheck =
196afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    addMediaCodecFromAttributes(false /* encoder */, attrs);
197afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
198afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mCurrentSection = SECTION_DECODER;
199afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
200afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
201afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
202afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
203afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        case SECTION_ENCODERS:
204afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        {
205afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (!strcmp(name, "MediaCodec")) {
206afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mInitCheck =
207afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    addMediaCodecFromAttributes(true /* encoder */, attrs);
208afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
209afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mCurrentSection = SECTION_ENCODER;
210afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
211afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
212afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
213afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
214afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        case SECTION_DECODER:
215afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        case SECTION_ENCODER:
216afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        {
217afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (!strcmp(name, "Quirk")) {
218afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mInitCheck = addQuirk(attrs);
219afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            } else if (!strcmp(name, "Type")) {
220afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mInitCheck = addTypeFromAttributes(attrs);
221afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
222afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
223afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
224afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
225afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        default:
226afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
227afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
228afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
229afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    ++mDepth;
230afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
231afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
232afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubervoid MediaCodecList::endElementHandler(const char *name) {
233afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (mInitCheck != OK) {
234afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return;
235afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
236afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
237afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    switch (mCurrentSection) {
238afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        case SECTION_DECODERS:
239afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        {
240afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (!strcmp(name, "Decoders")) {
241afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mCurrentSection = SECTION_TOPLEVEL;
242afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
243afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
244afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
245afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
246afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        case SECTION_ENCODERS:
247afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        {
248afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (!strcmp(name, "Encoders")) {
249afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mCurrentSection = SECTION_TOPLEVEL;
250afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
251afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
252afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
253afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
254afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        case SECTION_DECODER:
255afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        {
256afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (!strcmp(name, "MediaCodec")) {
257afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mCurrentSection = SECTION_DECODERS;
258afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
259afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
260afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
261afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
262afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        case SECTION_ENCODER:
263afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        {
264afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (!strcmp(name, "MediaCodec")) {
265afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mCurrentSection = SECTION_ENCODERS;
266afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
267afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
268afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
269afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
270afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        default:
271afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
272afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
273afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
274afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    --mDepth;
275afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
276afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
277afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberstatus_t MediaCodecList::addMediaCodecFromAttributes(
278afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        bool encoder, const char **attrs) {
279afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    const char *name = NULL;
280afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    const char *type = NULL;
281afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
282afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    size_t i = 0;
283afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    while (attrs[i] != NULL) {
284afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (!strcmp(attrs[i], "name")) {
285afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (attrs[i + 1] == NULL) {
286afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                return -EINVAL;
287afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
288afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            name = attrs[i + 1];
289afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            ++i;
290afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        } else if (!strcmp(attrs[i], "type")) {
291afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (attrs[i + 1] == NULL) {
292afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                return -EINVAL;
293afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
294afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            type = attrs[i + 1];
295afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            ++i;
296afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        } else {
297afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            return -EINVAL;
298afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
299afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
300afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        ++i;
301afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
302afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
303afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (name == NULL) {
304afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return -EINVAL;
305afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
306afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
307afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    addMediaCodec(encoder, name, type);
308afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
309afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return OK;
310afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
311afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
312afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubervoid MediaCodecList::addMediaCodec(
313afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        bool encoder, const char *name, const char *type) {
314afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodecInfos.push();
315afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    CodecInfo *info = &mCodecInfos.editItemAt(mCodecInfos.size() - 1);
316afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    info->mName = name;
317afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    info->mIsEncoder = encoder;
318afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    info->mTypes = 0;
319afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    info->mQuirks = 0;
320afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
321afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (type != NULL) {
322afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        addType(type);
323afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
324afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
325afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
326afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberstatus_t MediaCodecList::addQuirk(const char **attrs) {
327afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    const char *name = NULL;
328afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
329afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    size_t i = 0;
330afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    while (attrs[i] != NULL) {
331afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (!strcmp(attrs[i], "name")) {
332afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (attrs[i + 1] == NULL) {
333afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                return -EINVAL;
334afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
335afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            name = attrs[i + 1];
336afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            ++i;
337afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        } else {
338afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            return -EINVAL;
339afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
340afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
341afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        ++i;
342afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
343afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
344afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (name == NULL) {
345afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return -EINVAL;
346afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
347afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
348afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    uint32_t bit;
349afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    ssize_t index = mCodecQuirks.indexOfKey(name);
350afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (index < 0) {
351afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        bit = mCodecQuirks.size();
352afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
353afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (bit == 32) {
354afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            ALOGW("Too many distinct quirk names in configuration.");
355afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            return OK;
356afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
357afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
358afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        mCodecQuirks.add(name, bit);
359afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    } else {
360afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        bit = mCodecQuirks.valueAt(index);
361afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
362afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
363afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    CodecInfo *info = &mCodecInfos.editItemAt(mCodecInfos.size() - 1);
364afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    info->mQuirks |= 1ul << bit;
365afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
366afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return OK;
367afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
368afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
369afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberstatus_t MediaCodecList::addTypeFromAttributes(const char **attrs) {
370afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    const char *name = NULL;
371afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
372afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    size_t i = 0;
373afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    while (attrs[i] != NULL) {
374afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (!strcmp(attrs[i], "name")) {
375afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (attrs[i + 1] == NULL) {
376afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                return -EINVAL;
377afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
378afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            name = attrs[i + 1];
379afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            ++i;
380afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        } else {
381afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            return -EINVAL;
382afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
383afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
384afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        ++i;
385afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
386afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
387afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (name == NULL) {
388afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return -EINVAL;
389afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
390afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
391afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    addType(name);
392afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
393afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return OK;
394afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
395afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
396afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubervoid MediaCodecList::addType(const char *name) {
397afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    uint32_t bit;
398afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    ssize_t index = mTypes.indexOfKey(name);
399afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (index < 0) {
400afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        bit = mTypes.size();
401afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
402afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (bit == 32) {
403afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            ALOGW("Too many distinct type names in configuration.");
404afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            return;
405afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
406afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
407afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        mTypes.add(name, bit);
408afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    } else {
409afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        bit = mTypes.valueAt(index);
410afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
411afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
412afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    CodecInfo *info = &mCodecInfos.editItemAt(mCodecInfos.size() - 1);
413afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    info->mTypes |= 1ul << bit;
414afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
415afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
416afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberssize_t MediaCodecList::findCodecByType(
417afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        const char *type, bool encoder, size_t startIndex) const {
418afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    ssize_t typeIndex = mTypes.indexOfKey(type);
419afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
420afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (typeIndex < 0) {
421afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return -ENOENT;
422afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
423afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
424afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    uint32_t typeMask = 1ul << mTypes.valueAt(typeIndex);
425afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
426afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    while (startIndex < mCodecInfos.size()) {
427afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        const CodecInfo &info = mCodecInfos.itemAt(startIndex);
428afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
429afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (info.mIsEncoder == encoder && (info.mTypes & typeMask)) {
430afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            return startIndex;
431afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
432afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
433afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        ++startIndex;
434afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
435afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
436afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return -ENOENT;
437afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
438afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
439afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberssize_t MediaCodecList::findCodecByName(const char *name) const {
440afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    for (size_t i = 0; i < mCodecInfos.size(); ++i) {
441afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        const CodecInfo &info = mCodecInfos.itemAt(i);
442afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
443afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (info.mName == name) {
444afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            return i;
445afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
446afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
447afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
448afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return -ENOENT;
449afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
450afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
451afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberconst char *MediaCodecList::getCodecName(size_t index) const {
452afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (index >= mCodecInfos.size()) {
453afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return NULL;
454afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
455afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
456afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    const CodecInfo &info = mCodecInfos.itemAt(index);
457afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return info.mName.c_str();
458afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
459afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
460afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberbool MediaCodecList::codecHasQuirk(
461afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        size_t index, const char *quirkName) const {
462afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (index >= mCodecInfos.size()) {
463afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return NULL;
464afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
465afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
466afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    const CodecInfo &info = mCodecInfos.itemAt(index);
467afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
468afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (info.mQuirks != 0) {
469afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        ssize_t index = mCodecQuirks.indexOfKey(quirkName);
470afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (index >= 0 && info.mQuirks & (1ul << mCodecQuirks.valueAt(index))) {
471afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            return true;
472afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
473afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
474afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
475afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return false;
476afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
477afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
478afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}  // namespace android
479