MediaCodecList.cpp revision d74110cdef2becd4f7fd2334c34c3ca73f56b355
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) {
51d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar    parseTopLevelXMLFile("/etc/media_codecs.xml");
52d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar}
53afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
54d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnarvoid MediaCodecList::parseTopLevelXMLFile(const char *codecs_xml) {
55d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar    // get href_base
56d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar    char *href_base_end = strrchr(codecs_xml, '/');
57d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar    if (href_base_end != NULL) {
58d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar        mHrefBase = AString(codecs_xml, href_base_end - codecs_xml + 1);
59d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar    }
60d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar
61d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar    mInitCheck = OK;
62d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar    mCurrentSection = SECTION_TOPLEVEL;
63d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar    mDepth = 0;
64d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar
65d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar    parseXMLFile(codecs_xml);
66d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar
67d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar    if (mInitCheck != OK) {
68d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar        mCodecInfos.clear();
69d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar        mCodecQuirks.clear();
70afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return;
71afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
72afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
73d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar    // These are currently still used by the video editing suite.
74d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar    addMediaCodec(true /* encoder */, "AACEncoder", "audio/mp4a-latm");
75d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar    addMediaCodec(
76d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar            false /* encoder */, "OMX.google.raw.decoder", "audio/raw");
77afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
78d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar    for (size_t i = mCodecInfos.size(); i-- > 0;) {
79d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar        CodecInfo *info = &mCodecInfos.editItemAt(i);
80afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
81d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar        if (info->mTypes == 0) {
82d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar            // No types supported by this component???
83d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar            ALOGW("Component %s does not support any type of media?",
84d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar                  info->mName.c_str());
85ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber
86d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar            mCodecInfos.removeAt(i);
87d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar        }
88afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
89afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
90afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#if 0
91afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    for (size_t i = 0; i < mCodecInfos.size(); ++i) {
92afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        const CodecInfo &info = mCodecInfos.itemAt(i);
93afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
94afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        AString line = info.mName;
95afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        line.append(" supports ");
96afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        for (size_t j = 0; j < mTypes.size(); ++j) {
97afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            uint32_t value = mTypes.valueAt(j);
98afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
99afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (info.mTypes & (1ul << value)) {
100afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                line.append(mTypes.keyAt(j));
101afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                line.append(" ");
102afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
103afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
104afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
105afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        ALOGI("%s", line.c_str());
106afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
107afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#endif
108afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
109afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
110afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas HuberMediaCodecList::~MediaCodecList() {
111afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
112afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
113afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberstatus_t MediaCodecList::initCheck() const {
114afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return mInitCheck;
115afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
116afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
117d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnarvoid MediaCodecList::parseXMLFile(const char *path) {
118d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar    FILE *file = fopen(path, "r");
119d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar
120d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar    if (file == NULL) {
121d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar        ALOGW("unable to open media codecs configuration xml file: %s", path);
122d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar        mInitCheck = NAME_NOT_FOUND;
123d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar        return;
124d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar    }
125afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
126afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    XML_Parser parser = ::XML_ParserCreate(NULL);
127afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    CHECK(parser != NULL);
128afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
129afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    ::XML_SetUserData(parser, this);
130afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    ::XML_SetElementHandler(
131afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            parser, StartElementHandlerWrapper, EndElementHandlerWrapper);
132afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
133afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    const int BUFF_SIZE = 512;
134afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    while (mInitCheck == OK) {
135afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        void *buff = ::XML_GetBuffer(parser, BUFF_SIZE);
136afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (buff == NULL) {
137d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar            ALOGE("failed in call to XML_GetBuffer()");
138afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            mInitCheck = UNKNOWN_ERROR;
139afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
140afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
141afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
142afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        int bytes_read = ::fread(buff, 1, BUFF_SIZE, file);
143afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (bytes_read < 0) {
144afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            ALOGE("failed in call to read");
145afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            mInitCheck = ERROR_IO;
146afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
147afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
148afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
149d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar        XML_Status status = ::XML_ParseBuffer(parser, bytes_read, bytes_read == 0);
150d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar        if (status != XML_STATUS_OK) {
151d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar            ALOGE("malformed (%s)", ::XML_ErrorString(::XML_GetErrorCode(parser)));
152afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            mInitCheck = ERROR_MALFORMED;
153afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
154afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
155afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
156afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (bytes_read == 0) {
157afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
158afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
159afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
160afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
161afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    ::XML_ParserFree(parser);
162afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
163d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar    fclose(file);
164d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar    file = NULL;
165afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
166afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
167afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber// static
168afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubervoid MediaCodecList::StartElementHandlerWrapper(
169afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        void *me, const char *name, const char **attrs) {
170afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    static_cast<MediaCodecList *>(me)->startElementHandler(name, attrs);
171afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
172afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
173afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber// static
174afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubervoid MediaCodecList::EndElementHandlerWrapper(void *me, const char *name) {
175afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    static_cast<MediaCodecList *>(me)->endElementHandler(name);
176afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
177afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
178d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnarstatus_t MediaCodecList::includeXMLFile(const char **attrs) {
179d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar    const char *href = NULL;
180d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar    size_t i = 0;
181d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar    while (attrs[i] != NULL) {
182d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar        if (!strcmp(attrs[i], "href")) {
183d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar            if (attrs[i + 1] == NULL) {
184d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar                return -EINVAL;
185d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar            }
186d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar            href = attrs[i + 1];
187d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar            ++i;
188d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar        } else {
189d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar            return -EINVAL;
190d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar        }
191d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar        ++i;
192d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar    }
193d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar
194d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar    // For security reasons and for simplicity, file names can only contain
195d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar    // [a-zA-Z0-9_.] and must start with  media_codecs_ and end with .xml
196d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar    for (i = 0; href[i] != '\0'; i++) {
197d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar        if (href[i] == '.' || href[i] == '_' ||
198d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar                (href[i] >= '0' && href[i] <= '9') ||
199d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar                (href[i] >= 'A' && href[i] <= 'Z') ||
200d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar                (href[i] >= 'a' && href[i] <= 'z')) {
201d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar            continue;
202d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar        }
203d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar        ALOGE("invalid include file name: %s", href);
204d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar        return -EINVAL;
205d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar    }
206d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar
207d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar    AString filename = href;
208d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar    if (!filename.startsWith("media_codecs_") ||
209d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar        !filename.endsWith(".xml")) {
210d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar        ALOGE("invalid include file name: %s", href);
211d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar        return -EINVAL;
212d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar    }
213d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar    filename.insert(mHrefBase, 0);
214d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar
215d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar    parseXMLFile(filename.c_str());
216d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar    return mInitCheck;
217d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar}
218d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar
219afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubervoid MediaCodecList::startElementHandler(
220afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        const char *name, const char **attrs) {
221afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (mInitCheck != OK) {
222afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return;
223afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
224afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
225d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar    if (!strcmp(name, "Include")) {
226d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar        mInitCheck = includeXMLFile(attrs);
227d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar        if (mInitCheck == OK) {
228d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar            mPastSections.push(mCurrentSection);
229d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar            mCurrentSection = SECTION_INCLUDE;
230d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar        }
231d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar        ++mDepth;
232d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar        return;
233d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar    }
234d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar
235afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    switch (mCurrentSection) {
236afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        case SECTION_TOPLEVEL:
237afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        {
238afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (!strcmp(name, "Decoders")) {
239afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mCurrentSection = SECTION_DECODERS;
240afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            } else if (!strcmp(name, "Encoders")) {
241afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mCurrentSection = SECTION_ENCODERS;
242afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
243afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
244afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
245afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
246afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        case SECTION_DECODERS:
247afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        {
248afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (!strcmp(name, "MediaCodec")) {
249afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mInitCheck =
250afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    addMediaCodecFromAttributes(false /* encoder */, attrs);
251afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
252afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mCurrentSection = SECTION_DECODER;
253afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
254afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
255afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
256afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
257afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        case SECTION_ENCODERS:
258afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        {
259afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (!strcmp(name, "MediaCodec")) {
260afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mInitCheck =
261afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    addMediaCodecFromAttributes(true /* encoder */, attrs);
262afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
263afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mCurrentSection = SECTION_ENCODER;
264afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
265afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
266afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
267afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
268afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        case SECTION_DECODER:
269afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        case SECTION_ENCODER:
270afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        {
271afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (!strcmp(name, "Quirk")) {
272afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mInitCheck = addQuirk(attrs);
273afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            } else if (!strcmp(name, "Type")) {
274afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mInitCheck = addTypeFromAttributes(attrs);
275afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
276afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
277afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
278afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
279afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        default:
280afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
281afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
282afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
283afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    ++mDepth;
284afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
285afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
286afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubervoid MediaCodecList::endElementHandler(const char *name) {
287afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (mInitCheck != OK) {
288afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return;
289afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
290afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
291afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    switch (mCurrentSection) {
292afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        case SECTION_DECODERS:
293afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        {
294afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (!strcmp(name, "Decoders")) {
295afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mCurrentSection = SECTION_TOPLEVEL;
296afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
297afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
298afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
299afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
300afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        case SECTION_ENCODERS:
301afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        {
302afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (!strcmp(name, "Encoders")) {
303afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mCurrentSection = SECTION_TOPLEVEL;
304afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
305afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
306afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
307afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
308afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        case SECTION_DECODER:
309afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        {
310afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (!strcmp(name, "MediaCodec")) {
311afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mCurrentSection = SECTION_DECODERS;
312afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
313afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
314afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
315afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
316afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        case SECTION_ENCODER:
317afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        {
318afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (!strcmp(name, "MediaCodec")) {
319afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                mCurrentSection = SECTION_ENCODERS;
320afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
321afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
322afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
323afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
324d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar        case SECTION_INCLUDE:
325d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar        {
326d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar            if (!strcmp(name, "Include") && mPastSections.size() > 0) {
327d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar                mCurrentSection = mPastSections.top();
328d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar                mPastSections.pop();
329d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar            }
330d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar            break;
331d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar        }
332d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar
333afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        default:
334afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            break;
335afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
336afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
337afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    --mDepth;
338afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
339afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
340afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberstatus_t MediaCodecList::addMediaCodecFromAttributes(
341afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        bool encoder, const char **attrs) {
342afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    const char *name = NULL;
343afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    const char *type = NULL;
344afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
345afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    size_t i = 0;
346afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    while (attrs[i] != NULL) {
347afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (!strcmp(attrs[i], "name")) {
348afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (attrs[i + 1] == NULL) {
349afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                return -EINVAL;
350afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
351afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            name = attrs[i + 1];
352afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            ++i;
353afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        } else if (!strcmp(attrs[i], "type")) {
354afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (attrs[i + 1] == NULL) {
355afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                return -EINVAL;
356afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
357afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            type = attrs[i + 1];
358afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            ++i;
359afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        } else {
360afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            return -EINVAL;
361afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
362afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
363afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        ++i;
364afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
365afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
366afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (name == NULL) {
367afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return -EINVAL;
368afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
369afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
370afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    addMediaCodec(encoder, name, type);
371afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
372afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return OK;
373afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
374afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
375afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubervoid MediaCodecList::addMediaCodec(
376afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        bool encoder, const char *name, const char *type) {
377afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodecInfos.push();
378afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    CodecInfo *info = &mCodecInfos.editItemAt(mCodecInfos.size() - 1);
379afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    info->mName = name;
380afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    info->mIsEncoder = encoder;
381afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    info->mTypes = 0;
382afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    info->mQuirks = 0;
383afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
384afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (type != NULL) {
385afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        addType(type);
386afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
387afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
388afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
389afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberstatus_t MediaCodecList::addQuirk(const char **attrs) {
390afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    const char *name = NULL;
391afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
392afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    size_t i = 0;
393afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    while (attrs[i] != NULL) {
394afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (!strcmp(attrs[i], "name")) {
395afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (attrs[i + 1] == NULL) {
396afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                return -EINVAL;
397afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
398afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            name = attrs[i + 1];
399afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            ++i;
400afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        } else {
401afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            return -EINVAL;
402afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
403afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
404afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        ++i;
405afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
406afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
407afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (name == NULL) {
408afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return -EINVAL;
409afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
410afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
411afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    uint32_t bit;
412afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    ssize_t index = mCodecQuirks.indexOfKey(name);
413afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (index < 0) {
414afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        bit = mCodecQuirks.size();
415afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
416afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (bit == 32) {
417afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            ALOGW("Too many distinct quirk names in configuration.");
418afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            return OK;
419afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
420afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
421afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        mCodecQuirks.add(name, bit);
422afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    } else {
423afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        bit = mCodecQuirks.valueAt(index);
424afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
425afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
426afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    CodecInfo *info = &mCodecInfos.editItemAt(mCodecInfos.size() - 1);
427afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    info->mQuirks |= 1ul << bit;
428afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
429afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return OK;
430afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
431afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
432afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberstatus_t MediaCodecList::addTypeFromAttributes(const char **attrs) {
433afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    const char *name = NULL;
434afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
435afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    size_t i = 0;
436afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    while (attrs[i] != NULL) {
437afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (!strcmp(attrs[i], "name")) {
438afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (attrs[i + 1] == NULL) {
439afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                return -EINVAL;
440afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            }
441afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            name = attrs[i + 1];
442afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            ++i;
443afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        } else {
444afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            return -EINVAL;
445afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
446afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
447afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        ++i;
448afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
449afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
450afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (name == NULL) {
451afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return -EINVAL;
452afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
453afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
454afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    addType(name);
455afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
456afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return OK;
457afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
458afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
459afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubervoid MediaCodecList::addType(const char *name) {
460afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    uint32_t bit;
461afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    ssize_t index = mTypes.indexOfKey(name);
462afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (index < 0) {
463afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        bit = mTypes.size();
464afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
465afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (bit == 32) {
466afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            ALOGW("Too many distinct type names in configuration.");
467afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            return;
468afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
469afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
470afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        mTypes.add(name, bit);
471afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    } else {
472afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        bit = mTypes.valueAt(index);
473afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
474afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
475afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    CodecInfo *info = &mCodecInfos.editItemAt(mCodecInfos.size() - 1);
476afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    info->mTypes |= 1ul << bit;
477afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
478afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
479afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberssize_t MediaCodecList::findCodecByType(
480afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        const char *type, bool encoder, size_t startIndex) const {
481afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    ssize_t typeIndex = mTypes.indexOfKey(type);
482afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
483afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (typeIndex < 0) {
484afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return -ENOENT;
485afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
486afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
487afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    uint32_t typeMask = 1ul << mTypes.valueAt(typeIndex);
488afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
489afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    while (startIndex < mCodecInfos.size()) {
490afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        const CodecInfo &info = mCodecInfos.itemAt(startIndex);
491afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
492afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (info.mIsEncoder == encoder && (info.mTypes & typeMask)) {
493afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            return startIndex;
494afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
495afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
496afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        ++startIndex;
497afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
498afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
499afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return -ENOENT;
500afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
501afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
502afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberssize_t MediaCodecList::findCodecByName(const char *name) const {
503afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    for (size_t i = 0; i < mCodecInfos.size(); ++i) {
504afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        const CodecInfo &info = mCodecInfos.itemAt(i);
505afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
506afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (info.mName == name) {
507afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            return i;
508afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
509afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
510afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
511afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return -ENOENT;
512afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
513afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
51469829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Hubersize_t MediaCodecList::countCodecs() const {
51569829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    return mCodecInfos.size();
51669829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber}
51769829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
518afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberconst char *MediaCodecList::getCodecName(size_t index) const {
519afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (index >= mCodecInfos.size()) {
520afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return NULL;
521afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
522afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
523afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    const CodecInfo &info = mCodecInfos.itemAt(index);
524afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return info.mName.c_str();
525afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
526afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
52769829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huberbool MediaCodecList::isEncoder(size_t index) const {
52869829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    if (index >= mCodecInfos.size()) {
52969829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        return NULL;
53069829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    }
53169829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
53269829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    const CodecInfo &info = mCodecInfos.itemAt(index);
53369829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    return info.mIsEncoder;
53469829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber}
53569829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
536afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberbool MediaCodecList::codecHasQuirk(
537afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        size_t index, const char *quirkName) const {
538afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (index >= mCodecInfos.size()) {
539afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return NULL;
540afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
541afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
542afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    const CodecInfo &info = mCodecInfos.itemAt(index);
543afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
544afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (info.mQuirks != 0) {
545afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        ssize_t index = mCodecQuirks.indexOfKey(quirkName);
546afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (index >= 0 && info.mQuirks & (1ul << mCodecQuirks.valueAt(index))) {
547afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            return true;
548afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
549afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
550afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
551afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return false;
552afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
553afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
55469829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huberstatus_t MediaCodecList::getSupportedTypes(
55569829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        size_t index, Vector<AString> *types) const {
55669829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    types->clear();
55769829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
55869829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    if (index >= mCodecInfos.size()) {
55969829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        return -ERANGE;
56069829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    }
56169829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
56269829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    const CodecInfo &info = mCodecInfos.itemAt(index);
56369829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
56469829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    for (size_t i = 0; i < mTypes.size(); ++i) {
56569829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        uint32_t typeMask = 1ul << mTypes.valueAt(i);
56669829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
56769829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        if (info.mTypes & typeMask) {
56869829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber            types->push(mTypes.keyAt(i));
56969829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        }
57069829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    }
57169829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
57269829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    return OK;
57369829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber}
57469829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
57569829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huberstatus_t MediaCodecList::getCodecCapabilities(
57669829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        size_t index, const char *type,
57769829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        Vector<ProfileLevel> *profileLevels,
5782ee14000a38683220fb250d9e7300e1d71ccdaa0Lajos Molnar        Vector<uint32_t> *colorFormats,
5792ee14000a38683220fb250d9e7300e1d71ccdaa0Lajos Molnar        uint32_t *flags) const {
58069829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    profileLevels->clear();
58169829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    colorFormats->clear();
58269829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
58369829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    if (index >= mCodecInfos.size()) {
58469829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        return -ERANGE;
58569829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    }
58669829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
58769829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    const CodecInfo &info = mCodecInfos.itemAt(index);
58869829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
58969829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    OMXClient client;
59069829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    status_t err = client.connect();
59169829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    if (err != OK) {
59269829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        return err;
59369829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    }
59469829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
59569829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    CodecCapabilities caps;
59669829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    err = QueryCodec(
59769829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber            client.interface(),
59869829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber            info.mName.c_str(), type, info.mIsEncoder, &caps);
59969829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
60069829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    if (err != OK) {
60169829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        return err;
60269829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    }
60369829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
60469829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    for (size_t i = 0; i < caps.mProfileLevels.size(); ++i) {
60569829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        const CodecProfileLevel &src = caps.mProfileLevels.itemAt(i);
60669829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
60769829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        ProfileLevel profileLevel;
60869829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        profileLevel.mProfile = src.mProfile;
60969829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        profileLevel.mLevel = src.mLevel;
61069829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        profileLevels->push(profileLevel);
61169829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    }
61269829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
61369829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    for (size_t i = 0; i < caps.mColorFormats.size(); ++i) {
61469829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber        colorFormats->push(caps.mColorFormats.itemAt(i));
61569829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    }
61669829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
6172ee14000a38683220fb250d9e7300e1d71ccdaa0Lajos Molnar    *flags = caps.mFlags;
6182ee14000a38683220fb250d9e7300e1d71ccdaa0Lajos Molnar
61969829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber    return OK;
62069829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber}
62169829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber
622afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}  // namespace android
623