Sync up to v302

This commit is contained in:
Andy CrossGate Yan 2021-03-14 05:52:23 +00:00
parent 73446c001b
commit cacd8b0430
27 changed files with 2349 additions and 28 deletions

View File

@ -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", &params));
+
+ 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

View File

@ -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

View File

@ -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> &param : 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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 &param) {
+ 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

View File

@ -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,
+ &param, sizeof(param));
+ if (err == OK) {
+ numSlots = param.nBufferCountActual;
+ }
+
+ for (size_t i = 0; i < numSlots; ++i) {
source->onInputBufferAdded(i);
}
--
2.25.1

View File

@ -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,
- &param, 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,
+ &param, sizeof(param));
+ if (err == OK) {
+ numSlots = param.nBufferCountActual;
+ }
}
for (size_t i = 0; i < numSlots; ++i) {
--
2.25.1

View File

@ -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> &notify) {
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> &notify) {
notify->setInt32("aac-drc-album-mode", presentation.nDrcAlbumMode);
notify->setInt32("aac-drc-output-loudness",
presentation.nDrcOutputLoudness);
+ }
}
}
break;
--
2.25.1

View File

@ -0,0 +1,37 @@
From 109bc691f314f18f923c5c72fc82ff072c77eca3 Mon Sep 17 00:00:00 2001
From: N Harish <kqn736@zebra.com>
Date: Mon, 25 Jan 2021 17:22:33 +0530
Subject: [PATCH 40/40] Fix for TestDirectBootEmulated testcase
In case of emulated FBE the secrets are empty hence add this
exception to prevent from unlocking userkey.
Bug: 177617301
Test: android.appsecurity.cts.DirectBootHostTest#testDirectBootEmulated
Change-Id: I5be2ceb61d9ef47219862e75cc8ec03ab5513426
(cherry picked from commit 2912b101aaa34abfa9637f2f00c992e7d129b994)
---
.../core/java/com/android/server/StorageManagerService.java | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 87afdac45dae..179899ee6067 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -3295,6 +3295,12 @@ class StorageManagerService extends IStorageManager.Stub
enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
if (isFsEncrypted) {
+ // When a user has secure lock screen, require secret to actually unlock.
+ // This check is mostly in place for emulation mode.
+ if (StorageManager.isFileEncryptedEmulatedOnly() &&
+ mLockPatternUtils.isSecure(userId) && ArrayUtils.isEmpty(secret)) {
+ throw new IllegalStateException("Secret required to unlock secure user " + userId);
+ }
try {
mVold.unlockUserKey(userId, serialNumber, encodeBytes(token),
encodeBytes(secret));
--
2.25.1

View File

@ -0,0 +1,27 @@
From 8b9a1e5df3dd1b25b2cf9d83eca1353327697796 Mon Sep 17 00:00:00 2001
From: Pierre-Hugues Husson <phh@phh.me>
Date: Sat, 6 Mar 2021 18:39:15 -0500
Subject: [PATCH 41/41] Make secondary displays' lock screen black. Useful for
Moto Razr AOD
---
.../SystemUI/res-keyguard/layout/keyguard_presentation.xml | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml b/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml
index f4d34f4ca141..58650b26ceaf 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml
@@ -22,7 +22,8 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/presentation"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:background="@android:color/black">
<!-- This is mostly keyguard_status_view.xml with minor modifications -->
<com.android.keyguard.KeyguardStatusView
android:id="@+id/clock"
--
2.25.1

View File

@ -0,0 +1,50 @@
From 603b18beca562d922a546cb25d69778cf2af7c1d Mon Sep 17 00:00:00 2001
From: liyong <liyong@allwinnertech.com>
Date: Sat, 10 Oct 2020 17:08:47 +0800
Subject: [PATCH 12/13] DO NOT MERGE Correct physical orientation
setProjection already includes the physical orientation when updating
the DisplayDevice orientation. Therefore applying the physical
orientation when capturing a screenshot applies the rotation twice
which is incorrect.
Bug: 170512822
Test: run cts-on-gsi -m CtsInputMethodServiceHostTestCases -t android.inputmethodservice.cts.hostside.InputMethodServiceLifecycleTest#testImeVisibilityAfterImeSwitchingFull
run cts-on-gsi -m CtsInputMethodTestCases -t android.view.inputmethod.cts.FocusHandlingTest#testNonFocusablePopupWindowDoesNotAffectImeVisibility
run cts-on-gsi -m CtsInputMethodTestCases -t android.view.inputmethod.cts.ImeInsetsVisibilityTest#testEditTextPositionAndPersistWhenAboveImeWindowShown
run cts-on-gsi -m CtsInputMethodTestCases -t android.view.inputmethod.cts.ImeInsetsVisibilityTest#testImeVisibilityWhenImeFocusableChildPopup" />
run cts-on-gsi -m CtsInputMethodTestCases -t android.view.inputmethod.cts.InputMethodServiceTest#testRequestHideSelf
run cts-on-gsi -m CtsInputMethodTestCases -t android.view.inputmethod.cts.InputMethodServiceTest#testRequestShowSelf
run cts-on-gsi -m CtsInputMethodTestCases -t android.view.inputmethod.cts.KeyboardVisibilityControlTest#testBasicShowHideSoftInput
run cts-on-gsi -m CtsInputMethodTestCases -t android.view.inputmethod.cts.KeyboardVisibilityControlTest#testFloatingImeHideKeyboardAfterBackPressed
run cts-on-gsi -m CtsInputMethodTestCases -t android.view.inputmethod.cts.KeyboardVisibilityControlTest#testImeVisibilityWhenDismisingDialogWithImeFocused
run cts-on-gsi -m CtsInputMethodTestCases -t android.view.inputmethod.cts.KeyboardVisibilityControlTest#testShowHideKeyboardOnWebView
run cts-on-gsi -m CtsInputMethodTestCases -t android.view.inputmethod.cts.KeyboardVisibilityControlTest#testToggleSoftInput
run cts-on-gsi -m CtsInputMethodTestCases -t android.view.inputmethod.cts.SearchViewTest#testShowImeWhenSearchViewFocusInListView
run cts-on-gsi -m CtsInputMethodTestCases -t android.view.inputmethod.cts.SearchViewTest#testShowImeWithSearchViewFocus
run cts-on-gsi -m CtsInputMethodTestCases -t android.view.inputmethod.cts.SearchViewTest#testTapThenSetQuery
run cts-on-gsi -m CtsWindowManagerDeviceTestCases -t android.server.wm.WindowInsetsAnimationSynchronicityTests#testControl_rendersSynchronouslyBetweenImeWindowAndAppContent
run cts-on-gsi -m CtsWindowManagerDeviceTestCases -t android.server.wm.WindowInsetsAnimationSynchronicityTests#testShowAndHide_renderSynchronouslyBetweenImeWindowAndAppContent
Change-Id: I72aba3cdbae1075dcf9d99661bfd13fe5fd74c72
(cherry picked from commit d4d89976ea3f98248064fd755505ee5dc9b35c2f)
---
services/surfaceflinger/DisplayDevice.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index cb467ea29..ca7119e2c 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -313,7 +313,7 @@ private:
logicalOrientation = ui::Rotation::Rotation90;
}
- const ui::Rotation orientation = device->getPhysicalOrientation() + logicalOrientation;
+ const ui::Rotation orientation = logicalOrientation;
switch (orientation) {
case ui::ROTATION_0:
--
2.25.1

View File

@ -0,0 +1,68 @@
From 54a80ed3e7039548d565c4e40e2fa7a45c89bce8 Mon Sep 17 00:00:00 2001
From: SeYeong Byeon <sy.byeon@samsung.com>
Date: Tue, 15 Sep 2020 15:02:40 +0900
Subject: [PATCH 13/13] gralloc4: fix PlaneLayout encode typecasting
Fixes a bug where planeLayout members were being downcasted
to int32_t during the encoding step.
Bug: 168564125
Signed-off-by: SeYeong Byeon <sy.byeon@samsung.com>
Change-Id: I8d5139dbd253278193775380ca387d45bfe2589d
(cherry picked from commit 389ee53332904b49c8f9fb35ef4e9e624e1ee3d2)
---
libs/gralloc/types/Gralloc4.cpp | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/libs/gralloc/types/Gralloc4.cpp b/libs/gralloc/types/Gralloc4.cpp
index 53c68b723..e2f072a7a 100644
--- a/libs/gralloc/types/Gralloc4.cpp
+++ b/libs/gralloc/types/Gralloc4.cpp
@@ -706,35 +706,35 @@ status_t encodePlaneLayout(const PlaneLayout& input, OutputHidlVec* output) {
return err;
}
- err = encodeInteger<int64_t>(static_cast<int32_t>(input.offsetInBytes), output);
+ err = encodeInteger<int64_t>(static_cast<int64_t>(input.offsetInBytes), output);
if (err) {
return err;
}
- err = encodeInteger<int64_t>(static_cast<int32_t>(input.sampleIncrementInBits), output);
+ err = encodeInteger<int64_t>(static_cast<int64_t>(input.sampleIncrementInBits), output);
if (err) {
return err;
}
- err = encodeInteger<int64_t>(static_cast<int32_t>(input.strideInBytes), output);
+ err = encodeInteger<int64_t>(static_cast<int64_t>(input.strideInBytes), output);
if (err) {
return err;
}
- err = encodeInteger<int64_t>(static_cast<int32_t>(input.widthInSamples), output);
+ err = encodeInteger<int64_t>(static_cast<int64_t>(input.widthInSamples), output);
if (err) {
return err;
}
- err = encodeInteger<int64_t>(static_cast<int32_t>(input.heightInSamples), output);
+ err = encodeInteger<int64_t>(static_cast<int64_t>(input.heightInSamples), output);
if (err) {
return err;
}
- err = encodeInteger<int64_t>(static_cast<int32_t>(input.totalSizeInBytes), output);
+ err = encodeInteger<int64_t>(static_cast<int64_t>(input.totalSizeInBytes), output);
if (err) {
return err;
}
- err = encodeInteger<int64_t>(static_cast<int32_t>(input.horizontalSubsampling), output);
+ err = encodeInteger<int64_t>(static_cast<int64_t>(input.horizontalSubsampling), output);
if (err) {
return err;
}
- return encodeInteger<int64_t>(static_cast<int32_t>(input.verticalSubsampling), output);
+ return encodeInteger<int64_t>(static_cast<int64_t>(input.verticalSubsampling), output);
}
status_t decodePlaneLayout(InputHidlVec* input, PlaneLayout* output) {
--
2.25.1

View File

@ -0,0 +1,32 @@
From 28d9ac16f35106b40dd183dfc697023e056f3cae Mon Sep 17 00:00:00 2001
From: Pierre-Hugues Husson <phh@phh.me>
Date: Tue, 14 Aug 2018 21:48:19 +0200
Subject: [PATCH] Act as usb device when there is no hal, but we believe we are
a device
Change-Id: I036090738525fd8cc63534d52d02ab1852950a7d
---
.../usb/UsbConnectionBroadcastReceiver.java | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/com/android/settings/connecteddevice/usb/UsbConnectionBroadcastReceiver.java b/src/com/android/settings/connecteddevice/usb/UsbConnectionBroadcastReceiver.java
index a203534dde..86c8564bed 100644
--- a/src/com/android/settings/connecteddevice/usb/UsbConnectionBroadcastReceiver.java
+++ b/src/com/android/settings/connecteddevice/usb/UsbConnectionBroadcastReceiver.java
@@ -78,6 +78,13 @@ public class UsbConnectionBroadcastReceiver extends BroadcastReceiver implements
mFunctions = functions;
mDataRole = mUsbBackend.getDataRole();
mPowerRole = mUsbBackend.getPowerRole();
+ //If we have no USB HAL, mDataRole is invalid
+ //But we can't be connected AND have none data_role, so it's safe.
+ //It would be better to fix UsbManager when no HAL is available, but that's more work
+ if(mDataRole == UsbPortStatus.DATA_ROLE_NONE &&
+ intent.getExtras().getBoolean(UsbManager.USB_CONNECTED) &&
+ !intent.getExtras().getBoolean(UsbManager.USB_HOST_CONNECTED))
+ mDataRole = UsbPortStatus.DATA_ROLE_DEVICE;
} else if (UsbManager.ACTION_USB_PORT_CHANGED.equals(intent.getAction())) {
UsbPortStatus portStatus = intent.getExtras()
.getParcelable(UsbManager.EXTRA_PORT_STATUS);
--
2.25.1

View File

@ -0,0 +1,104 @@
From e9288c036c55b8d7cc1c3ba9e1b20a3ca4fb29e3 Mon Sep 17 00:00:00 2001
From: SzuWei Lin <szuweilin@google.com>
Date: Thu, 31 Dec 2020 16:52:39 +0800
Subject: [PATCH] Make ro.product.cpu.abilist* to be fetched dynamically
Basically, ro.product.cpu.abilist* are defined by
ro.vendor.cpu.abilist*. And they can be overried by
ro.odm.cpu.abilist* and ro.product.cpu.abilist*.
ro.system.cpu.abilist* are for fallback if others are no defined.
Bug: 176520383
Test: check the result by flashing aosp_arm64-userdebug on
Test: aosp_blueline-user and aosp_blueline-user hacked by
Test: 64-bits-only
Change-Id: I01ae01af099a4ec8fe3d4525edecc233a477ff60
---
init/property_service.cpp | 64 +++++++++++++++++++++++++++++++++++++++
1 file changed, 64 insertions(+)
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 42dd5afcb..44b51c2cf 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -874,6 +874,69 @@ static void property_derive_build_fingerprint() {
}
}
+// If the ro.product.cpu.abilist* properties have not been explicitly
+// set, derive them from ro.${partition}.product.cpu.abilist* properties.
+static void property_initialize_ro_cpu_abilist() {
+ // From high to low priority.
+ const char* kAbilistSources[] = {
+ "product",
+ "odm",
+ "vendor",
+ "system",
+ };
+ const std::string EMPTY = "";
+ const char* kAbilistProp = "ro.product.cpu.abilist";
+ const char* kAbilist32Prop = "ro.product.cpu.abilist32";
+ const char* kAbilist64Prop = "ro.product.cpu.abilist64";
+
+ // If the properties are defined explicitly, just use them.
+ if (GetProperty(kAbilistProp, EMPTY) != EMPTY) {
+ return;
+ }
+
+ // Find the first source defining these properties by order.
+ std::string abilist32_prop_val;
+ std::string abilist64_prop_val;
+ for (const auto& source : kAbilistSources) {
+ const auto abilist32_prop = std::string("ro.") + source + ".product.cpu.abilist32";
+ const auto abilist64_prop = std::string("ro.") + source + ".product.cpu.abilist64";
+ abilist32_prop_val = GetProperty(abilist32_prop, EMPTY);
+ abilist64_prop_val = GetProperty(abilist64_prop, EMPTY);
+ // The properties could be empty on 32-bit-only or 64-bit-only devices,
+ // but we cannot identify a property is empty or undefined by GetProperty().
+ // So, we assume both of these 2 properties are empty as undefined.
+ if (abilist32_prop_val != EMPTY || abilist64_prop_val != EMPTY) {
+ break;
+ }
+ }
+
+ // Merge ABI lists for ro.product.cpu.abilist
+ auto abilist_prop_val = abilist64_prop_val;
+ if (abilist32_prop_val != EMPTY) {
+ if (abilist_prop_val != EMPTY) {
+ abilist_prop_val += ",";
+ }
+ abilist_prop_val += abilist32_prop_val;
+ }
+
+ // Set these properties
+ const std::pair<const char*, const std::string&> set_prop_list[] = {
+ {kAbilistProp, abilist_prop_val},
+ {kAbilist32Prop, abilist32_prop_val},
+ {kAbilist64Prop, abilist64_prop_val},
+ };
+ for (const auto& [prop, prop_val] : set_prop_list) {
+ LOG(INFO) << "Setting property '" << prop << "' to '" << prop_val << "'";
+
+ std::string error;
+ uint32_t res = PropertySet(prop, prop_val, &error);
+ if (res != PROP_SUCCESS) {
+ LOG(ERROR) << "Error setting property '" << prop << "': err=" << res << " (" << error
+ << ")";
+ }
+ }
+}
+
void PropertyLoadBootDefaults() {
// TODO(b/117892318): merge prop.default and build.prop files into one
// We read the properties and their values into a map, in order to always allow properties
@@ -918,6 +981,7 @@ void PropertyLoadBootDefaults() {
property_initialize_ro_product_props();
property_derive_build_fingerprint();
+ property_initialize_ro_cpu_abilist();
if (android::base::GetBoolProperty("ro.persistent_properties.ready", false)) {
update_sys_usb_config();
--
2.25.1

View File

@ -0,0 +1,174 @@
From d3debf43a576aebfc505803eeb95b099c9129ae3 Mon Sep 17 00:00:00 2001
From: Nikita Ioffe <ioffe@google.com>
Date: Mon, 7 Sep 2020 10:27:25 +0100
Subject: [PATCH 10/12] Only store result of mount_all that mounted userdata
During boot sequence there can be multiple calls to mount_all. For the
userspace reboot to correctly remount userdata, we need to store the
return code of the one that was responsible in mounting userdata.
Test: adb root
Test: adb shell setprop init.userspace_reboot.is_supported 1
Test: adb reboot userspace
Test: checked dmsg
Bug: 166353152
Change-Id: Id0ae15f3bcf65fa54e4e72b76f64716c053af7fb
Merged-In: Id0ae15f3bcf65fa54e4e72b76f64716c053af7fb
(cherry picked from commit 9ede7ec273539d7ad6820bdf3f1f2f28433a9fb3)
---
fs_mgr/fs_mgr.cpp | 24 ++++++++++++++----------
fs_mgr/include/fs_mgr.h | 14 +++++++++++++-
init/builtins.cpp | 14 +++++++++++---
3 files changed, 38 insertions(+), 14 deletions(-)
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 30db652ed..bc2d8a475 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -1305,14 +1305,15 @@ static bool IsMountPointMounted(const std::string& mount_point) {
// When multiple fstab records share the same mount_point, it will try to mount each
// one in turn, and ignore any duplicates after a first successful mount.
// Returns -1 on error, and FS_MGR_MNTALL_* otherwise.
-int fs_mgr_mount_all(Fstab* fstab, int mount_mode) {
+MountAllResult fs_mgr_mount_all(Fstab* fstab, int mount_mode) {
int encryptable = FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE;
int error_count = 0;
CheckpointManager checkpoint_manager;
AvbUniquePtr avb_handle(nullptr);
+ bool userdata_mounted = false;
if (fstab->empty()) {
- return FS_MGR_MNTALL_FAIL;
+ return {FS_MGR_MNTALL_FAIL, userdata_mounted};
}
// Keep i int to prevent unsigned integer overflow from (i = top_idx - 1),
@@ -1352,7 +1353,7 @@ int fs_mgr_mount_all(Fstab* fstab, int mount_mode) {
}
// Terrible hack to make it possible to remount /data.
- // TODO: refact fs_mgr_mount_all and get rid of this.
+ // TODO: refactor fs_mgr_mount_all and get rid of this.
if (mount_mode == MOUNT_MODE_ONLY_USERDATA && current_entry.mount_point != "/data") {
continue;
}
@@ -1388,7 +1389,7 @@ int fs_mgr_mount_all(Fstab* fstab, int mount_mode) {
avb_handle = AvbHandle::Open();
if (!avb_handle) {
LERROR << "Failed to open AvbHandle";
- return FS_MGR_MNTALL_FAIL;
+ return {FS_MGR_MNTALL_FAIL, userdata_mounted};
}
}
if (avb_handle->SetUpAvbHashtree(&current_entry, true /* wait_for_verity_dev */) ==
@@ -1430,7 +1431,7 @@ int fs_mgr_mount_all(Fstab* fstab, int mount_mode) {
if (status == FS_MGR_MNTALL_FAIL) {
// Fatal error - no point continuing.
- return status;
+ return {status, userdata_mounted};
}
if (status != FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) {
@@ -1444,11 +1445,14 @@ int fs_mgr_mount_all(Fstab* fstab, int mount_mode) {
attempted_entry.mount_point},
nullptr)) {
LERROR << "Encryption failed";
- return FS_MGR_MNTALL_FAIL;
+ return {FS_MGR_MNTALL_FAIL, userdata_mounted};
}
}
}
+ if (current_entry.mount_point == "/data") {
+ userdata_mounted = true;
+ }
// Success! Go get the next one.
continue;
}
@@ -1546,9 +1550,9 @@ int fs_mgr_mount_all(Fstab* fstab, int mount_mode) {
#endif
if (error_count) {
- return FS_MGR_MNTALL_FAIL;
+ return {FS_MGR_MNTALL_FAIL, userdata_mounted};
} else {
- return encryptable;
+ return {encryptable, userdata_mounted};
}
}
@@ -1770,8 +1774,8 @@ int fs_mgr_remount_userdata_into_checkpointing(Fstab* fstab) {
}
LINFO << "Remounting /data";
// TODO(b/143970043): remove this hack after fs_mgr_mount_all is refactored.
- int result = fs_mgr_mount_all(fstab, MOUNT_MODE_ONLY_USERDATA);
- return result == FS_MGR_MNTALL_FAIL ? -1 : 0;
+ auto result = fs_mgr_mount_all(fstab, MOUNT_MODE_ONLY_USERDATA);
+ return result.code == FS_MGR_MNTALL_FAIL ? -1 : 0;
}
return 0;
}
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index 2a67b8c9f..11e36645e 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -60,8 +60,20 @@ enum mount_mode {
#define FS_MGR_MNTALL_DEV_NOT_ENCRYPTED 1
#define FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE 0
#define FS_MGR_MNTALL_FAIL (-1)
+
+struct MountAllResult {
+ // One of the FS_MGR_MNTALL_* returned code defined above.
+ int code;
+ // Whether userdata was mounted as a result of |fs_mgr_mount_all| call.
+ bool userdata_mounted;
+};
+
// fs_mgr_mount_all() updates fstab entries that reference device-mapper.
-int fs_mgr_mount_all(android::fs_mgr::Fstab* fstab, int mount_mode);
+// Returns a |MountAllResult|. The first element is one of the FS_MNG_MNTALL_* return codes
+// defined above, and the second element tells whether this call to fs_mgr_mount_all was responsible
+// for mounting userdata. Later is required for init to correctly enqueue fs-related events as part
+// of userdata remount during userspace reboot.
+MountAllResult fs_mgr_mount_all(android::fs_mgr::Fstab* fstab, int mount_mode);
#define FS_MGR_DOMNT_FAILED (-1)
#define FS_MGR_DOMNT_BUSY (-2)
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 0ac66f272..789316621 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -666,18 +666,26 @@ static Result<void> do_mount_all(const BuiltinArguments& args) {
}
}
- auto mount_fstab_return_code = fs_mgr_mount_all(&fstab, mount_all->mode);
+ auto mount_fstab_result = fs_mgr_mount_all(&fstab, mount_all->mode);
SetProperty(prop_name, std::to_string(t.duration().count()));
if (mount_all->import_rc) {
import_late(mount_all->rc_paths);
}
+ if (mount_fstab_result.userdata_mounted) {
+ // This call to fs_mgr_mount_all mounted userdata. Keep the result in
+ // order for userspace reboot to correctly remount userdata.
+ LOG(INFO) << "Userdata mounted using "
+ << (mount_all->fstab_path.empty() ? "(default fstab)" : mount_all->fstab_path)
+ << " result : " << mount_fstab_result.code;
+ initial_mount_fstab_return_code = mount_fstab_result.code;
+ }
+
if (queue_event) {
/* queue_fs_event will queue event based on mount_fstab return code
* and return processed return code*/
- initial_mount_fstab_return_code = mount_fstab_return_code;
- auto queue_fs_result = queue_fs_event(mount_fstab_return_code, false);
+ auto queue_fs_result = queue_fs_event(mount_fstab_result.code, false);
if (!queue_fs_result.ok()) {
return Error() << "queue_fs_event() failed: " << queue_fs_result.error();
}
--
2.25.1

View File

@ -0,0 +1,33 @@
From 60cf1d694c1550c0b9b8139e70d0627c54b44d6b Mon Sep 17 00:00:00 2001
From: Qilin Tan <qilin.tan@mediatek.com>
Date: Mon, 2 Nov 2020 11:25:09 +0800
Subject: [PATCH 11/12] Store result of mount_all for mounted userdata by
metadata encryption
When the userdata is mounted, its result will be stored and return.
But the result is not stored when the userdata is mounted with
metadata encryption. Store the result of metadata encryption mount.
Bug: 172180818
Test: run cts-on-gsi -m CtsUserspaceRebootHostSideTestCases
Change-Id: I88b1b4f6a2b1ed81773e18243cb6c46244dc1ba5
---
fs_mgr/fs_mgr.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index bc2d8a475..b20086e5d 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -1521,6 +1521,8 @@ MountAllResult fs_mgr_mount_all(Fstab* fstab, int mount_mode) {
attempted_entry.mount_point},
nullptr)) {
++error_count;
+ } else if (current_entry.mount_point == "/data") {
+ userdata_mounted = true;
}
encryptable = FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED;
continue;
--
2.25.1

View File

@ -0,0 +1,45 @@
From 26478551e8a20d3abf1c302e58ee8fee97cab728 Mon Sep 17 00:00:00 2001
From: Bowgo Tsai <bowgotsai@google.com>
Date: Fri, 4 Dec 2020 17:04:34 +0800
Subject: [PATCH 12/12] Adding 'postinstall' root dir unconditionally.
It is required to pass update_engine_unittests in GSI
compliance test. And it's clean to just add this mount
dir unconditionally.
Bug: 172696594
Test: `m init.environ.rc` and checks that $OUT/root/postinstall exists
Change-Id: Ib340a78af442ea66c45cecb373a9eb3c428f8dda
Merged-In: Ib340a78af442ea66c45cecb373a9eb3c428f8dda
---
rootdir/Android.mk | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index a9d0ed08a..7d383f522 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -78,7 +78,7 @@ endif
# create some directories (some are mount points) and symlinks
LOCAL_POST_INSTALL_CMD := mkdir -p $(addprefix $(TARGET_ROOT_OUT)/, \
dev proc sys system data data_mirror odm oem acct config storage mnt apex debug_ramdisk \
- linkerconfig $(BOARD_ROOT_EXTRA_FOLDERS)); \
+ linkerconfig postinstall $(BOARD_ROOT_EXTRA_FOLDERS)); \
ln -sf /system/bin $(TARGET_ROOT_OUT)/bin; \
ln -sf /system/etc $(TARGET_ROOT_OUT)/etc; \
ln -sf /data/user_de/0/com.android.shell/files/bugreports $(TARGET_ROOT_OUT)/bugreports; \
@@ -132,11 +132,6 @@ ifdef BOARD_ROOT_EXTRA_SYMLINKS
; mkdir -p $(dir $(TARGET_ROOT_OUT)/$(word 2,$(p))) \
; ln -sf $(word 1,$(p)) $(TARGET_ROOT_OUT)/$(word 2,$(p)))
endif
-# The A/B updater uses a top-level /postinstall directory to mount the new
-# system before reboot.
-ifeq ($(AB_OTA_UPDATER),true)
- LOCAL_POST_INSTALL_CMD += ; mkdir -p $(TARGET_ROOT_OUT)/postinstall
-endif
# The init symlink must be a post install command of a file that is to TARGET_ROOT_OUT.
# Since init.environ.rc is required for init and satisfies that requirement, we hijack it to create the symlink.
--
2.25.1

View File

@ -1,4 +1,4 @@
From d4880eec8fa830f6c8fe68fe1ebbb05adc5bbbb1 Mon Sep 17 00:00:00 2001 From 99e0657c0215e9ce9ba55aba5c41fbfe438c82e6 Mon Sep 17 00:00:00 2001
From: Pierre-Hugues Husson <phh@phh.me> From: Pierre-Hugues Husson <phh@phh.me>
Date: Mon, 28 Sep 2020 21:02:19 +0200 Date: Mon, 28 Sep 2020 21:02:19 +0200
Subject: [PATCH 2/2] Add special handling of vndk 26 (remove liblog.so from Subject: [PATCH 2/2] Add special handling of vndk 26 (remove liblog.so from
@ -6,12 +6,12 @@ Subject: [PATCH 2/2] Add special handling of vndk 26 (remove liblog.so from
Change-Id: I29b0bb6087ba58f69ee6406e003513bceb6785d8 Change-Id: I29b0bb6087ba58f69ee6406e003513bceb6785d8
--- ---
contents/namespace/vendordefault.cc | 16 ++++++++++++++-- contents/namespace/vendordefault.cc | 14 +++++++++++++-
contents/namespace/vndk.cc | 5 +++++ contents/namespace/vndk.cc | 5 +++++
2 files changed, 19 insertions(+), 2 deletions(-) 2 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/contents/namespace/vendordefault.cc b/contents/namespace/vendordefault.cc diff --git a/contents/namespace/vendordefault.cc b/contents/namespace/vendordefault.cc
index 6d56904..c93c489 100644 index b3be200..af53602 100644
--- a/contents/namespace/vendordefault.cc --- a/contents/namespace/vendordefault.cc
+++ b/contents/namespace/vendordefault.cc +++ b/contents/namespace/vendordefault.cc
@@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
@ -22,16 +22,7 @@ index 6d56904..c93c489 100644
#include "linkerconfig/namespacebuilder.h" #include "linkerconfig/namespacebuilder.h"
#include "linkerconfig/common.h" #include "linkerconfig/common.h"
@@ -92,7 +93,7 @@ Namespace BuildVendorDefaultNamespace([[maybe_unused]] const Context& ctx) { @@ -105,9 +106,20 @@ Namespace BuildVendorDefaultNamespace([[maybe_unused]] const Context& ctx) {
AsanPath::SAME_PATH);
}
- if (ctx.IsDefaultConfig() && GetVendorVndkVersion() == "27") {
+ if (ctx.IsDefaultConfig() && (GetVendorVndkVersion() == "27" || GetVendorVndkVersion()== "26")) {
ns.AddSearchPath("/vendor/${LIB}/hw", AsanPath::WITH_DATA_ASAN);
ns.AddSearchPath("/vendor/${LIB}/egl", AsanPath::WITH_DATA_ASAN);
}
@@ -107,9 +108,20 @@ Namespace BuildVendorDefaultNamespace([[maybe_unused]] const Context& ctx) {
ns.AddRequires(kVndkLiteVendorRequires); ns.AddRequires(kVndkLiteVendorRequires);
ns.AddProvides(GetSystemStubLibraries()); ns.AddProvides(GetSystemStubLibraries());
} else { } else {
@ -77,5 +68,5 @@ index a95db80..589f745 100644
} }
} // namespace contents } // namespace contents
-- --
2.17.1 2.25.1

View File

@ -1,4 +1,4 @@
From d6f033bfbd7c03b30a23b287e84b1608c35d6038 Mon Sep 17 00:00:00 2001 From d69f9a1231d08fd6508e7219b3298cdbc3158796 Mon Sep 17 00:00:00 2001
From: Pierre-Hugues Husson <phh@phh.me> From: Pierre-Hugues Husson <phh@phh.me>
Date: Mon, 16 Sep 2019 13:49:05 +0200 Date: Mon, 16 Sep 2019 13:49:05 +0200
Subject: [PATCH] Check needsCheckpoint only if checkpoint is supported Subject: [PATCH] Check needsCheckpoint only if checkpoint is supported
@ -9,22 +9,13 @@ vold will then hang in needsCheckpoint waiting for bootctrl
Change-Id: I2dafcbca7e994d7a3ac36ef3698590db2ab482fa Change-Id: I2dafcbca7e994d7a3ac36ef3698590db2ab482fa
--- ---
cryptfs.cpp | 6 ++++-- cryptfs.cpp | 4 +++-
1 file changed, 4 insertions(+), 2 deletions(-) 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/cryptfs.cpp b/cryptfs.cpp diff --git a/cryptfs.cpp b/cryptfs.cpp
index 063c5be..df48b15 100644 index 33f0913..7db1ef6 100644
--- a/cryptfs.cpp --- a/cryptfs.cpp
+++ b/cryptfs.cpp +++ b/cryptfs.cpp
@@ -1363,7 +1363,7 @@ static int create_crypto_blk_dev_hw(struct crypt_mnt_ftr* crypt_ftr, const unsig
load_count = load_crypto_mapping_table(crypt_ftr, master_key, real_blk_name, name, fd,
extra_params);
}
-
+
if (load_count < 0) {
SLOGE("Cannot load dm-crypt mapping table.\n");
goto errout;
@@ -1963,7 +1963,9 @@ static int cryptfs_restart_internal(int restart_main) { @@ -1963,7 +1963,9 @@ static int cryptfs_restart_internal(int restart_main) {
SLOGE("Failed to setexeccon"); SLOGE("Failed to setexeccon");
return -1; return -1;