Loading media/libstagefright/ACodecBufferChannel.cpp +39 −10 Original line number Diff line number Diff line Loading @@ -22,11 +22,14 @@ #include <C2Buffer.h> #include <Codec2BufferUtils.h> #include <android/hardware/cas/native/1.0/IDescrambler.h> #include <android/hardware/drm/1.0/types.h> #include <binder/MemoryDealer.h> #include <hidlmemory/FrameworkUtils.h> #include <media/openmax/OMX_Core.h> #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/AMessage.h> #include <media/stagefright/foundation/AUtils.h> #include <media/stagefright/MediaCodec.h> Loading Loading @@ -91,15 +94,27 @@ ACodecBufferChannel::ACodecBufferChannel( } status_t ACodecBufferChannel::queueInputBuffer(const sp<MediaCodecBuffer> &buffer) { if (mDealer != nullptr) { return -ENOSYS; } std::shared_ptr<const std::vector<const BufferInfo>> array( std::atomic_load(&mInputBuffers)); BufferInfoIterator it = findClientBuffer(array, buffer); if (it == array->end()) { return -ENOENT; } if (it->mClientBuffer != it->mCodecBuffer) { // Copy metadata from client to codec buffer. it->mCodecBuffer->meta()->clear(); int64_t timeUs; CHECK(it->mClientBuffer->meta()->findInt64("timeUs", &timeUs)); it->mCodecBuffer->meta()->setInt64("timeUs", timeUs); int32_t eos; if (it->mClientBuffer->meta()->findInt32("eos", &eos)) { it->mCodecBuffer->meta()->setInt32("eos", eos); } int32_t csd; if (it->mClientBuffer->meta()->findInt32("csd", &csd)) { it->mCodecBuffer->meta()->setInt32("csd", csd); } } ALOGV("queueInputBuffer #%d", it->mBufferId); sp<AMessage> msg = mInputBufferFilled->dup(); msg->setObject("buffer", it->mCodecBuffer); Loading Loading @@ -267,17 +282,31 @@ status_t ACodecBufferChannel::attachBuffer( } C2ConstLinearBlock block{c2Buffer->data().linearBlocks().front()}; C2ReadView view{block.map().get()}; if (view.capacity() > buffer->capacity()) { return -ENOSYS; } memcpy(buffer->base(), view.data(), view.capacity()); buffer->setRange(0, view.capacity()); size_t copyLength = std::min(size_t(view.capacity()), buffer->capacity()); ALOGV_IF(view.capacity() > buffer->capacity(), "view.capacity() = %zu, buffer->capacity() = %zu", view.capacity(), buffer->capacity()); memcpy(buffer->base(), view.data(), copyLength); buffer->setRange(0, copyLength); break; } case C2BufferData::GRAPHIC: { // TODO sp<ABuffer> imageData; if (!buffer->format()->findBuffer("image-data", &imageData)) { return -ENOSYS; } if (c2Buffer->data().graphicBlocks().size() != 1u) { return -ENOSYS; } C2ConstGraphicBlock block{c2Buffer->data().graphicBlocks().front()}; const C2GraphicView view{block.map().get()}; status_t err = ImageCopy( buffer->base(), (const MediaImage2 *)(imageData->base()), view); if (err != OK) { return err; } break; } case C2BufferData::LINEAR_CHUNKS: [[fallthrough]]; case C2BufferData::GRAPHIC_CHUNKS: [[fallthrough]]; default: Loading media/libstagefright/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -273,6 +273,7 @@ cc_library { "libutils", "libmedia_helper", "libsfplugin_ccodec", "libsfplugin_ccodec_utils", "libstagefright_codecbase", "libstagefright_foundation", "libstagefright_omx_utils", Loading media/libstagefright/MediaCodec.cpp +55 −3 Original line number Diff line number Diff line Loading @@ -2496,6 +2496,18 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { } break; } if (!mLeftover.empty()) { ssize_t index = dequeuePortBuffer(kPortIndexInput); CHECK_GE(index, 0); status_t err = handleLeftover(index); if (err != OK) { setStickyError(err); postActivityNotificationIfPossible(); cancelPendingDequeueOperations(); } break; } if (mFlags & kFlagIsAsync) { if (!mHaveInputSurface) { Loading Loading @@ -3185,7 +3197,15 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { break; } status_t err = onQueueInputBuffer(msg); status_t err = UNKNOWN_ERROR; if (!mLeftover.empty()) { mLeftover.push_back(msg); size_t index; msg->findSize("index", &index); err = handleLeftover(index); } else { err = onQueueInputBuffer(msg); } PostReplyWithError(replyID, err); break; Loading Loading @@ -3472,8 +3492,8 @@ status_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) { sp<hardware::HidlMemory> memory; size_t offset = 0; if ((mFlags & kFlagUseBlockModel) && mOwnerName.startsWith("codec2::")) { if (mCrypto) { if (mFlags & kFlagUseBlockModel) { if (hasCryptoOrDescrambler()) { constexpr size_t kInitialDealerCapacity = 1048576; // 1MB thread_local sp<MemoryDealer> sDealer = new MemoryDealer( kInitialDealerCapacity, "CSD(1MB)"); Loading Loading @@ -3598,6 +3618,9 @@ void MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex, bool isReclaim) { CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); Mutex::Autolock al(mBufferLock); if (portIndex == kPortIndexInput) { mLeftover.clear(); } for (size_t i = 0; i < mPortBuffers[portIndex].size(); ++i) { BufferInfo *info = &mPortBuffers[portIndex][i]; Loading Loading @@ -3728,7 +3751,26 @@ status_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) { err = mBufferChannel->attachEncryptedBuffer( memory, (mFlags & kFlagIsSecure), key, iv, mode, pattern, offset, subSamples, numSubSamples, buffer); } else { err = UNKNOWN_ERROR; } if (err == OK && !buffer->asC2Buffer() && c2Buffer && c2Buffer->data().type() == C2BufferData::LINEAR) { C2ConstLinearBlock block{c2Buffer->data().linearBlocks().front()}; if (block.size() > buffer->size()) { C2ConstLinearBlock leftover = block.subBlock( block.offset() + buffer->size(), block.size() - buffer->size()); sp<WrapperObject<std::shared_ptr<C2Buffer>>> obj{ new WrapperObject<std::shared_ptr<C2Buffer>>{ C2Buffer::CreateLinearBuffer(leftover)}}; msg->setObject("c2buffer", obj); mLeftover.push_front(msg); // Not sending EOS if we have leftovers flags &= ~BUFFER_FLAG_EOS; } } offset = buffer->offset(); size = buffer->size(); if (err != OK) { Loading Loading @@ -3793,6 +3835,16 @@ status_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) { return err; } status_t MediaCodec::handleLeftover(size_t index) { if (mLeftover.empty()) { return OK; } sp<AMessage> msg = mLeftover.front(); mLeftover.pop_front(); msg->setSize("index", index); return onQueueInputBuffer(msg); } //static size_t MediaCodec::CreateFramesRenderedMessage( const std::list<FrameRenderTracker::Info> &done, sp<AMessage> &msg) { Loading media/libstagefright/include/media/stagefright/MediaCodec.h +3 −0 Original line number Diff line number Diff line Loading @@ -515,6 +515,9 @@ private: class ReleaseSurface; std::unique_ptr<ReleaseSurface> mReleaseSurface; std::list<sp<AMessage>> mLeftover; status_t handleLeftover(size_t index); sp<BatteryChecker> mBatteryChecker; void statsBufferSent(int64_t presentationUs); Loading Loading
media/libstagefright/ACodecBufferChannel.cpp +39 −10 Original line number Diff line number Diff line Loading @@ -22,11 +22,14 @@ #include <C2Buffer.h> #include <Codec2BufferUtils.h> #include <android/hardware/cas/native/1.0/IDescrambler.h> #include <android/hardware/drm/1.0/types.h> #include <binder/MemoryDealer.h> #include <hidlmemory/FrameworkUtils.h> #include <media/openmax/OMX_Core.h> #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/AMessage.h> #include <media/stagefright/foundation/AUtils.h> #include <media/stagefright/MediaCodec.h> Loading Loading @@ -91,15 +94,27 @@ ACodecBufferChannel::ACodecBufferChannel( } status_t ACodecBufferChannel::queueInputBuffer(const sp<MediaCodecBuffer> &buffer) { if (mDealer != nullptr) { return -ENOSYS; } std::shared_ptr<const std::vector<const BufferInfo>> array( std::atomic_load(&mInputBuffers)); BufferInfoIterator it = findClientBuffer(array, buffer); if (it == array->end()) { return -ENOENT; } if (it->mClientBuffer != it->mCodecBuffer) { // Copy metadata from client to codec buffer. it->mCodecBuffer->meta()->clear(); int64_t timeUs; CHECK(it->mClientBuffer->meta()->findInt64("timeUs", &timeUs)); it->mCodecBuffer->meta()->setInt64("timeUs", timeUs); int32_t eos; if (it->mClientBuffer->meta()->findInt32("eos", &eos)) { it->mCodecBuffer->meta()->setInt32("eos", eos); } int32_t csd; if (it->mClientBuffer->meta()->findInt32("csd", &csd)) { it->mCodecBuffer->meta()->setInt32("csd", csd); } } ALOGV("queueInputBuffer #%d", it->mBufferId); sp<AMessage> msg = mInputBufferFilled->dup(); msg->setObject("buffer", it->mCodecBuffer); Loading Loading @@ -267,17 +282,31 @@ status_t ACodecBufferChannel::attachBuffer( } C2ConstLinearBlock block{c2Buffer->data().linearBlocks().front()}; C2ReadView view{block.map().get()}; if (view.capacity() > buffer->capacity()) { return -ENOSYS; } memcpy(buffer->base(), view.data(), view.capacity()); buffer->setRange(0, view.capacity()); size_t copyLength = std::min(size_t(view.capacity()), buffer->capacity()); ALOGV_IF(view.capacity() > buffer->capacity(), "view.capacity() = %zu, buffer->capacity() = %zu", view.capacity(), buffer->capacity()); memcpy(buffer->base(), view.data(), copyLength); buffer->setRange(0, copyLength); break; } case C2BufferData::GRAPHIC: { // TODO sp<ABuffer> imageData; if (!buffer->format()->findBuffer("image-data", &imageData)) { return -ENOSYS; } if (c2Buffer->data().graphicBlocks().size() != 1u) { return -ENOSYS; } C2ConstGraphicBlock block{c2Buffer->data().graphicBlocks().front()}; const C2GraphicView view{block.map().get()}; status_t err = ImageCopy( buffer->base(), (const MediaImage2 *)(imageData->base()), view); if (err != OK) { return err; } break; } case C2BufferData::LINEAR_CHUNKS: [[fallthrough]]; case C2BufferData::GRAPHIC_CHUNKS: [[fallthrough]]; default: Loading
media/libstagefright/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -273,6 +273,7 @@ cc_library { "libutils", "libmedia_helper", "libsfplugin_ccodec", "libsfplugin_ccodec_utils", "libstagefright_codecbase", "libstagefright_foundation", "libstagefright_omx_utils", Loading
media/libstagefright/MediaCodec.cpp +55 −3 Original line number Diff line number Diff line Loading @@ -2496,6 +2496,18 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { } break; } if (!mLeftover.empty()) { ssize_t index = dequeuePortBuffer(kPortIndexInput); CHECK_GE(index, 0); status_t err = handleLeftover(index); if (err != OK) { setStickyError(err); postActivityNotificationIfPossible(); cancelPendingDequeueOperations(); } break; } if (mFlags & kFlagIsAsync) { if (!mHaveInputSurface) { Loading Loading @@ -3185,7 +3197,15 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { break; } status_t err = onQueueInputBuffer(msg); status_t err = UNKNOWN_ERROR; if (!mLeftover.empty()) { mLeftover.push_back(msg); size_t index; msg->findSize("index", &index); err = handleLeftover(index); } else { err = onQueueInputBuffer(msg); } PostReplyWithError(replyID, err); break; Loading Loading @@ -3472,8 +3492,8 @@ status_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) { sp<hardware::HidlMemory> memory; size_t offset = 0; if ((mFlags & kFlagUseBlockModel) && mOwnerName.startsWith("codec2::")) { if (mCrypto) { if (mFlags & kFlagUseBlockModel) { if (hasCryptoOrDescrambler()) { constexpr size_t kInitialDealerCapacity = 1048576; // 1MB thread_local sp<MemoryDealer> sDealer = new MemoryDealer( kInitialDealerCapacity, "CSD(1MB)"); Loading Loading @@ -3598,6 +3618,9 @@ void MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex, bool isReclaim) { CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); Mutex::Autolock al(mBufferLock); if (portIndex == kPortIndexInput) { mLeftover.clear(); } for (size_t i = 0; i < mPortBuffers[portIndex].size(); ++i) { BufferInfo *info = &mPortBuffers[portIndex][i]; Loading Loading @@ -3728,7 +3751,26 @@ status_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) { err = mBufferChannel->attachEncryptedBuffer( memory, (mFlags & kFlagIsSecure), key, iv, mode, pattern, offset, subSamples, numSubSamples, buffer); } else { err = UNKNOWN_ERROR; } if (err == OK && !buffer->asC2Buffer() && c2Buffer && c2Buffer->data().type() == C2BufferData::LINEAR) { C2ConstLinearBlock block{c2Buffer->data().linearBlocks().front()}; if (block.size() > buffer->size()) { C2ConstLinearBlock leftover = block.subBlock( block.offset() + buffer->size(), block.size() - buffer->size()); sp<WrapperObject<std::shared_ptr<C2Buffer>>> obj{ new WrapperObject<std::shared_ptr<C2Buffer>>{ C2Buffer::CreateLinearBuffer(leftover)}}; msg->setObject("c2buffer", obj); mLeftover.push_front(msg); // Not sending EOS if we have leftovers flags &= ~BUFFER_FLAG_EOS; } } offset = buffer->offset(); size = buffer->size(); if (err != OK) { Loading Loading @@ -3793,6 +3835,16 @@ status_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) { return err; } status_t MediaCodec::handleLeftover(size_t index) { if (mLeftover.empty()) { return OK; } sp<AMessage> msg = mLeftover.front(); mLeftover.pop_front(); msg->setSize("index", index); return onQueueInputBuffer(msg); } //static size_t MediaCodec::CreateFramesRenderedMessage( const std::list<FrameRenderTracker::Info> &done, sp<AMessage> &msg) { Loading
media/libstagefright/include/media/stagefright/MediaCodec.h +3 −0 Original line number Diff line number Diff line Loading @@ -515,6 +515,9 @@ private: class ReleaseSurface; std::unique_ptr<ReleaseSurface> mReleaseSurface; std::list<sp<AMessage>> mLeftover; status_t handleLeftover(size_t index); sp<BatteryChecker> mBatteryChecker; void statsBufferSent(int64_t presentationUs); Loading