MediaCodecList.cpp revision afc16d667afa23f5aa00154ccad62f8c45cf5419
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");
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
448afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberconst char *MediaCodecList::getCodecName(size_t index) const {
449afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (index >= mCodecInfos.size()) {
450afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return NULL;
451afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
452afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
453afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    const CodecInfo &info = mCodecInfos.itemAt(index);
454afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return info.mName.c_str();
455afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
456afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
457afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberbool MediaCodecList::codecHasQuirk(
458afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        size_t index, const char *quirkName) const {
459afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (index >= mCodecInfos.size()) {
460afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return NULL;
461afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
462afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
463afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    const CodecInfo &info = mCodecInfos.itemAt(index);
464afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
465afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (info.mQuirks != 0) {
466afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        ssize_t index = mCodecQuirks.indexOfKey(quirkName);
467afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (index >= 0 && info.mQuirks & (1ul << mCodecQuirks.valueAt(index))) {
468afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            return true;
469afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
470afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
471afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
472afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return false;
473afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
474afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
475afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}  // namespace android
476