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