19e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu/* 29e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu * Copyright 2015 The Android Open Source Project 39e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu * 49e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu * Licensed under the Apache License, Version 2.0 (the "License"); 59e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu * you may not use this file except in compliance with the License. 69e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu * You may obtain a copy of the License at 79e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu * 89e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu * http://www.apache.org/licenses/LICENSE-2.0 99e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu * 109e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu * Unless required by applicable law or agreed to in writing, software 119e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu * distributed under the License is distributed on an "AS IS" BASIS, 129e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu * See the License for the specific language governing permissions and 149e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu * limitations under the License. 159e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu */ 169e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu 179e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu//#define LOG_NDEBUG 0 189e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu#define LOG_TAG "MediaCodecListOverrides" 199e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu#include <utils/Log.h> 209e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu 219e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu#include "MediaCodecListOverrides.h" 229e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu 2319352b3287480394aa9963276305d5168a7adf85Ronghua Wu#include <cutils/properties.h> 249e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu#include <gui/Surface.h> 259e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu#include <media/ICrypto.h> 269e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu#include <media/IMediaCodecList.h> 279e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu#include <media/MediaCodecInfo.h> 289ba21b9418d10ddcc39f08901e24fbf43d82b2bcRonghua Wu#include <media/MediaResourcePolicy.h> 2979608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang#include <media/openmax/OMX_IVCommon.h> 309e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu#include <media/stagefright/foundation/AMessage.h> 319e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu#include <media/stagefright/MediaCodec.h> 3279608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang#include <media/stagefright/MediaCodecList.h> 339e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu 349e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wunamespace android { 359e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu 3665c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wuconst char *kProfilingResults = "/data/misc/media/media_codecs_profiling_results.xml"; 3765c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu 3819352b3287480394aa9963276305d5168a7adf85Ronghua WuAString getProfilingVersionString() { 3919352b3287480394aa9963276305d5168a7adf85Ronghua Wu char val[PROPERTY_VALUE_MAX]; 4019352b3287480394aa9963276305d5168a7adf85Ronghua Wu if (property_get("ro.build.display.id", val, NULL) && (strlen(val) > 0)) { 4119352b3287480394aa9963276305d5168a7adf85Ronghua Wu return AStringPrintf("<!-- Profiled-with: %s -->", val); 4219352b3287480394aa9963276305d5168a7adf85Ronghua Wu } 4319352b3287480394aa9963276305d5168a7adf85Ronghua Wu 4419352b3287480394aa9963276305d5168a7adf85Ronghua Wu return "<!-- Profiled-with: UNKNOWN_BUILD_ID -->"; 4519352b3287480394aa9963276305d5168a7adf85Ronghua Wu} 4619352b3287480394aa9963276305d5168a7adf85Ronghua Wu 479e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu// a limit to avoid allocating unreasonable number of codec instances in the measurement. 489e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu// this should be in sync with the MAX_SUPPORTED_INSTANCES defined in MediaCodecInfo.java. 499e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wustatic const int kMaxInstances = 32; 509e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu 519e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu// TODO: move MediaCodecInfo to C++. Until then, some temp methods to parse out info. 529e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wustatic bool getMeasureSize(sp<MediaCodecInfo::Capabilities> caps, int32_t *width, int32_t *height) { 539e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu AString sizeRange; 549e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu if (!caps->getDetails()->findString("size-range", &sizeRange)) { 559e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu return false; 569e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu } 579e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu AString minSize; 589e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu AString maxSize; 599e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu if (!splitString(sizeRange, "-", &minSize, &maxSize)) { 609e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu return false; 619e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu } 629e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu AString sWidth; 639e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu AString sHeight; 649e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu if (!splitString(minSize, "x", &sWidth, &sHeight)) { 659e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu if (!splitString(minSize, "*", &sWidth, &sHeight)) { 669e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu return false; 679e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu } 689e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu } 699e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu 709e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu *width = strtol(sWidth.c_str(), NULL, 10); 719e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu *height = strtol(sHeight.c_str(), NULL, 10); 729e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu return (*width > 0) && (*height > 0); 739e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu} 749e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu 759e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wustatic void getMeasureBitrate(sp<MediaCodecInfo::Capabilities> caps, int32_t *bitrate) { 769e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu // Until have native MediaCodecInfo, we cannot get bitrates based on profile/levels. 779e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu // We use 200000 as default value for our measurement. 789e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu *bitrate = 200000; 799e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu AString bitrateRange; 809e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu if (!caps->getDetails()->findString("bitrate-range", &bitrateRange)) { 819e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu return; 829e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu } 839e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu AString minBitrate; 849e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu AString maxBitrate; 859e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu if (!splitString(bitrateRange, "-", &minBitrate, &maxBitrate)) { 869e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu return; 879e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu } 889e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu 899e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu *bitrate = strtol(minBitrate.c_str(), NULL, 10); 909e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu} 919e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu 929e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wustatic sp<AMessage> getMeasureFormat( 939e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu bool isEncoder, AString mime, sp<MediaCodecInfo::Capabilities> caps) { 949e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu sp<AMessage> format = new AMessage(); 959e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu format->setString("mime", mime); 969e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu 979e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu if (isEncoder) { 989e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu int32_t bitrate = 0; 999e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu getMeasureBitrate(caps, &bitrate); 1009e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu format->setInt32("bitrate", bitrate); 10179608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang format->setInt32("encoder", 1); 1029e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu } 1039e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu 1049e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu if (mime.startsWith("video/")) { 1059e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu int32_t width = 0; 1069e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu int32_t height = 0; 1079e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu if (!getMeasureSize(caps, &width, &height)) { 1089e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu return NULL; 1099e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu } 1109e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu format->setInt32("width", width); 1119e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu format->setInt32("height", height); 1129e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu 1139e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu Vector<uint32_t> colorFormats; 1149e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu caps->getSupportedColorFormats(&colorFormats); 1159e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu if (colorFormats.size() == 0) { 1169e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu return NULL; 1179e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu } 1189e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu format->setInt32("color-format", colorFormats[0]); 1199e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu 1209e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu format->setFloat("frame-rate", 10.0); 1219e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu format->setInt32("i-frame-interval", 10); 1229e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu } else { 1239e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu // TODO: profile hw audio 1249e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu return NULL; 1259e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu } 1269e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu 1279e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu return format; 1289e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu} 1299e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu 13079608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhangstatic size_t doProfileEncoderInputBuffers( 13179608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang AString name, AString mime, sp<MediaCodecInfo::Capabilities> caps) { 13279608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang ALOGV("doProfileEncoderInputBuffers: name %s, mime %s", name.c_str(), mime.c_str()); 13379608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang 13479608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang sp<AMessage> format = getMeasureFormat(true /* isEncoder */, mime, caps); 13579608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang if (format == NULL) { 13679608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang return 0; 13779608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang } 13879608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang 13979608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang format->setInt32("color-format", OMX_COLOR_FormatAndroidOpaque); 14079608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang ALOGV("doProfileEncoderInputBuffers: format %s", format->debugString().c_str()); 14179608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang 14279608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang status_t err = OK; 14379608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang sp<ALooper> looper = new ALooper; 14479608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang looper->setName("MediaCodec_looper"); 14579608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang looper->start( 14679608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang false /* runOnCallingThread */, false /* canCallJava */, ANDROID_PRIORITY_AUDIO); 14779608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang 14879608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang sp<MediaCodec> codec = MediaCodec::CreateByComponentName(looper, name.c_str(), &err); 14979608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang if (err != OK) { 15079608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang ALOGE("Failed to create codec: %s", name.c_str()); 15179608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang return 0; 15279608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang } 15379608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang 15479608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang err = codec->configure(format, NULL, NULL, MediaCodec::CONFIGURE_FLAG_ENCODE); 15579608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang if (err != OK) { 15679608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang ALOGE("Failed to configure codec: %s with mime: %s", name.c_str(), mime.c_str()); 15779608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang codec->release(); 15879608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang return 0; 15979608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang } 16079608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang 16179608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang sp<IGraphicBufferProducer> bufferProducer; 16279608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang err = codec->createInputSurface(&bufferProducer); 16379608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang if (err != OK) { 16479608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang ALOGE("Failed to create surface: %s with mime: %s", name.c_str(), mime.c_str()); 16579608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang codec->release(); 16679608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang return 0; 16779608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang } 16879608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang 16979608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang int minUndequeued = 0; 17079608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang err = bufferProducer->query( 17179608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeued); 17279608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang if (err != OK) { 17379608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang ALOGE("Failed to query NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS"); 17479608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang minUndequeued = 0; 17579608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang } 17679608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang 17779608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang err = codec->release(); 17879608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang if (err != OK) { 17979608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang ALOGW("Failed to release codec: %s with mime: %s", name.c_str(), mime.c_str()); 18079608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang } 18179608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang 18279608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang return minUndequeued; 18379608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang} 18479608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang 1859e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wustatic size_t doProfileCodecs( 1869e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu bool isEncoder, AString name, AString mime, sp<MediaCodecInfo::Capabilities> caps) { 1879e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu sp<AMessage> format = getMeasureFormat(isEncoder, mime, caps); 1889e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu if (format == NULL) { 1899e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu return 0; 1909e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu } 1919e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu ALOGV("doProfileCodecs %s %s %s %s", 1929e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu name.c_str(), mime.c_str(), isEncoder ? "encoder" : "decoder", 1939e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu format->debugString().c_str()); 1949e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu 1959e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu status_t err = OK; 1969e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu Vector<sp<MediaCodec>> codecs; 1979e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu while (err == OK && codecs.size() < kMaxInstances) { 1989e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu sp<ALooper> looper = new ALooper; 1999e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu looper->setName("MediaCodec_looper"); 200ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("doProfileCodecs for codec #%zu", codecs.size()); 2019e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu ALOGV("doProfileCodecs start looper"); 2029e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu looper->start( 2039e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu false /* runOnCallingThread */, false /* canCallJava */, ANDROID_PRIORITY_AUDIO); 2049e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu ALOGV("doProfileCodecs CreateByComponentName"); 2059e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu sp<MediaCodec> codec = MediaCodec::CreateByComponentName(looper, name.c_str(), &err); 2069e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu if (err != OK) { 2079e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu ALOGV("Failed to create codec: %s", name.c_str()); 2089e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu break; 2099e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu } 2109e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu const sp<Surface> nativeWindow; 2119e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu const sp<ICrypto> crypto; 21279608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang uint32_t flags = isEncoder ? MediaCodec::CONFIGURE_FLAG_ENCODE : 0; 2139e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu ALOGV("doProfileCodecs configure"); 2149e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu err = codec->configure(format, nativeWindow, crypto, flags); 2159e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu if (err != OK) { 2169e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu ALOGV("Failed to configure codec: %s with mime: %s", name.c_str(), mime.c_str()); 2179e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu codec->release(); 2189e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu break; 2199e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu } 2209e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu ALOGV("doProfileCodecs start"); 2219e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu err = codec->start(); 2229e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu if (err != OK) { 2239e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu ALOGV("Failed to start codec: %s with mime: %s", name.c_str(), mime.c_str()); 2249e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu codec->release(); 2259e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu break; 2269e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu } 2279e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu codecs.push_back(codec); 2289e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu } 2299e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu 2309e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu for (size_t i = 0; i < codecs.size(); ++i) { 2319e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu ALOGV("doProfileCodecs release %s", name.c_str()); 2329e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu err = codecs[i]->release(); 2339e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu if (err != OK) { 2349e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu ALOGE("Failed to release codec: %s with mime: %s", name.c_str(), mime.c_str()); 2359e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu } 2369e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu } 2379e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu 2389e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu return codecs.size(); 2399e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu} 2409e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu 2419e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wubool splitString(const AString &s, const AString &delimiter, AString *s1, AString *s2) { 2429e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu ssize_t pos = s.find(delimiter.c_str()); 2439e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu if (pos < 0) { 2449e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu return false; 2459e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu } 2469e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu *s1 = AString(s, 0, pos); 2479e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu *s2 = AString(s, pos + 1, s.size() - pos - 1); 2489e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu return true; 2499e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu} 2509e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu 2519e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wubool splitString( 2529e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu const AString &s, const AString &delimiter, AString *s1, AString *s2, AString *s3) { 2539e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu AString temp; 2549e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu if (!splitString(s, delimiter, s1, &temp)) { 2559e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu return false; 2569e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu } 2579e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu if (!splitString(temp, delimiter, s2, s3)) { 2589e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu return false; 2599e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu } 2609e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu return true; 2619e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu} 2629e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu 26365c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wuvoid profileCodecs(const Vector<sp<MediaCodecInfo>> &infos) { 2649ba21b9418d10ddcc39f08901e24fbf43d82b2bcRonghua Wu CodecSettings global_results; 26565c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu KeyedVector<AString, CodecSettings> encoder_results; 26665c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu KeyedVector<AString, CodecSettings> decoder_results; 2679ba21b9418d10ddcc39f08901e24fbf43d82b2bcRonghua Wu profileCodecs(infos, &global_results, &encoder_results, &decoder_results); 26865c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu exportResultsToXML(kProfilingResults, global_results, encoder_results, decoder_results); 26965c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu} 27065c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu 2719e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wuvoid profileCodecs( 2729e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu const Vector<sp<MediaCodecInfo>> &infos, 2739ba21b9418d10ddcc39f08901e24fbf43d82b2bcRonghua Wu CodecSettings *global_results, 27465c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu KeyedVector<AString, CodecSettings> *encoder_results, 27565c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu KeyedVector<AString, CodecSettings> *decoder_results, 2769e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu bool forceToMeasure) { 2779e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu KeyedVector<AString, sp<MediaCodecInfo::Capabilities>> codecsNeedMeasure; 2789ba21b9418d10ddcc39f08901e24fbf43d82b2bcRonghua Wu AString supportMultipleSecureCodecs = "true"; 27979608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang size_t maxEncoderInputBuffers = 0; 2809e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu for (size_t i = 0; i < infos.size(); ++i) { 2819e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu const sp<MediaCodecInfo> info = infos[i]; 2829e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu AString name = info->getCodecName(); 2839e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu if (name.startsWith("OMX.google.") || 2849e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu // TODO: reenable below codecs once fixed 2859e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu name == "OMX.Intel.VideoDecoder.VP9.hybrid") { 2869e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu continue; 2879e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu } 2889e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu 2899e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu Vector<AString> mimes; 2909e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu info->getSupportedMimes(&mimes); 2919e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu for (size_t i = 0; i < mimes.size(); ++i) { 2929e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu const sp<MediaCodecInfo::Capabilities> &caps = 2939e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu info->getCapabilitiesFor(mimes[i].c_str()); 2940f29c9d205ff03286da629d30fddd5dd5ca020dbRonghua Wu if (!forceToMeasure && 2950f29c9d205ff03286da629d30fddd5dd5ca020dbRonghua Wu (caps->getDetails()->contains("max-supported-instances") || 2960f29c9d205ff03286da629d30fddd5dd5ca020dbRonghua Wu caps->getDetails()->contains("max-concurrent-instances"))) { 2979e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu continue; 2989e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu } 2999e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu 3009e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu size_t max = doProfileCodecs(info->isEncoder(), name, mimes[i], caps); 3019e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu if (max > 0) { 3029e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu CodecSettings settings; 3039e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu char maxStr[32]; 304ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar sprintf(maxStr, "%zu", max); 3059e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu settings.add("max-supported-instances", maxStr); 3069e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu 3079e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu AString key = name; 3089e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu key.append(" "); 3099e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu key.append(mimes[i]); 3109e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu 31165c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu if (info->isEncoder()) { 31265c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu encoder_results->add(key, settings); 31365c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu } else { 31465c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu decoder_results->add(key, settings); 31565c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu } 3169ba21b9418d10ddcc39f08901e24fbf43d82b2bcRonghua Wu 3179ba21b9418d10ddcc39f08901e24fbf43d82b2bcRonghua Wu if (name.endsWith(".secure")) { 3189ba21b9418d10ddcc39f08901e24fbf43d82b2bcRonghua Wu if (max <= 1) { 3199ba21b9418d10ddcc39f08901e24fbf43d82b2bcRonghua Wu supportMultipleSecureCodecs = "false"; 3209ba21b9418d10ddcc39f08901e24fbf43d82b2bcRonghua Wu } 3219ba21b9418d10ddcc39f08901e24fbf43d82b2bcRonghua Wu } 32279608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang if (info->isEncoder() && mimes[i].startsWith("video/")) { 32379608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang size_t encoderInputBuffers = 32479608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang doProfileEncoderInputBuffers(name, mimes[i], caps); 32579608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang if (encoderInputBuffers > maxEncoderInputBuffers) { 32679608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang maxEncoderInputBuffers = encoderInputBuffers; 32779608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang } 32879608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang } 3299e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu } 3309e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu } 3319e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu } 33279608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang if (maxEncoderInputBuffers > 0) { 33379608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang char tmp[32]; 33479608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang sprintf(tmp, "%zu", maxEncoderInputBuffers); 33579608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang global_results->add(kMaxEncoderInputBuffers, tmp); 33679608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang } 3379ba21b9418d10ddcc39f08901e24fbf43d82b2bcRonghua Wu global_results->add(kPolicySupportsMultipleSecureCodecs, supportMultipleSecureCodecs); 3389e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu} 3399e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu 34065c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wustatic AString globalResultsToXml(const CodecSettings& results) { 34165c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu AString ret; 3429e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu for (size_t i = 0; i < results.size(); ++i) { 34365c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu AString setting = AStringPrintf( 34465c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu " <Setting name=\"%s\" value=\"%s\" />\n", 34565c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu results.keyAt(i).c_str(), 34665c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu results.valueAt(i).c_str()); 34765c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu ret.append(setting); 3489e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu } 34965c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu return ret; 35065c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu} 3519e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu 35265c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wustatic AString codecResultsToXml(const KeyedVector<AString, CodecSettings>& results) { 35365c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu AString ret; 3549e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu for (size_t i = 0; i < results.size(); ++i) { 3559e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu AString name; 3569e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu AString mime; 35765c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu if (!splitString(results.keyAt(i), " ", &name, &mime)) { 3589e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu continue; 3599e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu } 36065c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu AString codec = 36165c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu AStringPrintf(" <MediaCodec name=\"%s\" type=\"%s\" update=\"true\" >\n", 36265c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu name.c_str(), 36365c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu mime.c_str()); 36465c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu ret.append(codec); 3659e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu CodecSettings settings = results.valueAt(i); 3669e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu for (size_t i = 0; i < settings.size(); ++i) { 3679e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu // WARNING: we assume all the settings are "Limit". Currently we have only one type 3689e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu // of setting in this case, which is "max-supported-instances". 36965c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu AString setting = AStringPrintf( 37065c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu " <Limit name=\"%s\" value=\"%s\" />\n", 3719e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu settings.keyAt(i).c_str(), 3729e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu settings.valueAt(i).c_str()); 37365c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu ret.append(setting); 3749e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu } 37565c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu ret.append(" </MediaCodec>\n"); 37665c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu } 37765c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu return ret; 37865c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu} 37965c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu 38065c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wuvoid exportResultsToXML( 38165c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu const char *fileName, 38265c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu const CodecSettings& global_results, 38365c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu const KeyedVector<AString, CodecSettings>& encoder_results, 38465c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu const KeyedVector<AString, CodecSettings>& decoder_results) { 38565c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu if (global_results.size() == 0 && encoder_results.size() == 0 && decoder_results.size() == 0) { 38665c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu return; 3879e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu } 3889e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu 38965c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu AString overrides; 39019352b3287480394aa9963276305d5168a7adf85Ronghua Wu overrides.append(getProfilingVersionString()); 39119352b3287480394aa9963276305d5168a7adf85Ronghua Wu overrides.append("\n"); 39265c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu overrides.append("<MediaCodecs>\n"); 39365c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu if (global_results.size() > 0) { 39465c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu overrides.append(" <Settings>\n"); 39565c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu overrides.append(globalResultsToXml(global_results)); 39665c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu overrides.append(" </Settings>\n"); 39765c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu } 39865c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu if (encoder_results.size() > 0) { 39965c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu overrides.append(" <Encoders>\n"); 40065c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu overrides.append(codecResultsToXml(encoder_results)); 40165c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu overrides.append(" </Encoders>\n"); 40265c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu } 40365c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu if (decoder_results.size() > 0) { 40465c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu overrides.append(" <Decoders>\n"); 40565c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu overrides.append(codecResultsToXml(decoder_results)); 40665c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu overrides.append(" </Decoders>\n"); 4073b0da19c78f6a61ed343a07f2448b94faafe4c02Lajos Molnar } 40865c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu overrides.append("</MediaCodecs>\n"); 4099e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu 41065c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu FILE *f = fopen(fileName, "wb"); 4119e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu if (f == NULL) { 4129e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu ALOGE("Failed to open %s for writing.", fileName); 4139e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu return; 4149e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu } 4159e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu if (fwrite(overrides.c_str(), 1, overrides.size(), f) != overrides.size()) { 4169e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu ALOGE("Failed to write to %s.", fileName); 4179e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu } 4189e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu fclose(f); 4199e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu} 4209e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu 4219e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu} // namespace android 422