summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmds/stagefright/codec.cpp35
-rw-r--r--include/media/stagefright/MediaCodec.h5
-rw-r--r--media/libstagefright/MediaCodec.cpp72
3 files changed, 77 insertions, 35 deletions
diff --git a/cmds/stagefright/codec.cpp b/cmds/stagefright/codec.cpp
index 5a43829d..f3370a54 100644
--- a/cmds/stagefright/codec.cpp
+++ b/cmds/stagefright/codec.cpp
@@ -50,8 +50,6 @@ namespace android {
struct CodecState {
sp<MediaCodec> mCodec;
- Vector<sp<ABuffer> > mCSD;
- size_t mCSDIndex;
Vector<sp<ABuffer> > mInBuffers;
Vector<sp<ABuffer> > mOutBuffers;
bool mSignalledInputEOS;
@@ -126,19 +124,8 @@ static int decode(
CHECK_EQ(err, (status_t)OK);
- size_t j = 0;
- sp<ABuffer> buffer;
- while (format->findBuffer(StringPrintf("csd-%d", j).c_str(), &buffer)) {
- state->mCSD.push_back(buffer);
-
- ++j;
- }
-
- state->mCSDIndex = 0;
state->mSignalledInputEOS = false;
state->mSawOutputEOS = false;
-
- ALOGV("got %d pieces of codec specific data.", state->mCSD.size());
}
CHECK(!stateByTrack.isEmpty());
@@ -157,28 +144,6 @@ static int decode(
ALOGV("got %d input and %d output buffers",
state->mInBuffers.size(), state->mOutBuffers.size());
-
- while (state->mCSDIndex < state->mCSD.size()) {
- size_t index;
- status_t err = codec->dequeueInputBuffer(&index, -1ll);
- CHECK_EQ(err, (status_t)OK);
-
- const sp<ABuffer> &srcBuffer =
- state->mCSD.itemAt(state->mCSDIndex++);
-
- const sp<ABuffer> &buffer = state->mInBuffers.itemAt(index);
-
- memcpy(buffer->data(), srcBuffer->data(), srcBuffer->size());
-
- err = codec->queueInputBuffer(
- index,
- 0 /* offset */,
- srcBuffer->size(),
- 0ll /* timeUs */,
- MediaCodec::BUFFER_FLAG_CODECCONFIG);
-
- CHECK_EQ(err, (status_t)OK);
- }
}
bool sawInputEOS = false;
diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h
index d09049ed..d96007b0 100644
--- a/include/media/stagefright/MediaCodec.h
+++ b/include/media/stagefright/MediaCodec.h
@@ -186,6 +186,8 @@ private:
sp<ICrypto> mCrypto;
+ List<sp<ABuffer> > mCSD;
+
MediaCodec(const sp<ALooper> &looper);
static status_t PostAndAwaitResponse(
@@ -205,6 +207,9 @@ private:
bool handleDequeueOutputBuffer(uint32_t replyID, bool newRequest = false);
void cancelPendingDequeueOperations();
+ void extractCSD(const sp<AMessage> &format);
+ status_t queueCSDInputBuffer(size_t bufferIndex);
+
DISALLOW_EVIL_CONSTRUCTORS(MediaCodec);
};
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 2df0dd29..e032cfcd 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -646,6 +646,28 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
break;
}
+ if (!mCSD.empty()) {
+ ssize_t index = dequeuePortBuffer(kPortIndexInput);
+ CHECK_GE(index, 0);
+
+ // If codec specific data had been specified as
+ // part of the format in the call to configure and
+ // if there's more csd left, we submit it here
+ // clients only get access to input buffers once
+ // this data has been exhausted.
+
+ status_t err = queueCSDInputBuffer(index);
+
+ if (err != OK) {
+ ALOGE("queueCSDInputBuffer failed w/ error %d",
+ err);
+
+ mFlags |= kFlagStickyError;
+ cancelPendingDequeueOperations();
+ }
+ break;
+ }
+
if (mFlags & kFlagDequeueInputPending) {
CHECK(handleDequeueInputBuffer(mDequeueInputReplyID));
@@ -811,6 +833,8 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
format->setInt32("encoder", true);
}
+ extractCSD(format);
+
mCodec->initiateConfigureComponent(format);
break;
}
@@ -1107,6 +1131,54 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
}
}
+void MediaCodec::extractCSD(const sp<AMessage> &format) {
+ mCSD.clear();
+
+ size_t i = 0;
+ for (;;) {
+ sp<ABuffer> csd;
+ if (!format->findBuffer(StringPrintf("csd-%u", i).c_str(), &csd)) {
+ break;
+ }
+
+ mCSD.push_back(csd);
+ ++i;
+ }
+
+ ALOGV("Found %u pieces of codec specific data.", mCSD.size());
+}
+
+status_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) {
+ CHECK(!mCSD.empty());
+
+ BufferInfo *info =
+ &mPortBuffers[kPortIndexInput].editItemAt(bufferIndex);
+
+ sp<ABuffer> csd = *mCSD.begin();
+ mCSD.erase(mCSD.begin());
+
+ const sp<ABuffer> &codecInputData =
+ (mCrypto != NULL) ? info->mEncryptedData : info->mData;
+
+ if (csd->size() > codecInputData->capacity()) {
+ return -EINVAL;
+ }
+
+ memcpy(codecInputData->data(), csd->data(), csd->size());
+
+ AString errorDetailMsg;
+
+ sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id());
+ msg->setSize("index", bufferIndex);
+ msg->setSize("offset", 0);
+ msg->setSize("size", csd->size());
+ msg->setInt64("timeUs", 0ll);
+ msg->setInt32("flags", BUFFER_FLAG_CODECCONFIG);
+ msg->setPointer("errorDetailMsg", &errorDetailMsg);
+
+ return onQueueInputBuffer(msg);
+}
+
void MediaCodec::setState(State newState) {
if (newState == INITIALIZED) {
delete mSoftRenderer;