Sync up to v302
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
From 8d97b4814211158932b8482888f5b7bcc8a5a21e Mon Sep 17 00:00:00 2001
|
||||
From: Houxiang Dai <houxiang.dai@mediatek.com>
|
||||
Date: Thu, 23 Jul 2020 14:07:22 +0800
|
||||
Subject: [PATCH 17/30] ACodec: Handle HDR10+ metadata at
|
||||
OutputPortSettingsChangedState
|
||||
|
||||
[Description]
|
||||
handle kWhatSetParameters message in OutputPortSettingsChangedState
|
||||
handle OMX_EventConfigUpdate event in OutputPortSettingsChangedState
|
||||
|
||||
In HDR10+ test, we have to associate each HDR10+ metadata to a particular
|
||||
frame. If receive a kWhatSetParameters message with "hdr10-plus-info"
|
||||
buffer, it should not be deferred in OutputPortSettingsChangedState and
|
||||
adopt OMX_SetConfig to associates this config with the next input buffer
|
||||
sent in OMX_EmptyThisBuffer. The OMX_EventConfigUpdate event report from
|
||||
component should be handled also in OutputPortSettingsChangedState,
|
||||
where is to associate updated "hdr10-plus-info" metadata with the next
|
||||
output buffer sent via FillBufferDone callback.
|
||||
|
||||
Bug: 157213958
|
||||
Bug: 157435393
|
||||
Change-Id: I27e4614487414063831fa760b9e9ca96b1c3712c
|
||||
(cherry picked from commit c111aa4fda9b5b434edb1b46898ff8dd7e51cec6)
|
||||
---
|
||||
media/libstagefright/ACodec.cpp | 36 ++++++++++++++++++++++++++++++---
|
||||
1 file changed, 33 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
|
||||
index b9d0f5bb72..f843c7f45f 100644
|
||||
--- a/media/libstagefright/ACodec.cpp
|
||||
+++ b/media/libstagefright/ACodec.cpp
|
||||
@@ -8296,13 +8296,34 @@ bool ACodec::OutputPortSettingsChangedState::onMessageReceived(
|
||||
FALLTHROUGH_INTENDED;
|
||||
}
|
||||
case kWhatResume:
|
||||
+ {
|
||||
+ ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
|
||||
+
|
||||
+ mCodec->deferMessage(msg);
|
||||
+ handled = true;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
case kWhatSetParameters:
|
||||
{
|
||||
- if (msg->what() == kWhatResume) {
|
||||
- ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
|
||||
+ sp<AMessage> params;
|
||||
+ CHECK(msg->findMessage("params", ¶ms));
|
||||
+
|
||||
+ sp<ABuffer> hdr10PlusInfo;
|
||||
+ if (params->findBuffer("hdr10-plus-info", &hdr10PlusInfo)) {
|
||||
+ if (hdr10PlusInfo != nullptr && hdr10PlusInfo->size() > 0) {
|
||||
+ (void)mCodec->setHdr10PlusInfo(hdr10PlusInfo);
|
||||
+ }
|
||||
+ params->removeEntryAt(params->findEntryByName("hdr10-plus-info"));
|
||||
+
|
||||
+ if (params->countEntries() == 0) {
|
||||
+ msg->removeEntryAt(msg->findEntryByName("params"));
|
||||
+ }
|
||||
}
|
||||
|
||||
- mCodec->deferMessage(msg);
|
||||
+ if (msg->countEntries() > 0) {
|
||||
+ mCodec->deferMessage(msg);
|
||||
+ }
|
||||
handled = true;
|
||||
break;
|
||||
}
|
||||
@@ -8417,6 +8438,15 @@ bool ACodec::OutputPortSettingsChangedState::onOMXEvent(
|
||||
return false;
|
||||
}
|
||||
|
||||
+ case OMX_EventConfigUpdate:
|
||||
+ {
|
||||
+ CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
|
||||
+
|
||||
+ mCodec->onConfigUpdate((OMX_INDEXTYPE)data2);
|
||||
+
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
default:
|
||||
return BaseState::onOMXEvent(event, data1, data2);
|
||||
}
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
From f3953cb4a425f0e91b52f5f23d54c0a09162815f Mon Sep 17 00:00:00 2001
|
||||
From: wangchenyang <daniellingyx@gmail.com>
|
||||
Date: Thu, 24 Dec 2020 16:55:50 +0800
|
||||
Subject: [PATCH 18/30] Codec2: Initialize InputSurfaceWrapper::Config
|
||||
structure fields
|
||||
|
||||
Initialize the fields of Config structure of
|
||||
InputSurfaceWrapper class. If not initialised, there
|
||||
is a chance of junk values being used during configure
|
||||
|
||||
Bug: 171763471
|
||||
Bug: 175443996
|
||||
Test: TH
|
||||
|
||||
Change-Id: Id5ac827df0c2ef6ad761ab5a235162a9358c1704
|
||||
(cherry picked from commit a1ab7eb891728b77cc4bf03fedd21574bd8ec586)
|
||||
---
|
||||
media/codec2/sfplugin/InputSurfaceWrapper.h | 28 ++++++++++-----------
|
||||
1 file changed, 14 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/media/codec2/sfplugin/InputSurfaceWrapper.h b/media/codec2/sfplugin/InputSurfaceWrapper.h
|
||||
index bb35763f41..479acb109b 100644
|
||||
--- a/media/codec2/sfplugin/InputSurfaceWrapper.h
|
||||
+++ b/media/codec2/sfplugin/InputSurfaceWrapper.h
|
||||
@@ -61,24 +61,24 @@ public:
|
||||
/// Input Surface configuration
|
||||
struct Config {
|
||||
// IN PARAMS (GBS)
|
||||
- float mMinFps; // minimum fps (repeat frame to achieve this)
|
||||
- float mMaxFps; // max fps (via frame drop)
|
||||
- float mCaptureFps; // capture fps
|
||||
- float mCodedFps; // coded fps
|
||||
- bool mSuspended; // suspended
|
||||
- int64_t mTimeOffsetUs; // time offset (input => codec)
|
||||
- int64_t mSuspendAtUs; // suspend/resume time
|
||||
- int64_t mStartAtUs; // start time
|
||||
- bool mStopped; // stopped
|
||||
- int64_t mStopAtUs; // stop time
|
||||
+ float mMinFps = 0.0; // minimum fps (repeat frame to achieve this)
|
||||
+ float mMaxFps = 0.0; // max fps (via frame drop)
|
||||
+ float mCaptureFps = 0.0; // capture fps
|
||||
+ float mCodedFps = 0.0; // coded fps
|
||||
+ bool mSuspended = false; // suspended
|
||||
+ int64_t mTimeOffsetUs = 0; // time offset (input => codec)
|
||||
+ int64_t mSuspendAtUs = 0; // suspend/resume time
|
||||
+ int64_t mStartAtUs = 0; // start time
|
||||
+ bool mStopped = false; // stopped
|
||||
+ int64_t mStopAtUs = 0; // stop time
|
||||
|
||||
// OUT PARAMS (GBS)
|
||||
- int64_t mInputDelayUs; // delay between encoder input and surface input
|
||||
+ int64_t mInputDelayUs = 0; // delay between encoder input and surface input
|
||||
|
||||
// IN PARAMS (CODEC WRAPPER)
|
||||
- float mFixedAdjustedFps; // fixed fps via PTS manipulation
|
||||
- float mMinAdjustedFps; // minimum fps via PTS manipulation
|
||||
- uint64_t mUsage; // consumer usage
|
||||
+ float mFixedAdjustedFps = 0.0; // fixed fps via PTS manipulation
|
||||
+ float mMinAdjustedFps = 0.0; // minimum fps via PTS manipulation
|
||||
+ uint64_t mUsage = 0; // consumer usage
|
||||
};
|
||||
|
||||
/**
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
From a141c7102252377bc882b982b36980edb60f931e Mon Sep 17 00:00:00 2001
|
||||
From: Wonsik Kim <wonsik@google.com>
|
||||
Date: Tue, 5 Jan 2021 18:58:15 -0800
|
||||
Subject: [PATCH 19/30] CCodec: store flushed config as work items
|
||||
|
||||
Store flushed config as work items and queue them to the component
|
||||
directly, instead of going through MediaCodecBuffer.
|
||||
|
||||
Bug: 176501678
|
||||
Test: atest CtsMediaTestCases -- --module-arg CtsMediaTestCases:size:small
|
||||
Test: atest CtsMediaTestCases:AdaptivePlaybackTest
|
||||
Merged-In: I19991101c388eca49226ad2abc37df9cea22dbb8
|
||||
Change-Id: I19991101c388eca49226ad2abc37df9cea22dbb8
|
||||
(cherry picked from commit 5ebfcb24855e526ec040b9f41d216f7604b8981a)
|
||||
---
|
||||
media/codec2/sfplugin/CCodecBufferChannel.cpp | 119 ++++++++----------
|
||||
media/codec2/sfplugin/CCodecBufferChannel.h | 2 +-
|
||||
2 files changed, 53 insertions(+), 68 deletions(-)
|
||||
|
||||
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
|
||||
index 1654b11c31..b8ca41b9a8 100644
|
||||
--- a/media/codec2/sfplugin/CCodecBufferChannel.cpp
|
||||
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
|
||||
@@ -1300,54 +1300,30 @@ status_t CCodecBufferChannel::requestInitialInputBuffers() {
|
||||
return a.capacity < b.capacity;
|
||||
});
|
||||
|
||||
- {
|
||||
- Mutexed<std::list<sp<ABuffer>>>::Locked configs(mFlushedConfigs);
|
||||
- if (!configs->empty()) {
|
||||
- while (!configs->empty()) {
|
||||
- sp<ABuffer> config = configs->front();
|
||||
- configs->pop_front();
|
||||
- // Find the smallest input buffer that can fit the config.
|
||||
- auto i = std::find_if(
|
||||
- clientInputBuffers.begin(),
|
||||
- clientInputBuffers.end(),
|
||||
- [cfgSize = config->size()](const ClientInputBuffer& b) {
|
||||
- return b.capacity >= cfgSize;
|
||||
- });
|
||||
- if (i == clientInputBuffers.end()) {
|
||||
- ALOGW("[%s] no input buffer large enough for the config "
|
||||
- "(%zu bytes)",
|
||||
- mName, config->size());
|
||||
- return NO_MEMORY;
|
||||
- }
|
||||
- sp<MediaCodecBuffer> buffer = i->buffer;
|
||||
- memcpy(buffer->base(), config->data(), config->size());
|
||||
- buffer->setRange(0, config->size());
|
||||
- buffer->meta()->clear();
|
||||
- buffer->meta()->setInt64("timeUs", 0);
|
||||
- buffer->meta()->setInt32("csd", 1);
|
||||
- if (queueInputBufferInternal(buffer) != OK) {
|
||||
- ALOGW("[%s] Error while queueing a flushed config",
|
||||
- mName);
|
||||
- return UNKNOWN_ERROR;
|
||||
- }
|
||||
- clientInputBuffers.erase(i);
|
||||
- }
|
||||
- } else if (oStreamFormat.value == C2BufferData::LINEAR &&
|
||||
- (!prepend || prepend.value == PREPEND_HEADER_TO_NONE)) {
|
||||
- sp<MediaCodecBuffer> buffer = clientInputBuffers.front().buffer;
|
||||
- // WORKAROUND: Some apps expect CSD available without queueing
|
||||
- // any input. Queue an empty buffer to get the CSD.
|
||||
- buffer->setRange(0, 0);
|
||||
- buffer->meta()->clear();
|
||||
- buffer->meta()->setInt64("timeUs", 0);
|
||||
- if (queueInputBufferInternal(buffer) != OK) {
|
||||
- ALOGW("[%s] Error while queueing an empty buffer to get CSD",
|
||||
- mName);
|
||||
- return UNKNOWN_ERROR;
|
||||
- }
|
||||
- clientInputBuffers.pop_front();
|
||||
+ std::list<std::unique_ptr<C2Work>> flushedConfigs;
|
||||
+ mFlushedConfigs.lock()->swap(flushedConfigs);
|
||||
+ if (!flushedConfigs.empty()) {
|
||||
+ err = mComponent->queue(&flushedConfigs);
|
||||
+ if (err != C2_OK) {
|
||||
+ ALOGW("[%s] Error while queueing a flushed config", mName);
|
||||
+ return UNKNOWN_ERROR;
|
||||
}
|
||||
}
|
||||
+ if (oStreamFormat.value == C2BufferData::LINEAR &&
|
||||
+ (!prepend || prepend.value == PREPEND_HEADER_TO_NONE)) {
|
||||
+ sp<MediaCodecBuffer> buffer = clientInputBuffers.front().buffer;
|
||||
+ // WORKAROUND: Some apps expect CSD available without queueing
|
||||
+ // any input. Queue an empty buffer to get the CSD.
|
||||
+ buffer->setRange(0, 0);
|
||||
+ buffer->meta()->clear();
|
||||
+ buffer->meta()->setInt64("timeUs", 0);
|
||||
+ if (queueInputBufferInternal(buffer) != OK) {
|
||||
+ ALOGW("[%s] Error while queueing an empty buffer to get CSD",
|
||||
+ mName);
|
||||
+ return UNKNOWN_ERROR;
|
||||
+ }
|
||||
+ clientInputBuffers.pop_front();
|
||||
+ }
|
||||
|
||||
for (const ClientInputBuffer& clientInputBuffer: clientInputBuffers) {
|
||||
mCallback->onInputBufferAvailable(
|
||||
@@ -1396,27 +1372,36 @@ void CCodecBufferChannel::release() {
|
||||
|
||||
void CCodecBufferChannel::flush(const std::list<std::unique_ptr<C2Work>> &flushedWork) {
|
||||
ALOGV("[%s] flush", mName);
|
||||
- {
|
||||
- Mutexed<std::list<sp<ABuffer>>>::Locked configs(mFlushedConfigs);
|
||||
- for (const std::unique_ptr<C2Work> &work : flushedWork) {
|
||||
- if (!(work->input.flags & C2FrameData::FLAG_CODEC_CONFIG)) {
|
||||
- continue;
|
||||
- }
|
||||
- if (work->input.buffers.empty()
|
||||
- || work->input.buffers.front()->data().linearBlocks().empty()) {
|
||||
- ALOGD("[%s] no linear codec config data found", mName);
|
||||
- continue;
|
||||
- }
|
||||
- C2ReadView view =
|
||||
- work->input.buffers.front()->data().linearBlocks().front().map().get();
|
||||
- if (view.error() != C2_OK) {
|
||||
- ALOGD("[%s] failed to map flushed codec config data: %d", mName, view.error());
|
||||
- continue;
|
||||
- }
|
||||
- configs->push_back(ABuffer::CreateAsCopy(view.data(), view.capacity()));
|
||||
- ALOGV("[%s] stashed flushed codec config data (size=%u)", mName, view.capacity());
|
||||
- }
|
||||
- }
|
||||
+ std::list<std::unique_ptr<C2Work>> configs;
|
||||
+ for (const std::unique_ptr<C2Work> &work : flushedWork) {
|
||||
+ if (!(work->input.flags & C2FrameData::FLAG_CODEC_CONFIG)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (work->input.buffers.empty()
|
||||
+ || work->input.buffers.front() == nullptr
|
||||
+ || work->input.buffers.front()->data().linearBlocks().empty()) {
|
||||
+ ALOGD("[%s] no linear codec config data found", mName);
|
||||
+ continue;
|
||||
+ }
|
||||
+ std::unique_ptr<C2Work> copy(new C2Work);
|
||||
+ copy->input.flags = C2FrameData::flags_t(work->input.flags | C2FrameData::FLAG_DROP_FRAME);
|
||||
+ copy->input.ordinal = work->input.ordinal;
|
||||
+ copy->input.buffers.insert(
|
||||
+ copy->input.buffers.begin(),
|
||||
+ work->input.buffers.begin(),
|
||||
+ work->input.buffers.end());
|
||||
+ for (const std::unique_ptr<C2Param> ¶m : work->input.configUpdate) {
|
||||
+ copy->input.configUpdate.push_back(C2Param::Copy(*param));
|
||||
+ }
|
||||
+ copy->input.infoBuffers.insert(
|
||||
+ copy->input.infoBuffers.begin(),
|
||||
+ work->input.infoBuffers.begin(),
|
||||
+ work->input.infoBuffers.end());
|
||||
+ copy->worklets.emplace_back(new C2Worklet);
|
||||
+ configs.push_back(std::move(copy));
|
||||
+ ALOGV("[%s] stashed flushed codec config data", mName);
|
||||
+ }
|
||||
+ mFlushedConfigs.lock()->swap(configs);
|
||||
{
|
||||
Mutexed<Input>::Locked input(mInput);
|
||||
input->buffers->flush();
|
||||
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.h b/media/codec2/sfplugin/CCodecBufferChannel.h
|
||||
index 046c5c3c49..e2c9aaa287 100644
|
||||
--- a/media/codec2/sfplugin/CCodecBufferChannel.h
|
||||
+++ b/media/codec2/sfplugin/CCodecBufferChannel.h
|
||||
@@ -277,7 +277,7 @@ private:
|
||||
uint32_t outputDelay;
|
||||
};
|
||||
Mutexed<Output> mOutput;
|
||||
- Mutexed<std::list<sp<ABuffer>>> mFlushedConfigs;
|
||||
+ Mutexed<std::list<std::unique_ptr<C2Work>>> mFlushedConfigs;
|
||||
|
||||
std::atomic_uint64_t mFrameIndex;
|
||||
std::atomic_uint64_t mFirstValidFrameIndex;
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
From bfa866666f0fb3e95755e5fb5d22a89c1fdd6767 Mon Sep 17 00:00:00 2001
|
||||
From: David Stevens <stevensd@google.com>
|
||||
Date: Tue, 20 Oct 2020 15:00:41 +0900
|
||||
Subject: [PATCH 20/30] BufferPool: limit number of idle buffers in caches
|
||||
|
||||
Some systems have limits on the total number of graphics buffers that
|
||||
can be allocated, not just the total size. When dealing with
|
||||
particularly small buffers, the caches could end up retaining 1000s of
|
||||
buffers. This change adds an additional eviction trigger based on the
|
||||
number of idle cached buffers.
|
||||
|
||||
Bug: 170702290
|
||||
Bug: 171553040
|
||||
Test: android.video.cts.VideoEncoderDecoderTest on ARCVM
|
||||
Change-Id: If3f4433ba1794ccb624b864a56619c8613a315f2
|
||||
(cherry picked from commit 0f50e523ef1404f9afbaa7b919e2801e5d94012a)
|
||||
Merged-In: If3f4433ba1794ccb624b864a56619c8613a315f2
|
||||
---
|
||||
media/bufferpool/2.0/AccessorImpl.cpp | 13 +++++++++----
|
||||
media/bufferpool/2.0/AccessorImpl.h | 6 ++++++
|
||||
media/bufferpool/2.0/BufferPoolClient.cpp | 12 ++++++++++--
|
||||
3 files changed, 25 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/media/bufferpool/2.0/AccessorImpl.cpp b/media/bufferpool/2.0/AccessorImpl.cpp
|
||||
index 6111feafb9..1d2562e41d 100644
|
||||
--- a/media/bufferpool/2.0/AccessorImpl.cpp
|
||||
+++ b/media/bufferpool/2.0/AccessorImpl.cpp
|
||||
@@ -39,6 +39,8 @@ namespace {
|
||||
|
||||
static constexpr size_t kMinAllocBytesForEviction = 1024*1024*15;
|
||||
static constexpr size_t kMinBufferCountForEviction = 25;
|
||||
+ static constexpr size_t kMaxUnusedBufferCount = 64;
|
||||
+ static constexpr size_t kUnusedBufferCountTarget = kMaxUnusedBufferCount - 16;
|
||||
|
||||
static constexpr nsecs_t kEvictGranularityNs = 1000000000; // 1 sec
|
||||
static constexpr nsecs_t kEvictDurationNs = 5000000000; // 5 secs
|
||||
@@ -724,9 +726,11 @@ ResultStatus Accessor::Impl::BufferPool::addNewBuffer(
|
||||
}
|
||||
|
||||
void Accessor::Impl::BufferPool::cleanUp(bool clearCache) {
|
||||
- if (clearCache || mTimestampUs > mLastCleanUpUs + kCleanUpDurationUs) {
|
||||
+ if (clearCache || mTimestampUs > mLastCleanUpUs + kCleanUpDurationUs ||
|
||||
+ mStats.buffersNotInUse() > kMaxUnusedBufferCount) {
|
||||
mLastCleanUpUs = mTimestampUs;
|
||||
- if (mTimestampUs > mLastLogUs + kLogDurationUs) {
|
||||
+ if (mTimestampUs > mLastLogUs + kLogDurationUs ||
|
||||
+ mStats.buffersNotInUse() > kMaxUnusedBufferCount) {
|
||||
mLastLogUs = mTimestampUs;
|
||||
ALOGD("bufferpool2 %p : %zu(%zu size) total buffers - "
|
||||
"%zu(%zu size) used buffers - %zu/%zu (recycle/alloc) - "
|
||||
@@ -737,8 +741,9 @@ void Accessor::Impl::BufferPool::cleanUp(bool clearCache) {
|
||||
mStats.mTotalFetches, mStats.mTotalTransfers);
|
||||
}
|
||||
for (auto freeIt = mFreeBuffers.begin(); freeIt != mFreeBuffers.end();) {
|
||||
- if (!clearCache && (mStats.mSizeCached < kMinAllocBytesForEviction
|
||||
- || mBuffers.size() < kMinBufferCountForEviction)) {
|
||||
+ if (!clearCache && mStats.buffersNotInUse() <= kUnusedBufferCountTarget &&
|
||||
+ (mStats.mSizeCached < kMinAllocBytesForEviction ||
|
||||
+ mBuffers.size() < kMinBufferCountForEviction)) {
|
||||
break;
|
||||
}
|
||||
auto it = mBuffers.find(*freeIt);
|
||||
diff --git a/media/bufferpool/2.0/AccessorImpl.h b/media/bufferpool/2.0/AccessorImpl.h
|
||||
index cd1b4d08c1..3d39941337 100644
|
||||
--- a/media/bufferpool/2.0/AccessorImpl.h
|
||||
+++ b/media/bufferpool/2.0/AccessorImpl.h
|
||||
@@ -193,6 +193,12 @@ private:
|
||||
: mSizeCached(0), mBuffersCached(0), mSizeInUse(0), mBuffersInUse(0),
|
||||
mTotalAllocations(0), mTotalRecycles(0), mTotalTransfers(0), mTotalFetches(0) {}
|
||||
|
||||
+ /// # of currently unused buffers
|
||||
+ size_t buffersNotInUse() const {
|
||||
+ ALOG_ASSERT(mBuffersCached >= mBuffersInUse);
|
||||
+ return mBuffersCached - mBuffersInUse;
|
||||
+ }
|
||||
+
|
||||
/// A new buffer is allocated on an allocation request.
|
||||
void onBufferAllocated(size_t allocSize) {
|
||||
mSizeCached += allocSize;
|
||||
diff --git a/media/bufferpool/2.0/BufferPoolClient.cpp b/media/bufferpool/2.0/BufferPoolClient.cpp
|
||||
index 342fef6b9d..9308b8159b 100644
|
||||
--- a/media/bufferpool/2.0/BufferPoolClient.cpp
|
||||
+++ b/media/bufferpool/2.0/BufferPoolClient.cpp
|
||||
@@ -32,6 +32,8 @@ namespace implementation {
|
||||
static constexpr int64_t kReceiveTimeoutUs = 1000000; // 100ms
|
||||
static constexpr int kPostMaxRetry = 3;
|
||||
static constexpr int kCacheTtlUs = 1000000; // TODO: tune
|
||||
+static constexpr size_t kMaxCachedBufferCount = 64;
|
||||
+static constexpr size_t kCachedBufferCountTarget = kMaxCachedBufferCount - 16;
|
||||
|
||||
class BufferPoolClient::Impl
|
||||
: public std::enable_shared_from_this<BufferPoolClient::Impl> {
|
||||
@@ -136,6 +138,10 @@ private:
|
||||
--mActive;
|
||||
mLastChangeUs = getTimestampNow();
|
||||
}
|
||||
+
|
||||
+ int cachedBufferCount() const {
|
||||
+ return mBuffers.size() - mActive;
|
||||
+ }
|
||||
} mCache;
|
||||
|
||||
// FMQ - release notifier
|
||||
@@ -668,10 +674,12 @@ bool BufferPoolClient::Impl::syncReleased(uint32_t messageId) {
|
||||
// should have mCache.mLock
|
||||
void BufferPoolClient::Impl::evictCaches(bool clearCache) {
|
||||
int64_t now = getTimestampNow();
|
||||
- if (now >= mLastEvictCacheUs + kCacheTtlUs || clearCache) {
|
||||
+ if (now >= mLastEvictCacheUs + kCacheTtlUs ||
|
||||
+ clearCache || mCache.cachedBufferCount() > kMaxCachedBufferCount) {
|
||||
size_t evicted = 0;
|
||||
for (auto it = mCache.mBuffers.begin(); it != mCache.mBuffers.end();) {
|
||||
- if (!it->second->hasCache() && (it->second->expire() || clearCache)) {
|
||||
+ if (!it->second->hasCache() && (it->second->expire() ||
|
||||
+ clearCache || mCache.cachedBufferCount() > kCachedBufferCountTarget)) {
|
||||
it = mCache.mBuffers.erase(it);
|
||||
++evicted;
|
||||
} else {
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
From 7e08eb2a701487a4b56b449fd5758b8ab5cfce90 Mon Sep 17 00:00:00 2001
|
||||
From: Taehwan Kim <t_h.kim@samsung.com>
|
||||
Date: Thu, 17 Sep 2020 12:26:40 +0900
|
||||
Subject: [PATCH 21/30] CCodec: fix underflow issue on handleImageData
|
||||
|
||||
the logic is assumed that gralloc does assume a contiguous mapping
|
||||
at GraphicView2MediaImageConverter() in Codec2Buffer.
|
||||
if it doesn't, underflow could happen because
|
||||
type of variable is unsigned.
|
||||
|
||||
Bug: 168757280
|
||||
|
||||
Change-Id: I04e13d0680af74e76d96d3ab10a549f6368205cf
|
||||
Signed-off-by: Taehwan Kim <t_h.kim@samsung.com>
|
||||
(cherry picked from commit fd9b809147b78330d1db7ec17e200071e779fd46)
|
||||
---
|
||||
media/codec2/sfplugin/CCodecBuffers.cpp | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/media/codec2/sfplugin/CCodecBuffers.cpp b/media/codec2/sfplugin/CCodecBuffers.cpp
|
||||
index bddaa9f22b..692da584ce 100644
|
||||
--- a/media/codec2/sfplugin/CCodecBuffers.cpp
|
||||
+++ b/media/codec2/sfplugin/CCodecBuffers.cpp
|
||||
@@ -91,7 +91,9 @@ void CCodecBuffers::handleImageData(const sp<Codec2Buffer> &buffer) {
|
||||
newFormat->setInt32(KEY_STRIDE, stride);
|
||||
ALOGD("[%s] updating stride = %d", mName, stride);
|
||||
if (img->mNumPlanes > 1 && stride > 0) {
|
||||
- int32_t vstride = (img->mPlane[1].mOffset - img->mPlane[0].mOffset) / stride;
|
||||
+ int64_t offsetDelta =
|
||||
+ (int64_t)img->mPlane[1].mOffset - (int64_t)img->mPlane[0].mOffset;
|
||||
+ int32_t vstride = int32_t(offsetDelta / stride);
|
||||
newFormat->setInt32(KEY_SLICE_HEIGHT, vstride);
|
||||
ALOGD("[%s] updating vstride = %d", mName, vstride);
|
||||
}
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
From 73517d3e56b2ee0eb171af1e68fa1c729eadd564 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Essick <essick@google.com>
|
||||
Date: Mon, 14 Sep 2020 17:05:07 -0700
|
||||
Subject: [PATCH 22/30] OMX Opus decoder omits sample rate / channel count
|
||||
|
||||
The OMX Opus decoder doesn't signal back the channel/samplerate info to
|
||||
the framework, leading to a CTS failure when checking required values.
|
||||
|
||||
Based on an AOSP patch provided by denis.hsu@mediatek.com
|
||||
|
||||
Bug: 166695414
|
||||
Test: CtsMediaTestCases android.media.cts.DecoderTest#testDecodeOpusChannelsAndRates
|
||||
Change-Id: If710405caea4be6336b4aec3aa0c051ad3c0fe95
|
||||
(cherry picked from commit 74d4b70841b2aa3154b10b82ebcc6737d1d36a6d)
|
||||
---
|
||||
media/libstagefright/ACodec.cpp | 26 +++++++++++++++++++
|
||||
.../codecs/opus/dec/SoftOpus.cpp | 11 +++++---
|
||||
.../libstagefright/codecs/opus/dec/SoftOpus.h | 2 ++
|
||||
.../include/media/stagefright/ACodec.h | 1 +
|
||||
4 files changed, 37 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
|
||||
index f843c7f45f..7ea444dc77 100644
|
||||
--- a/media/libstagefright/ACodec.cpp
|
||||
+++ b/media/libstagefright/ACodec.cpp
|
||||
@@ -2247,6 +2247,12 @@ status_t ACodec::configureCodec(
|
||||
}
|
||||
err = setupG711Codec(encoder, sampleRate, numChannels);
|
||||
}
|
||||
+ } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_OPUS)) {
|
||||
+ int32_t numChannels = 1, sampleRate = 48000;
|
||||
+ if (msg->findInt32("channel-count", &numChannels) &&
|
||||
+ msg->findInt32("sample-rate", &sampleRate)) {
|
||||
+ err = setupOpusCodec(encoder, sampleRate, numChannels);
|
||||
+ }
|
||||
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
|
||||
// numChannels needs to be set to properly communicate PCM values.
|
||||
int32_t numChannels = 2, sampleRate = 44100, compressionLevel = -1;
|
||||
@@ -3120,6 +3126,26 @@ status_t ACodec::setupG711Codec(bool encoder, int32_t sampleRate, int32_t numCha
|
||||
kPortIndexInput, sampleRate, numChannels);
|
||||
}
|
||||
|
||||
+status_t ACodec::setupOpusCodec(bool encoder, int32_t sampleRate, int32_t numChannels) {
|
||||
+ if (encoder) {
|
||||
+ return INVALID_OPERATION;
|
||||
+ }
|
||||
+ OMX_AUDIO_PARAM_ANDROID_OPUSTYPE def;
|
||||
+ InitOMXParams(&def);
|
||||
+ def.nPortIndex = kPortIndexInput;
|
||||
+ status_t err = mOMXNode->getParameter(
|
||||
+ (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus, &def, sizeof(def));
|
||||
+ if (err != OK) {
|
||||
+ ALOGE("setupOpusCodec(): Error %d getting OMX_IndexParamAudioAndroidOpus parameter", err);
|
||||
+ return err;
|
||||
+ }
|
||||
+ def.nSampleRate = sampleRate;
|
||||
+ def.nChannels = numChannels;
|
||||
+ err = mOMXNode->setParameter(
|
||||
+ (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus, &def, sizeof(def));
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
status_t ACodec::setupFlacCodec(
|
||||
bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel,
|
||||
AudioEncoding encoding) {
|
||||
diff --git a/media/libstagefright/codecs/opus/dec/SoftOpus.cpp b/media/libstagefright/codecs/opus/dec/SoftOpus.cpp
|
||||
index 4f61aa8be2..5bb1879da1 100644
|
||||
--- a/media/libstagefright/codecs/opus/dec/SoftOpus.cpp
|
||||
+++ b/media/libstagefright/codecs/opus/dec/SoftOpus.cpp
|
||||
@@ -58,6 +58,8 @@ SoftOpus::SoftOpus(
|
||||
mInputBufferCount(0),
|
||||
mDecoder(NULL),
|
||||
mHeader(NULL),
|
||||
+ mNumChannels(1),
|
||||
+ mSamplingRate(kRate),
|
||||
mCodecDelay(0),
|
||||
mSeekPreRoll(0),
|
||||
mAnchorTimeUs(0),
|
||||
@@ -169,11 +171,11 @@ OMX_ERRORTYPE SoftOpus::internalGetParameter(
|
||||
}
|
||||
|
||||
opusParams->nAudioBandWidth = 0;
|
||||
- opusParams->nSampleRate = kRate;
|
||||
+ opusParams->nSampleRate = mSamplingRate;
|
||||
opusParams->nBitRate = 0;
|
||||
|
||||
if (!isConfigured()) {
|
||||
- opusParams->nChannels = 1;
|
||||
+ opusParams->nChannels = mNumChannels;
|
||||
} else {
|
||||
opusParams->nChannels = mHeader->channels;
|
||||
}
|
||||
@@ -274,7 +276,8 @@ OMX_ERRORTYPE SoftOpus::internalSetParameter(
|
||||
if (opusParams->nPortIndex != 0) {
|
||||
return OMX_ErrorUndefined;
|
||||
}
|
||||
-
|
||||
+ mNumChannels = opusParams->nChannels;
|
||||
+ mSamplingRate = opusParams->nSampleRate;
|
||||
return OMX_ErrorNone;
|
||||
}
|
||||
|
||||
@@ -496,6 +499,8 @@ void SoftOpus::onQueueFilled(OMX_U32 /* portIndex */) {
|
||||
*(reinterpret_cast<int64_t*>(inHeader->pBuffer +
|
||||
inHeader->nOffset)),
|
||||
kRate);
|
||||
+ mSamplingRate = kRate;
|
||||
+ mNumChannels = mHeader->channels;
|
||||
notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
|
||||
mOutputPortSettingsChange = AWAITING_DISABLED;
|
||||
}
|
||||
diff --git a/media/libstagefright/codecs/opus/dec/SoftOpus.h b/media/libstagefright/codecs/opus/dec/SoftOpus.h
|
||||
index 91cafa14c7..00058c8212 100644
|
||||
--- a/media/libstagefright/codecs/opus/dec/SoftOpus.h
|
||||
+++ b/media/libstagefright/codecs/opus/dec/SoftOpus.h
|
||||
@@ -70,6 +70,8 @@ private:
|
||||
OpusMSDecoder *mDecoder;
|
||||
OpusHeader *mHeader;
|
||||
|
||||
+ int32_t mNumChannels;
|
||||
+ int32_t mSamplingRate;
|
||||
int64_t mCodecDelay;
|
||||
int64_t mSeekPreRoll;
|
||||
int64_t mSamplesToDiscard;
|
||||
diff --git a/media/libstagefright/include/media/stagefright/ACodec.h b/media/libstagefright/include/media/stagefright/ACodec.h
|
||||
index 83e92b9f43..105e7f7f98 100644
|
||||
--- a/media/libstagefright/include/media/stagefright/ACodec.h
|
||||
+++ b/media/libstagefright/include/media/stagefright/ACodec.h
|
||||
@@ -499,6 +499,7 @@ private:
|
||||
status_t setupAMRCodec(bool encoder, bool isWAMR, int32_t bitRate);
|
||||
status_t setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels);
|
||||
|
||||
+ status_t setupOpusCodec(bool encoder, int32_t sampleRate, int32_t numChannels);
|
||||
status_t setupFlacCodec(
|
||||
bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel,
|
||||
AudioEncoding encoding);
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
From bf69673517df3b7c1f90cc07621f8af998310110 Mon Sep 17 00:00:00 2001
|
||||
From: Wonsik Kim <wonsik@google.com>
|
||||
Date: Tue, 22 Sep 2020 18:44:47 -0700
|
||||
Subject: [PATCH 23/30] ACodec: submit extra output metadata buffers if in low
|
||||
latency mode
|
||||
|
||||
Bug: 166250452
|
||||
Test: atest CtsMediaTestCases:DecoderTest
|
||||
Merged-In: I134a16a70e8ac94dbd4f505c0a5553a3ca0f87a2
|
||||
Change-Id: I134a16a70e8ac94dbd4f505c0a5553a3ca0f87a2
|
||||
(cherry picked from commit 7e0bb3845b3059c0ee5bd33e506368828cca40fe)
|
||||
---
|
||||
media/libstagefright/ACodec.cpp | 39 ++++++++++++++++++-
|
||||
.../include/media/stagefright/ACodec.h | 2 +
|
||||
2 files changed, 39 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
|
||||
index 7ea444dc77..0f8cd39edb 100644
|
||||
--- a/media/libstagefright/ACodec.cpp
|
||||
+++ b/media/libstagefright/ACodec.cpp
|
||||
@@ -279,6 +279,13 @@ protected:
|
||||
|
||||
void postFillThisBuffer(BufferInfo *info);
|
||||
|
||||
+ void maybePostExtraOutputMetadataBufferRequest() {
|
||||
+ if (!mPendingExtraOutputMetadataBufferRequest) {
|
||||
+ (new AMessage(kWhatSubmitExtraOutputMetadataBuffer, mCodec))->post();
|
||||
+ mPendingExtraOutputMetadataBufferRequest = true;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
private:
|
||||
// Handles an OMX message. Returns true iff message was handled.
|
||||
bool onOMXMessage(const sp<AMessage> &msg);
|
||||
@@ -302,6 +309,8 @@ private:
|
||||
|
||||
void getMoreInputDataIfPossible();
|
||||
|
||||
+ bool mPendingExtraOutputMetadataBufferRequest;
|
||||
+
|
||||
DISALLOW_EVIL_CONSTRUCTORS(BaseState);
|
||||
};
|
||||
|
||||
@@ -555,6 +564,7 @@ ACodec::ACodec()
|
||||
mShutdownInProgress(false),
|
||||
mExplicitShutdown(false),
|
||||
mIsLegacyVP9Decoder(false),
|
||||
+ mIsLowLatency(false),
|
||||
mEncoderDelay(0),
|
||||
mEncoderPadding(0),
|
||||
mRotationDegrees(0),
|
||||
@@ -2425,6 +2435,7 @@ status_t ACodec::setLowLatency(int32_t lowLatency) {
|
||||
if (err != OK) {
|
||||
ALOGE("decoder can not set low-latency to %d (err %d)", lowLatency, err);
|
||||
}
|
||||
+ mIsLowLatency = (lowLatency && err == OK);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -5785,7 +5796,8 @@ status_t ACodec::requestIDRFrame() {
|
||||
|
||||
ACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
|
||||
: AState(parentState),
|
||||
- mCodec(codec) {
|
||||
+ mCodec(codec),
|
||||
+ mPendingExtraOutputMetadataBufferRequest(false) {
|
||||
}
|
||||
|
||||
ACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
|
||||
@@ -5886,6 +5898,21 @@ bool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
|
||||
break;
|
||||
}
|
||||
|
||||
+ case kWhatSubmitExtraOutputMetadataBuffer: {
|
||||
+ mPendingExtraOutputMetadataBufferRequest = false;
|
||||
+ if (getPortMode(kPortIndexOutput) == RESUBMIT_BUFFERS && mCodec->mIsLowLatency) {
|
||||
+ // Decoders often need more than one output buffer to be
|
||||
+ // submitted before processing a single input buffer.
|
||||
+ // For low latency codecs, we don't want to wait for more input
|
||||
+ // to be queued to get those output buffers submitted.
|
||||
+ if (mCodec->submitOutputMetadataBuffer() == OK
|
||||
+ && mCodec->mMetadataBuffersToSubmit > 0) {
|
||||
+ maybePostExtraOutputMetadataBufferRequest();
|
||||
+ }
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -6242,7 +6269,12 @@ void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
|
||||
(outputMode == FREE_BUFFERS ? "FREE" :
|
||||
outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
|
||||
if (outputMode == RESUBMIT_BUFFERS) {
|
||||
- mCodec->submitOutputMetadataBuffer();
|
||||
+ status_t err = mCodec->submitOutputMetadataBuffer();
|
||||
+ if (mCodec->mIsLowLatency
|
||||
+ && err == OK
|
||||
+ && mCodec->mMetadataBuffersToSubmit > 0) {
|
||||
+ maybePostExtraOutputMetadataBufferRequest();
|
||||
+ }
|
||||
}
|
||||
}
|
||||
info->checkReadFence("onInputBufferFilled");
|
||||
@@ -7388,6 +7420,9 @@ void ACodec::ExecutingState::submitOutputMetaBuffers() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
+ if (mCodec->mIsLowLatency) {
|
||||
+ maybePostExtraOutputMetadataBufferRequest();
|
||||
+ }
|
||||
|
||||
// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
|
||||
mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
|
||||
diff --git a/media/libstagefright/include/media/stagefright/ACodec.h b/media/libstagefright/include/media/stagefright/ACodec.h
|
||||
index 105e7f7f98..8ef92783ec 100644
|
||||
--- a/media/libstagefright/include/media/stagefright/ACodec.h
|
||||
+++ b/media/libstagefright/include/media/stagefright/ACodec.h
|
||||
@@ -147,6 +147,7 @@ private:
|
||||
kWhatReleaseCodecInstance = 'relC',
|
||||
kWhatForceStateTransition = 'fstt',
|
||||
kWhatCheckIfStuck = 'Cstk',
|
||||
+ kWhatSubmitExtraOutputMetadataBuffer = 'sbxo',
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -272,6 +273,7 @@ private:
|
||||
bool mShutdownInProgress;
|
||||
bool mExplicitShutdown;
|
||||
bool mIsLegacyVP9Decoder;
|
||||
+ bool mIsLowLatency;
|
||||
|
||||
// If "mKeepComponentAllocated" we only transition back to Loaded state
|
||||
// and do not release the component instance.
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
From 20517633099c124e1c639fab9b693c32875c7fba Mon Sep 17 00:00:00 2001
|
||||
From: Paras Nagda <pnagda@codeaurora.org>
|
||||
Date: Tue, 27 Oct 2020 13:01:47 +0530
|
||||
Subject: [PATCH 24/30] NuPlayerRenderer: Reset negative media time to zero
|
||||
|
||||
Reset negative media time to zero before call is made to
|
||||
Mediaclock's setStartingTimeMedia().
|
||||
|
||||
Test:run android.mediastress.cts.HEVCR1080pAacLongPlayerTest#testPlay00 on gsi
|
||||
|
||||
Bug: 170621757
|
||||
Bug: 171945667
|
||||
Bug: 170797642
|
||||
Bug: 171562715
|
||||
Bug: 171850618
|
||||
Change-Id: I2c405007b38229038119760423156bd53a2701c0
|
||||
---
|
||||
media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
|
||||
index c30f048c2d..7e8fe45121 100644
|
||||
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
|
||||
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
|
||||
@@ -922,6 +922,11 @@ size_t NuPlayer::Renderer::fillAudioBuffer(void *buffer, size_t size) {
|
||||
firstEntry = false;
|
||||
int64_t mediaTimeUs;
|
||||
CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs));
|
||||
+ if (mediaTimeUs < 0) {
|
||||
+ ALOGD("fillAudioBuffer: reset negative media time %.2f secs to zero",
|
||||
+ mediaTimeUs / 1E6);
|
||||
+ mediaTimeUs = 0;
|
||||
+ }
|
||||
ALOGV("fillAudioBuffer: rendering audio at media time %.2f secs", mediaTimeUs / 1E6);
|
||||
setAudioFirstAnchorTimeIfNeeded_l(mediaTimeUs);
|
||||
}
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
From 3e4bfa2b9f1516d70f117c16abfa7bb7b085faf5 Mon Sep 17 00:00:00 2001
|
||||
From: Wonsik Kim <wonsik@google.com>
|
||||
Date: Thu, 12 Nov 2020 11:14:42 -0800
|
||||
Subject: [PATCH 25/30] C2OMXNode: read delay from component to determine
|
||||
buffer count
|
||||
|
||||
Bug: 169398817
|
||||
Test: atest CtsMediaTestCases -- --module-arg CtsMediaTestCases:size:small
|
||||
Test: atest CtsMediaTestCases:VideoEncoderTest
|
||||
Change-Id: I76a3411addd83108d2da2c8f74df55acab03a365
|
||||
(cherry picked from commit 414eb15c3c6cd7e1677245508fd23899bef01feb)
|
||||
---
|
||||
media/codec2/sfplugin/C2OMXNode.cpp | 21 ++++++++++++++++++++-
|
||||
1 file changed, 20 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/media/codec2/sfplugin/C2OMXNode.cpp b/media/codec2/sfplugin/C2OMXNode.cpp
|
||||
index c7588e9a51..dd1f4858a5 100644
|
||||
--- a/media/codec2/sfplugin/C2OMXNode.cpp
|
||||
+++ b/media/codec2/sfplugin/C2OMXNode.cpp
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <C2AllocatorGralloc.h>
|
||||
#include <C2BlockInternal.h>
|
||||
#include <C2Component.h>
|
||||
+#include <C2Config.h>
|
||||
#include <C2PlatformSupport.h>
|
||||
|
||||
#include <OMX_Component.h>
|
||||
@@ -44,6 +45,8 @@ namespace android {
|
||||
|
||||
namespace {
|
||||
|
||||
+constexpr OMX_U32 kPortIndexInput = 0;
|
||||
+
|
||||
class Buffer2D : public C2Buffer {
|
||||
public:
|
||||
explicit Buffer2D(C2ConstGraphicBlock block) : C2Buffer({ block }) {}
|
||||
@@ -200,11 +203,27 @@ status_t C2OMXNode::getParameter(OMX_INDEXTYPE index, void *params, size_t size)
|
||||
return BAD_VALUE;
|
||||
}
|
||||
OMX_PARAM_PORTDEFINITIONTYPE *pDef = (OMX_PARAM_PORTDEFINITIONTYPE *)params;
|
||||
- // TODO: read these from intf()
|
||||
+ if (pDef->nPortIndex != kPortIndexInput) {
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
pDef->nBufferCountActual = 16;
|
||||
+
|
||||
+ std::shared_ptr<Codec2Client::Component> comp = mComp.lock();
|
||||
+ C2PortActualDelayTuning::input inputDelay(0);
|
||||
+ C2ActualPipelineDelayTuning pipelineDelay(0);
|
||||
+ c2_status_t c2err = comp->query(
|
||||
+ {&inputDelay, &pipelineDelay}, {}, C2_DONT_BLOCK, nullptr);
|
||||
+ if (c2err == C2_OK || c2err == C2_BAD_INDEX) {
|
||||
+ pDef->nBufferCountActual = 4;
|
||||
+ pDef->nBufferCountActual += (inputDelay ? inputDelay.value : 0u);
|
||||
+ pDef->nBufferCountActual += (pipelineDelay ? pipelineDelay.value : 0u);
|
||||
+ }
|
||||
+
|
||||
pDef->eDomain = OMX_PortDomainVideo;
|
||||
pDef->format.video.nFrameWidth = mWidth;
|
||||
pDef->format.video.nFrameHeight = mHeight;
|
||||
+ pDef->format.video.eColorFormat = OMX_COLOR_FormatAndroidOpaque;
|
||||
err = OK;
|
||||
break;
|
||||
}
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
From 9a6c5d750f7060922c4a9675f45df15310e75d5b Mon Sep 17 00:00:00 2001
|
||||
From: Sungtak Lee <taklee@google.com>
|
||||
Date: Sun, 8 Nov 2020 00:07:27 -0800
|
||||
Subject: [PATCH 26/30] CCodec: Increase max linear buffer size for 8K video
|
||||
|
||||
Increase max linear buffer size to fit a 8K video frame.
|
||||
|
||||
Bug: 172190459
|
||||
Bug: 173683705
|
||||
Bug: 173725276
|
||||
Bug: 173768931
|
||||
Test: atest CtsMediaTestCases -- --module-arg CtsMediaTestCases:size:small
|
||||
|
||||
Change-Id: I47cfc2718447ac51be0f90638d7e7055fd7d95ba
|
||||
(cherry picked from commit 5692578e0d3ff5eb273a63ee9a4f07b719508973)
|
||||
---
|
||||
media/codec2/sfplugin/CCodecBuffers.h | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/media/codec2/sfplugin/CCodecBuffers.h b/media/codec2/sfplugin/CCodecBuffers.h
|
||||
index 4772ab53eb..c383a7ce1a 100644
|
||||
--- a/media/codec2/sfplugin/CCodecBuffers.h
|
||||
+++ b/media/codec2/sfplugin/CCodecBuffers.h
|
||||
@@ -33,8 +33,8 @@ class MemoryDealer;
|
||||
class SkipCutBuffer;
|
||||
|
||||
constexpr size_t kLinearBufferSize = 1048576;
|
||||
-// This can fit 4K RGBA frame, and most likely client won't need more than this.
|
||||
-constexpr size_t kMaxLinearBufferSize = 4096 * 2304 * 4;
|
||||
+// This can fit an 8K frame.
|
||||
+constexpr size_t kMaxLinearBufferSize = 7680 * 4320 * 2;
|
||||
|
||||
/**
|
||||
* Base class for representation of buffers at one port.
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
From 55aa1d77e5fa44434fa4ec7976bd3d4ef0bd4629 Mon Sep 17 00:00:00 2001
|
||||
From: Lajos Molnar <lajos@google.com>
|
||||
Date: Wed, 12 Aug 2020 15:56:31 -0700
|
||||
Subject: [PATCH 27/30] omx: calculate nodePrefix only for components listed in
|
||||
IOmx
|
||||
|
||||
Also make common prefix matching case insensitive.
|
||||
|
||||
Bug: 162578527
|
||||
Change-Id: Iaf66967fd519e0c3eabb8f0c320b8c7e7fd03497
|
||||
(cherry picked from commit 42f653bd87672f3427bdb522f46c55502e6d20d1)
|
||||
---
|
||||
media/libstagefright/omx/1.0/OmxStore.cpp | 20 ++++++++++++++++++--
|
||||
1 file changed, 18 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/media/libstagefright/omx/1.0/OmxStore.cpp b/media/libstagefright/omx/1.0/OmxStore.cpp
|
||||
index 67f478ead0..b5c116656f 100644
|
||||
--- a/media/libstagefright/omx/1.0/OmxStore.cpp
|
||||
+++ b/media/libstagefright/omx/1.0/OmxStore.cpp
|
||||
@@ -54,6 +54,24 @@ OmxStore::OmxStore(
|
||||
});
|
||||
}
|
||||
|
||||
+ if (!nodes.empty()) {
|
||||
+ auto anyNode = nodes.cbegin();
|
||||
+ std::string::const_iterator first = anyNode->cbegin();
|
||||
+ std::string::const_iterator last = anyNode->cend();
|
||||
+ for (const std::string &name : nodes) {
|
||||
+ std::string::const_iterator it1 = first;
|
||||
+ for (std::string::const_iterator it2 = name.cbegin();
|
||||
+ it1 != last && it2 != name.cend() && tolower(*it1) == tolower(*it2);
|
||||
+ ++it1, ++it2) {
|
||||
+ }
|
||||
+ last = it1;
|
||||
+ }
|
||||
+ mPrefix = std::string(first, last);
|
||||
+ LOG(INFO) << "omx common prefix: '" << mPrefix.c_str() << "'";
|
||||
+ } else {
|
||||
+ LOG(INFO) << "omx common prefix: no nodes";
|
||||
+ }
|
||||
+
|
||||
MediaCodecsXmlParser parser;
|
||||
parser.parseXmlFilesInSearchDirs(xmlNames, searchDirs);
|
||||
if (profilingResultsXmlPath != nullptr) {
|
||||
@@ -112,8 +130,6 @@ OmxStore::OmxStore(
|
||||
mRoleList[i] = std::move(role);
|
||||
++i;
|
||||
}
|
||||
-
|
||||
- mPrefix = parser.getCommonPrefix();
|
||||
}
|
||||
|
||||
OmxStore::~OmxStore() {
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
From 7fda1fcb614eab32aec99713919c2e915cca1ccd Mon Sep 17 00:00:00 2001
|
||||
From: Wonsik Kim <wonsik@google.com>
|
||||
Date: Wed, 25 Nov 2020 10:12:32 -0800
|
||||
Subject: [PATCH 28/30] C2AllocatorBlob: allow multiple maps
|
||||
|
||||
Test: CtsMediaTestCases:DecoderTest
|
||||
Test: CtsMediaV2TestCases:CodecDecoderTest
|
||||
Test: VtsHalMediaC2V1_0TargetVideoDecTest
|
||||
Test: VtsHalMediaC2V1_0TargetVideoEncTest
|
||||
Test: VtsHalMediaC2V1_0TargetAudioDecTest
|
||||
Test: VtsHalMediaC2V1_0TargetAudioEncTest
|
||||
Bug: 173730101
|
||||
Change-Id: Ief24371e19c8e957ea218ffd9bbfd516353b0cc9
|
||||
(cherry picked from d04f34cdd8c7ce1a3249a9fbfdd18ca989bb1685)
|
||||
---
|
||||
media/codec2/vndk/C2AllocatorBlob.cpp | 72 ++++++++++++++++++++++++---
|
||||
1 file changed, 66 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/media/codec2/vndk/C2AllocatorBlob.cpp b/media/codec2/vndk/C2AllocatorBlob.cpp
|
||||
index 50c9e59af8..aa054998f8 100644
|
||||
--- a/media/codec2/vndk/C2AllocatorBlob.cpp
|
||||
+++ b/media/codec2/vndk/C2AllocatorBlob.cpp
|
||||
@@ -17,6 +17,8 @@
|
||||
// #define LOG_NDEBUG 0
|
||||
#define LOG_TAG "C2AllocatorBlob"
|
||||
|
||||
+#include <set>
|
||||
+
|
||||
#include <C2AllocatorBlob.h>
|
||||
#include <C2PlatformSupport.h>
|
||||
|
||||
@@ -67,6 +69,10 @@ public:
|
||||
private:
|
||||
const std::shared_ptr<C2GraphicAllocation> mGraphicAllocation;
|
||||
const C2Allocator::id_t mAllocatorId;
|
||||
+
|
||||
+ std::mutex mMapLock;
|
||||
+ std::multiset<std::pair<size_t, size_t>> mMappedOffsetSize;
|
||||
+ uint8_t *mMappedAddr;
|
||||
};
|
||||
|
||||
C2AllocationBlob::C2AllocationBlob(
|
||||
@@ -74,20 +80,74 @@ C2AllocationBlob::C2AllocationBlob(
|
||||
C2Allocator::id_t allocatorId)
|
||||
: C2LinearAllocation(capacity),
|
||||
mGraphicAllocation(std::move(graphicAllocation)),
|
||||
- mAllocatorId(allocatorId) {}
|
||||
+ mAllocatorId(allocatorId),
|
||||
+ mMappedAddr(nullptr) {}
|
||||
|
||||
-C2AllocationBlob::~C2AllocationBlob() {}
|
||||
+C2AllocationBlob::~C2AllocationBlob() {
|
||||
+ if (mMappedAddr) {
|
||||
+ C2Rect rect(capacity(), kLinearBufferHeight);
|
||||
+ mGraphicAllocation->unmap(&mMappedAddr, rect, nullptr);
|
||||
+ }
|
||||
+}
|
||||
|
||||
c2_status_t C2AllocationBlob::map(size_t offset, size_t size, C2MemoryUsage usage,
|
||||
C2Fence* fence, void** addr /* nonnull */) {
|
||||
+ *addr = nullptr;
|
||||
+ if (size > capacity() || offset > capacity() || offset > capacity() - size) {
|
||||
+ ALOGV("C2AllocationBlob: map: bad offset / size: offset=%zu size=%zu capacity=%u",
|
||||
+ offset, size, capacity());
|
||||
+ return C2_BAD_VALUE;
|
||||
+ }
|
||||
+ std::unique_lock<std::mutex> lock(mMapLock);
|
||||
+ if (mMappedAddr) {
|
||||
+ *addr = mMappedAddr + offset;
|
||||
+ mMappedOffsetSize.insert({offset, size});
|
||||
+ ALOGV("C2AllocationBlob: mapped from existing mapping: offset=%zu size=%zu capacity=%u",
|
||||
+ offset, size, capacity());
|
||||
+ return C2_OK;
|
||||
+ }
|
||||
C2PlanarLayout layout;
|
||||
- C2Rect rect = C2Rect(size, kLinearBufferHeight).at(offset, 0u);
|
||||
- return mGraphicAllocation->map(rect, usage, fence, &layout, reinterpret_cast<uint8_t**>(addr));
|
||||
+ C2Rect rect = C2Rect(capacity(), kLinearBufferHeight);
|
||||
+ c2_status_t err = mGraphicAllocation->map(rect, usage, fence, &layout, &mMappedAddr);
|
||||
+ if (err != C2_OK) {
|
||||
+ ALOGV("C2AllocationBlob: map failed: offset=%zu size=%zu capacity=%u err=%d",
|
||||
+ offset, size, capacity(), err);
|
||||
+ mMappedAddr = nullptr;
|
||||
+ return err;
|
||||
+ }
|
||||
+ *addr = mMappedAddr + offset;
|
||||
+ mMappedOffsetSize.insert({offset, size});
|
||||
+ ALOGV("C2AllocationBlob: new map succeeded: offset=%zu size=%zu capacity=%u",
|
||||
+ offset, size, capacity());
|
||||
+ return C2_OK;
|
||||
}
|
||||
|
||||
c2_status_t C2AllocationBlob::unmap(void* addr, size_t size, C2Fence* fenceFd) {
|
||||
- C2Rect rect(size, kLinearBufferHeight);
|
||||
- return mGraphicAllocation->unmap(reinterpret_cast<uint8_t**>(&addr), rect, fenceFd);
|
||||
+ std::unique_lock<std::mutex> lock(mMapLock);
|
||||
+ uint8_t *u8Addr = static_cast<uint8_t *>(addr);
|
||||
+ if (u8Addr < mMappedAddr || mMappedAddr + capacity() < u8Addr + size) {
|
||||
+ ALOGV("C2AllocationBlob: unmap: Bad addr / size: addr=%p size=%zu capacity=%u",
|
||||
+ addr, size, capacity());
|
||||
+ return C2_BAD_VALUE;
|
||||
+ }
|
||||
+ auto it = mMappedOffsetSize.find(std::make_pair(u8Addr - mMappedAddr, size));
|
||||
+ if (it == mMappedOffsetSize.end()) {
|
||||
+ ALOGV("C2AllocationBlob: unrecognized map: addr=%p size=%zu capacity=%u",
|
||||
+ addr, size, capacity());
|
||||
+ return C2_BAD_VALUE;
|
||||
+ }
|
||||
+ mMappedOffsetSize.erase(it);
|
||||
+ if (!mMappedOffsetSize.empty()) {
|
||||
+ ALOGV("C2AllocationBlob: still maintain mapping: addr=%p size=%zu capacity=%u",
|
||||
+ addr, size, capacity());
|
||||
+ return C2_OK;
|
||||
+ }
|
||||
+ C2Rect rect(capacity(), kLinearBufferHeight);
|
||||
+ c2_status_t err = mGraphicAllocation->unmap(&mMappedAddr, rect, fenceFd);
|
||||
+ ALOGV("C2AllocationBlob: last unmap: addr=%p size=%zu capacity=%u err=%d",
|
||||
+ addr, size, capacity(), err);
|
||||
+ mMappedAddr = nullptr;
|
||||
+ return err;
|
||||
}
|
||||
|
||||
/* ====================================== BLOB ALLOCATOR ====================================== */
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,546 @@
|
||||
From 607c1d606efd9f955ad7545dbfdaf38450c5ce20 Mon Sep 17 00:00:00 2001
|
||||
From: Wonsik Kim <wonsik@google.com>
|
||||
Date: Thu, 3 Dec 2020 11:07:58 -0800
|
||||
Subject: [PATCH 29/30] CCodec: fix ByteBuffer mode image
|
||||
|
||||
- Set offset to (0,0) of Y plane.
|
||||
- Fix wrapping criteria.
|
||||
|
||||
Bug: 169379476
|
||||
Test: atest CtsMediaTestCases -- --module-arg CtsMediaTestCases:size:small
|
||||
Test: atest ccodec_unit_test
|
||||
Change-Id: Ic7e074ddaef277833707363b0b9fecfe210bd57f
|
||||
(cherry picked from commit 2eb063152f67e886472ed42c07f3634a5eb63f19)
|
||||
---
|
||||
media/codec2/sfplugin/CCodecBuffers.cpp | 3 +
|
||||
media/codec2/sfplugin/Codec2Buffer.cpp | 14 +-
|
||||
.../sfplugin/tests/CCodecBuffers_test.cpp | 450 +++++++++++++++++-
|
||||
3 files changed, 456 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/media/codec2/sfplugin/CCodecBuffers.cpp b/media/codec2/sfplugin/CCodecBuffers.cpp
|
||||
index 692da584ce..566a18fbee 100644
|
||||
--- a/media/codec2/sfplugin/CCodecBuffers.cpp
|
||||
+++ b/media/codec2/sfplugin/CCodecBuffers.cpp
|
||||
@@ -96,6 +96,9 @@ void CCodecBuffers::handleImageData(const sp<Codec2Buffer> &buffer) {
|
||||
int32_t vstride = int32_t(offsetDelta / stride);
|
||||
newFormat->setInt32(KEY_SLICE_HEIGHT, vstride);
|
||||
ALOGD("[%s] updating vstride = %d", mName, vstride);
|
||||
+ buffer->setRange(
|
||||
+ img->mPlane[0].mOffset,
|
||||
+ buffer->size() - img->mPlane[0].mOffset);
|
||||
}
|
||||
}
|
||||
setFormat(newFormat);
|
||||
diff --git a/media/codec2/sfplugin/Codec2Buffer.cpp b/media/codec2/sfplugin/Codec2Buffer.cpp
|
||||
index 25e7da9206..19414a0a0c 100644
|
||||
--- a/media/codec2/sfplugin/Codec2Buffer.cpp
|
||||
+++ b/media/codec2/sfplugin/Codec2Buffer.cpp
|
||||
@@ -276,20 +276,22 @@ public:
|
||||
int32_t planeSize = 0;
|
||||
for (uint32_t i = 0; i < layout.numPlanes; ++i) {
|
||||
const C2PlaneInfo &plane = layout.planes[i];
|
||||
- ssize_t minOffset = plane.minOffset(mWidth, mHeight);
|
||||
- ssize_t maxOffset = plane.maxOffset(mWidth, mHeight);
|
||||
+ int64_t planeStride = std::abs(plane.rowInc / plane.colInc);
|
||||
+ ssize_t minOffset = plane.minOffset(
|
||||
+ mWidth / plane.colSampling, mHeight / plane.rowSampling);
|
||||
+ ssize_t maxOffset = plane.maxOffset(
|
||||
+ mWidth / plane.colSampling, mHeight / plane.rowSampling);
|
||||
if (minPtr > mView.data()[i] + minOffset) {
|
||||
minPtr = mView.data()[i] + minOffset;
|
||||
}
|
||||
if (maxPtr < mView.data()[i] + maxOffset) {
|
||||
maxPtr = mView.data()[i] + maxOffset;
|
||||
}
|
||||
- planeSize += std::abs(plane.rowInc) * align(mHeight, 64)
|
||||
- / plane.rowSampling / plane.colSampling
|
||||
- * divUp(mAllocatedDepth, 8u);
|
||||
+ planeSize += planeStride * divUp(mAllocatedDepth, 8u)
|
||||
+ * align(mHeight, 64) / plane.rowSampling;
|
||||
}
|
||||
|
||||
- if ((maxPtr - minPtr + 1) <= planeSize) {
|
||||
+ if (minPtr == mView.data()[0] && (maxPtr - minPtr + 1) <= planeSize) {
|
||||
// FIXME: this is risky as reading/writing data out of bound results
|
||||
// in an undefined behavior, but gralloc does assume a
|
||||
// contiguous mapping
|
||||
diff --git a/media/codec2/sfplugin/tests/CCodecBuffers_test.cpp b/media/codec2/sfplugin/tests/CCodecBuffers_test.cpp
|
||||
index 5bee605276..ad8f6e555b 100644
|
||||
--- a/media/codec2/sfplugin/tests/CCodecBuffers_test.cpp
|
||||
+++ b/media/codec2/sfplugin/tests/CCodecBuffers_test.cpp
|
||||
@@ -18,22 +18,31 @@
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
+#include <media/stagefright/foundation/AString.h>
|
||||
#include <media/stagefright/MediaCodecConstants.h>
|
||||
|
||||
+#include <C2BlockInternal.h>
|
||||
#include <C2PlatformSupport.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
+static std::shared_ptr<RawGraphicOutputBuffers> GetRawGraphicOutputBuffers(
|
||||
+ int32_t width, int32_t height) {
|
||||
+ std::shared_ptr<RawGraphicOutputBuffers> buffers =
|
||||
+ std::make_shared<RawGraphicOutputBuffers>("test");
|
||||
+ sp<AMessage> format{new AMessage};
|
||||
+ format->setInt32(KEY_WIDTH, width);
|
||||
+ format->setInt32(KEY_HEIGHT, height);
|
||||
+ buffers->setFormat(format);
|
||||
+ return buffers;
|
||||
+}
|
||||
+
|
||||
TEST(RawGraphicOutputBuffersTest, ChangeNumSlots) {
|
||||
constexpr int32_t kWidth = 3840;
|
||||
constexpr int32_t kHeight = 2160;
|
||||
|
||||
std::shared_ptr<RawGraphicOutputBuffers> buffers =
|
||||
- std::make_shared<RawGraphicOutputBuffers>("test");
|
||||
- sp<AMessage> format{new AMessage};
|
||||
- format->setInt32("width", kWidth);
|
||||
- format->setInt32("height", kHeight);
|
||||
- buffers->setFormat(format);
|
||||
+ GetRawGraphicOutputBuffers(kWidth, kHeight);
|
||||
|
||||
std::shared_ptr<C2BlockPool> pool;
|
||||
ASSERT_EQ(OK, GetCodec2BlockPool(C2BlockPool::BASIC_GRAPHIC, nullptr, &pool));
|
||||
@@ -96,4 +105,435 @@ TEST(RawGraphicOutputBuffersTest, ChangeNumSlots) {
|
||||
}
|
||||
}
|
||||
|
||||
+class TestGraphicAllocation : public C2GraphicAllocation {
|
||||
+public:
|
||||
+ TestGraphicAllocation(
|
||||
+ uint32_t width,
|
||||
+ uint32_t height,
|
||||
+ const C2PlanarLayout &layout,
|
||||
+ size_t capacity,
|
||||
+ std::vector<size_t> offsets)
|
||||
+ : C2GraphicAllocation(width, height),
|
||||
+ mLayout(layout),
|
||||
+ mMemory(capacity, 0xAA),
|
||||
+ mOffsets(offsets) {
|
||||
+ }
|
||||
+
|
||||
+ c2_status_t map(
|
||||
+ C2Rect rect, C2MemoryUsage usage, C2Fence *fence,
|
||||
+ C2PlanarLayout *layout, uint8_t **addr) override {
|
||||
+ (void)rect;
|
||||
+ (void)usage;
|
||||
+ (void)fence;
|
||||
+ *layout = mLayout;
|
||||
+ for (size_t i = 0; i < mLayout.numPlanes; ++i) {
|
||||
+ addr[i] = mMemory.data() + mOffsets[i];
|
||||
+ }
|
||||
+ return C2_OK;
|
||||
+ }
|
||||
+
|
||||
+ c2_status_t unmap(uint8_t **, C2Rect, C2Fence *) override { return C2_OK; }
|
||||
+
|
||||
+ C2Allocator::id_t getAllocatorId() const override { return -1; }
|
||||
+
|
||||
+ const C2Handle *handle() const override { return nullptr; }
|
||||
+
|
||||
+ bool equals(const std::shared_ptr<const C2GraphicAllocation> &other) const override {
|
||||
+ return other.get() == this;
|
||||
+ }
|
||||
+
|
||||
+private:
|
||||
+ C2PlanarLayout mLayout;
|
||||
+ std::vector<uint8_t> mMemory;
|
||||
+ std::vector<uint8_t *> mAddr;
|
||||
+ std::vector<size_t> mOffsets;
|
||||
+};
|
||||
+
|
||||
+class LayoutTest : public ::testing::TestWithParam<std::tuple<bool, std::string, bool, int32_t>> {
|
||||
+private:
|
||||
+ static C2PlanarLayout YUVPlanarLayout(int32_t stride) {
|
||||
+ C2PlanarLayout layout = {
|
||||
+ C2PlanarLayout::TYPE_YUV,
|
||||
+ 3, /* numPlanes */
|
||||
+ 3, /* rootPlanes */
|
||||
+ {}, /* planes --- to be filled below */
|
||||
+ };
|
||||
+ layout.planes[C2PlanarLayout::PLANE_Y] = {
|
||||
+ C2PlaneInfo::CHANNEL_Y,
|
||||
+ 1, /* colInc */
|
||||
+ stride, /* rowInc */
|
||||
+ 1, /* colSampling */
|
||||
+ 1, /* rowSampling */
|
||||
+ 8, /* allocatedDepth */
|
||||
+ 8, /* bitDepth */
|
||||
+ 0, /* rightShift */
|
||||
+ C2PlaneInfo::NATIVE,
|
||||
+ C2PlanarLayout::PLANE_Y, /* rootIx */
|
||||
+ 0, /* offset */
|
||||
+ };
|
||||
+ layout.planes[C2PlanarLayout::PLANE_U] = {
|
||||
+ C2PlaneInfo::CHANNEL_CB,
|
||||
+ 1, /* colInc */
|
||||
+ stride / 2, /* rowInc */
|
||||
+ 2, /* colSampling */
|
||||
+ 2, /* rowSampling */
|
||||
+ 8, /* allocatedDepth */
|
||||
+ 8, /* bitDepth */
|
||||
+ 0, /* rightShift */
|
||||
+ C2PlaneInfo::NATIVE,
|
||||
+ C2PlanarLayout::PLANE_U, /* rootIx */
|
||||
+ 0, /* offset */
|
||||
+ };
|
||||
+ layout.planes[C2PlanarLayout::PLANE_V] = {
|
||||
+ C2PlaneInfo::CHANNEL_CR,
|
||||
+ 1, /* colInc */
|
||||
+ stride / 2, /* rowInc */
|
||||
+ 2, /* colSampling */
|
||||
+ 2, /* rowSampling */
|
||||
+ 8, /* allocatedDepth */
|
||||
+ 8, /* bitDepth */
|
||||
+ 0, /* rightShift */
|
||||
+ C2PlaneInfo::NATIVE,
|
||||
+ C2PlanarLayout::PLANE_V, /* rootIx */
|
||||
+ 0, /* offset */
|
||||
+ };
|
||||
+ return layout;
|
||||
+ }
|
||||
+
|
||||
+ static C2PlanarLayout YUVSemiPlanarLayout(int32_t stride) {
|
||||
+ C2PlanarLayout layout = {
|
||||
+ C2PlanarLayout::TYPE_YUV,
|
||||
+ 3, /* numPlanes */
|
||||
+ 2, /* rootPlanes */
|
||||
+ {}, /* planes --- to be filled below */
|
||||
+ };
|
||||
+ layout.planes[C2PlanarLayout::PLANE_Y] = {
|
||||
+ C2PlaneInfo::CHANNEL_Y,
|
||||
+ 1, /* colInc */
|
||||
+ stride, /* rowInc */
|
||||
+ 1, /* colSampling */
|
||||
+ 1, /* rowSampling */
|
||||
+ 8, /* allocatedDepth */
|
||||
+ 8, /* bitDepth */
|
||||
+ 0, /* rightShift */
|
||||
+ C2PlaneInfo::NATIVE,
|
||||
+ C2PlanarLayout::PLANE_Y, /* rootIx */
|
||||
+ 0, /* offset */
|
||||
+ };
|
||||
+ layout.planes[C2PlanarLayout::PLANE_U] = {
|
||||
+ C2PlaneInfo::CHANNEL_CB,
|
||||
+ 2, /* colInc */
|
||||
+ stride, /* rowInc */
|
||||
+ 2, /* colSampling */
|
||||
+ 2, /* rowSampling */
|
||||
+ 8, /* allocatedDepth */
|
||||
+ 8, /* bitDepth */
|
||||
+ 0, /* rightShift */
|
||||
+ C2PlaneInfo::NATIVE,
|
||||
+ C2PlanarLayout::PLANE_U, /* rootIx */
|
||||
+ 0, /* offset */
|
||||
+ };
|
||||
+ layout.planes[C2PlanarLayout::PLANE_V] = {
|
||||
+ C2PlaneInfo::CHANNEL_CR,
|
||||
+ 2, /* colInc */
|
||||
+ stride, /* rowInc */
|
||||
+ 2, /* colSampling */
|
||||
+ 2, /* rowSampling */
|
||||
+ 8, /* allocatedDepth */
|
||||
+ 8, /* bitDepth */
|
||||
+ 0, /* rightShift */
|
||||
+ C2PlaneInfo::NATIVE,
|
||||
+ C2PlanarLayout::PLANE_U, /* rootIx */
|
||||
+ 1, /* offset */
|
||||
+ };
|
||||
+ return layout;
|
||||
+ }
|
||||
+
|
||||
+ static C2PlanarLayout YVUSemiPlanarLayout(int32_t stride) {
|
||||
+ C2PlanarLayout layout = {
|
||||
+ C2PlanarLayout::TYPE_YUV,
|
||||
+ 3, /* numPlanes */
|
||||
+ 2, /* rootPlanes */
|
||||
+ {}, /* planes --- to be filled below */
|
||||
+ };
|
||||
+ layout.planes[C2PlanarLayout::PLANE_Y] = {
|
||||
+ C2PlaneInfo::CHANNEL_Y,
|
||||
+ 1, /* colInc */
|
||||
+ stride, /* rowInc */
|
||||
+ 1, /* colSampling */
|
||||
+ 1, /* rowSampling */
|
||||
+ 8, /* allocatedDepth */
|
||||
+ 8, /* bitDepth */
|
||||
+ 0, /* rightShift */
|
||||
+ C2PlaneInfo::NATIVE,
|
||||
+ C2PlanarLayout::PLANE_Y, /* rootIx */
|
||||
+ 0, /* offset */
|
||||
+ };
|
||||
+ layout.planes[C2PlanarLayout::PLANE_U] = {
|
||||
+ C2PlaneInfo::CHANNEL_CB,
|
||||
+ 2, /* colInc */
|
||||
+ stride, /* rowInc */
|
||||
+ 2, /* colSampling */
|
||||
+ 2, /* rowSampling */
|
||||
+ 8, /* allocatedDepth */
|
||||
+ 8, /* bitDepth */
|
||||
+ 0, /* rightShift */
|
||||
+ C2PlaneInfo::NATIVE,
|
||||
+ C2PlanarLayout::PLANE_V, /* rootIx */
|
||||
+ 1, /* offset */
|
||||
+ };
|
||||
+ layout.planes[C2PlanarLayout::PLANE_V] = {
|
||||
+ C2PlaneInfo::CHANNEL_CR,
|
||||
+ 2, /* colInc */
|
||||
+ stride, /* rowInc */
|
||||
+ 2, /* colSampling */
|
||||
+ 2, /* rowSampling */
|
||||
+ 8, /* allocatedDepth */
|
||||
+ 8, /* bitDepth */
|
||||
+ 0, /* rightShift */
|
||||
+ C2PlaneInfo::NATIVE,
|
||||
+ C2PlanarLayout::PLANE_V, /* rootIx */
|
||||
+ 0, /* offset */
|
||||
+ };
|
||||
+ return layout;
|
||||
+ }
|
||||
+
|
||||
+ static std::shared_ptr<C2GraphicBlock> CreateGraphicBlock(
|
||||
+ uint32_t width,
|
||||
+ uint32_t height,
|
||||
+ const C2PlanarLayout &layout,
|
||||
+ size_t capacity,
|
||||
+ std::vector<size_t> offsets) {
|
||||
+ std::shared_ptr<C2GraphicAllocation> alloc = std::make_shared<TestGraphicAllocation>(
|
||||
+ width,
|
||||
+ height,
|
||||
+ layout,
|
||||
+ capacity,
|
||||
+ offsets);
|
||||
+
|
||||
+ return _C2BlockFactory::CreateGraphicBlock(alloc);
|
||||
+ }
|
||||
+
|
||||
+ static constexpr uint8_t GetPixelValue(uint8_t value, uint32_t row, uint32_t col) {
|
||||
+ return (uint32_t(value) * row + col) & 0xFF;
|
||||
+ }
|
||||
+
|
||||
+ static void FillPlane(C2GraphicView &view, size_t index, uint8_t value) {
|
||||
+ C2PlanarLayout layout = view.layout();
|
||||
+
|
||||
+ uint8_t *rowPtr = view.data()[index];
|
||||
+ C2PlaneInfo plane = layout.planes[index];
|
||||
+ for (uint32_t row = 0; row < view.height() / plane.rowSampling; ++row) {
|
||||
+ uint8_t *colPtr = rowPtr;
|
||||
+ for (uint32_t col = 0; col < view.width() / plane.colSampling; ++col) {
|
||||
+ *colPtr = GetPixelValue(value, row, col);
|
||||
+ colPtr += plane.colInc;
|
||||
+ }
|
||||
+ rowPtr += plane.rowInc;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ static void FillBlock(const std::shared_ptr<C2GraphicBlock> &block) {
|
||||
+ C2GraphicView view = block->map().get();
|
||||
+
|
||||
+ FillPlane(view, C2PlanarLayout::PLANE_Y, 'Y');
|
||||
+ FillPlane(view, C2PlanarLayout::PLANE_U, 'U');
|
||||
+ FillPlane(view, C2PlanarLayout::PLANE_V, 'V');
|
||||
+ }
|
||||
+
|
||||
+ static bool VerifyPlane(
|
||||
+ const MediaImage2 *mediaImage,
|
||||
+ const uint8_t *base,
|
||||
+ uint32_t index,
|
||||
+ uint8_t value,
|
||||
+ std::string *errorMsg) {
|
||||
+ *errorMsg = "";
|
||||
+ MediaImage2::PlaneInfo plane = mediaImage->mPlane[index];
|
||||
+ const uint8_t *rowPtr = base + plane.mOffset;
|
||||
+ for (uint32_t row = 0; row < mediaImage->mHeight / plane.mVertSubsampling; ++row) {
|
||||
+ const uint8_t *colPtr = rowPtr;
|
||||
+ for (uint32_t col = 0; col < mediaImage->mWidth / plane.mHorizSubsampling; ++col) {
|
||||
+ if (GetPixelValue(value, row, col) != *colPtr) {
|
||||
+ *errorMsg = AStringPrintf("row=%u col=%u expected=%02x actual=%02x",
|
||||
+ row, col, GetPixelValue(value, row, col), *colPtr).c_str();
|
||||
+ return false;
|
||||
+ }
|
||||
+ colPtr += plane.mColInc;
|
||||
+ }
|
||||
+ rowPtr += plane.mRowInc;
|
||||
+ }
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+public:
|
||||
+ static constexpr int32_t kWidth = 320;
|
||||
+ static constexpr int32_t kHeight = 240;
|
||||
+ static constexpr int32_t kGapLength = kWidth * kHeight * 10;
|
||||
+
|
||||
+ static std::shared_ptr<C2Buffer> CreateAndFillBufferFromParam(const ParamType ¶m) {
|
||||
+ bool contiguous = std::get<0>(param);
|
||||
+ std::string planeOrderStr = std::get<1>(param);
|
||||
+ bool planar = std::get<2>(param);
|
||||
+ int32_t stride = std::get<3>(param);
|
||||
+
|
||||
+ C2PlanarLayout::plane_index_t planeOrder[3];
|
||||
+ C2PlanarLayout layout;
|
||||
+
|
||||
+ if (planeOrderStr.size() != 3) {
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+ for (size_t i = 0; i < 3; ++i) {
|
||||
+ C2PlanarLayout::plane_index_t planeIndex;
|
||||
+ switch (planeOrderStr[i]) {
|
||||
+ case 'Y': planeIndex = C2PlanarLayout::PLANE_Y; break;
|
||||
+ case 'U': planeIndex = C2PlanarLayout::PLANE_U; break;
|
||||
+ case 'V': planeIndex = C2PlanarLayout::PLANE_V; break;
|
||||
+ default: return nullptr;
|
||||
+ }
|
||||
+ planeOrder[i] = planeIndex;
|
||||
+ }
|
||||
+
|
||||
+ if (planar) {
|
||||
+ layout = YUVPlanarLayout(stride);
|
||||
+ } else { // semi-planar
|
||||
+ for (size_t i = 0; i < 3; ++i) {
|
||||
+ if (planeOrder[i] == C2PlanarLayout::PLANE_U) {
|
||||
+ layout = YUVSemiPlanarLayout(stride);
|
||||
+ break;
|
||||
+ }
|
||||
+ if (planeOrder[i] == C2PlanarLayout::PLANE_V) {
|
||||
+ layout = YVUSemiPlanarLayout(stride);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ size_t yPlaneSize = stride * kHeight;
|
||||
+ size_t uvPlaneSize = stride * kHeight / 4;
|
||||
+ size_t capacity = yPlaneSize + uvPlaneSize * 2;
|
||||
+ std::vector<size_t> offsets(3);
|
||||
+
|
||||
+ if (!contiguous) {
|
||||
+ if (planar) {
|
||||
+ capacity += kGapLength * 2;
|
||||
+ } else { // semi-planar
|
||||
+ capacity += kGapLength;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ offsets[planeOrder[0]] = 0;
|
||||
+ size_t planeSize = (planeOrder[0] == C2PlanarLayout::PLANE_Y) ? yPlaneSize : uvPlaneSize;
|
||||
+ for (size_t i = 1; i < 3; ++i) {
|
||||
+ offsets[planeOrder[i]] = offsets[planeOrder[i - 1]] + planeSize;
|
||||
+ if (!contiguous) {
|
||||
+ offsets[planeOrder[i]] += kGapLength;
|
||||
+ }
|
||||
+ planeSize = (planeOrder[i] == C2PlanarLayout::PLANE_Y) ? yPlaneSize : uvPlaneSize;
|
||||
+ if (!planar // semi-planar
|
||||
+ && planeOrder[i - 1] != C2PlanarLayout::PLANE_Y
|
||||
+ && planeOrder[i] != C2PlanarLayout::PLANE_Y) {
|
||||
+ offsets[planeOrder[i]] = offsets[planeOrder[i - 1]] + 1;
|
||||
+ planeSize = uvPlaneSize * 2 - 1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ std::shared_ptr<C2GraphicBlock> block = CreateGraphicBlock(
|
||||
+ kWidth,
|
||||
+ kHeight,
|
||||
+ layout,
|
||||
+ capacity,
|
||||
+ offsets);
|
||||
+ FillBlock(block);
|
||||
+ return C2Buffer::CreateGraphicBuffer(
|
||||
+ block->share(block->crop(), C2Fence()));
|
||||
+ }
|
||||
+
|
||||
+ static bool VerifyClientBuffer(
|
||||
+ const sp<MediaCodecBuffer> &buffer, std::string *errorMsg) {
|
||||
+ *errorMsg = "";
|
||||
+ sp<ABuffer> imageData;
|
||||
+ if (!buffer->format()->findBuffer("image-data", &imageData)) {
|
||||
+ *errorMsg = "Missing image data";
|
||||
+ return false;
|
||||
+ }
|
||||
+ MediaImage2 *mediaImage = (MediaImage2 *)imageData->data();
|
||||
+ if (mediaImage->mType != MediaImage2::MEDIA_IMAGE_TYPE_YUV) {
|
||||
+ *errorMsg = AStringPrintf("Unexpected type: %d", mediaImage->mType).c_str();
|
||||
+ return false;
|
||||
+ }
|
||||
+ std::string planeErrorMsg;
|
||||
+ if (!VerifyPlane(mediaImage, buffer->base(), MediaImage2::Y, 'Y', &planeErrorMsg)) {
|
||||
+ *errorMsg = "Y plane does not match: " + planeErrorMsg;
|
||||
+ return false;
|
||||
+ }
|
||||
+ if (!VerifyPlane(mediaImage, buffer->base(), MediaImage2::U, 'U', &planeErrorMsg)) {
|
||||
+ *errorMsg = "U plane does not match: " + planeErrorMsg;
|
||||
+ return false;
|
||||
+ }
|
||||
+ if (!VerifyPlane(mediaImage, buffer->base(), MediaImage2::V, 'V', &planeErrorMsg)) {
|
||||
+ *errorMsg = "V plane does not match: " + planeErrorMsg;
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ int32_t width, height, stride;
|
||||
+ buffer->format()->findInt32(KEY_WIDTH, &width);
|
||||
+ buffer->format()->findInt32(KEY_HEIGHT, &height);
|
||||
+ buffer->format()->findInt32(KEY_STRIDE, &stride);
|
||||
+
|
||||
+ MediaImage2 legacyYLayout = {
|
||||
+ MediaImage2::MEDIA_IMAGE_TYPE_Y,
|
||||
+ 1, // mNumPlanes
|
||||
+ uint32_t(width),
|
||||
+ uint32_t(height),
|
||||
+ 8,
|
||||
+ 8,
|
||||
+ {}, // mPlane
|
||||
+ };
|
||||
+ legacyYLayout.mPlane[MediaImage2::Y] = {
|
||||
+ 0, // mOffset
|
||||
+ 1, // mColInc
|
||||
+ stride, // mRowInc
|
||||
+ 1, // mHorizSubsampling
|
||||
+ 1, // mVertSubsampling
|
||||
+ };
|
||||
+ if (!VerifyPlane(&legacyYLayout, buffer->data(), MediaImage2::Y, 'Y', &planeErrorMsg)) {
|
||||
+ *errorMsg = "Y plane by legacy layout does not match: " + planeErrorMsg;
|
||||
+ return false;
|
||||
+ }
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+};
|
||||
+
|
||||
+TEST_P(LayoutTest, VerifyLayout) {
|
||||
+ std::shared_ptr<RawGraphicOutputBuffers> buffers =
|
||||
+ GetRawGraphicOutputBuffers(kWidth, kHeight);
|
||||
+
|
||||
+ std::shared_ptr<C2Buffer> c2Buffer = CreateAndFillBufferFromParam(GetParam());
|
||||
+ ASSERT_NE(nullptr, c2Buffer);
|
||||
+ sp<MediaCodecBuffer> clientBuffer;
|
||||
+ size_t index;
|
||||
+ ASSERT_EQ(OK, buffers->registerBuffer(c2Buffer, &index, &clientBuffer));
|
||||
+ ASSERT_NE(nullptr, clientBuffer);
|
||||
+ std::string errorMsg;
|
||||
+ ASSERT_TRUE(VerifyClientBuffer(clientBuffer, &errorMsg)) << errorMsg;
|
||||
+}
|
||||
+
|
||||
+INSTANTIATE_TEST_SUITE_P(
|
||||
+ RawGraphicOutputBuffersTest,
|
||||
+ LayoutTest,
|
||||
+ ::testing::Combine(
|
||||
+ ::testing::Bool(), /* contiguous */
|
||||
+ ::testing::Values("YUV", "YVU", "UVY", "VUY"),
|
||||
+ ::testing::Bool(), /* planar */
|
||||
+ ::testing::Values(320, 512)),
|
||||
+ [](const ::testing::TestParamInfo<LayoutTest::ParamType> &info) {
|
||||
+ std::string contiguous = std::get<0>(info.param) ? "Contiguous" : "Noncontiguous";
|
||||
+ std::string planar = std::get<2>(info.param) ? "Planar" : "SemiPlanar";
|
||||
+ return contiguous
|
||||
+ + std::get<1>(info.param)
|
||||
+ + planar
|
||||
+ + std::to_string(std::get<3>(info.param));
|
||||
+ });
|
||||
+
|
||||
} // namespace android
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
From 9a240b125c01838dcd7be395354cd8d740b0923b Mon Sep 17 00:00:00 2001
|
||||
From: Taehwan Kim <t_h.kim@samsung.com>
|
||||
Date: Thu, 26 Nov 2020 22:40:40 +0900
|
||||
Subject: [PATCH 30/30] CCodec: GraphicBufferSourceWrapper: fix to apply
|
||||
nBufferCountActual for deciding number of inputs
|
||||
|
||||
Bug: 169398817
|
||||
|
||||
Change-Id: I58cd7da35a3ddc4abdb58df954307acf329c7ee7
|
||||
Signed-off-by: Taehwan Kim <t_h.kim@samsung.com>
|
||||
(cherry picked from commit 8b3bcddbc98af38d64a1ffefd5932b498f9d4c36)
|
||||
---
|
||||
media/codec2/sfplugin/CCodec.cpp | 15 +++++++++++++--
|
||||
1 file changed, 13 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
|
||||
index 54107bd852..2f16ca1104 100644
|
||||
--- a/media/codec2/sfplugin/CCodec.cpp
|
||||
+++ b/media/codec2/sfplugin/CCodec.cpp
|
||||
@@ -246,8 +246,19 @@ public:
|
||||
if (source == nullptr) {
|
||||
return NO_INIT;
|
||||
}
|
||||
- constexpr size_t kNumSlots = 16;
|
||||
- for (size_t i = 0; i < kNumSlots; ++i) {
|
||||
+
|
||||
+ size_t numSlots = 4;
|
||||
+ constexpr OMX_U32 kPortIndexInput = 0;
|
||||
+
|
||||
+ OMX_PARAM_PORTDEFINITIONTYPE param;
|
||||
+ param.nPortIndex = kPortIndexInput;
|
||||
+ status_t err = mNode->getParameter(OMX_IndexParamPortDefinition,
|
||||
+ ¶m, sizeof(param));
|
||||
+ if (err == OK) {
|
||||
+ numSlots = param.nBufferCountActual;
|
||||
+ }
|
||||
+
|
||||
+ for (size_t i = 0; i < numSlots; ++i) {
|
||||
source->onInputBufferAdded(i);
|
||||
}
|
||||
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
From c833b08d188dbb1294e164958c51ac2afb0e3e2e Mon Sep 17 00:00:00 2001
|
||||
From: Wonsik Kim <wonsik@google.com>
|
||||
Date: Tue, 5 Jan 2021 18:55:22 -0800
|
||||
Subject: [PATCH 31/32] CCodec: workaround for frame drops
|
||||
|
||||
Retain old behavior for lower resolution (<=4K) to workaround
|
||||
possible frame drops.
|
||||
|
||||
Bug: 175354926
|
||||
Bug: 175182085
|
||||
Test: atest CtsCameraTestCases:RecordingTest
|
||||
Change-Id: I170102e928714c5b48817bf7915f55ce8a6280f0
|
||||
---
|
||||
media/codec2/sfplugin/CCodec.cpp | 23 ++++++++++++++---------
|
||||
1 file changed, 14 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
|
||||
index 2f16ca1104..55ff18f4a2 100644
|
||||
--- a/media/codec2/sfplugin/CCodec.cpp
|
||||
+++ b/media/codec2/sfplugin/CCodec.cpp
|
||||
@@ -247,15 +247,20 @@ public:
|
||||
return NO_INIT;
|
||||
}
|
||||
|
||||
- size_t numSlots = 4;
|
||||
- constexpr OMX_U32 kPortIndexInput = 0;
|
||||
-
|
||||
- OMX_PARAM_PORTDEFINITIONTYPE param;
|
||||
- param.nPortIndex = kPortIndexInput;
|
||||
- status_t err = mNode->getParameter(OMX_IndexParamPortDefinition,
|
||||
- ¶m, sizeof(param));
|
||||
- if (err == OK) {
|
||||
- numSlots = param.nBufferCountActual;
|
||||
+ size_t numSlots = 16;
|
||||
+ // WORKAROUND: having more slots improve performance while consuming
|
||||
+ // more memory. This is a temporary workaround to reduce memory for
|
||||
+ // larger-than-4K scenario.
|
||||
+ if (mWidth * mHeight > 4096 * 2340) {
|
||||
+ constexpr OMX_U32 kPortIndexInput = 0;
|
||||
+
|
||||
+ OMX_PARAM_PORTDEFINITIONTYPE param;
|
||||
+ param.nPortIndex = kPortIndexInput;
|
||||
+ status_t err = mNode->getParameter(OMX_IndexParamPortDefinition,
|
||||
+ ¶m, sizeof(param));
|
||||
+ if (err == OK) {
|
||||
+ numSlots = param.nBufferCountActual;
|
||||
+ }
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < numSlots; ++i) {
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
From 624cfc90b8bedb024f289772960f3cd7072fa940 Mon Sep 17 00:00:00 2001
|
||||
From: Pierre-Hugues Husson <phh@phh.me>
|
||||
Date: Sat, 6 Mar 2021 19:15:24 -0500
|
||||
Subject: [PATCH 32/32] Fix AAC decoder failing to instantiate
|
||||
|
||||
This has been caused by I50fcc5ef35cb7e96592c2267652228b5fa074ba9
|
||||
Non-Android 11 vendors won't provide those calls, and will thus fail.
|
||||
---
|
||||
media/libstagefright/ACodec.cpp | 5 ++---
|
||||
1 file changed, 2 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
|
||||
index 0f8cd39edb..35cdf86319 100644
|
||||
--- a/media/libstagefright/ACodec.cpp
|
||||
+++ b/media/libstagefright/ACodec.cpp
|
||||
@@ -5340,9 +5340,7 @@ status_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> ¬ify) {
|
||||
err = mOMXNode->getParameter(
|
||||
(OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacDrcPresentation,
|
||||
&presentation, sizeof(presentation));
|
||||
- if (err != OK) {
|
||||
- return err;
|
||||
- }
|
||||
+ if (err == OK) {
|
||||
notify->setInt32("aac-encoded-target-level",
|
||||
presentation.nEncodedTargetLevel);
|
||||
notify->setInt32("aac-drc-cut-level", presentation.nDrcCut);
|
||||
@@ -5355,6 +5353,7 @@ status_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> ¬ify) {
|
||||
notify->setInt32("aac-drc-album-mode", presentation.nDrcAlbumMode);
|
||||
notify->setInt32("aac-drc-output-loudness",
|
||||
presentation.nDrcOutputLoudness);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
break;
|
||||
--
|
||||
2.25.1
|
||||
|
||||
Reference in New Issue
Block a user