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