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 65eee82e44548f17253c2e06b25725f91c7b549ec2Lajos Molnarsp<MediaCodecList::BinderDeathObserver> MediaCodecList::sBinderDeathObserver; 66eee82e44548f17253c2e06b25725f91c7b549ec2Lajos Molnar 67eee82e44548f17253c2e06b25725f91c7b549ec2Lajos Molnarvoid MediaCodecList::BinderDeathObserver::binderDied(const wp<IBinder> &who __unused) { 68eee82e44548f17253c2e06b25725f91c7b549ec2Lajos Molnar Mutex::Autolock _l(sRemoteInitMutex); 69eee82e44548f17253c2e06b25725f91c7b549ec2Lajos Molnar sRemoteList.clear(); 70eee82e44548f17253c2e06b25725f91c7b549ec2Lajos Molnar sBinderDeathObserver.clear(); 71eee82e44548f17253c2e06b25725f91c7b549ec2Lajos Molnar} 72eee82e44548f17253c2e06b25725f91c7b549ec2Lajos Molnar 7360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar// static 7460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnarsp<IMediaCodecList> MediaCodecList::getInstance() { 751381d4b5c0385aec3741073e5998773b064c1fb0Lajos Molnar Mutex::Autolock _l(sRemoteInitMutex); 761381d4b5c0385aec3741073e5998773b064c1fb0Lajos Molnar if (sRemoteList == NULL) { 771381d4b5c0385aec3741073e5998773b064c1fb0Lajos Molnar sp<IBinder> binder = 781381d4b5c0385aec3741073e5998773b064c1fb0Lajos Molnar defaultServiceManager()->getService(String16("media.player")); 791381d4b5c0385aec3741073e5998773b064c1fb0Lajos Molnar sp<IMediaPlayerService> service = 801381d4b5c0385aec3741073e5998773b064c1fb0Lajos Molnar interface_cast<IMediaPlayerService>(binder); 811381d4b5c0385aec3741073e5998773b064c1fb0Lajos Molnar if (service.get() != NULL) { 821381d4b5c0385aec3741073e5998773b064c1fb0Lajos Molnar sRemoteList = service->getCodecList(); 83eee82e44548f17253c2e06b25725f91c7b549ec2Lajos Molnar if (sRemoteList != NULL) { 84eee82e44548f17253c2e06b25725f91c7b549ec2Lajos Molnar sBinderDeathObserver = new BinderDeathObserver(); 85eee82e44548f17253c2e06b25725f91c7b549ec2Lajos Molnar binder->linkToDeath(sBinderDeathObserver.get()); 86eee82e44548f17253c2e06b25725f91c7b549ec2Lajos Molnar } 871381d4b5c0385aec3741073e5998773b064c1fb0Lajos Molnar } 881381d4b5c0385aec3741073e5998773b064c1fb0Lajos Molnar if (sRemoteList == NULL) { 891381d4b5c0385aec3741073e5998773b064c1fb0Lajos Molnar // if failed to get remote list, create local list 901381d4b5c0385aec3741073e5998773b064c1fb0Lajos Molnar sRemoteList = getLocalInstance(); 911381d4b5c0385aec3741073e5998773b064c1fb0Lajos Molnar } 921381d4b5c0385aec3741073e5998773b064c1fb0Lajos Molnar } 931381d4b5c0385aec3741073e5998773b064c1fb0Lajos Molnar return sRemoteList; 94afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber} 95afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 96afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas HuberMediaCodecList::MediaCodecList() 97afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber : mInitCheck(NO_INIT) { 98d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar parseTopLevelXMLFile("/etc/media_codecs.xml"); 99d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar} 100afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 101d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnarvoid MediaCodecList::parseTopLevelXMLFile(const char *codecs_xml) { 102d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar // get href_base 103d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar char *href_base_end = strrchr(codecs_xml, '/'); 104d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar if (href_base_end != NULL) { 105d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar mHrefBase = AString(codecs_xml, href_base_end - codecs_xml + 1); 106d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar } 107d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar 10860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mInitCheck = OK; // keeping this here for safety 109d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar mCurrentSection = SECTION_TOPLEVEL; 110d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar mDepth = 0; 111d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar 11260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar OMXClient client; 11360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mInitCheck = client.connect(); 11460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar if (mInitCheck != OK) { 11560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar return; 11660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar } 11760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mOMX = client.interface(); 118d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar parseXMLFile(codecs_xml); 11960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mOMX.clear(); 120d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar 121d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar if (mInitCheck != OK) { 122d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar mCodecInfos.clear(); 123afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return; 124afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 125afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 126d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar for (size_t i = mCodecInfos.size(); i-- > 0;) { 12760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar const MediaCodecInfo &info = *mCodecInfos.itemAt(i).get(); 128afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 12960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar if (info.mCaps.size() == 0) { 130d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar // No types supported by this component??? 131d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar ALOGW("Component %s does not support any type of media?", 13260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar info.mName.c_str()); 133ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber 134d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar mCodecInfos.removeAt(i); 135513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar#if LOG_NDEBUG == 0 136513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else { 13760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar for (size_t type_ix = 0; type_ix < info.mCaps.size(); ++type_ix) { 13860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar AString mime = info.mCaps.keyAt(type_ix); 13960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar const sp<MediaCodecInfo::Capabilities> &caps = info.mCaps.valueAt(type_ix); 14060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar 14160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar ALOGV("%s codec info for %s: %s", info.mName.c_str(), mime.c_str(), 14260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar caps->getDetails()->debugString().c_str()); 14360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar ALOGV(" flags=%d", caps->getFlags()); 14460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar { 14560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar Vector<uint32_t> colorFormats; 14660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar caps->getSupportedColorFormats(&colorFormats); 14760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar AString nice; 14860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar for (size_t ix = 0; ix < colorFormats.size(); ix++) { 14960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar if (ix > 0) { 15060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar nice.append(", "); 15160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar } 15260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar nice.append(colorFormats.itemAt(ix)); 15360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar } 15460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar ALOGV(" colors=[%s]", nice.c_str()); 15560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar } 15660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar { 15760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar Vector<MediaCodecInfo::ProfileLevel> profileLevels; 15860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar caps->getSupportedProfileLevels(&profileLevels); 15960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar AString nice; 16060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar for (size_t ix = 0; ix < profileLevels.size(); ix++) { 16160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar if (ix > 0) { 16260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar nice.append(", "); 16360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar } 16460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar const MediaCodecInfo::ProfileLevel &pl = 16560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar profileLevels.itemAt(ix); 16660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar nice.append(pl.mProfile); 16760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar nice.append("/"); 16860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar nice.append(pl.mLevel); 16960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar } 17060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar ALOGV(" levels=[%s]", nice.c_str()); 171513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 172513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 173513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar#endif 174d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar } 175afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 176afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 177afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#if 0 178afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber for (size_t i = 0; i < mCodecInfos.size(); ++i) { 179afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber const CodecInfo &info = mCodecInfos.itemAt(i); 180afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 181afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber AString line = info.mName; 182afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber line.append(" supports "); 183afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber for (size_t j = 0; j < mTypes.size(); ++j) { 184afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber uint32_t value = mTypes.valueAt(j); 185afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 186afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (info.mTypes & (1ul << value)) { 187afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber line.append(mTypes.keyAt(j)); 188afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber line.append(" "); 189afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 190afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 191afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 192afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber ALOGI("%s", line.c_str()); 193afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 194afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#endif 195afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber} 196afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 197afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas HuberMediaCodecList::~MediaCodecList() { 198afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber} 199afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 200afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberstatus_t MediaCodecList::initCheck() const { 201afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return mInitCheck; 202afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber} 203afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 204d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnarvoid MediaCodecList::parseXMLFile(const char *path) { 205d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar FILE *file = fopen(path, "r"); 206d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar 207d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar if (file == NULL) { 208d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar ALOGW("unable to open media codecs configuration xml file: %s", path); 209d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar mInitCheck = NAME_NOT_FOUND; 210d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar return; 211d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar } 212afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 213afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber XML_Parser parser = ::XML_ParserCreate(NULL); 214afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber CHECK(parser != NULL); 215afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 216afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber ::XML_SetUserData(parser, this); 217afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber ::XML_SetElementHandler( 218afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber parser, StartElementHandlerWrapper, EndElementHandlerWrapper); 219afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 220afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber const int BUFF_SIZE = 512; 221afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber while (mInitCheck == OK) { 222afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber void *buff = ::XML_GetBuffer(parser, BUFF_SIZE); 223afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (buff == NULL) { 224d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar ALOGE("failed in call to XML_GetBuffer()"); 225afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber mInitCheck = UNKNOWN_ERROR; 226afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber break; 227afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 228afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 229afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber int bytes_read = ::fread(buff, 1, BUFF_SIZE, file); 230afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (bytes_read < 0) { 231afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber ALOGE("failed in call to read"); 232afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber mInitCheck = ERROR_IO; 233afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber break; 234afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 235afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 236d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar XML_Status status = ::XML_ParseBuffer(parser, bytes_read, bytes_read == 0); 237d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar if (status != XML_STATUS_OK) { 238d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar ALOGE("malformed (%s)", ::XML_ErrorString(::XML_GetErrorCode(parser))); 239afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber mInitCheck = ERROR_MALFORMED; 240afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber break; 241afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 242afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 243afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (bytes_read == 0) { 244afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber break; 245afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 246afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 247afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 248afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber ::XML_ParserFree(parser); 249afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 250d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar fclose(file); 251d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar file = NULL; 252afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber} 253afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 254afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber// static 255afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubervoid MediaCodecList::StartElementHandlerWrapper( 256afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber void *me, const char *name, const char **attrs) { 257afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber static_cast<MediaCodecList *>(me)->startElementHandler(name, attrs); 258afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber} 259afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 260afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber// static 261afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubervoid MediaCodecList::EndElementHandlerWrapper(void *me, const char *name) { 262afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber static_cast<MediaCodecList *>(me)->endElementHandler(name); 263afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber} 264afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 265d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnarstatus_t MediaCodecList::includeXMLFile(const char **attrs) { 266d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar const char *href = NULL; 267d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar size_t i = 0; 268d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar while (attrs[i] != NULL) { 269d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar if (!strcmp(attrs[i], "href")) { 270d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar if (attrs[i + 1] == NULL) { 271d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar return -EINVAL; 272d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar } 273d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar href = attrs[i + 1]; 274d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar ++i; 275d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar } else { 276d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar return -EINVAL; 277d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar } 278d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar ++i; 279d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar } 280d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar 281d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar // For security reasons and for simplicity, file names can only contain 282d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar // [a-zA-Z0-9_.] and must start with media_codecs_ and end with .xml 283d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar for (i = 0; href[i] != '\0'; i++) { 284d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar if (href[i] == '.' || href[i] == '_' || 285d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar (href[i] >= '0' && href[i] <= '9') || 286d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar (href[i] >= 'A' && href[i] <= 'Z') || 287d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar (href[i] >= 'a' && href[i] <= 'z')) { 288d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar continue; 289d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar } 290d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar ALOGE("invalid include file name: %s", href); 291d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar return -EINVAL; 292d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar } 293d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar 294d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar AString filename = href; 295d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar if (!filename.startsWith("media_codecs_") || 296d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar !filename.endsWith(".xml")) { 297d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar ALOGE("invalid include file name: %s", href); 298d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar return -EINVAL; 299d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar } 300d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar filename.insert(mHrefBase, 0); 301d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar 302d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar parseXMLFile(filename.c_str()); 303d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar return mInitCheck; 304d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar} 305d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar 306afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubervoid MediaCodecList::startElementHandler( 307afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber const char *name, const char **attrs) { 308afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (mInitCheck != OK) { 309afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return; 310afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 311afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 312513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar bool inType = true; 313513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 314d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar if (!strcmp(name, "Include")) { 315d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar mInitCheck = includeXMLFile(attrs); 316d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar if (mInitCheck == OK) { 317d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar mPastSections.push(mCurrentSection); 318d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar mCurrentSection = SECTION_INCLUDE; 319d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar } 320d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar ++mDepth; 321d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar return; 322d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar } 323d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar 324afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber switch (mCurrentSection) { 325afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber case SECTION_TOPLEVEL: 326afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber { 327afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (!strcmp(name, "Decoders")) { 328afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber mCurrentSection = SECTION_DECODERS; 329afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } else if (!strcmp(name, "Encoders")) { 330afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber mCurrentSection = SECTION_ENCODERS; 331afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 332afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber break; 333afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 334afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 335afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber case SECTION_DECODERS: 336afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber { 337afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (!strcmp(name, "MediaCodec")) { 338afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber mInitCheck = 339afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber addMediaCodecFromAttributes(false /* encoder */, attrs); 340afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 341afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber mCurrentSection = SECTION_DECODER; 342afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 343afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber break; 344afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 345afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 346afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber case SECTION_ENCODERS: 347afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber { 348afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (!strcmp(name, "MediaCodec")) { 349afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber mInitCheck = 350afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber addMediaCodecFromAttributes(true /* encoder */, attrs); 351afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 352afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber mCurrentSection = SECTION_ENCODER; 353afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 354afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber break; 355afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 356afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 357afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber case SECTION_DECODER: 358afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber case SECTION_ENCODER: 359afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber { 360afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (!strcmp(name, "Quirk")) { 361afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber mInitCheck = addQuirk(attrs); 362afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } else if (!strcmp(name, "Type")) { 363afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber mInitCheck = addTypeFromAttributes(attrs); 364513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar mCurrentSection = 365513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar (mCurrentSection == SECTION_DECODER 366513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar ? SECTION_DECODER_TYPE : SECTION_ENCODER_TYPE); 367513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 368513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 369513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar inType = false; 370513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar // fall through 371513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 372513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar case SECTION_DECODER_TYPE: 373513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar case SECTION_ENCODER_TYPE: 374513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar { 375513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar // ignore limits and features specified outside of type 37660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar bool outside = !inType && !mCurrentInfo->mHasSoleMime; 377513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (outside && (!strcmp(name, "Limit") || !strcmp(name, "Feature"))) { 378513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar ALOGW("ignoring %s specified outside of a Type", name); 379513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else if (!strcmp(name, "Limit")) { 380513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar mInitCheck = addLimit(attrs); 381513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else if (!strcmp(name, "Feature")) { 382513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar mInitCheck = addFeature(attrs); 383afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 384afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber break; 385afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 386afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 387afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber default: 388afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber break; 389afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 390afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 391afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber ++mDepth; 392afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber} 393afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 394afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubervoid MediaCodecList::endElementHandler(const char *name) { 395afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (mInitCheck != OK) { 396afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return; 397afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 398afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 399afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber switch (mCurrentSection) { 400afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber case SECTION_DECODERS: 401afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber { 402afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (!strcmp(name, "Decoders")) { 403afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber mCurrentSection = SECTION_TOPLEVEL; 404afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 405afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber break; 406afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 407afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 408afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber case SECTION_ENCODERS: 409afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber { 410afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (!strcmp(name, "Encoders")) { 411afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber mCurrentSection = SECTION_TOPLEVEL; 412afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 413afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber break; 414afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 415afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 416513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar case SECTION_DECODER_TYPE: 417513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar case SECTION_ENCODER_TYPE: 418513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar { 419513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (!strcmp(name, "Type")) { 420513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar mCurrentSection = 421513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar (mCurrentSection == SECTION_DECODER_TYPE 422513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar ? SECTION_DECODER : SECTION_ENCODER); 423513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 42460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mCurrentInfo->complete(); 425513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 426513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar break; 427513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 428513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 429afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber case SECTION_DECODER: 430afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber { 431afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (!strcmp(name, "MediaCodec")) { 432afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber mCurrentSection = SECTION_DECODERS; 43360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mCurrentInfo->complete(); 43460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mCurrentInfo = NULL; 435afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 436afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber break; 437afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 438afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 439afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber case SECTION_ENCODER: 440afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber { 441afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (!strcmp(name, "MediaCodec")) { 442afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber mCurrentSection = SECTION_ENCODERS; 44360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mCurrentInfo->complete();; 44460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mCurrentInfo = NULL; 445afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 446afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber break; 447afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 448afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 449d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar case SECTION_INCLUDE: 450d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar { 451d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar if (!strcmp(name, "Include") && mPastSections.size() > 0) { 452d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar mCurrentSection = mPastSections.top(); 453d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar mPastSections.pop(); 454d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar } 455d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar break; 456d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar } 457d74110cdef2becd4f7fd2334c34c3ca73f56b355Lajos Molnar 458afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber default: 459afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber break; 460afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 461afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 462afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber --mDepth; 463afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber} 464afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 465afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberstatus_t MediaCodecList::addMediaCodecFromAttributes( 466afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber bool encoder, const char **attrs) { 467afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber const char *name = NULL; 468afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber const char *type = NULL; 469afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 470afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber size_t i = 0; 471afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber while (attrs[i] != NULL) { 472afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (!strcmp(attrs[i], "name")) { 473afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (attrs[i + 1] == NULL) { 474afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return -EINVAL; 475afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 476afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber name = attrs[i + 1]; 477afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber ++i; 478afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } else if (!strcmp(attrs[i], "type")) { 479afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (attrs[i + 1] == NULL) { 480afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return -EINVAL; 481afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 482afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber type = attrs[i + 1]; 483afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber ++i; 484afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } else { 485afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return -EINVAL; 486afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 487afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 488afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber ++i; 489afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 490afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 491afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (name == NULL) { 492afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return -EINVAL; 493afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 494afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 49560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mCurrentInfo = new MediaCodecInfo(name, encoder, type); 4966ff58f04f78886b07c72c0118eb71a78d08f5651Lajos Molnar // The next step involves trying to load the codec, which may 4976ff58f04f78886b07c72c0118eb71a78d08f5651Lajos Molnar // fail. Only list the codec if this succeeds. 4986ff58f04f78886b07c72c0118eb71a78d08f5651Lajos Molnar // However, keep mCurrentInfo object around until parsing 4996ff58f04f78886b07c72c0118eb71a78d08f5651Lajos Molnar // of full codec info is completed. 5006ff58f04f78886b07c72c0118eb71a78d08f5651Lajos Molnar if (initializeCapabilities(type) == OK) { 5016ff58f04f78886b07c72c0118eb71a78d08f5651Lajos Molnar mCodecInfos.push_back(mCurrentInfo); 5026ff58f04f78886b07c72c0118eb71a78d08f5651Lajos Molnar } 5036ff58f04f78886b07c72c0118eb71a78d08f5651Lajos Molnar return OK; 504afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber} 505afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 50660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnarstatus_t MediaCodecList::initializeCapabilities(const char *type) { 5076ff58f04f78886b07c72c0118eb71a78d08f5651Lajos Molnar if (type == NULL) { 5086ff58f04f78886b07c72c0118eb71a78d08f5651Lajos Molnar return OK; 5096ff58f04f78886b07c72c0118eb71a78d08f5651Lajos Molnar } 5106ff58f04f78886b07c72c0118eb71a78d08f5651Lajos Molnar 51160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar ALOGV("initializeCapabilities %s:%s", 51260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mCurrentInfo->mName.c_str(), type); 51360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar 51460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar CodecCapabilities caps; 51560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar status_t err = QueryCodec( 51660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mOMX, 51760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mCurrentInfo->mName.c_str(), 51860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar type, 51960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mCurrentInfo->mIsEncoder, 52060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar &caps); 52160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar if (err != OK) { 52260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar return err; 523afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 52460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar 52560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar return mCurrentInfo->initializeCapabilities(caps); 526afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber} 527afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 528afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberstatus_t MediaCodecList::addQuirk(const char **attrs) { 529afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber const char *name = NULL; 530afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 531afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber size_t i = 0; 532afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber while (attrs[i] != NULL) { 533afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (!strcmp(attrs[i], "name")) { 534afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (attrs[i + 1] == NULL) { 535afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return -EINVAL; 536afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 537afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber name = attrs[i + 1]; 538afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber ++i; 539afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } else { 540afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return -EINVAL; 541afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 542afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 543afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber ++i; 544afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 545afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 546afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (name == NULL) { 547afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return -EINVAL; 548afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 549afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 55060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mCurrentInfo->addQuirk(name); 551afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return OK; 552afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber} 553afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 554afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberstatus_t MediaCodecList::addTypeFromAttributes(const char **attrs) { 555afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber const char *name = NULL; 556afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 557afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber size_t i = 0; 558afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber while (attrs[i] != NULL) { 559afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (!strcmp(attrs[i], "name")) { 560afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (attrs[i + 1] == NULL) { 561afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return -EINVAL; 562afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 563afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber name = attrs[i + 1]; 564afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber ++i; 565afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } else { 566afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return -EINVAL; 567afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 568afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 569afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber ++i; 570afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 571afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 572afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (name == NULL) { 573afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return -EINVAL; 574afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 575afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 57660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar status_t ret = mCurrentInfo->addMime(name); 5776ff58f04f78886b07c72c0118eb71a78d08f5651Lajos Molnar if (ret != OK) { 5786ff58f04f78886b07c72c0118eb71a78d08f5651Lajos Molnar return ret; 579513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 5806ff58f04f78886b07c72c0118eb71a78d08f5651Lajos Molnar 5816ff58f04f78886b07c72c0118eb71a78d08f5651Lajos Molnar // The next step involves trying to load the codec, which may 5826ff58f04f78886b07c72c0118eb71a78d08f5651Lajos Molnar // fail. Handle this gracefully (by not reporting such mime). 5836ff58f04f78886b07c72c0118eb71a78d08f5651Lajos Molnar if (initializeCapabilities(name) != OK) { 5846ff58f04f78886b07c72c0118eb71a78d08f5651Lajos Molnar mCurrentInfo->removeMime(name); 5856ff58f04f78886b07c72c0118eb71a78d08f5651Lajos Molnar } 5866ff58f04f78886b07c72c0118eb71a78d08f5651Lajos Molnar return OK; 587afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber} 588afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 58960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar// legacy method for non-advanced codecs 590afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberssize_t MediaCodecList::findCodecByType( 591afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber const char *type, bool encoder, size_t startIndex) const { 59260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar static const char *advancedFeatures[] = { 59360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar "feature-secure-playback", 59460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar "feature-tunneled-playback", 59560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar }; 596afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 59760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar size_t numCodecs = mCodecInfos.size(); 59860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar for (; startIndex < numCodecs; ++startIndex) { 59960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar const MediaCodecInfo &info = *mCodecInfos.itemAt(startIndex).get(); 600afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 60160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar if (info.isEncoder() != encoder) { 60260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar continue; 60360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar } 60460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar sp<MediaCodecInfo::Capabilities> capabilities = info.getCapabilitiesFor(type); 60560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar if (capabilities == NULL) { 60660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar continue; 60760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar } 60860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar const sp<AMessage> &details = capabilities->getDetails(); 609afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 61060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar int32_t required; 61160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar bool isAdvanced = false; 61260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar for (size_t ix = 0; ix < ARRAY_SIZE(advancedFeatures); ix++) { 61360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar if (details->findInt32(advancedFeatures[ix], &required) && 61460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar required != 0) { 61560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar isAdvanced = true; 61660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar break; 61760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar } 61860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar } 619afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 62060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar if (!isAdvanced) { 621afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return startIndex; 622afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 623afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 624afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 625afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return -ENOENT; 626afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber} 627afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 628513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnarstatic status_t limitFoundMissingAttr(AString name, const char *attr, bool found = true) { 629513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar ALOGE("limit '%s' with %s'%s' attribute", name.c_str(), 630513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar (found ? "" : "no "), attr); 631513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return -EINVAL; 632513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar} 633513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 634513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnarstatic status_t limitError(AString name, const char *msg) { 635513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar ALOGE("limit '%s' %s", name.c_str(), msg); 636513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return -EINVAL; 637513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar} 638513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 639513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnarstatic status_t limitInvalidAttr(AString name, const char *attr, AString value) { 640513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar ALOGE("limit '%s' with invalid '%s' attribute (%s)", name.c_str(), 641513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar attr, value.c_str()); 642513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return -EINVAL; 643513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar} 644513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 645513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnarstatus_t MediaCodecList::addLimit(const char **attrs) { 646513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar sp<AMessage> msg = new AMessage(); 647513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 648513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar size_t i = 0; 649513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar while (attrs[i] != NULL) { 650513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (attrs[i + 1] == NULL) { 651513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return -EINVAL; 652513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 653513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 654513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar // attributes with values 655513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (!strcmp(attrs[i], "name") 656513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar || !strcmp(attrs[i], "default") 657513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar || !strcmp(attrs[i], "in") 658513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar || !strcmp(attrs[i], "max") 659513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar || !strcmp(attrs[i], "min") 660513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar || !strcmp(attrs[i], "range") 661513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar || !strcmp(attrs[i], "ranges") 662513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar || !strcmp(attrs[i], "scale") 663513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar || !strcmp(attrs[i], "value")) { 664513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar msg->setString(attrs[i], attrs[i + 1]); 665513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar ++i; 666513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else { 667513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return -EINVAL; 668513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 669513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar ++i; 670513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 671513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 672513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar AString name; 673513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (!msg->findString("name", &name)) { 674513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar ALOGE("limit with no 'name' attribute"); 675513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return -EINVAL; 676513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 677513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 678513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar // size, blocks, bitrate, frame-rate, blocks-per-second, aspect-ratio: range 679513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar // quality: range + default + [scale] 680513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar // complexity: range + default 681513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar bool found; 68260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar 683513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (name == "aspect-ratio" || name == "bitrate" || name == "block-count" 684513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar || name == "blocks-per-second" || name == "complexity" 685513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar || name == "frame-rate" || name == "quality" || name == "size") { 686513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar AString min, max; 687513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (msg->findString("min", &min) && msg->findString("max", &max)) { 688513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar min.append("-"); 689513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar min.append(max); 690513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (msg->contains("range") || msg->contains("value")) { 691513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return limitError(name, "has 'min' and 'max' as well as 'range' or " 692513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar "'value' attributes"); 693513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 694513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar msg->setString("range", min); 695513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else if (msg->contains("min") || msg->contains("max")) { 696513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return limitError(name, "has only 'min' or 'max' attribute"); 697513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else if (msg->findString("value", &max)) { 698513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar min = max; 699513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar min.append("-"); 700513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar min.append(max); 701513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (msg->contains("range")) { 702513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return limitError(name, "has both 'range' and 'value' attributes"); 703513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 704513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar msg->setString("range", min); 705513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 706513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 707513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar AString range, scale = "linear", def, in_; 708513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (!msg->findString("range", &range)) { 709513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return limitError(name, "with no 'range', 'value' or 'min'/'max' attributes"); 710513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 711513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 712513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if ((name == "quality" || name == "complexity") ^ 713513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar (found = msg->findString("default", &def))) { 714513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return limitFoundMissingAttr(name, "default", found); 715513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 716513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (name != "quality" && msg->findString("scale", &scale)) { 717513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return limitFoundMissingAttr(name, "scale"); 718513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 719513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if ((name == "aspect-ratio") ^ (found = msg->findString("in", &in_))) { 720513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return limitFoundMissingAttr(name, "in", found); 721513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 722513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 723513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (name == "aspect-ratio") { 724513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (!(in_ == "pixels") && !(in_ == "blocks")) { 725513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return limitInvalidAttr(name, "in", in_); 726513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 727513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar in_.erase(5, 1); // (pixel|block)-aspect-ratio 728513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar in_.append("-"); 729513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar in_.append(name); 730513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar name = in_; 731513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 732513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (name == "quality") { 73360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mCurrentInfo->addDetail("quality-scale", scale); 734513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 735513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (name == "quality" || name == "complexity") { 736513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar AString tag = name; 737513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar tag.append("-default"); 73860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mCurrentInfo->addDetail(tag, def); 739513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 740513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar AString tag = name; 741513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar tag.append("-range"); 74260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mCurrentInfo->addDetail(tag, range); 743513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else { 744513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar AString max, value, ranges; 745513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (msg->contains("default")) { 746513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return limitFoundMissingAttr(name, "default"); 747513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else if (msg->contains("in")) { 748513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return limitFoundMissingAttr(name, "in"); 749513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else if ((name == "channel-count") ^ 750513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar (found = msg->findString("max", &max))) { 751513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return limitFoundMissingAttr(name, "max", found); 752513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else if (msg->contains("min")) { 753513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return limitFoundMissingAttr(name, "min"); 754513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else if (msg->contains("range")) { 755513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return limitFoundMissingAttr(name, "range"); 756513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else if ((name == "sample-rate") ^ 757513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar (found = msg->findString("ranges", &ranges))) { 758513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return limitFoundMissingAttr(name, "ranges", found); 759513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else if (msg->contains("scale")) { 760513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return limitFoundMissingAttr(name, "scale"); 761513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else if ((name == "alignment" || name == "block-size") ^ 762513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar (found = msg->findString("value", &value))) { 763513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return limitFoundMissingAttr(name, "value", found); 764513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 765513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 766513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (max.size()) { 767513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar AString tag = "max-"; 768513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar tag.append(name); 76960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mCurrentInfo->addDetail(tag, max); 770513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else if (value.size()) { 77160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mCurrentInfo->addDetail(name, value); 772513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else if (ranges.size()) { 773513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar AString tag = name; 774513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar tag.append("-ranges"); 77560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar mCurrentInfo->addDetail(tag, ranges); 776513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else { 777513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar ALOGW("Ignoring unrecognized limit '%s'", name.c_str()); 778513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 779513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 780513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return OK; 781513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar} 782513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 783513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnarstatic bool parseBoolean(const char *s) { 784513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (!strcasecmp(s, "true") || !strcasecmp(s, "yes") || !strcasecmp(s, "y")) { 785513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return true; 786513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 787513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar char *end; 788513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar unsigned long res = strtoul(s, &end, 10); 789513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return *s != '\0' && *end == '\0' && res > 0; 790513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar} 791513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 792513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnarstatus_t MediaCodecList::addFeature(const char **attrs) { 793513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar size_t i = 0; 794513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar const char *name = NULL; 795513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar int32_t optional = -1; 796513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar int32_t required = -1; 797732c6d955524ead6c31e6e1bafbd41ea4cee525dLajos Molnar const char *value = NULL; 798513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 799513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar while (attrs[i] != NULL) { 800513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (attrs[i + 1] == NULL) { 801513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return -EINVAL; 802513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 803513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 804513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar // attributes with values 805513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (!strcmp(attrs[i], "name")) { 806513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar name = attrs[i + 1]; 807513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar ++i; 808513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else if (!strcmp(attrs[i], "optional") || !strcmp(attrs[i], "required")) { 809513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar int value = (int)parseBoolean(attrs[i + 1]); 810513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (!strcmp(attrs[i], "optional")) { 811513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar optional = value; 812513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else { 813513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar required = value; 814513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 815513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar ++i; 816732c6d955524ead6c31e6e1bafbd41ea4cee525dLajos Molnar } else if (!strcmp(attrs[i], "value")) { 817732c6d955524ead6c31e6e1bafbd41ea4cee525dLajos Molnar value = attrs[i + 1]; 818732c6d955524ead6c31e6e1bafbd41ea4cee525dLajos Molnar ++i; 819513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } else { 820513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return -EINVAL; 821513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 822513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar ++i; 823513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 824513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (name == NULL) { 825513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar ALOGE("feature with no 'name' attribute"); 826513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return -EINVAL; 827513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 828513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 829513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar if (optional == required && optional != -1) { 830513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar ALOGE("feature '%s' is both/neither optional and required", name); 831513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return -EINVAL; 832513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar } 833513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 834732c6d955524ead6c31e6e1bafbd41ea4cee525dLajos Molnar if ((optional != -1 || required != -1) && (value != NULL)) { 835732c6d955524ead6c31e6e1bafbd41ea4cee525dLajos Molnar ALOGE("feature '%s' has both a value and optional/required attribute", name); 836732c6d955524ead6c31e6e1bafbd41ea4cee525dLajos Molnar return -EINVAL; 837732c6d955524ead6c31e6e1bafbd41ea4cee525dLajos Molnar } 838732c6d955524ead6c31e6e1bafbd41ea4cee525dLajos Molnar 839732c6d955524ead6c31e6e1bafbd41ea4cee525dLajos Molnar if (value != NULL) { 840732c6d955524ead6c31e6e1bafbd41ea4cee525dLajos Molnar mCurrentInfo->addFeature(name, value); 841732c6d955524ead6c31e6e1bafbd41ea4cee525dLajos Molnar } else { 842732c6d955524ead6c31e6e1bafbd41ea4cee525dLajos Molnar mCurrentInfo->addFeature(name, (required == 1) || (optional == 0)); 843732c6d955524ead6c31e6e1bafbd41ea4cee525dLajos Molnar } 844513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar return OK; 845513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar} 846513d967dae82cd03e67bff17b927cf869d9bc43eLajos Molnar 847afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberssize_t MediaCodecList::findCodecByName(const char *name) const { 848afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber for (size_t i = 0; i < mCodecInfos.size(); ++i) { 84960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar const MediaCodecInfo &info = *mCodecInfos.itemAt(i).get(); 850afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 851afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber if (info.mName == name) { 852afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return i; 853afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 854afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 855afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 856afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber return -ENOENT; 857afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber} 858afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 85969829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Hubersize_t MediaCodecList::countCodecs() const { 86069829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber return mCodecInfos.size(); 86169829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber} 86269829f3bd09ee4e6be49fee8795c5df24c4da70eAndreas Huber 863afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber} // namespace android 864