CCodec: handle delay config update
Bug: 130223947
Test: atest CtsMediaTestCases -- --module-arg CtsMediaTestCases:size:small
Test: manual test with software codecs changing delay randomly
Change-Id: Ia574522a44df22f9638bc4049d7418843a76b57b
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index f5a4d94..de28820 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -1724,8 +1724,11 @@
& C2FrameData::FLAG_DISCARD_FRAME) == 0) {
// copy buffer info to config
- std::vector<std::unique_ptr<C2Param>> updates =
- std::move(work->worklets.front()->output.configUpdate);
+ std::vector<std::unique_ptr<C2Param>> updates;
+ for (const std::unique_ptr<C2Param> ¶m
+ : work->worklets.front()->output.configUpdate) {
+ updates.push_back(C2Param::Copy(*param));
+ }
unsigned stream = 0;
for (const std::shared_ptr<C2Buffer> &buf : work->worklets.front()->output.buffers) {
for (const std::shared_ptr<const C2Info> &info : buf->info()) {
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
index 7669421..eb20b20 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.cpp
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
@@ -210,22 +210,36 @@
}
}
+// Input
+
+CCodecBufferChannel::Input::Input() : extraBuffers("extra") {}
+
// CCodecBufferChannel
CCodecBufferChannel::CCodecBufferChannel(
const std::shared_ptr<CCodecCallback> &callback)
: mHeapSeqNum(-1),
mCCodecCallback(callback),
- mNumInputSlots(kSmoothnessFactor),
- mNumOutputSlots(kSmoothnessFactor),
mDelay(0),
mFrameIndex(0u),
mFirstValidFrameIndex(0u),
mMetaMode(MODE_NONE),
mInputMetEos(false) {
mOutputSurface.lock()->maxDequeueBuffers = kSmoothnessFactor + kRenderingDepth;
- Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
- buffers->reset(new DummyInputBuffers(""));
+ {
+ Mutexed<Input>::Locked input(mInput);
+ input->buffers.reset(new DummyInputBuffers(""));
+ input->extraBuffers.flush();
+ input->inputDelay = 0u;
+ input->pipelineDelay = 0u;
+ input->numSlots = kSmoothnessFactor;
+ input->numExtraSlots = 0u;
+ }
+ {
+ Mutexed<Output>::Locked output(mOutput);
+ output->outputDelay = 0u;
+ output->numSlots = kSmoothnessFactor;
+ }
}
CCodecBufferChannel::~CCodecBufferChannel() {
@@ -255,7 +269,7 @@
return mInputSurface->signalEndOfInputStream();
}
-status_t CCodecBufferChannel::queueInputBufferInternal(const sp<MediaCodecBuffer> &buffer) {
+status_t CCodecBufferChannel::queueInputBufferInternal(sp<MediaCodecBuffer> buffer) {
int64_t timeUs;
CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
@@ -287,13 +301,31 @@
uint64_t queuedFrameIndex = work->input.ordinal.frameIndex.peeku();
std::vector<std::shared_ptr<C2Buffer>> queuedBuffers;
+ sp<Codec2Buffer> copy;
if (buffer->size() > 0u) {
- Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
+ Mutexed<Input>::Locked input(mInput);
std::shared_ptr<C2Buffer> c2buffer;
- if (!(*buffers)->releaseBuffer(buffer, &c2buffer, false)) {
+ if (!input->buffers->releaseBuffer(buffer, &c2buffer, false)) {
return -ENOENT;
}
+ // TODO: we want to delay copying buffers.
+ if (input->extraBuffers.numComponentBuffers() < input->numExtraSlots) {
+ copy = input->buffers->cloneAndReleaseBuffer(buffer);
+ if (copy != nullptr) {
+ (void)input->extraBuffers.assignSlot(copy);
+ if (!input->extraBuffers.releaseSlot(copy, &c2buffer, false)) {
+ return UNKNOWN_ERROR;
+ }
+ bool released = input->buffers->releaseBuffer(buffer, nullptr, true);
+ ALOGV("[%s] queueInputBuffer: buffer copied; %sreleased",
+ mName, released ? "" : "not ");
+ buffer.clear();
+ } else {
+ ALOGW("[%s] queueInputBuffer: failed to copy a buffer; this may cause input "
+ "buffer starvation on component.", mName);
+ }
+ }
work->input.buffers.push_back(c2buffer);
queuedBuffers.push_back(c2buffer);
} else if (eos) {
@@ -343,9 +375,15 @@
}
}
if (err == C2_OK) {
- Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
- bool released = (*buffers)->releaseBuffer(buffer, nullptr, true);
- ALOGV("[%s] queueInputBuffer: buffer %sreleased", mName, released ? "" : "not ");
+ Mutexed<Input>::Locked input(mInput);
+ bool released = false;
+ if (buffer) {
+ released = input->buffers->releaseBuffer(buffer, nullptr, true);
+ } else if (copy) {
+ released = input->extraBuffers.releaseSlot(copy, nullptr, true);
+ }
+ ALOGV("[%s] queueInputBuffer: buffer%s %sreleased",
+ mName, (buffer == nullptr) ? "(copy)" : "", released ? "" : "not ");
}
feedInputBufferIfAvailableInternal();
@@ -492,20 +530,21 @@
mPipelineWatcher.lock()->pipelineFull()) {
return;
} else {
- Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
- if ((*buffers)->numClientBuffers() >= mNumOutputSlots) {
+ Mutexed<Output>::Locked output(mOutput);
+ if (output->buffers->numClientBuffers() >= output->numSlots) {
return;
}
}
- for (size_t i = 0; i < mNumInputSlots; ++i) {
+ size_t numInputSlots = mInput.lock()->numSlots;
+ for (size_t i = 0; i < numInputSlots; ++i) {
sp<MediaCodecBuffer> inBuffer;
size_t index;
{
- Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
- if ((*buffers)->numClientBuffers() >= mNumInputSlots) {
+ Mutexed<Input>::Locked input(mInput);
+ if (input->buffers->numClientBuffers() >= input->numSlots) {
return;
}
- if (!(*buffers)->requestNewBuffer(&index, &inBuffer)) {
+ if (!input->buffers->requestNewBuffer(&index, &inBuffer)) {
ALOGV("[%s] no new buffer available", mName);
break;
}
@@ -521,9 +560,9 @@
std::shared_ptr<C2Buffer> c2Buffer;
bool released = false;
{
- Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
- if (*buffers) {
- released = (*buffers)->releaseBuffer(buffer, &c2Buffer);
+ Mutexed<Output>::Locked output(mOutput);
+ if (output->buffers) {
+ released = output->buffers->releaseBuffer(buffer, &c2Buffer);
}
}
// NOTE: some apps try to releaseOutputBuffer() with timestamp and/or render
@@ -685,14 +724,14 @@
ALOGV("[%s] discardBuffer: %p", mName, buffer.get());
bool released = false;
{
- Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
- if (*buffers && (*buffers)->releaseBuffer(buffer, nullptr, true)) {
+ Mutexed<Input>::Locked input(mInput);
+ if (input->buffers && input->buffers->releaseBuffer(buffer, nullptr, true)) {
released = true;
}
}
{
- Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
- if (*buffers && (*buffers)->releaseBuffer(buffer, nullptr)) {
+ Mutexed<Output>::Locked output(mOutput);
+ if (output->buffers && output->buffers->releaseBuffer(buffer, nullptr)) {
released = true;
}
}
@@ -707,24 +746,24 @@
void CCodecBufferChannel::getInputBufferArray(Vector<sp<MediaCodecBuffer>> *array) {
array->clear();
- Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
+ Mutexed<Input>::Locked input(mInput);
- if (!(*buffers)->isArrayMode()) {
- *buffers = (*buffers)->toArrayMode(mNumInputSlots);
+ if (!input->buffers->isArrayMode()) {
+ input->buffers = input->buffers->toArrayMode(input->numSlots);
}
- (*buffers)->getArray(array);
+ input->buffers->getArray(array);
}
void CCodecBufferChannel::getOutputBufferArray(Vector<sp<MediaCodecBuffer>> *array) {
array->clear();
- Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
+ Mutexed<Output>::Locked output(mOutput);
- if (!(*buffers)->isArrayMode()) {
- *buffers = (*buffers)->toArrayMode(mNumOutputSlots);
+ if (!output->buffers->isArrayMode()) {
+ output->buffers = output->buffers->toArrayMode(output->numSlots);
}
- (*buffers)->getArray(array);
+ output->buffers->getArray(array);
}
status_t CCodecBufferChannel::start(
@@ -773,8 +812,8 @@
uint32_t pipelineDelayValue = pipelineDelay ? pipelineDelay.value : 0;
uint32_t outputDelayValue = outputDelay ? outputDelay.value : 0;
- mNumInputSlots = inputDelayValue + pipelineDelayValue + kSmoothnessFactor;
- mNumOutputSlots = outputDelayValue + kSmoothnessFactor;
+ size_t numInputSlots = inputDelayValue + pipelineDelayValue + kSmoothnessFactor;
+ size_t numOutputSlots = outputDelayValue + kSmoothnessFactor;
mDelay = inputDelayValue + pipelineDelayValue + outputDelayValue;
// TODO: get this from input format
@@ -848,14 +887,17 @@
}
bool forceArrayMode = false;
- Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
+ Mutexed<Input>::Locked input(mInput);
+ input->numSlots = numInputSlots;
+ input->extraBuffers.flush();
+ input->numExtraSlots = 0u;
if (graphic) {
if (mInputSurface) {
- buffers->reset(new DummyInputBuffers(mName));
+ input->buffers.reset(new DummyInputBuffers(mName));
} else if (mMetaMode == MODE_ANW) {
- buffers->reset(new GraphicMetadataInputBuffers(mName));
+ input->buffers.reset(new GraphicMetadataInputBuffers(mName));
} else {
- buffers->reset(new GraphicInputBuffers(mNumInputSlots, mName));
+ input->buffers.reset(new GraphicInputBuffers(numInputSlots, mName));
}
} else {
if (hasCryptoOrDescrambler()) {
@@ -868,7 +910,7 @@
if (mDealer == nullptr) {
mDealer = new MemoryDealer(
align(capacity, MemoryDealer::getAllocationAlignment())
- * (mNumInputSlots + 1),
+ * (numInputSlots + 1),
"EncryptedLinearInputBuffers");
mDecryptDestination = mDealer->allocate((size_t)capacity);
}
@@ -877,24 +919,24 @@
} else {
mHeapSeqNum = -1;
}
- buffers->reset(new EncryptedLinearInputBuffers(
+ input->buffers.reset(new EncryptedLinearInputBuffers(
secure, mDealer, mCrypto, mHeapSeqNum, (size_t)capacity,
- mNumInputSlots, mName));
+ numInputSlots, mName));
forceArrayMode = true;
} else {
- buffers->reset(new LinearInputBuffers(mName));
+ input->buffers.reset(new LinearInputBuffers(mName));
}
}
- (*buffers)->setFormat(inputFormat);
+ input->buffers->setFormat(inputFormat);
if (err == C2_OK) {
- (*buffers)->setPool(pool);
+ input->buffers->setPool(pool);
} else {
// TODO: error
}
if (forceArrayMode) {
- *buffers = (*buffers)->toArrayMode(mNumInputSlots);
+ input->buffers = input->buffers->toArrayMode(numInputSlots);
}
}
@@ -903,7 +945,7 @@
uint32_t outputGeneration;
{
Mutexed<OutputSurface>::Locked output(mOutputSurface);
- output->maxDequeueBuffers = mNumOutputSlots + reorderDepth.value + kRenderingDepth;
+ output->maxDequeueBuffers = numOutputSlots + reorderDepth.value + kRenderingDepth;
outputSurface = output->surface ?
output->surface->getIGraphicBufferProducer() : nullptr;
if (outputSurface) {
@@ -1011,18 +1053,18 @@
outputPoolId_ = pools->outputPoolId;
}
- Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
-
+ Mutexed<Output>::Locked output(mOutput);
+ output->numSlots = numOutputSlots;
if (graphic) {
if (outputSurface) {
- buffers->reset(new GraphicOutputBuffers(mName));
+ output->buffers.reset(new GraphicOutputBuffers(mName));
} else {
- buffers->reset(new RawGraphicOutputBuffers(mNumOutputSlots, mName));
+ output->buffers.reset(new RawGraphicOutputBuffers(numOutputSlots, mName));
}
} else {
- buffers->reset(new LinearOutputBuffers(mName));
+ output->buffers.reset(new LinearOutputBuffers(mName));
}
- (*buffers)->setFormat(outputFormat->dup());
+ output->buffers->setFormat(outputFormat->dup());
// Try to set output surface to created block pool if given.
@@ -1038,7 +1080,7 @@
// WORKAROUND: if we're using early CSD workaround we convert to
// array mode, to appease apps assuming the output
// buffers to be of the same size.
- (*buffers) = (*buffers)->toArrayMode(mNumOutputSlots);
+ output->buffers = output->buffers->toArrayMode(numOutputSlots);
int32_t channelCount;
int32_t sampleRate;
@@ -1055,7 +1097,7 @@
if (delay || padding) {
// We need write access to the buffers, and we're already in
// array mode.
- (*buffers)->initSkipCutBuffer(delay, padding, sampleRate, channelCount);
+ output->buffers->initSkipCutBuffer(delay, padding, sampleRate, channelCount);
}
}
}
@@ -1090,14 +1132,14 @@
if (err != C2_OK) {
return UNKNOWN_ERROR;
}
+ size_t numInputSlots = mInput.lock()->numSlots;
std::vector<sp<MediaCodecBuffer>> toBeQueued;
- // TODO: use proper buffer depth instead of this random value
- for (size_t i = 0; i < mNumInputSlots; ++i) {
+ for (size_t i = 0; i < numInputSlots; ++i) {
size_t index;
sp<MediaCodecBuffer> buffer;
{
- Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
- if (!(*buffers)->requestNewBuffer(&index, &buffer)) {
+ Mutexed<Input>::Locked input(mInput);
+ if (!input->buffers->requestNewBuffer(&index, &buffer)) {
if (i == 0) {
ALOGW("[%s] start: cannot allocate memory at all", mName);
return NO_MEMORY;
@@ -1182,12 +1224,13 @@
}
}
{
- Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
- (*buffers)->flush();
+ Mutexed<Input>::Locked input(mInput);
+ input->buffers->flush();
+ input->extraBuffers.flush();
}
{
- Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
- (*buffers)->flush(flushedWork);
+ Mutexed<Output>::Locked output(mOutput);
+ output->buffers->flush(flushedWork);
}
mReorderStash.lock()->flush();
mPipelineWatcher.lock()->flush();
@@ -1210,8 +1253,11 @@
mPipelineWatcher.lock()->onInputBufferReleased(frameIndex, arrayIndex);
bool newInputSlotAvailable;
{
- Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
- newInputSlotAvailable = (*buffers)->expireComponentBuffer(buffer);
+ Mutexed<Input>::Locked input(mInput);
+ newInputSlotAvailable = input->buffers->expireComponentBuffer(buffer);
+ if (!newInputSlotAvailable) {
+ (void)input->extraBuffers.expireComponentBuffer(buffer);
+ }
}
if (newInputSlotAvailable) {
feedInputBufferIfAvailable();
@@ -1269,6 +1315,7 @@
}
}
+ std::optional<uint32_t> newInputDelay, newPipelineDelay;
while (!worklet->output.configUpdate.empty()) {
std::unique_ptr<C2Param> param;
worklet->output.configUpdate.back().swap(param);
@@ -1280,8 +1327,10 @@
mReorderStash.lock()->setDepth(reorderDepth.value);
ALOGV("[%s] onWorkDone: updated reorder depth to %u",
mName, reorderDepth.value);
+ size_t numOutputSlots = mOutput.lock()->numSlots;
Mutexed<OutputSurface>::Locked output(mOutputSurface);
- output->maxDequeueBuffers = mNumOutputSlots + reorderDepth.value + kRenderingDepth;
+ output->maxDequeueBuffers =
+ numOutputSlots + reorderDepth.value + kRenderingDepth;
if (output->surface) {
output->surface->setMaxDequeuedBufferCount(output->maxDequeueBuffers);
}
@@ -1301,18 +1350,86 @@
}
break;
}
+ case C2PortActualDelayTuning::CORE_INDEX: {
+ if (param->isGlobal()) {
+ C2ActualPipelineDelayTuning pipelineDelay;
+ if (pipelineDelay.updateFrom(*param)) {
+ ALOGV("[%s] onWorkDone: updating pipeline delay %u",
+ mName, pipelineDelay.value);
+ newPipelineDelay = pipelineDelay.value;
+ (void)mPipelineWatcher.lock()->pipelineDelay(pipelineDelay.value);
+ }
+ }
+ if (param->forInput()) {
+ C2PortActualDelayTuning::input inputDelay;
+ if (inputDelay.updateFrom(*param)) {
+ ALOGV("[%s] onWorkDone: updating input delay %u",
+ mName, inputDelay.value);
+ newInputDelay = inputDelay.value;
+ (void)mPipelineWatcher.lock()->inputDelay(inputDelay.value);
+ }
+ }
+ if (param->forOutput()) {
+ C2PortActualDelayTuning::output outputDelay;
+ if (outputDelay.updateFrom(*param)) {
+ ALOGV("[%s] onWorkDone: updating output delay %u",
+ mName, outputDelay.value);
+ (void)mPipelineWatcher.lock()->outputDelay(outputDelay.value);
+
+ bool outputBuffersChanged = false;
+ Mutexed<Output>::Locked output(mOutput);
+ output->outputDelay = outputDelay.value;
+ size_t numOutputSlots = outputDelay.value + kSmoothnessFactor;
+ if (output->numSlots < numOutputSlots) {
+ output->numSlots = numOutputSlots;
+ if (output->buffers->isArrayMode()) {
+ OutputBuffersArray *array =
+ (OutputBuffersArray *)output->buffers.get();
+ ALOGV("[%s] onWorkDone: growing output buffer array to %zu",
+ mName, numOutputSlots);
+ array->grow(numOutputSlots);
+ outputBuffersChanged = true;
+ }
+ }
+ output.unlock();
+
+ if (outputBuffersChanged) {
+ mCCodecCallback->onOutputBuffersChanged();
+ }
+ }
+ }
+ break;
+ }
default:
ALOGV("[%s] onWorkDone: unrecognized config update (%08X)",
mName, param->index());
break;
}
}
+ if (newInputDelay || newPipelineDelay) {
+ Mutexed<Input>::Locked input(mInput);
+ size_t newNumSlots =
+ newInputDelay.value_or(input->inputDelay) +
+ newPipelineDelay.value_or(input->pipelineDelay) +
+ kSmoothnessFactor;
+ if (input->buffers->isArrayMode()) {
+ if (input->numSlots >= newNumSlots) {
+ input->numExtraSlots = 0;
+ } else {
+ input->numExtraSlots = newNumSlots - input->numSlots;
+ }
+ ALOGV("[%s] onWorkDone: updated number of extra slots to %zu (input array mode)",
+ mName, input->numExtraSlots);
+ } else {
+ input->numSlots = newNumSlots;
+ }
+ }
if (outputFormat != nullptr) {
- Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
+ Mutexed<Output>::Locked output(mOutput);
ALOGD("[%s] onWorkDone: output format changed to %s",
mName, outputFormat->debugString().c_str());
- (*buffers)->setFormat(outputFormat);
+ output->buffers->setFormat(outputFormat);
AString mediaType;
if (outputFormat->findString(KEY_MIME, &mediaType)
@@ -1321,7 +1438,7 @@
int32_t sampleRate;
if (outputFormat->findInt32(KEY_CHANNEL_COUNT, &channelCount)
&& outputFormat->findInt32(KEY_SAMPLE_RATE, &sampleRate)) {
- (*buffers)->updateSkipCutBuffer(sampleRate, channelCount);
+ output->buffers->updateSkipCutBuffer(sampleRate, channelCount);
}
}
}
@@ -1356,20 +1473,18 @@
timestamp.peekll());
if (initData != nullptr) {
- Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
- if ((*buffers)->registerCsd(initData, &index, &outBuffer) == OK) {
+ Mutexed<Output>::Locked output(mOutput);
+ if (output->buffers->registerCsd(initData, &index, &outBuffer) == OK) {
outBuffer->meta()->setInt64("timeUs", timestamp.peek());
outBuffer->meta()->setInt32("flags", MediaCodec::BUFFER_FLAG_CODECCONFIG);
ALOGV("[%s] onWorkDone: csd index = %zu [%p]", mName, index, outBuffer.get());
- buffers.unlock();
+ output.unlock();
mCallback->onOutputBufferAvailable(index, outBuffer);
- buffers.lock();
} else {
ALOGD("[%s] onWorkDone: unable to register csd", mName);
- buffers.unlock();
+ output.unlock();
mCCodecCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
- buffers.lock();
return false;
}
}
@@ -1421,22 +1536,22 @@
break;
}
- Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
- status_t err = (*buffers)->registerBuffer(entry.buffer, &index, &outBuffer);
+ Mutexed<Output>::Locked output(mOutput);
+ status_t err = output->buffers->registerBuffer(entry.buffer, &index, &outBuffer);
if (err != OK) {
bool outputBuffersChanged = false;
if (err != WOULD_BLOCK) {
- if (!(*buffers)->isArrayMode()) {
- *buffers = (*buffers)->toArrayMode(mNumOutputSlots);
+ if (!output->buffers->isArrayMode()) {
+ output->buffers = output->buffers->toArrayMode(output->numSlots);
}
- OutputBuffersArray *array = (OutputBuffersArray *)buffers->get();
+ OutputBuffersArray *array = (OutputBuffersArray *)output->buffers.get();
array->realloc(entry.buffer);
outputBuffersChanged = true;
}
ALOGV("[%s] sendOutputBuffers: unable to register output buffer", mName);
reorder->defer(entry);
- buffers.unlock();
+ output.unlock();
reorder.unlock();
if (outputBuffersChanged) {
@@ -1444,7 +1559,7 @@
}
return;
}
- buffers.unlock();
+ output.unlock();
reorder.unlock();
outBuffer->meta()->setInt64("timeUs", entry.timestamp);
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.h b/media/codec2/sfplugin/CCodecBufferChannel.h
index 9aec82d..ae57678 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.h
+++ b/media/codec2/sfplugin/CCodecBufferChannel.h
@@ -209,7 +209,7 @@
void feedInputBufferIfAvailable();
void feedInputBufferIfAvailableInternal();
- status_t queueInputBufferInternal(const sp<MediaCodecBuffer> &buffer);
+ status_t queueInputBufferInternal(sp<MediaCodecBuffer> buffer);
bool handleWork(
std::unique_ptr<C2Work> work, const sp<AMessage> &outputFormat,
const C2StreamInitDataInfo::output *initData);
@@ -228,13 +228,26 @@
QueueSync mQueueSync;
std::vector<std::unique_ptr<C2Param>> mParamsToBeSet;
- size_t mNumInputSlots;
- size_t mNumOutputSlots;
size_t mDelay;
- Mutexed<std::unique_ptr<InputBuffers>> mInputBuffers;
+ struct Input {
+ Input();
+
+ std::unique_ptr<InputBuffers> buffers;
+ size_t numSlots;
+ FlexBuffersImpl extraBuffers;
+ size_t numExtraSlots;
+ uint32_t inputDelay;
+ uint32_t pipelineDelay;
+ };
+ Mutexed<Input> mInput;
+ struct Output {
+ std::unique_ptr<OutputBuffers> buffers;
+ size_t numSlots;
+ uint32_t outputDelay;
+ };
+ Mutexed<Output> mOutput;
Mutexed<std::list<sp<ABuffer>>> mFlushedConfigs;
- Mutexed<std::unique_ptr<OutputBuffers>> mOutputBuffers;
std::atomic_uint64_t mFrameIndex;
std::atomic_uint64_t mFirstValidFrameIndex;
diff --git a/media/codec2/sfplugin/CCodecBuffers.cpp b/media/codec2/sfplugin/CCodecBuffers.cpp
index fb0efce..5ebd5bd 100644
--- a/media/codec2/sfplugin/CCodecBuffers.cpp
+++ b/media/codec2/sfplugin/CCodecBuffers.cpp
@@ -98,6 +98,26 @@
}
}
+// InputBuffers
+
+sp<Codec2Buffer> InputBuffers::cloneAndReleaseBuffer(const sp<MediaCodecBuffer> &buffer) {
+ sp<Codec2Buffer> copy = createNewBuffer();
+ if (copy == nullptr) {
+ return nullptr;
+ }
+ std::shared_ptr<C2Buffer> c2buffer;
+ if (!releaseBuffer(buffer, &c2buffer, true)) {
+ return nullptr;
+ }
+ if (!copy->canCopy(c2buffer)) {
+ return nullptr;
+ }
+ if (!copy->copy(c2buffer)) {
+ return nullptr;
+ }
+ return copy;
+}
+
// OutputBuffers
void OutputBuffers::initSkipCutBuffer(
@@ -197,6 +217,8 @@
mPool.push_front(std::move(vec));
}
+// FlexBuffersImpl
+
size_t FlexBuffersImpl::assignSlot(const sp<Codec2Buffer> &buffer) {
for (size_t i = 0; i < mBuffers.size(); ++i) {
if (mBuffers[i].clientBuffer == nullptr
@@ -209,8 +231,6 @@
return mBuffers.size() - 1;
}
-// FlexBuffersImpl
-
bool FlexBuffersImpl::releaseSlot(
const sp<MediaCodecBuffer> &buffer,
std::shared_ptr<C2Buffer> *c2buffer,
@@ -270,6 +290,14 @@
});
}
+size_t FlexBuffersImpl::numComponentBuffers() const {
+ return std::count_if(
+ mBuffers.begin(), mBuffers.end(),
+ [](const Entry &entry) {
+ return !entry.compBuffer.expired();
+ });
+}
+
// BuffersArrayImpl
void BuffersArrayImpl::initialize(
@@ -395,6 +423,14 @@
}
}
+void BuffersArrayImpl::grow(
+ size_t newSize, std::function<sp<Codec2Buffer>()> alloc) {
+ CHECK_LT(mBuffers.size(), newSize);
+ while (mBuffers.size() < newSize) {
+ mBuffers.push_back({ alloc(), std::weak_ptr<C2Buffer>(), false });
+ }
+}
+
size_t BuffersArrayImpl::numClientBuffers() const {
return std::count_if(
mBuffers.begin(), mBuffers.end(),
@@ -409,6 +445,7 @@
const FlexBuffersImpl &impl,
size_t minSize,
std::function<sp<Codec2Buffer>()> allocate) {
+ mAllocate = allocate;
mImpl.initialize(impl, minSize, allocate);
}
@@ -448,18 +485,14 @@
return mImpl.numClientBuffers();
}
+sp<Codec2Buffer> InputBuffersArray::createNewBuffer() {
+ return mAllocate();
+}
+
// LinearInputBuffers
bool LinearInputBuffers::requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) {
- int32_t capacity = kLinearBufferSize;
- (void)mFormat->findInt32(KEY_MAX_INPUT_SIZE, &capacity);
- if ((size_t)capacity > kMaxLinearBufferSize) {
- ALOGD("client requested %d, capped to %zu", capacity, kMaxLinearBufferSize);
- capacity = kMaxLinearBufferSize;
- }
- // TODO: proper max input size
- // TODO: read usage from intf
- sp<Codec2Buffer> newBuffer = alloc((size_t)capacity);
+ sp<Codec2Buffer> newBuffer = createNewBuffer();
if (newBuffer == nullptr) {
return false;
}
@@ -486,16 +519,7 @@
mImpl.flush();
}
-std::unique_ptr<InputBuffers> LinearInputBuffers::toArrayMode(
- size_t size) {
- int32_t capacity = kLinearBufferSize;
- (void)mFormat->findInt32(KEY_MAX_INPUT_SIZE, &capacity);
- if ((size_t)capacity > kMaxLinearBufferSize) {
- ALOGD("client requested %d, capped to %zu", capacity, kMaxLinearBufferSize);
- capacity = kMaxLinearBufferSize;
- }
- // TODO: proper max input size
- // TODO: read usage from intf
+std::unique_ptr<InputBuffers> LinearInputBuffers::toArrayMode(size_t size) {
std::unique_ptr<InputBuffersArray> array(
new InputBuffersArray(mComponentName.c_str(), "1D-Input[N]"));
array->setPool(mPool);
@@ -503,7 +527,9 @@
array->initialize(
mImpl,
size,
- [this, capacity] () -> sp<Codec2Buffer> { return alloc(capacity); });
+ [pool = mPool, format = mFormat] () -> sp<Codec2Buffer> {
+ return Alloc(pool, format);
+ });
return std::move(array);
}
@@ -511,16 +537,30 @@
return mImpl.numClientBuffers();
}
-sp<Codec2Buffer> LinearInputBuffers::alloc(size_t size) {
+// static
+sp<Codec2Buffer> LinearInputBuffers::Alloc(
+ const std::shared_ptr<C2BlockPool> &pool, const sp<AMessage> &format) {
+ int32_t capacity = kLinearBufferSize;
+ (void)format->findInt32(KEY_MAX_INPUT_SIZE, &capacity);
+ if ((size_t)capacity > kMaxLinearBufferSize) {
+ ALOGD("client requested %d, capped to %zu", capacity, kMaxLinearBufferSize);
+ capacity = kMaxLinearBufferSize;
+ }
+
+ // TODO: read usage from intf
C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
std::shared_ptr<C2LinearBlock> block;
- c2_status_t err = mPool->fetchLinearBlock(size, usage, &block);
+ c2_status_t err = pool->fetchLinearBlock(capacity, usage, &block);
if (err != C2_OK) {
return nullptr;
}
- return LinearBlockBuffer::Allocate(mFormat, block);
+ return LinearBlockBuffer::Allocate(format, block);
+}
+
+sp<Codec2Buffer> LinearInputBuffers::createNewBuffer() {
+ return Alloc(mPool, mFormat);
}
// EncryptedLinearInputBuffers
@@ -537,7 +577,7 @@
mUsage({0, 0}),
mDealer(dealer),
mCrypto(crypto),
- mHeapSeqNum(heapSeqNum) {
+ mMemoryVector(new std::vector<Entry>){
if (secure) {
mUsage = { C2MemoryUsage::READ_PROTECTED, 0 };
} else {
@@ -550,16 +590,48 @@
mName, i);
break;
}
- mMemoryVector.push_back({std::weak_ptr<C2LinearBlock>(), memory});
+ mMemoryVector->push_back({std::weak_ptr<C2LinearBlock>(), memory, heapSeqNum});
}
}
-sp<Codec2Buffer> EncryptedLinearInputBuffers::alloc(size_t size) {
+std::unique_ptr<InputBuffers> EncryptedLinearInputBuffers::toArrayMode(size_t size) {
+ std::unique_ptr<InputBuffersArray> array(
+ new InputBuffersArray(mComponentName.c_str(), "1D-EncryptedInput[N]"));
+ array->setPool(mPool);
+ array->setFormat(mFormat);
+ array->initialize(
+ mImpl,
+ size,
+ [pool = mPool,
+ format = mFormat,
+ usage = mUsage,
+ memoryVector = mMemoryVector] () -> sp<Codec2Buffer> {
+ return Alloc(pool, format, usage, memoryVector);
+ });
+ return std::move(array);
+}
+
+
+// static
+sp<Codec2Buffer> EncryptedLinearInputBuffers::Alloc(
+ const std::shared_ptr<C2BlockPool> &pool,
+ const sp<AMessage> &format,
+ C2MemoryUsage usage,
+ const std::shared_ptr<std::vector<EncryptedLinearInputBuffers::Entry>> &memoryVector) {
+ int32_t capacity = kLinearBufferSize;
+ (void)format->findInt32(KEY_MAX_INPUT_SIZE, &capacity);
+ if ((size_t)capacity > kMaxLinearBufferSize) {
+ ALOGD("client requested %d, capped to %zu", capacity, kMaxLinearBufferSize);
+ capacity = kMaxLinearBufferSize;
+ }
+
sp<IMemory> memory;
size_t slot = 0;
- for (; slot < mMemoryVector.size(); ++slot) {
- if (mMemoryVector[slot].block.expired()) {
- memory = mMemoryVector[slot].memory;
+ int32_t heapSeqNum = -1;
+ for (; slot < memoryVector->size(); ++slot) {
+ if (memoryVector->at(slot).block.expired()) {
+ memory = memoryVector->at(slot).memory;
+ heapSeqNum = memoryVector->at(slot).heapSeqNum;
break;
}
}
@@ -568,13 +640,18 @@
}
std::shared_ptr<C2LinearBlock> block;
- c2_status_t err = mPool->fetchLinearBlock(size, mUsage, &block);
+ c2_status_t err = pool->fetchLinearBlock(capacity, usage, &block);
if (err != C2_OK || block == nullptr) {
return nullptr;
}
- mMemoryVector[slot].block = block;
- return new EncryptedLinearBlockBuffer(mFormat, block, memory, mHeapSeqNum);
+ memoryVector->at(slot).block = block;
+ return new EncryptedLinearBlockBuffer(format, block, memory, heapSeqNum);
+}
+
+sp<Codec2Buffer> EncryptedLinearInputBuffers::createNewBuffer() {
+ // TODO: android_2020
+ return nullptr;
}
// GraphicMetadataInputBuffers
@@ -587,12 +664,7 @@
bool GraphicMetadataInputBuffers::requestNewBuffer(
size_t *index, sp<MediaCodecBuffer> *buffer) {
- std::shared_ptr<C2Allocator> alloc;
- c2_status_t err = mStore->fetchAllocator(mPool->getAllocatorId(), &alloc);
- if (err != C2_OK) {
- return false;
- }
- sp<GraphicMetadataBuffer> newBuffer = new GraphicMetadataBuffer(mFormat, alloc);
+ sp<Codec2Buffer> newBuffer = createNewBuffer();
if (newBuffer == nullptr) {
return false;
}
@@ -642,6 +714,15 @@
return mImpl.numClientBuffers();
}
+sp<Codec2Buffer> GraphicMetadataInputBuffers::createNewBuffer() {
+ std::shared_ptr<C2Allocator> alloc;
+ c2_status_t err = mStore->fetchAllocator(mPool->getAllocatorId(), &alloc);
+ if (err != C2_OK) {
+ return nullptr;
+ }
+ return new GraphicMetadataBuffer(mFormat, alloc);
+}
+
// GraphicInputBuffers
GraphicInputBuffers::GraphicInputBuffers(
@@ -652,11 +733,7 @@
kMaxLinearBufferSize * numInputSlots)) { }
bool GraphicInputBuffers::requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) {
- // TODO: proper max input size
- // TODO: read usage from intf
- C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
- sp<GraphicBlockBuffer> newBuffer = AllocateGraphicBuffer(
- mPool, mFormat, HAL_PIXEL_FORMAT_YV12, usage, mLocalBufferPool);
+ sp<Codec2Buffer> newBuffer = createNewBuffer();
if (newBuffer == nullptr) {
return false;
}
@@ -703,12 +780,20 @@
return mImpl.numClientBuffers();
}
+sp<Codec2Buffer> GraphicInputBuffers::createNewBuffer() {
+ // TODO: read usage from intf
+ C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+ return AllocateGraphicBuffer(
+ mPool, mFormat, HAL_PIXEL_FORMAT_YV12, usage, mLocalBufferPool);
+}
+
// OutputBuffersArray
void OutputBuffersArray::initialize(
const FlexBuffersImpl &impl,
size_t minSize,
std::function<sp<Codec2Buffer>()> allocate) {
+ mAlloc = allocate;
mImpl.initialize(impl, minSize, allocate);
}
@@ -781,8 +866,11 @@
mImpl.getArray(array);
}
+size_t OutputBuffersArray::numClientBuffers() const {
+ return mImpl.numClientBuffers();
+}
+
void OutputBuffersArray::realloc(const std::shared_ptr<C2Buffer> &c2buffer) {
- std::function<sp<Codec2Buffer>()> alloc;
switch (c2buffer->data().type()) {
case C2BufferData::LINEAR: {
uint32_t size = kLinearBufferSize;
@@ -792,7 +880,7 @@
} else {
size = kMaxLinearBufferSize;
}
- alloc = [format = mFormat, size] {
+ mAlloc = [format = mFormat, size] {
return new LocalLinearBuffer(format, new ABuffer(size));
};
break;
@@ -808,11 +896,11 @@
ALOGD("Unsupported type: %d", (int)c2buffer->data().type());
return;
}
- mImpl.realloc(alloc);
+ mImpl.realloc(mAlloc);
}
-size_t OutputBuffersArray::numClientBuffers() const {
- return mImpl.numClientBuffers();
+void OutputBuffersArray::grow(size_t newSize) {
+ mImpl.grow(newSize, mAlloc);
}
// FlexOutputBuffers
@@ -861,10 +949,8 @@
std::unique_ptr<OutputBuffersArray> array(new OutputBuffersArray(mComponentName.c_str()));
array->setFormat(mFormat);
array->transferSkipCutBuffer(mSkipCutBuffer);
- array->initialize(
- mImpl,
- size,
- [this]() { return allocateArrayBuffer(); });
+ std::function<sp<Codec2Buffer>()> alloc = getAlloc();
+ array->initialize(mImpl, size, alloc);
return std::move(array);
}
@@ -906,9 +992,11 @@
return clientBuffer;
}
-sp<Codec2Buffer> LinearOutputBuffers::allocateArrayBuffer() {
- // TODO: proper max output size
- return new LocalLinearBuffer(mFormat, new ABuffer(kLinearBufferSize));
+std::function<sp<Codec2Buffer>()> LinearOutputBuffers::getAlloc() {
+ return [format = mFormat]{
+ // TODO: proper max output size
+ return new LocalLinearBuffer(format, new ABuffer(kLinearBufferSize));
+ };
}
// GraphicOutputBuffers
@@ -917,8 +1005,10 @@
return new DummyContainerBuffer(mFormat, buffer);
}
-sp<Codec2Buffer> GraphicOutputBuffers::allocateArrayBuffer() {
- return new DummyContainerBuffer(mFormat);
+std::function<sp<Codec2Buffer>()> GraphicOutputBuffers::getAlloc() {
+ return [format = mFormat]{
+ return new DummyContainerBuffer(format);
+ };
}
// RawGraphicOutputBuffers
@@ -952,12 +1042,14 @@
}
}
-sp<Codec2Buffer> RawGraphicOutputBuffers::allocateArrayBuffer() {
- return ConstGraphicBlockBuffer::AllocateEmpty(
- mFormat,
- [lbp = mLocalBufferPool](size_t capacity) {
- return lbp->newBuffer(capacity);
- });
+std::function<sp<Codec2Buffer>()> RawGraphicOutputBuffers::getAlloc() {
+ return [format = mFormat, lbp = mLocalBufferPool]{
+ return ConstGraphicBlockBuffer::AllocateEmpty(
+ format,
+ [lbp](size_t capacity) {
+ return lbp->newBuffer(capacity);
+ });
+ };
}
} // namespace android
diff --git a/media/codec2/sfplugin/CCodecBuffers.h b/media/codec2/sfplugin/CCodecBuffers.h
index f5d9fee..461fbd5 100644
--- a/media/codec2/sfplugin/CCodecBuffers.h
+++ b/media/codec2/sfplugin/CCodecBuffers.h
@@ -134,7 +134,18 @@
*/
virtual std::unique_ptr<InputBuffers> toArrayMode(size_t size) = 0;
+ /**
+ * Release the buffer obtained from requestNewBuffer(), and create a deep
+ * copy clone of the buffer.
+ *
+ * \return the deep copy clone of the buffer; nullptr if cloning is not
+ * possible.
+ */
+ sp<Codec2Buffer> cloneAndReleaseBuffer(const sp<MediaCodecBuffer> &buffer);
+
protected:
+ virtual sp<Codec2Buffer> createNewBuffer() = 0;
+
// Pool to obtain blocks for input buffers.
std::shared_ptr<C2BlockPool> mPool;
@@ -346,6 +357,12 @@
*/
size_t numClientBuffers() const;
+ /**
+ * Return the number of buffers that are sent to the component but not
+ * returned back yet.
+ */
+ size_t numComponentBuffers() const;
+
private:
friend class BuffersArrayImpl;
@@ -446,6 +463,16 @@
void realloc(std::function<sp<Codec2Buffer>()> alloc);
/**
+ * Grow the array to the new size. It is a programming error to supply
+ * smaller size as the new size.
+ *
+ * \param newSize[in] new size of the array.
+ * \param alloc[in] the alllocation function for client buffers to fill
+ * the new empty slots.
+ */
+ void grow(size_t newSize, std::function<sp<Codec2Buffer>()> alloc);
+
+ /**
* Return the number of buffers that are sent to the client but not released
* yet.
*/
@@ -506,8 +533,12 @@
size_t numClientBuffers() const final;
+protected:
+ sp<Codec2Buffer> createNewBuffer() override;
+
private:
BuffersArrayImpl mImpl;
+ std::function<sp<Codec2Buffer>()> mAllocate;
};
class LinearInputBuffers : public InputBuffers {
@@ -529,18 +560,18 @@
void flush() override;
- std::unique_ptr<InputBuffers> toArrayMode(size_t size) final;
+ std::unique_ptr<InputBuffers> toArrayMode(size_t size) override;
size_t numClientBuffers() const final;
- /**
- * Allocate a client buffer with the given size. This method may be
- * overridden to support different kind of linear buffers (e.g. encrypted).
- */
- virtual sp<Codec2Buffer> alloc(size_t size);
+protected:
+ sp<Codec2Buffer> createNewBuffer() override;
+
+ FlexBuffersImpl mImpl;
private:
- FlexBuffersImpl mImpl;
+ static sp<Codec2Buffer> Alloc(
+ const std::shared_ptr<C2BlockPool> &pool, const sp<AMessage> &format);
};
class EncryptedLinearInputBuffers : public LinearInputBuffers {
@@ -556,18 +587,28 @@
~EncryptedLinearInputBuffers() override = default;
- sp<Codec2Buffer> alloc(size_t size) override;
+ std::unique_ptr<InputBuffers> toArrayMode(size_t size) override;
+
+protected:
+ sp<Codec2Buffer> createNewBuffer() override;
private:
- C2MemoryUsage mUsage;
- sp<MemoryDealer> mDealer;
- sp<ICrypto> mCrypto;
- int32_t mHeapSeqNum;
struct Entry {
std::weak_ptr<C2LinearBlock> block;
sp<IMemory> memory;
+ int32_t heapSeqNum;
};
- std::vector<Entry> mMemoryVector;
+
+ static sp<Codec2Buffer> Alloc(
+ const std::shared_ptr<C2BlockPool> &pool,
+ const sp<AMessage> &format,
+ C2MemoryUsage usage,
+ const std::shared_ptr<std::vector<Entry>> &memoryVector);
+
+ C2MemoryUsage mUsage;
+ sp<MemoryDealer> mDealer;
+ sp<ICrypto> mCrypto;
+ std::shared_ptr<std::vector<Entry>> mMemoryVector;
};
class GraphicMetadataInputBuffers : public InputBuffers {
@@ -591,6 +632,9 @@
size_t numClientBuffers() const final;
+protected:
+ sp<Codec2Buffer> createNewBuffer() override;
+
private:
FlexBuffersImpl mImpl;
std::shared_ptr<C2AllocatorStore> mStore;
@@ -619,6 +663,9 @@
size_t numClientBuffers() const final;
+protected:
+ sp<Codec2Buffer> createNewBuffer() override;
+
private:
FlexBuffersImpl mImpl;
std::shared_ptr<LocalBufferPool> mLocalBufferPool;
@@ -658,6 +705,11 @@
size_t numClientBuffers() const final {
return 0u;
}
+
+protected:
+ sp<Codec2Buffer> createNewBuffer() override {
+ return nullptr;
+ }
};
class OutputBuffersArray : public OutputBuffers {
@@ -704,6 +756,8 @@
void getArray(Vector<sp<MediaCodecBuffer>> *array) const final;
+ size_t numClientBuffers() const final;
+
/**
* Reallocate the array, filled with buffers with the same size as given
* buffer.
@@ -712,10 +766,17 @@
*/
void realloc(const std::shared_ptr<C2Buffer> &c2buffer);
- size_t numClientBuffers() const final;
+ /**
+ * Grow the array to the new size. It is a programming error to supply
+ * smaller size as the new size.
+ *
+ * \param newSize[in] new size of the array.
+ */
+ void grow(size_t newSize);
private:
BuffersArrayImpl mImpl;
+ std::function<sp<Codec2Buffer>()> mAlloc;
};
class FlexOutputBuffers : public OutputBuffers {
@@ -755,12 +816,15 @@
virtual sp<Codec2Buffer> wrap(const std::shared_ptr<C2Buffer> &buffer) = 0;
/**
- * Return an appropriate Codec2Buffer object for the type of buffers, to be
- * used as an empty array buffer.
+ * Return a function that allocates an appropriate Codec2Buffer object for
+ * the type of buffers, to be used as an empty array buffer. The function
+ * must not refer to this pointer, since it may be used after this object
+ * destructs.
*
- * \return appropriate Codec2Buffer object which can copy() from C2Buffers.
+ * \return a function that allocates appropriate Codec2Buffer object,
+ * which can copy() from C2Buffers.
*/
- virtual sp<Codec2Buffer> allocateArrayBuffer() = 0;
+ virtual std::function<sp<Codec2Buffer>()> getAlloc() = 0;
private:
FlexBuffersImpl mImpl;
@@ -776,7 +840,7 @@
sp<Codec2Buffer> wrap(const std::shared_ptr<C2Buffer> &buffer) override;
- sp<Codec2Buffer> allocateArrayBuffer() override;
+ std::function<sp<Codec2Buffer>()> getAlloc() override;
};
class GraphicOutputBuffers : public FlexOutputBuffers {
@@ -786,7 +850,7 @@
sp<Codec2Buffer> wrap(const std::shared_ptr<C2Buffer> &buffer) override;
- sp<Codec2Buffer> allocateArrayBuffer() override;
+ std::function<sp<Codec2Buffer>()> getAlloc() override;
};
class RawGraphicOutputBuffers : public FlexOutputBuffers {
@@ -797,7 +861,7 @@
sp<Codec2Buffer> wrap(const std::shared_ptr<C2Buffer> &buffer) override;
- sp<Codec2Buffer> allocateArrayBuffer() override;
+ std::function<sp<Codec2Buffer>()> getAlloc() override;
private:
std::shared_ptr<LocalBufferPool> mLocalBufferPool;
diff --git a/media/codec2/sfplugin/Codec2Buffer.h b/media/codec2/sfplugin/Codec2Buffer.h
index dd618aa..36dcab9 100644
--- a/media/codec2/sfplugin/Codec2Buffer.h
+++ b/media/codec2/sfplugin/Codec2Buffer.h
@@ -226,10 +226,10 @@
const std::shared_ptr<C2GraphicBlock> &block,
std::function<sp<ABuffer>(size_t)> alloc);
- std::shared_ptr<C2Buffer> asC2Buffer() override;
-
virtual ~GraphicBlockBuffer() = default;
+ std::shared_ptr<C2Buffer> asC2Buffer() override;
+
private:
GraphicBlockBuffer(
const sp<AMessage> &format,
@@ -260,11 +260,10 @@
*/
GraphicMetadataBuffer(
const sp<AMessage> &format, const std::shared_ptr<C2Allocator> &alloc);
+ virtual ~GraphicMetadataBuffer() = default;
std::shared_ptr<C2Buffer> asC2Buffer() override;
- virtual ~GraphicMetadataBuffer() = default;
-
private:
GraphicMetadataBuffer() = delete;
@@ -307,12 +306,12 @@
const sp<AMessage> &format,
std::function<sp<ABuffer>(size_t)> alloc);
+ virtual ~ConstGraphicBlockBuffer() = default;
+
std::shared_ptr<C2Buffer> asC2Buffer() override;
bool canCopy(const std::shared_ptr<C2Buffer> &buffer) const override;
bool copy(const std::shared_ptr<C2Buffer> &buffer) override;
- virtual ~ConstGraphicBlockBuffer() = default;
-
private:
ConstGraphicBlockBuffer(
const sp<AMessage> &format,