CCodec: only start feeding input buffers after start is signaled
This fixes a race where an empty initial input buffer could get
fed and returned before start actually completes (causing an
invalid state error).
Test: cts-tradefed run singleCommand cts -m CtsMediaTestCases -t android.media.cts.VideoEncoderTest
Bug: 90469941
Change-Id: I3983b8e257c0c58735fc7a3bc3ea5a445aa2fd1b
diff --git a/media/sfplugin/CCodec.cpp b/media/sfplugin/CCodec.cpp
index a5f382e..dbaac80 100644
--- a/media/sfplugin/CCodec.cpp
+++ b/media/sfplugin/CCodec.cpp
@@ -1011,6 +1011,8 @@
return;
}
mCallback->onStartCompleted();
+
+ (void)mChannel->requestInitialInputBuffers();
}
void CCodec::initiateShutdown(bool keepComponentAllocated) {
@@ -1215,6 +1217,8 @@
}
state->set(RUNNING);
}
+
+ (void)mChannel->requestInitialInputBuffers();
}
void CCodec::signalSetParameters(const sp<AMessage> ¶ms) {
diff --git a/media/sfplugin/CCodecBufferChannel.cpp b/media/sfplugin/CCodecBufferChannel.cpp
index 611f145..8c7556d 100644
--- a/media/sfplugin/CCodecBufferChannel.cpp
+++ b/media/sfplugin/CCodecBufferChannel.cpp
@@ -1906,6 +1906,10 @@
mPendingFeed = 0;
mSync.start();
+ return OK;
+}
+
+status_t CCodecBufferChannel::requestInitialInputBuffers() {
if (mInputSurface == nullptr) {
// TODO: use proper buffer depth instead of this random value
for (size_t i = 0; i < kMinInputBufferArraySize; ++i) {
@@ -1924,6 +1928,7 @@
}
}
if (buffer) {
+ ALOGV("[%s] input buffer %zu available", mName, index);
mCallback->onInputBufferAvailable(index, buffer);
}
}
diff --git a/media/sfplugin/CCodecBufferChannel.h b/media/sfplugin/CCodecBufferChannel.h
index 2127e2b..e802b9f 100644
--- a/media/sfplugin/CCodecBufferChannel.h
+++ b/media/sfplugin/CCodecBufferChannel.h
@@ -96,11 +96,16 @@
/**
* Start queueing buffers to the component. This object should never queue
- * buffers before this call.
+ * buffers before this call has completed.
*/
status_t start(const sp<AMessage> &inputFormat, const sp<AMessage> &outputFormat);
/**
+ * Request initial input buffers to be filled by client.
+ */
+ status_t requestInitialInputBuffers();
+
+ /**
* Stop queueing buffers to the component. This object should never queue
* buffers after this call, until start() is called.
*/