summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/media/stagefright/MediaCodecList.h2
-rw-r--r--media/libstagefright/MediaCodec.cpp30
-rw-r--r--media/libstagefright/MediaCodecList.cpp2
-rw-r--r--media/libstagefright/MediaCodecListOverrides.cpp76
-rw-r--r--media/libstagefright/omx/OMXNodeInstance.cpp10
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);