CCodec: make config consistent before/after flush
If the CSD is processed before flush, make sure client and component
are in sync.
Bug: 141097367
Bug: 142542964
Bug: 149537770
Test: atest CtsMediaTestCases -- --module-arg CtsMediaTestCases:size:small
Change-Id: Ia51591770a4fdac1c1334a94fa8d6b2776da1a81
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index 39263f9..6f51e4d 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -1323,6 +1323,8 @@
mCallback->onError(err2, ACTION_CODE_FATAL);
return;
}
+ // We're not starting after flush.
+ (void)mSentConfigAfterResume.test_and_set();
err2 = mChannel->start(inputFormat, outputFormat, buffersBoundToCodec);
if (err2 != OK) {
mCallback->onError(err2, ACTION_CODE_FATAL);
@@ -1555,18 +1557,27 @@
}
void CCodec::signalResume() {
- auto setResuming = [this] {
+ std::shared_ptr<Codec2Client::Component> comp;
+ auto setResuming = [this, &comp] {
Mutexed<State>::Locked state(mState);
if (state->get() != FLUSHED) {
return UNKNOWN_ERROR;
}
state->set(RESUMING);
+ comp = state->comp;
return OK;
};
if (tryAndReportOnError(setResuming) != OK) {
return;
}
+ mSentConfigAfterResume.clear();
+ {
+ Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
+ const std::unique_ptr<Config> &config = *configLocked;
+ config->queryConfiguration(comp);
+ }
+
(void)mChannel->start(nullptr, nullptr, [&]{
Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
const std::unique_ptr<Config> &config = *configLocked;
@@ -1770,7 +1781,7 @@
// handle configuration changes in work done
Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
const std::unique_ptr<Config> &config = *configLocked;
- bool changed = false;
+ bool changed = !mSentConfigAfterResume.test_and_set();
Config::Watcher<C2StreamInitDataInfo::output> initData =
config->watch<C2StreamInitDataInfo::output>();
if (!work->worklets.empty()
@@ -1802,7 +1813,9 @@
++stream;
}
- changed = config->updateConfiguration(updates, config->mOutputDomain);
+ if (config->updateConfiguration(updates, config->mOutputDomain)) {
+ changed = true;
+ }
// copy standard infos to graphic buffers if not already present (otherwise, we
// may overwrite the actual intermediate value with a final value)
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
index 035dca8..b869bd9 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.cpp
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
@@ -1457,6 +1457,24 @@
std::unique_ptr<C2Work> work,
const sp<AMessage> &outputFormat,
const C2StreamInitDataInfo::output *initData) {
+ if (outputFormat != nullptr) {
+ Mutexed<Output>::Locked output(mOutput);
+ ALOGD("[%s] onWorkDone: output format changed to %s",
+ mName, outputFormat->debugString().c_str());
+ output->buffers->setFormat(outputFormat);
+
+ AString mediaType;
+ if (outputFormat->findString(KEY_MIME, &mediaType)
+ && mediaType == MIMETYPE_AUDIO_RAW) {
+ int32_t channelCount;
+ int32_t sampleRate;
+ if (outputFormat->findInt32(KEY_CHANNEL_COUNT, &channelCount)
+ && outputFormat->findInt32(KEY_SAMPLE_RATE, &sampleRate)) {
+ output->buffers->updateSkipCutBuffer(sampleRate, channelCount);
+ }
+ }
+ }
+
if ((work->input.ordinal.frameIndex - mFirstValidFrameIndex.load()).peek() < 0) {
// Discard frames from previous generation.
ALOGD("[%s] Discard frames from previous generation.", mName);
@@ -1634,24 +1652,6 @@
}
}
- if (outputFormat != nullptr) {
- Mutexed<Output>::Locked output(mOutput);
- ALOGD("[%s] onWorkDone: output format changed to %s",
- mName, outputFormat->debugString().c_str());
- output->buffers->setFormat(outputFormat);
-
- AString mediaType;
- if (outputFormat->findString(KEY_MIME, &mediaType)
- && mediaType == MIMETYPE_AUDIO_RAW) {
- int32_t channelCount;
- int32_t sampleRate;
- if (outputFormat->findInt32(KEY_CHANNEL_COUNT, &channelCount)
- && outputFormat->findInt32(KEY_SAMPLE_RATE, &sampleRate)) {
- output->buffers->updateSkipCutBuffer(sampleRate, channelCount);
- }
- }
- }
-
int32_t flags = 0;
if (worklet->output.flags & C2FrameData::FLAG_END_OF_STREAM) {
flags |= MediaCodec::BUFFER_FLAG_EOS;
diff --git a/media/codec2/sfplugin/include/media/stagefright/CCodec.h b/media/codec2/sfplugin/include/media/stagefright/CCodec.h
index 6ff2c4a..4797426 100644
--- a/media/codec2/sfplugin/include/media/stagefright/CCodec.h
+++ b/media/codec2/sfplugin/include/media/stagefright/CCodec.h
@@ -17,6 +17,7 @@
#ifndef C_CODEC_H_
#define C_CODEC_H_
+#include <atomic>
#include <chrono>
#include <list>
#include <memory>
@@ -192,6 +193,7 @@
typedef CCodecConfig Config;
Mutexed<std::unique_ptr<CCodecConfig>> mConfig;
Mutexed<std::list<std::unique_ptr<C2Work>>> mWorkDoneQueue;
+ std::atomic_flag mSentConfigAfterResume;
friend class CCodecCallbackImpl;