Merge "AudioFlinger: update log printing for 22.2"
diff --git a/media/codec2/components/flac/C2SoftFlacDec.cpp b/media/codec2/components/flac/C2SoftFlacDec.cpp
index e70c289..49892a4 100644
--- a/media/codec2/components/flac/C2SoftFlacDec.cpp
+++ b/media/codec2/components/flac/C2SoftFlacDec.cpp
@@ -221,6 +221,11 @@
 
     uint8_t *input = const_cast<uint8_t *>(rView.data() + inOffset);
     if (codecConfig) {
+        if (mHasStreamInfo) {
+            ALOGV("Ignore Codec Config");
+            fillEmptyWork(work);
+            return;
+        }
         status_t decoderErr = mFLACDecoder->parseMetadata(input, inSize);
         if (decoderErr != OK && decoderErr != WOULD_BLOCK) {
             ALOGE("process: FLACDecoder parseMetaData returns error %d", decoderErr);
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index 343cf29..b47e546 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -38,6 +38,7 @@
 #include <media/omx/1.0/WOmxNode.h>
 #include <media/openmax/OMX_Core.h>
 #include <media/openmax/OMX_IndexExt.h>
+#include <media/stagefright/foundation/avc_utils.h>
 #include <media/stagefright/omx/1.0/WGraphicBufferSource.h>
 #include <media/stagefright/omx/OmxGraphicBufferSource.h>
 #include <media/stagefright/CCodec.h>
@@ -513,6 +514,44 @@
     }
 }
 
+void AmendOutputFormatWithCodecSpecificData(
+        const uint8_t *data, size_t size, const std::string mediaType,
+        const sp<AMessage> &outputFormat) {
+    if (mediaType == MIMETYPE_VIDEO_AVC) {
+        // Codec specific data should be SPS and PPS in a single buffer,
+        // each prefixed by a startcode (0x00 0x00 0x00 0x01).
+        // We separate the two and put them into the output format
+        // under the keys "csd-0" and "csd-1".
+
+        unsigned csdIndex = 0;
+
+        const uint8_t *nalStart;
+        size_t nalSize;
+        while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) {
+            sp<ABuffer> csd = new ABuffer(nalSize + 4);
+            memcpy(csd->data(), "\x00\x00\x00\x01", 4);
+            memcpy(csd->data() + 4, nalStart, nalSize);
+
+            outputFormat->setBuffer(
+                    AStringPrintf("csd-%u", csdIndex).c_str(), csd);
+
+            ++csdIndex;
+        }
+
+        if (csdIndex != 2) {
+            ALOGW("Expected two NAL units from AVC codec config, but %u found",
+                    csdIndex);
+        }
+    } else {
+        // For everything else we just stash the codec specific data into
+        // the output format as a single piece of csd under "csd-0".
+        sp<ABuffer> csd = new ABuffer(size);
+        memcpy(csd->data(), data, size);
+        csd->setRange(0, size);
+        outputFormat->setBuffer("csd-0", csd);
+    }
+}
+
 }  // namespace
 
 // CCodec::ClientListener
@@ -2149,7 +2188,7 @@
             }
 
             // handle configuration changes in work done
-            std::unique_ptr<C2Param> initData;
+            std::shared_ptr<const C2StreamInitDataInfo::output> initData;
             sp<AMessage> outputFormat = nullptr;
             {
                 Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
@@ -2228,13 +2267,15 @@
                     config->mInputSurface->onInputBufferDone(work->input.ordinal.frameIndex);
                 }
                 if (initDataWatcher.hasChanged()) {
-                    initData = C2Param::Copy(*initDataWatcher.update().get());
+                    initData = initDataWatcher.update();
+                    AmendOutputFormatWithCodecSpecificData(
+                            initData->m.value, initData->flexCount(), config->mCodingMediaType,
+                            config->mOutputFormat);
                 }
                 outputFormat = config->mOutputFormat;
             }
             mChannel->onWorkDone(
-                    std::move(work), outputFormat,
-                    initData ? (C2StreamInitDataInfo::output *)initData.get() : nullptr);
+                    std::move(work), outputFormat, initData ? initData.get() : nullptr);
             break;
         }
         case kWhatWatch: {
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
index 4485a1b..5a58fd8 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.cpp
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
@@ -1629,7 +1629,8 @@
         }
     }
 
-    std::optional<uint32_t> newInputDelay, newPipelineDelay;
+    std::optional<uint32_t> newInputDelay, newPipelineDelay, newOutputDelay, newReorderDepth;
+    std::optional<C2Config::ordinal_key_t> newReorderKey;
     bool needMaxDequeueBufferCountUpdate = false;
     while (!worklet->output.configUpdate.empty()) {
         std::unique_ptr<C2Param> param;
@@ -1641,7 +1642,7 @@
                 if (reorderDepth.updateFrom(*param)) {
                     ALOGV("[%s] onWorkDone: updated reorder depth to %u",
                           mName, reorderDepth.value);
-                    mOutput.lock()->buffers->setReorderDepth(reorderDepth.value);
+                    newReorderDepth = reorderDepth.value;
                     needMaxDequeueBufferCountUpdate = true;
                 } else {
                     ALOGD("[%s] onWorkDone: failed to read reorder depth",
@@ -1652,7 +1653,7 @@
             case C2PortReorderKeySetting::CORE_INDEX: {
                 C2PortReorderKeySetting::output reorderKey;
                 if (reorderKey.updateFrom(*param)) {
-                    mOutput.lock()->buffers->setReorderKey(reorderKey.value);
+                    newReorderKey = reorderKey.value;
                     ALOGV("[%s] onWorkDone: updated reorder key to %u",
                           mName, reorderKey.value);
                 } else {
@@ -1687,35 +1688,9 @@
                         ALOGV("[%s] onWorkDone: updating output delay %u",
                               mName, outputDelay.value);
                         (void)mPipelineWatcher.lock()->outputDelay(outputDelay.value);
+                        newOutputDelay = outputDelay.value;
                         needMaxDequeueBufferCountUpdate = true;
 
-                        bool outputBuffersChanged = false;
-                        size_t numOutputSlots = 0;
-                        {
-                            Mutexed<Output>::Locked output(mOutput);
-                            if (!output->buffers) {
-                                return false;
-                            }
-                            output->outputDelay = outputDelay.value;
-                            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;
-                                }
-                            }
-                            numOutputSlots = output->numSlots;
-                        }
-
-                        if (outputBuffersChanged) {
-                            mCCodecCallback->onOutputBuffersChanged();
-                        }
                     }
                 }
                 break;
@@ -1755,14 +1730,43 @@
             input->numSlots = newNumSlots;
         }
     }
-    if (needMaxDequeueBufferCountUpdate) {
-        size_t numOutputSlots = 0;
-        uint32_t reorderDepth = 0;
-        {
-            Mutexed<Output>::Locked output(mOutput);
-            numOutputSlots = output->numSlots;
-            reorderDepth = output->buffers ? output->buffers->getReorderDepth() : 0;
+    size_t numOutputSlots = 0;
+    uint32_t reorderDepth = 0;
+    bool outputBuffersChanged = false;
+    if (newReorderKey || newReorderDepth || needMaxDequeueBufferCountUpdate) {
+        Mutexed<Output>::Locked output(mOutput);
+        if (!output->buffers) {
+            return false;
         }
+        numOutputSlots = output->numSlots;
+        if (newReorderKey) {
+            output->buffers->setReorderKey(newReorderKey.value());
+        }
+        if (newReorderDepth) {
+            output->buffers->setReorderDepth(newReorderDepth.value());
+        }
+        reorderDepth = output->buffers->getReorderDepth();
+        if (newOutputDelay) {
+            output->outputDelay = newOutputDelay.value();
+            numOutputSlots = newOutputDelay.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;
+                }
+            }
+        }
+        numOutputSlots = output->numSlots;
+    }
+    if (outputBuffersChanged) {
+        mCCodecCallback->onOutputBuffersChanged();
+    }
+    if (needMaxDequeueBufferCountUpdate) {
         Mutexed<OutputSurface>::Locked output(mOutputSurface);
         output->maxDequeueBuffers = numOutputSlots + reorderDepth + kRenderingDepth;
         if (output->surface) {
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 0fa2e3f..c9b6340 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -1333,16 +1333,12 @@
     // the reclaimResource call doesn't consider the requester's buffer size for now.
     resources.push_back(MediaResource::GraphicMemoryResource(1));
     for (int i = 0; i <= kMaxRetry; ++i) {
-        if (i > 0) {
-            // Don't try to reclaim resource for the first time.
-            if (!mResourceManagerProxy->reclaimResource(resources)) {
-                break;
-            }
-        }
-
         sp<AMessage> response;
         err = PostAndAwaitResponse(msg, &response);
         if (err != OK && err != INVALID_OPERATION) {
+            if (isResourceError(err) && !mResourceManagerProxy->reclaimResource(resources)) {
+                break;
+            }
             // MediaCodec now set state to UNINITIALIZED upon any fatal error.
             // To maintain backward-compatibility, do a reset() to put codec
             // back into INITIALIZED state.
@@ -3663,7 +3659,8 @@
         // format as necessary.
         int32_t flags = 0;
         (void) buffer->meta()->findInt32("flags", &flags);
-        if ((flags & BUFFER_FLAG_CODECCONFIG) && !(mFlags & kFlagIsSecure)) {
+        if ((flags & BUFFER_FLAG_CODECCONFIG) && !(mFlags & kFlagIsSecure)
+                && !mOwnerName.startsWith("codec2::")) {
             status_t err =
                 amendOutputFormatWithCodecSpecificData(buffer);