Loading include/media/stagefright/MediaCodecList.h +2 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,8 @@ namespace android { extern const char *kMaxEncoderInputBuffers; struct AMessage; struct MediaCodecList : public BnMediaCodecList { Loading media/libstagefright/MediaCodec.cpp +30 −0 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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; Loading @@ -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); } Loading media/libstagefright/MediaCodecList.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,8 @@ namespace android { const char *kMaxEncoderInputBuffers = "max-video-encoder-input-buffers"; static Mutex sInitMutex; static MediaCodecList *gCodecList = NULL; Loading media/libstagefright/MediaCodecListOverrides.cpp +72 −4 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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/")) { Loading Loading @@ -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()); Loading @@ -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) { Loading Loading @@ -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(); Loading Loading @@ -251,8 +307,20 @@ 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); } Loading media/libstagefright/omx/OMXNodeInstance.cpp +1 −9 Original line number Diff line number Diff line Loading @@ -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); Loading Loading
include/media/stagefright/MediaCodecList.h +2 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,8 @@ namespace android { extern const char *kMaxEncoderInputBuffers; struct AMessage; struct MediaCodecList : public BnMediaCodecList { Loading
media/libstagefright/MediaCodec.cpp +30 −0 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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; Loading @@ -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); } Loading
media/libstagefright/MediaCodecList.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,8 @@ namespace android { const char *kMaxEncoderInputBuffers = "max-video-encoder-input-buffers"; static Mutex sInitMutex; static MediaCodecList *gCodecList = NULL; Loading
media/libstagefright/MediaCodecListOverrides.cpp +72 −4 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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/")) { Loading Loading @@ -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()); Loading @@ -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) { Loading Loading @@ -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(); Loading Loading @@ -251,8 +307,20 @@ 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); } Loading
media/libstagefright/omx/OMXNodeInstance.cpp +1 −9 Original line number Diff line number Diff line Loading @@ -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); Loading