From 79608158c2254fe1357959157f2d0c1560a8a6c6 Mon Sep 17 00:00:00 2001 From: Chong Zhang Date: Tue, 19 May 2015 17:30:34 -0700 Subject: stagefright: measure max encoder buffer count for persistent surface bug: 19127604 Change-Id: I9a9b29b527d20f43a5a0188380baf2242bd31507 --- media/libstagefright/MediaCodecListOverrides.cpp | 76 ++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 4 deletions(-) (limited to 'media/libstagefright/MediaCodecListOverrides.cpp') diff --git a/media/libstagefright/MediaCodecListOverrides.cpp b/media/libstagefright/MediaCodecListOverrides.cpp index 0d95676..006454d 100644 --- a/media/libstagefright/MediaCodecListOverrides.cpp +++ b/media/libstagefright/MediaCodecListOverrides.cpp @@ -25,8 +25,10 @@ #include #include #include +#include #include #include +#include namespace android { @@ -86,6 +88,7 @@ static sp getMeasureFormat( int32_t bitrate = 0; getMeasureBitrate(caps, &bitrate); format->setInt32("bitrate", bitrate); + format->setInt32("encoder", 1); } if (mime.startsWith("video/")) { @@ -114,15 +117,67 @@ static sp getMeasureFormat( return format; } +static size_t doProfileEncoderInputBuffers( + AString name, AString mime, sp caps) { + ALOGV("doProfileEncoderInputBuffers: name %s, mime %s", name.c_str(), mime.c_str()); + + sp format = getMeasureFormat(true /* isEncoder */, mime, caps); + if (format == NULL) { + return 0; + } + + format->setInt32("color-format", OMX_COLOR_FormatAndroidOpaque); + ALOGV("doProfileEncoderInputBuffers: format %s", format->debugString().c_str()); + + status_t err = OK; + sp looper = new ALooper; + looper->setName("MediaCodec_looper"); + looper->start( + false /* runOnCallingThread */, false /* canCallJava */, ANDROID_PRIORITY_AUDIO); + + sp codec = MediaCodec::CreateByComponentName(looper, name.c_str(), &err); + if (err != OK) { + ALOGE("Failed to create codec: %s", name.c_str()); + return 0; + } + + err = codec->configure(format, NULL, NULL, MediaCodec::CONFIGURE_FLAG_ENCODE); + if (err != OK) { + ALOGE("Failed to configure codec: %s with mime: %s", name.c_str(), mime.c_str()); + codec->release(); + return 0; + } + + sp bufferProducer; + err = codec->createInputSurface(&bufferProducer); + if (err != OK) { + ALOGE("Failed to create surface: %s with mime: %s", name.c_str(), mime.c_str()); + codec->release(); + return 0; + } + + int minUndequeued = 0; + err = bufferProducer->query( + NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeued); + if (err != OK) { + ALOGE("Failed to query NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS"); + minUndequeued = 0; + } + + err = codec->release(); + if (err != OK) { + ALOGW("Failed to release codec: %s with mime: %s", name.c_str(), mime.c_str()); + } + + return minUndequeued; +} + static size_t doProfileCodecs( bool isEncoder, AString name, AString mime, sp caps) { sp format = getMeasureFormat(isEncoder, mime, caps); if (format == NULL) { return 0; } - if (isEncoder) { - format->setInt32("encoder", 1); - } ALOGV("doProfileCodecs %s %s %s %s", name.c_str(), mime.c_str(), isEncoder ? "encoder" : "decoder", format->debugString().c_str()); @@ -144,7 +199,7 @@ static size_t doProfileCodecs( } const sp nativeWindow; const sp crypto; - uint32_t flags = 0; + uint32_t flags = isEncoder ? MediaCodec::CONFIGURE_FLAG_ENCODE : 0; ALOGV("doProfileCodecs configure"); err = codec->configure(format, nativeWindow, crypto, flags); if (err != OK) { @@ -211,6 +266,7 @@ void profileCodecs( bool forceToMeasure) { KeyedVector> codecsNeedMeasure; AString supportMultipleSecureCodecs = "true"; + size_t maxEncoderInputBuffers = 0; for (size_t i = 0; i < infos.size(); ++i) { const sp info = infos[i]; AString name = info->getCodecName(); @@ -251,9 +307,21 @@ void profileCodecs( supportMultipleSecureCodecs = "false"; } } + if (info->isEncoder() && mimes[i].startsWith("video/")) { + size_t encoderInputBuffers = + doProfileEncoderInputBuffers(name, mimes[i], caps); + if (encoderInputBuffers > maxEncoderInputBuffers) { + maxEncoderInputBuffers = encoderInputBuffers; + } + } } } } + if (maxEncoderInputBuffers > 0) { + char tmp[32]; + sprintf(tmp, "%zu", maxEncoderInputBuffers); + global_results->add(kMaxEncoderInputBuffers, tmp); + } global_results->add(kPolicySupportsMultipleSecureCodecs, supportMultipleSecureCodecs); } -- cgit v1.1