diff options
| author | Chong Zhang <chz@google.com> | 2015-05-19 17:30:34 -0700 | 
|---|---|---|
| committer | Chong Zhang <chz@google.com> | 2015-05-21 18:12:21 -0700 | 
| commit | 79608158c2254fe1357959157f2d0c1560a8a6c6 (patch) | |
| tree | 17e8aede8ce700ae9c169a23fad547eac5c6bc6a | |
| parent | 2232aee25e4df7d04446912e8ad9e9dc44d8ec16 (diff) | |
| download | frameworks_av-79608158c2254fe1357959157f2d0c1560a8a6c6.zip frameworks_av-79608158c2254fe1357959157f2d0c1560a8a6c6.tar.gz frameworks_av-79608158c2254fe1357959157f2d0c1560a8a6c6.tar.bz2  | |
stagefright: measure max encoder buffer count for persistent surface
bug: 19127604
Change-Id: I9a9b29b527d20f43a5a0188380baf2242bd31507
| -rw-r--r-- | include/media/stagefright/MediaCodecList.h | 2 | ||||
| -rw-r--r-- | media/libstagefright/MediaCodec.cpp | 30 | ||||
| -rw-r--r-- | media/libstagefright/MediaCodecList.cpp | 2 | ||||
| -rw-r--r-- | media/libstagefright/MediaCodecListOverrides.cpp | 76 | ||||
| -rw-r--r-- | media/libstagefright/omx/OMXNodeInstance.cpp | 10 | 
5 files changed, 107 insertions, 13 deletions
diff --git a/include/media/stagefright/MediaCodecList.h b/include/media/stagefright/MediaCodecList.h index ce34338..df5e519 100644 --- a/include/media/stagefright/MediaCodecList.h +++ b/include/media/stagefright/MediaCodecList.h @@ -32,6 +32,8 @@  namespace android { +extern const char *kMaxEncoderInputBuffers; +  struct AMessage;  struct MediaCodecList : public BnMediaCodecList { diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp index 46c154d..6f22e26 100644 --- a/media/libstagefright/MediaCodec.cpp +++ b/media/libstagefright/MediaCodec.cpp @@ -26,6 +26,7 @@  #include <binder/IPCThreadState.h>  #include <binder/IServiceManager.h>  #include <binder/MemoryDealer.h> +#include <gui/BufferQueue.h>  #include <gui/Surface.h>  #include <media/ICrypto.h>  #include <media/IOMX.h> @@ -320,6 +321,27 @@ sp<PersistentSurface> MediaCodec::CreatePersistentInputSurface() {      CHECK_EQ(client.connect(), (status_t)OK);      sp<IOMX> omx = client.interface(); +    const sp<IMediaCodecList> mediaCodecList = MediaCodecList::getInstance(); +    if (mediaCodecList == NULL) { +        ALOGE("Failed to obtain MediaCodecList!"); +        return NULL; // if called from Java should raise IOException +    } + +    AString tmp; +    sp<AMessage> globalSettings = mediaCodecList->getGlobalSettings(); +    if (globalSettings == NULL || !globalSettings->findString( +            kMaxEncoderInputBuffers, &tmp)) { +        ALOGE("Failed to get encoder input buffer count!"); +        return NULL; +    } + +    int32_t bufferCount = strtol(tmp.c_str(), NULL, 10); +    if (bufferCount <= 0 +            || bufferCount > BufferQueue::MAX_MAX_ACQUIRED_BUFFERS) { +        ALOGE("Encoder input buffer count is invalid!"); +        return NULL; +    } +      sp<IGraphicBufferProducer> bufferProducer;      sp<IGraphicBufferConsumer> bufferConsumer; @@ -331,6 +353,14 @@ sp<PersistentSurface> MediaCodec::CreatePersistentInputSurface() {          return NULL;      } +    err = bufferConsumer->setMaxAcquiredBufferCount(bufferCount); + +    if (err != NO_ERROR) { +        ALOGE("Unable to set BQ max acquired buffer count to %u: %d", +                bufferCount, err); +        return NULL; +    } +      return new PersistentSurface(bufferProducer, bufferConsumer);  } diff --git a/media/libstagefright/MediaCodecList.cpp b/media/libstagefright/MediaCodecList.cpp index d2352bc..6708828 100644 --- a/media/libstagefright/MediaCodecList.cpp +++ b/media/libstagefright/MediaCodecList.cpp @@ -42,6 +42,8 @@  namespace android { +const char *kMaxEncoderInputBuffers = "max-video-encoder-input-buffers"; +  static Mutex sInitMutex;  static MediaCodecList *gCodecList = NULL; 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 <media/IMediaCodecList.h>  #include <media/MediaCodecInfo.h>  #include <media/MediaResourcePolicy.h> +#include <media/openmax/OMX_IVCommon.h>  #include <media/stagefright/foundation/AMessage.h>  #include <media/stagefright/MediaCodec.h> +#include <media/stagefright/MediaCodecList.h>  namespace android { @@ -86,6 +88,7 @@ static sp<AMessage> 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<AMessage> getMeasureFormat(      return format;  } +static size_t doProfileEncoderInputBuffers( +        AString name, AString mime, sp<MediaCodecInfo::Capabilities> caps) { +    ALOGV("doProfileEncoderInputBuffers: name %s, mime %s", name.c_str(), mime.c_str()); + +    sp<AMessage> 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<ALooper> looper = new ALooper; +    looper->setName("MediaCodec_looper"); +    looper->start( +            false /* runOnCallingThread */, false /* canCallJava */, ANDROID_PRIORITY_AUDIO); + +    sp<MediaCodec> 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<IGraphicBufferProducer> 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<MediaCodecInfo::Capabilities> caps) {      sp<AMessage> 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<Surface> nativeWindow;          const sp<ICrypto> 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<AString, sp<MediaCodecInfo::Capabilities>> codecsNeedMeasure;      AString supportMultipleSecureCodecs = "true"; +    size_t maxEncoderInputBuffers = 0;      for (size_t i = 0; i < infos.size(); ++i) {          const sp<MediaCodecInfo> 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);  } diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp index 91cee73..0540a82 100644 --- a/media/libstagefright/omx/OMXNodeInstance.cpp +++ b/media/libstagefright/omx/OMXNodeInstance.cpp @@ -868,17 +868,9 @@ status_t OMXNodeInstance::createPersistentInputSurface(      consumer->setConsumerName(name);      consumer->setConsumerUsageBits(GRALLOC_USAGE_HW_VIDEO_ENCODER); -    status_t err = consumer->setMaxAcquiredBufferCount( -            BufferQueue::MAX_MAX_ACQUIRED_BUFFERS); -    if (err != NO_ERROR) { -        ALOGE("Unable to set BQ max acquired buffer count to %u: %d", -                BufferQueue::MAX_MAX_ACQUIRED_BUFFERS, err); -        return err; -    } -      sp<BufferQueue::ProxyConsumerListener> proxy =          new BufferQueue::ProxyConsumerListener(NULL); -    err = consumer->consumerConnect(proxy, false); +    status_t err = consumer->consumerConnect(proxy, false);      if (err != NO_ERROR) {          ALOGE("Error connecting to BufferQueue: %s (%d)",                  strerror(-err), err);  | 
