summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/MediaCodec.cpp
diff options
context:
space:
mode:
authorAndy McFadden <fadden@android.com>2013-02-19 07:28:30 -0800
committerAndy McFadden <fadden@android.com>2013-03-04 15:03:53 -0800
commitf779bb50d9746d9526541c3e6dcdf619cac941b7 (patch)
treecee03011ebf84cfcd704ead0744e0b53dd91c4f7 /media/libstagefright/MediaCodec.cpp
parent10774e144b3c99afad9a5070ccf50fdb12b5fb4e (diff)
downloadframeworks_av-f779bb50d9746d9526541c3e6dcdf619cac941b7.zip
frameworks_av-f779bb50d9746d9526541c3e6dcdf619cac941b7.tar.gz
frameworks_av-f779bb50d9746d9526541c3e6dcdf619cac941b7.tar.bz2
Implement Surface input to MediaCodec.
Also, renamed a CHECK_INTERFACE macro that was clashing with the Binder version. Bug 7991062 Change-Id: If5e6ed0a06d9f67975497676e4b05abe3aa3d6c0
Diffstat (limited to 'media/libstagefright/MediaCodec.cpp')
-rw-r--r--media/libstagefright/MediaCodec.cpp101
1 files changed, 101 insertions, 0 deletions
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 83be0fd..79ea04c 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -30,6 +30,7 @@
#include <media/stagefright/foundation/AString.h>
#include <media/stagefright/foundation/hexdump.h>
#include <media/stagefright/ACodec.h>
+#include <media/stagefright/BufferProducerWrapper.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/NativeWindowWrapper.h>
@@ -62,6 +63,7 @@ MediaCodec::MediaCodec(const sp<ALooper> &looper)
: mState(UNINITIALIZED),
mLooper(looper),
mCodec(new ACodec),
+ mReplyID(0),
mFlags(0),
mSoftRenderer(NULL),
mDequeueInputTimeoutGeneration(0),
@@ -154,6 +156,28 @@ status_t MediaCodec::configure(
return PostAndAwaitResponse(msg, &response);
}
+status_t MediaCodec::createInputSurface(
+ sp<IGraphicBufferProducer>* bufferProducer) {
+ sp<AMessage> msg = new AMessage(kWhatCreateInputSurface, id());
+
+ // TODO(fadden): require MediaFormat colorFormat == AndroidOpaque
+
+ sp<AMessage> response;
+ status_t err = PostAndAwaitResponse(msg, &response);
+ if (err == NO_ERROR) {
+ // unwrap the sp<IGraphicBufferProducer>
+ sp<RefBase> obj;
+ bool found = response->findObject("input-surface", &obj);
+ CHECK(found);
+ sp<BufferProducerWrapper> wrapper(
+ static_cast<BufferProducerWrapper*>(obj.get()));
+ *bufferProducer = wrapper->getBufferProducer();
+ } else {
+ ALOGW("createInputSurface failed, err=%d", err);
+ }
+ return err;
+}
+
status_t MediaCodec::start() {
sp<AMessage> msg = new AMessage(kWhatStart, id());
@@ -232,6 +256,8 @@ status_t MediaCodec::queueSecureInputBuffer(
}
status_t MediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) {
+ // TODO(fadden): fail if an input Surface has been configured
+
sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, id());
msg->setInt64("timeoutUs", timeoutUs);
@@ -288,6 +314,13 @@ status_t MediaCodec::releaseOutputBuffer(size_t index) {
return PostAndAwaitResponse(msg, &response);
}
+status_t MediaCodec::signalEndOfInputStream() {
+ sp<AMessage> msg = new AMessage(kWhatSignalEndOfInputStream, id());
+
+ sp<AMessage> response;
+ return PostAndAwaitResponse(msg, &response);
+}
+
status_t MediaCodec::getOutputFormat(sp<AMessage> *format) const {
sp<AMessage> msg = new AMessage(kWhatGetOutputFormat, id());
@@ -575,6 +608,36 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
break;
}
+ case ACodec::kWhatInputSurfaceCreated:
+ {
+ // response to ACodec::kWhatCreateInputSurface
+ status_t err = NO_ERROR;
+ sp<AMessage> response = new AMessage();
+ if (!msg->findInt32("err", &err)) {
+ sp<RefBase> obj;
+ msg->findObject("input-surface", &obj);
+ CHECK(obj != NULL);
+ response->setObject("input-surface", obj);
+ } else {
+ response->setInt32("err", err);
+ }
+ response->postReply(mReplyID);
+ break;
+ }
+
+ case ACodec::kWhatSignaledInputEOS:
+ {
+ // response to ACodec::kWhatSignalEndOfInputStream
+ sp<AMessage> response = new AMessage();
+ status_t err;
+ if (msg->findInt32("err", &err)) {
+ response->setInt32("err", err);
+ }
+ response->postReply(mReplyID);
+ break;
+ }
+
+
case ACodec::kWhatBuffersAllocated:
{
int32_t portIndex;
@@ -881,6 +944,25 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
break;
}
+ case kWhatCreateInputSurface:
+ {
+ uint32_t replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+
+ // Must be configured, but can't have been started yet.
+ if (mState != CONFIGURED) {
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", INVALID_OPERATION);
+
+ response->postReply(replyID);
+ break;
+ }
+
+ mReplyID = replyID;
+ mCodec->initiateCreateInputSurface();
+ break;
+ }
+
case kWhatStart:
{
uint32_t replyID;
@@ -947,6 +1029,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
case kWhatDequeueInputBuffer:
{
+ // TODO(fadden): make this fail if we're using an input Surface
uint32_t replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
@@ -1093,6 +1176,24 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
break;
}
+ case kWhatSignalEndOfInputStream:
+ {
+ uint32_t replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+
+ if (mState != STARTED || (mFlags & kFlagStickyError)) {
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", INVALID_OPERATION);
+
+ response->postReply(replyID);
+ break;
+ }
+
+ mReplyID = replyID;
+ mCodec->signalEndOfInputStream();
+ break;
+ }
+
case kWhatGetBuffers:
{
uint32_t replyID;