From 8ee516a515c70a492c395b67ce12e19e7d159804 Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Tue, 8 May 2012 11:21:26 -0700 Subject: Submit codec specific data automatically if it is contained in the format passed to MediaCodec::configure. Change-Id: I8ef6755e8389ec47b44a9c70904ea6c03a00f4f2 related-to-bug: 6364139 --- media/libstagefright/MediaCodec.cpp | 72 +++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) (limited to 'media/libstagefright/MediaCodec.cpp') diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp index 2df0dd2..e032cfc 100644 --- a/media/libstagefright/MediaCodec.cpp +++ b/media/libstagefright/MediaCodec.cpp @@ -646,6 +646,28 @@ void MediaCodec::onMessageReceived(const sp &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 &msg) { format->setInt32("encoder", true); } + extractCSD(format); + mCodec->initiateConfigureComponent(format); break; } @@ -1107,6 +1131,54 @@ void MediaCodec::onMessageReceived(const sp &msg) { } } +void MediaCodec::extractCSD(const sp &format) { + mCSD.clear(); + + size_t i = 0; + for (;;) { + sp 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 csd = *mCSD.begin(); + mCSD.erase(mCSD.begin()); + + const sp &codecInputData = + (mCrypto != NULL) ? info->mEncryptedData : info->mData; + + if (csd->size() > codecInputData->capacity()) { + return -EINVAL; + } + + memcpy(codecInputData->data(), csd->data(), csd->size()); + + AString errorDetailMsg; + + sp 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; -- cgit v1.1