MediaCodecList.cpp revision 60b1c0e79d12a1c70758bc8d060156924635f8ba
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 2160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar#include <binder/IServiceManager.h> 2260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar 2360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar#include <media/IMediaCodecList.h> 2460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar#include <media/IMediaPlayerService.h> 2560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar#include <media/MediaCodecInfo.h> 26afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 27afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/foundation/ADebug.h> 28513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar#include <media/stagefright/foundation/AMessage.h> 2960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar#include <media/stagefright/MediaCodecList.h> 30afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/MediaErrors.h> 3169829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber#include <media/stagefright/OMXClient.h> 3269829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber#include <media/stagefright/OMXCodec.h> 3360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar 34afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <utils/threads.h> 35afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 36e8057dd8208f0a185109992339a995c518b12780Elliott Hughes#include <libexpat/expat.h> 37afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 38afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubernamespace android { 39afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 40afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberstatic Mutex sInitMutex; 41afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 4260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnarstatic MediaCodecList *gCodecList = NULL; 4360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar 44afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber// static 4560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnarsp<IMediaCodecList> MediaCodecList::sCodecList; 46afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 47afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber// static 4860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnarsp<IMediaCodecList> MediaCodecList::getLocalInstance() { 49afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber Mutex::Autolock autoLock(sInitMutex); 50afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 5160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar if (gCodecList == NULL) { 5260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar gCodecList = new MediaCodecList; 5360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar if (gCodecList->initCheck() == OK) { 5460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar sCodecList = gCodecList; 5560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar } 56afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 57afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 5860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar return sCodecList; 5960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar} 6060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar 6160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnarstatic Mutex sRemoteInitMutex; 6260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar 6360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnarsp<IMediaCodecList> MediaCodecList::sRemoteList; 6460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar 6560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar// static 6660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnarsp<IMediaCodecList> MediaCodecList::getInstance() { 6760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar return getLocalInstance(); 68afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber} 69afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 70afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas HuberMediaCodecList::MediaCodecList() 71afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber : mInitCheck(NO_INIT) { 72d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar parseTopLevelXMLFile("/etc/media_codecs.xml"); 73d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar} 74afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 75d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnarvoid MediaCodecList::parseTopLevelXMLFile(const char *codecs_xml) { 76d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar // get href_base 77d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar char *href_base_end = strrchr(codecs_xml, '/'); 78d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar if (href_base_end != NULL) { 79d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar mHrefBase = AString(codecs_xml, href_base_end - codecs_xml + 1); 80d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar } 81d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar 8260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mInitCheck = OK; // keeping this here for safety 83d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar mCurrentSection = SECTION_TOPLEVEL; 84d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar mDepth = 0; 85d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar 8660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar OMXClient client; 8760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mInitCheck = client.connect(); 8860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar if (mInitCheck != OK) { 8960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar return; 9060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar } 9160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mOMX = client.interface(); 92d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar parseXMLFile(codecs_xml); 9360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mOMX.clear(); 94d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar 95d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar if (mInitCheck != OK) { 96d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar mCodecInfos.clear(); 97afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return; 98afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 99afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 100d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar for (size_t i = mCodecInfos.size(); i-- > 0;) { 10160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar const MediaCodecInfo &info = *mCodecInfos.itemAt(i).get(); 102afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 10360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar if (info.mCaps.size() == 0) { 104d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar // No types supported by this component??? 105d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar ALOGW("Component %s does not support any type of media?", 10660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar info.mName.c_str()); 107ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber 108d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar mCodecInfos.removeAt(i); 109513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar#if LOG_NDEBUG == 0 110513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else { 11160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar for (size_t type_ix = 0; type_ix < info.mCaps.size(); ++type_ix) { 11260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar AString mime = info.mCaps.keyAt(type_ix); 11360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar const sp<MediaCodecInfo::Capabilities> &caps = info.mCaps.valueAt(type_ix); 11460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar 11560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar ALOGV("%s codec info for %s: %s", info.mName.c_str(), mime.c_str(), 11660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar caps->getDetails()->debugString().c_str()); 11760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar ALOGV(" flags=%d", caps->getFlags()); 11860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar { 11960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar Vector<uint32_t> colorFormats; 12060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar caps->getSupportedColorFormats(&colorFormats); 12160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar AString nice; 12260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar for (size_t ix = 0; ix < colorFormats.size(); ix++) { 12360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar if (ix > 0) { 12460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar nice.append(", "); 12560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar } 12660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar nice.append(colorFormats.itemAt(ix)); 12760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar } 12860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar ALOGV(" colors=[%s]", nice.c_str()); 12960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar } 13060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar { 13160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar Vector<MediaCodecInfo::ProfileLevel> profileLevels; 13260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar caps->getSupportedProfileLevels(&profileLevels); 13360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar AString nice; 13460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar for (size_t ix = 0; ix < profileLevels.size(); ix++) { 13560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar if (ix > 0) { 13660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar nice.append(", "); 13760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar } 13860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar const MediaCodecInfo::ProfileLevel &pl = 13960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar profileLevels.itemAt(ix); 14060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar nice.append(pl.mProfile); 14160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar nice.append("/"); 14260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar nice.append(pl.mLevel); 14360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar } 14460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar ALOGV(" levels=[%s]", nice.c_str()); 145513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 146513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 147513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar#endif 148d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar } 149afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 150afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 151afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#if 0 152afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber for (size_t i = 0; i < mCodecInfos.size(); ++i) { 153afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber const CodecInfo &info = mCodecInfos.itemAt(i); 154afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 155afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber AString line = info.mName; 156afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber line.append(" supports "); 157afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber for (size_t j = 0; j < mTypes.size(); ++j) { 158afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber uint32_t value = mTypes.valueAt(j); 159afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 160afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (info.mTypes & (1ul << value)) { 161afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber line.append(mTypes.keyAt(j)); 162afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber line.append(" "); 163afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 164afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 165afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 166afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber ALOGI("%s", line.c_str()); 167afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 168afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#endif 169afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber} 170afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 171afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas HuberMediaCodecList::~MediaCodecList() { 172afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber} 173afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 174afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberstatus_t MediaCodecList::initCheck() const { 175afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return mInitCheck; 176afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber} 177afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 178d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnarvoid MediaCodecList::parseXMLFile(const char *path) { 179d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar FILE *file = fopen(path, "r"); 180d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar 181d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar if (file == NULL) { 182d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar ALOGW("unable to open media codecs configuration xml file: %s", path); 183d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar mInitCheck = NAME_NOT_FOUND; 184d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar return; 185d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar } 186afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 187afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber XML_Parser parser = ::XML_ParserCreate(NULL); 188afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber CHECK(parser != NULL); 189afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 190afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber ::XML_SetUserData(parser, this); 191afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber ::XML_SetElementHandler( 192afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber parser, StartElementHandlerWrapper, EndElementHandlerWrapper); 193afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 194afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber const int BUFF_SIZE = 512; 195afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber while (mInitCheck == OK) { 196afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber void *buff = ::XML_GetBuffer(parser, BUFF_SIZE); 197afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (buff == NULL) { 198d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar ALOGE("failed in call to XML_GetBuffer()"); 199afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber mInitCheck = UNKNOWN_ERROR; 200afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber break; 201afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 202afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 203afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber int bytes_read = ::fread(buff, 1, BUFF_SIZE, file); 204afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (bytes_read < 0) { 205afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber ALOGE("failed in call to read"); 206afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber mInitCheck = ERROR_IO; 207afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber break; 208afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 209afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 210d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar XML_Status status = ::XML_ParseBuffer(parser, bytes_read, bytes_read == 0); 211d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar if (status != XML_STATUS_OK) { 212d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar ALOGE("malformed (%s)", ::XML_ErrorString(::XML_GetErrorCode(parser))); 213afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber mInitCheck = ERROR_MALFORMED; 214afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber break; 215afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 216afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 217afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (bytes_read == 0) { 218afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber break; 219afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 220afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 221afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 222afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber ::XML_ParserFree(parser); 223afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 224d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar fclose(file); 225d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar file = NULL; 226afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber} 227afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 228afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber// static 229afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubervoid MediaCodecList::StartElementHandlerWrapper( 230afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber void *me, const char *name, const char **attrs) { 231afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber static_cast<MediaCodecList *>(me)->startElementHandler(name, attrs); 232afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber} 233afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 234afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber// static 235afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubervoid MediaCodecList::EndElementHandlerWrapper(void *me, const char *name) { 236afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber static_cast<MediaCodecList *>(me)->endElementHandler(name); 237afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber} 238afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 239d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnarstatus_t MediaCodecList::includeXMLFile(const char **attrs) { 240d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar const char *href = NULL; 241d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar size_t i = 0; 242d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar while (attrs[i] != NULL) { 243d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar if (!strcmp(attrs[i], "href")) { 244d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar if (attrs[i + 1] == NULL) { 245d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar return -EINVAL; 246d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar } 247d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar href = attrs[i + 1]; 248d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar ++i; 249d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar } else { 250d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar return -EINVAL; 251d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar } 252d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar ++i; 253d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar } 254d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar 255d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar // For security reasons and for simplicity, file names can only contain 256d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar // [a-zA-Z0-9_.] and must start with media_codecs_ and end with .xml 257d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar for (i = 0; href[i] != '\0'; i++) { 258d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar if (href[i] == '.' || href[i] == '_' || 259d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar (href[i] >= '0' && href[i] <= '9') || 260d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar (href[i] >= 'A' && href[i] <= 'Z') || 261d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar (href[i] >= 'a' && href[i] <= 'z')) { 262d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar continue; 263d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar } 264d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar ALOGE("invalid include file name: %s", href); 265d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar return -EINVAL; 266d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar } 267d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar 268d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar AString filename = href; 269d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar if (!filename.startsWith("media_codecs_") || 270d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar !filename.endsWith(".xml")) { 271d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar ALOGE("invalid include file name: %s", href); 272d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar return -EINVAL; 273d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar } 274d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar filename.insert(mHrefBase, 0); 275d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar 276d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar parseXMLFile(filename.c_str()); 277d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar return mInitCheck; 278d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar} 279d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar 280afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubervoid MediaCodecList::startElementHandler( 281afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber const char *name, const char **attrs) { 282afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (mInitCheck != OK) { 283afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return; 284afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 285afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 286513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar bool inType = true; 287513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 288d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar if (!strcmp(name, "Include")) { 289d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar mInitCheck = includeXMLFile(attrs); 290d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar if (mInitCheck == OK) { 291d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar mPastSections.push(mCurrentSection); 292d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar mCurrentSection = SECTION_INCLUDE; 293d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar } 294d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar ++mDepth; 295d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar return; 296d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar } 297d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar 298afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber switch (mCurrentSection) { 299afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber case SECTION_TOPLEVEL: 300afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber { 301afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (!strcmp(name, "Decoders")) { 302afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber mCurrentSection = SECTION_DECODERS; 303afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } else if (!strcmp(name, "Encoders")) { 304afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber mCurrentSection = SECTION_ENCODERS; 305afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 306afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber break; 307afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 308afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 309afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber case SECTION_DECODERS: 310afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber { 311afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (!strcmp(name, "MediaCodec")) { 312afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber mInitCheck = 313afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber addMediaCodecFromAttributes(false /* encoder */, attrs); 314afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 315afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber mCurrentSection = SECTION_DECODER; 316afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 317afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber break; 318afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 319afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 320afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber case SECTION_ENCODERS: 321afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber { 322afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (!strcmp(name, "MediaCodec")) { 323afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber mInitCheck = 324afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber addMediaCodecFromAttributes(true /* encoder */, attrs); 325afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 326afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber mCurrentSection = SECTION_ENCODER; 327afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 328afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber break; 329afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 330afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 331afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber case SECTION_DECODER: 332afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber case SECTION_ENCODER: 333afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber { 334afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (!strcmp(name, "Quirk")) { 335afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber mInitCheck = addQuirk(attrs); 336afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } else if (!strcmp(name, "Type")) { 337afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber mInitCheck = addTypeFromAttributes(attrs); 338513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar mCurrentSection = 339513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar (mCurrentSection == SECTION_DECODER 340513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar ? SECTION_DECODER_TYPE : SECTION_ENCODER_TYPE); 341513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 342513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 343513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar inType = false; 344513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar // fall through 345513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 346513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar case SECTION_DECODER_TYPE: 347513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar case SECTION_ENCODER_TYPE: 348513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar { 349513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar // ignore limits and features specified outside of type 35060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar bool outside = !inType && !mCurrentInfo->mHasSoleMime; 351513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (outside && (!strcmp(name, "Limit") || !strcmp(name, "Feature"))) { 352513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar ALOGW("ignoring %s specified outside of a Type", name); 353513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else if (!strcmp(name, "Limit")) { 354513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar mInitCheck = addLimit(attrs); 355513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else if (!strcmp(name, "Feature")) { 356513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar mInitCheck = addFeature(attrs); 357afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 358afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber break; 359afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 360afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 361afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber default: 362afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber break; 363afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 364afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 365afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber ++mDepth; 366afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber} 367afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 368afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubervoid MediaCodecList::endElementHandler(const char *name) { 369afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (mInitCheck != OK) { 370afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return; 371afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 372afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 373afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber switch (mCurrentSection) { 374afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber case SECTION_DECODERS: 375afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber { 376afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (!strcmp(name, "Decoders")) { 377afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber mCurrentSection = SECTION_TOPLEVEL; 378afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 379afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber break; 380afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 381afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 382afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber case SECTION_ENCODERS: 383afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber { 384afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (!strcmp(name, "Encoders")) { 385afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber mCurrentSection = SECTION_TOPLEVEL; 386afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 387afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber break; 388afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 389afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 390513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar case SECTION_DECODER_TYPE: 391513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar case SECTION_ENCODER_TYPE: 392513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar { 393513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (!strcmp(name, "Type")) { 394513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar mCurrentSection = 395513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar (mCurrentSection == SECTION_DECODER_TYPE 396513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar ? SECTION_DECODER : SECTION_ENCODER); 397513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 39860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mCurrentInfo->complete(); 399513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 400513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar break; 401513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 402513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 403afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber case SECTION_DECODER: 404afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber { 405afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (!strcmp(name, "MediaCodec")) { 406afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber mCurrentSection = SECTION_DECODERS; 40760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mCurrentInfo->complete(); 40860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mCurrentInfo = NULL; 409afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 410afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber break; 411afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 412afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 413afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber case SECTION_ENCODER: 414afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber { 415afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (!strcmp(name, "MediaCodec")) { 416afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber mCurrentSection = SECTION_ENCODERS; 41760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mCurrentInfo->complete();; 41860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mCurrentInfo = NULL; 419afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 420afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber break; 421afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 422afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 423d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar case SECTION_INCLUDE: 424d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar { 425d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar if (!strcmp(name, "Include") && mPastSections.size() > 0) { 426d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar mCurrentSection = mPastSections.top(); 427d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar mPastSections.pop(); 428d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar } 429d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar break; 430d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar } 431d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar 432afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber default: 433afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber break; 434afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 435afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 436afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber --mDepth; 437afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber} 438afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 439afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberstatus_t MediaCodecList::addMediaCodecFromAttributes( 440afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber bool encoder, const char **attrs) { 441afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber const char *name = NULL; 442afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber const char *type = NULL; 443afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 444afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber size_t i = 0; 445afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber while (attrs[i] != NULL) { 446afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (!strcmp(attrs[i], "name")) { 447afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (attrs[i + 1] == NULL) { 448afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return -EINVAL; 449afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 450afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber name = attrs[i + 1]; 451afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber ++i; 452afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } else if (!strcmp(attrs[i], "type")) { 453afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (attrs[i + 1] == NULL) { 454afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return -EINVAL; 455afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 456afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber type = attrs[i + 1]; 457afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber ++i; 458afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } else { 459afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return -EINVAL; 460afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 461afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 462afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber ++i; 463afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 464afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 465afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (name == NULL) { 466afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return -EINVAL; 467afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 468afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 46960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mCurrentInfo = new MediaCodecInfo(name, encoder, type); 47060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mCodecInfos.push_back(mCurrentInfo); 47160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar return initializeCapabilities(type); 472afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber} 473afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 47460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnarstatus_t MediaCodecList::initializeCapabilities(const char *type) { 47560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar ALOGV("initializeCapabilities %s:%s", 47660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mCurrentInfo->mName.c_str(), type); 47760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar 47860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar CodecCapabilities caps; 47960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar status_t err = QueryCodec( 48060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mOMX, 48160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mCurrentInfo->mName.c_str(), 48260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar type, 48360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mCurrentInfo->mIsEncoder, 48460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar &caps); 48560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar if (err != OK) { 48660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar return err; 487afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 48860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar 48960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar return mCurrentInfo->initializeCapabilities(caps); 490afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber} 491afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 492afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberstatus_t MediaCodecList::addQuirk(const char **attrs) { 493afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber const char *name = NULL; 494afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 495afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber size_t i = 0; 496afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber while (attrs[i] != NULL) { 497afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (!strcmp(attrs[i], "name")) { 498afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (attrs[i + 1] == NULL) { 499afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return -EINVAL; 500afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 501afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber name = attrs[i + 1]; 502afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber ++i; 503afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } else { 504afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return -EINVAL; 505afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 506afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 507afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber ++i; 508afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 509afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 510afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (name == NULL) { 511afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return -EINVAL; 512afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 513afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 51460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mCurrentInfo->addQuirk(name); 515afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return OK; 516afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber} 517afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 518afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberstatus_t MediaCodecList::addTypeFromAttributes(const char **attrs) { 519afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber const char *name = NULL; 520afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 521afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber size_t i = 0; 522afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber while (attrs[i] != NULL) { 523afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (!strcmp(attrs[i], "name")) { 524afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (attrs[i + 1] == NULL) { 525afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return -EINVAL; 526afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 527afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber name = attrs[i + 1]; 528afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber ++i; 529afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } else { 530afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return -EINVAL; 531afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 532afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 533afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber ++i; 534afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 535afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 536afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (name == NULL) { 537afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return -EINVAL; 538afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 539afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 54060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar status_t ret = mCurrentInfo->addMime(name); 54160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar if (ret == OK) { 54260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar ret = initializeCapabilities(name); 543513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 54460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar return ret; 545afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber} 546afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 54760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar// legacy method for non-advanced codecs 548afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberssize_t MediaCodecList::findCodecByType( 549afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber const char *type, bool encoder, size_t startIndex) const { 55060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar static const char *advancedFeatures[] = { 55160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar "feature-secure-playback", 55260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar "feature-tunneled-playback", 55360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar }; 554afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 55560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar size_t numCodecs = mCodecInfos.size(); 55660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar for (; startIndex < numCodecs; ++startIndex) { 55760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar const MediaCodecInfo &info = *mCodecInfos.itemAt(startIndex).get(); 558afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 55960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar if (info.isEncoder() != encoder) { 56060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar continue; 56160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar } 56260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar sp<MediaCodecInfo::Capabilities> capabilities = info.getCapabilitiesFor(type); 56360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar if (capabilities == NULL) { 56460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar continue; 56560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar } 56660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar const sp<AMessage> &details = capabilities->getDetails(); 567afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 56860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar int32_t required; 56960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar bool isAdvanced = false; 57060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar for (size_t ix = 0; ix < ARRAY_SIZE(advancedFeatures); ix++) { 57160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar if (details->findInt32(advancedFeatures[ix], &required) && 57260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar required != 0) { 57360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar isAdvanced = true; 57460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar break; 57560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar } 57660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar } 577afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 57860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar if (!isAdvanced) { 579afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return startIndex; 580afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 581afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 582afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 583afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return -ENOENT; 584afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber} 585afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 586513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnarstatic status_t limitFoundMissingAttr(AString name, const char *attr, bool found = true) { 587513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar ALOGE("limit '%s' with %s'%s' attribute", name.c_str(), 588513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar (found ? "" : "no "), attr); 589513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return -EINVAL; 590513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar} 591513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 592513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnarstatic status_t limitError(AString name, const char *msg) { 593513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar ALOGE("limit '%s' %s", name.c_str(), msg); 594513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return -EINVAL; 595513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar} 596513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 597513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnarstatic status_t limitInvalidAttr(AString name, const char *attr, AString value) { 598513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar ALOGE("limit '%s' with invalid '%s' attribute (%s)", name.c_str(), 599513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar attr, value.c_str()); 600513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return -EINVAL; 601513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar} 602513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 603513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnarstatus_t MediaCodecList::addLimit(const char **attrs) { 604513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar sp<AMessage> msg = new AMessage(); 605513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 606513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar size_t i = 0; 607513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar while (attrs[i] != NULL) { 608513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (attrs[i + 1] == NULL) { 609513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return -EINVAL; 610513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 611513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 612513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar // attributes with values 613513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (!strcmp(attrs[i], "name") 614513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar || !strcmp(attrs[i], "default") 615513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar || !strcmp(attrs[i], "in") 616513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar || !strcmp(attrs[i], "max") 617513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar || !strcmp(attrs[i], "min") 618513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar || !strcmp(attrs[i], "range") 619513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar || !strcmp(attrs[i], "ranges") 620513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar || !strcmp(attrs[i], "scale") 621513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar || !strcmp(attrs[i], "value")) { 622513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar msg->setString(attrs[i], attrs[i + 1]); 623513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar ++i; 624513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else { 625513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return -EINVAL; 626513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 627513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar ++i; 628513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 629513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 630513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar AString name; 631513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (!msg->findString("name", &name)) { 632513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar ALOGE("limit with no 'name' attribute"); 633513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return -EINVAL; 634513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 635513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 636513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar // size, blocks, bitrate, frame-rate, blocks-per-second, aspect-ratio: range 637513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar // quality: range + default + [scale] 638513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar // complexity: range + default 639513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar bool found; 64060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar 641513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (name == "aspect-ratio" || name == "bitrate" || name == "block-count" 642513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar || name == "blocks-per-second" || name == "complexity" 643513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar || name == "frame-rate" || name == "quality" || name == "size") { 644513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar AString min, max; 645513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (msg->findString("min", &min) && msg->findString("max", &max)) { 646513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar min.append("-"); 647513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar min.append(max); 648513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (msg->contains("range") || msg->contains("value")) { 649513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return limitError(name, "has 'min' and 'max' as well as 'range' or " 650513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar "'value' attributes"); 651513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 652513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar msg->setString("range", min); 653513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else if (msg->contains("min") || msg->contains("max")) { 654513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return limitError(name, "has only 'min' or 'max' attribute"); 655513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else if (msg->findString("value", &max)) { 656513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar min = max; 657513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar min.append("-"); 658513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar min.append(max); 659513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (msg->contains("range")) { 660513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return limitError(name, "has both 'range' and 'value' attributes"); 661513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 662513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar msg->setString("range", min); 663513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 664513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 665513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar AString range, scale = "linear", def, in_; 666513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (!msg->findString("range", &range)) { 667513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return limitError(name, "with no 'range', 'value' or 'min'/'max' attributes"); 668513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 669513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 670513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if ((name == "quality" || name == "complexity") ^ 671513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar (found = msg->findString("default", &def))) { 672513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return limitFoundMissingAttr(name, "default", found); 673513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 674513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (name != "quality" && msg->findString("scale", &scale)) { 675513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return limitFoundMissingAttr(name, "scale"); 676513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 677513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if ((name == "aspect-ratio") ^ (found = msg->findString("in", &in_))) { 678513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return limitFoundMissingAttr(name, "in", found); 679513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 680513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 681513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (name == "aspect-ratio") { 682513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (!(in_ == "pixels") && !(in_ == "blocks")) { 683513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return limitInvalidAttr(name, "in", in_); 684513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 685513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar in_.erase(5, 1); // (pixel|block)-aspect-ratio 686513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar in_.append("-"); 687513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar in_.append(name); 688513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar name = in_; 689513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 690513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (name == "quality") { 69160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mCurrentInfo->addDetail("quality-scale", scale); 692513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 693513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (name == "quality" || name == "complexity") { 694513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar AString tag = name; 695513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar tag.append("-default"); 69660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mCurrentInfo->addDetail(tag, def); 697513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 698513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar AString tag = name; 699513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar tag.append("-range"); 70060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mCurrentInfo->addDetail(tag, range); 701513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else { 702513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar AString max, value, ranges; 703513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (msg->contains("default")) { 704513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return limitFoundMissingAttr(name, "default"); 705513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else if (msg->contains("in")) { 706513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return limitFoundMissingAttr(name, "in"); 707513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else if ((name == "channel-count") ^ 708513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar (found = msg->findString("max", &max))) { 709513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return limitFoundMissingAttr(name, "max", found); 710513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else if (msg->contains("min")) { 711513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return limitFoundMissingAttr(name, "min"); 712513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else if (msg->contains("range")) { 713513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return limitFoundMissingAttr(name, "range"); 714513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else if ((name == "sample-rate") ^ 715513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar (found = msg->findString("ranges", &ranges))) { 716513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return limitFoundMissingAttr(name, "ranges", found); 717513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else if (msg->contains("scale")) { 718513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return limitFoundMissingAttr(name, "scale"); 719513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else if ((name == "alignment" || name == "block-size") ^ 720513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar (found = msg->findString("value", &value))) { 721513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return limitFoundMissingAttr(name, "value", found); 722513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 723513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 724513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (max.size()) { 725513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar AString tag = "max-"; 726513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar tag.append(name); 72760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mCurrentInfo->addDetail(tag, max); 728513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else if (value.size()) { 72960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mCurrentInfo->addDetail(name, value); 730513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else if (ranges.size()) { 731513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar AString tag = name; 732513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar tag.append("-ranges"); 73360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mCurrentInfo->addDetail(tag, ranges); 734513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else { 735513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar ALOGW("Ignoring unrecognized limit '%s'", name.c_str()); 736513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 737513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 738513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return OK; 739513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar} 740513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 741513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnarstatic bool parseBoolean(const char *s) { 742513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (!strcasecmp(s, "true") || !strcasecmp(s, "yes") || !strcasecmp(s, "y")) { 743513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return true; 744513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 745513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar char *end; 746513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar unsigned long res = strtoul(s, &end, 10); 747513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return *s != '\0' && *end == '\0' && res > 0; 748513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar} 749513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 750513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnarstatus_t MediaCodecList::addFeature(const char **attrs) { 751513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar size_t i = 0; 752513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar const char *name = NULL; 753513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar int32_t optional = -1; 754513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar int32_t required = -1; 755513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 756513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar while (attrs[i] != NULL) { 757513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (attrs[i + 1] == NULL) { 758513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return -EINVAL; 759513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 760513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 761513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar // attributes with values 762513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (!strcmp(attrs[i], "name")) { 763513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar name = attrs[i + 1]; 764513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar ++i; 765513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else if (!strcmp(attrs[i], "optional") || !strcmp(attrs[i], "required")) { 766513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar int value = (int)parseBoolean(attrs[i + 1]); 767513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (!strcmp(attrs[i], "optional")) { 768513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar optional = value; 769513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else { 770513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar required = value; 771513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 772513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar ++i; 773513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else { 774513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return -EINVAL; 775513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 776513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar ++i; 777513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 778513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (name == NULL) { 779513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar ALOGE("feature with no 'name' attribute"); 780513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return -EINVAL; 781513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 782513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 783513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (optional == required && optional != -1) { 784513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar ALOGE("feature '%s' is both/neither optional and required", name); 785513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return -EINVAL; 786513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 787513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 78860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mCurrentInfo->addFeature(name, (required == 1) || (optional == 0)); 789513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return OK; 790513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar} 791513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 792afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberssize_t MediaCodecList::findCodecByName(const char *name) const { 793afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber for (size_t i = 0; i < mCodecInfos.size(); ++i) { 79460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar const MediaCodecInfo &info = *mCodecInfos.itemAt(i).get(); 795afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 796afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (info.mName == name) { 797afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return i; 798afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 799afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 800afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 801afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return -ENOENT; 802afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber} 803afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 80469829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Hubersize_t MediaCodecList::countCodecs() const { 80569829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber return mCodecInfos.size(); 80669829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber} 80769829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber 808afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber} // namespace android 809