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> &params) {
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.
      */