diff options
author | Andreas Huber <andih@google.com> | 2012-05-08 11:21:26 -0700 |
---|---|---|
committer | Andreas Huber <andih@google.com> | 2012-05-08 11:26:22 -0700 |
commit | 8ee516a515c70a492c395b67ce12e19e7d159804 (patch) | |
tree | ae968718f25cd7972a03c00e7496a6deb225fc1f /media/libstagefright/MediaCodec.cpp | |
parent | a62bde0a391f65a418d77c46e6ba468433d81dba (diff) | |
download | frameworks_av-8ee516a515c70a492c395b67ce12e19e7d159804.zip frameworks_av-8ee516a515c70a492c395b67ce12e19e7d159804.tar.gz frameworks_av-8ee516a515c70a492c395b67ce12e19e7d159804.tar.bz2 |
Submit codec specific data automatically
if it is contained in the format passed to MediaCodec::configure.
Change-Id: I8ef6755e8389ec47b44a9c70904ea6c03a00f4f2
related-to-bug: 6364139
Diffstat (limited to 'media/libstagefright/MediaCodec.cpp')
-rw-r--r-- | media/libstagefright/MediaCodec.cpp | 72 |
1 files changed, 72 insertions, 0 deletions
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<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; |