Snap for 10611805 from 469520deb227d43ece62881ad12d2f8be192fc71 to mainline-adservices-release

Change-Id: I25900e74ed738d1aa556b19022e7c6c30803f241
diff --git a/camera/ndk/include/camera/NdkCameraMetadataTags.h b/camera/ndk/include/camera/NdkCameraMetadataTags.h
index bd679e5..af00e55 100644
--- a/camera/ndk/include/camera/NdkCameraMetadataTags.h
+++ b/camera/ndk/include/camera/NdkCameraMetadataTags.h
@@ -5384,7 +5384,7 @@
      * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraMetadata.html#SENSOR_PIXEL_MODE_DEFAULT">CameraMetadata#SENSOR_PIXEL_MODE_DEFAULT</a> mode.
      * They can be queried through
      * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics.html#get">CameraCharacteristics#get</a> with
-     * <a href="https://developer.android.com/reference/CameraCharacteristics.html#SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION)">CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION)</a>.
+     * <a href="https://developer.android.com/reference/CameraCharacteristics.html#SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION">CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION</a>.
      * Unless reported by both
      * <a href="https://developer.android.com/reference/android/hardware/camera2/params/StreamConfigurationMap.html">StreamConfigurationMap</a>s, the outputs from
      * <code>android.scaler.streamConfigurationMapMaximumResolution</code> and
@@ -5399,13 +5399,12 @@
      * <ul>
      * <li>
      * <p>The mandatory stream combinations listed in
-     *   <a href="https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics/mandatoryMaximumResolutionStreamCombinations.html">mandatoryMaximumResolutionStreamCombinations</a>
-     *   would not apply.</p>
+     *   android.scaler.mandatoryMaximumResolutionStreamCombinations  would not apply.</p>
      * </li>
      * <li>
      * <p>The bayer pattern of {@code RAW} streams when
      *   <a href="https://developer.android.com/reference/android/hardware/camera2/CameraMetadata.html#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION">CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION</a>
-     *   is selected will be the one listed in <a href="https://developer.android.com/reference/android/sensor/info/binningFactor.html">binningFactor</a>.</p>
+     *   is selected will be the one listed in ACAMERA_SENSOR_INFO_BINNING_FACTOR.</p>
      * </li>
      * <li>
      * <p>The following keys will always be present:</p>
@@ -5419,6 +5418,7 @@
      * </ul>
      *
      * @see ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION
+     * @see ACAMERA_SENSOR_INFO_BINNING_FACTOR
      * @see ACAMERA_SENSOR_INFO_PIXEL_ARRAY_SIZE_MAXIMUM_RESOLUTION
      * @see ACAMERA_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION
      */
diff --git a/media/codec2/components/flac/C2SoftFlacEnc.cpp b/media/codec2/components/flac/C2SoftFlacEnc.cpp
index 182edfb..591d56d 100644
--- a/media/codec2/components/flac/C2SoftFlacEnc.cpp
+++ b/media/codec2/components/flac/C2SoftFlacEnc.cpp
@@ -188,12 +188,6 @@
     return onStop();
 }
 
-static void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
-    work->worklets.front()->output.flags = work->input.flags;
-    work->worklets.front()->output.buffers.clear();
-    work->worklets.front()->output.ordinal = work->input.ordinal;
-}
-
 void C2SoftFlacEnc::process(
         const std::unique_ptr<C2Work> &work,
         const std::shared_ptr<C2BlockPool> &pool) {
@@ -245,12 +239,10 @@
         mWroteHeader = true;
     }
 
-    const uint32_t sampleRate = mIntf->getSampleRate();
     const uint32_t channelCount = mIntf->getChannelCount();
     const bool inputFloat = mIntf->getPcmEncodingInfo() == C2Config::PCM_FLOAT;
     const unsigned sampleSize = inputFloat ? sizeof(float) : sizeof(int16_t);
     const unsigned frameSize = channelCount * sampleSize;
-    const uint64_t outTimeStamp = mProcessedSamples * 1000000ll / sampleRate;
 
     size_t outCapacity = inSize;
     outCapacity += mBlockSize * frameSize;
@@ -270,6 +262,33 @@
         return;
     }
 
+    class FillWork {
+    public:
+        FillWork(uint32_t flags, C2WorkOrdinalStruct ordinal,
+                 const std::shared_ptr<C2Buffer> &buffer)
+            : mFlags(flags), mOrdinal(ordinal), mBuffer(buffer) {}
+        ~FillWork() = default;
+
+        void operator()(const std::unique_ptr<C2Work> &work) {
+            work->worklets.front()->output.flags = (C2FrameData::flags_t)mFlags;
+            work->worklets.front()->output.buffers.clear();
+            work->worklets.front()->output.ordinal = mOrdinal;
+            work->workletsProcessed = 1u;
+            work->result = C2_OK;
+            if (mBuffer) {
+                work->worklets.front()->output.buffers.push_back(mBuffer);
+            }
+            ALOGV("timestamp = %lld, index = %lld, w/%s buffer",
+                  mOrdinal.timestamp.peekll(), mOrdinal.frameIndex.peekll(),
+                  mBuffer ? "" : "o");
+        }
+
+    private:
+        const uint32_t mFlags;
+        const C2WorkOrdinalStruct mOrdinal;
+        const std::shared_ptr<C2Buffer> mBuffer;
+    };
+
     mEncoderWriteData = true;
     mEncoderReturnedNbBytes = 0;
     size_t inPos = 0;
@@ -308,14 +327,33 @@
         mOutputBlock.reset();
         return;
     }
-    fillEmptyWork(work);
-    if (mEncoderReturnedNbBytes != 0) {
-        std::shared_ptr<C2Buffer> buffer = createLinearBuffer(std::move(mOutputBlock), 0, mEncoderReturnedNbBytes);
-        work->worklets.front()->output.buffers.push_back(buffer);
-        work->worklets.front()->output.ordinal.timestamp = mAnchorTimeStamp + outTimeStamp;
-    } else {
-        ALOGV("encoder process_interleaved returned without data to write");
+
+    // cloneAndSend will create clone of work when more than one encoded frame is produced
+    while (mOutputBuffers.size() > 1) {
+        const OutputBuffer& front = mOutputBuffers.front();
+        C2WorkOrdinalStruct ordinal = work->input.ordinal;
+        ordinal.frameIndex = front.frameIndex;
+        ordinal.timestamp = front.timestampUs;
+        cloneAndSend(work->input.ordinal.frameIndex.peeku(), work,
+                     FillWork(C2FrameData::FLAG_INCOMPLETE, ordinal, front.buffer));
+        mOutputBuffers.pop_front();
     }
+
+    std::shared_ptr<C2Buffer> buffer;
+    C2WorkOrdinalStruct ordinal = work->input.ordinal;
+    if (mOutputBuffers.size() == 1) {
+        const OutputBuffer& front = mOutputBuffers.front();
+        ordinal.frameIndex = front.frameIndex;
+        ordinal.timestamp = front.timestampUs;
+        buffer = front.buffer;
+        mOutputBuffers.pop_front();
+    }
+    // finish the response for the overall transaction.
+    // this includes any final frame that the encoder produced during this request
+    // this response is required even if no data was encoded.
+    FillWork((C2FrameData::flags_t)(eos ? C2FrameData::FLAG_END_OF_STREAM : 0),
+             ordinal, buffer)(work);
+
     mOutputBlock = nullptr;
     if (eos) {
         mSignalledOutputEos = true;
@@ -349,6 +387,8 @@
     // write encoded data
     C2WriteView wView = mOutputBlock->map().get();
     uint8_t* outData = wView.data();
+    const uint32_t sampleRate = mIntf->getSampleRate();
+    const uint64_t outTimeStamp = mProcessedSamples * 1000000ll / sampleRate;
     ALOGV("writing %zu bytes of encoded data on output", bytes);
     // increment mProcessedSamples to maintain audio synchronization during
     // play back
@@ -359,7 +399,12 @@
         return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
     }
     memcpy(outData + mEncoderReturnedNbBytes, buffer, bytes);
+
+    std::shared_ptr<C2Buffer> c2Buffer =
+        createLinearBuffer(mOutputBlock, mEncoderReturnedNbBytes, bytes);
+    mOutputBuffers.push_back({c2Buffer, mAnchorTimeStamp + outTimeStamp, current_frame});
     mEncoderReturnedNbBytes += bytes;
+
     return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
 }
 
diff --git a/media/codec2/components/flac/C2SoftFlacEnc.h b/media/codec2/components/flac/C2SoftFlacEnc.h
index b3f01d5..a971ab5 100644
--- a/media/codec2/components/flac/C2SoftFlacEnc.h
+++ b/media/codec2/components/flac/C2SoftFlacEnc.h
@@ -79,6 +79,12 @@
     unsigned mHeaderOffset;
     bool mWroteHeader;
     char mHeader[FLAC_HEADER_SIZE];
+    struct OutputBuffer {
+        std::shared_ptr<C2Buffer> buffer;
+        c2_cntr64_t timestampUs;
+        std::uint64_t frameIndex;
+    };
+    std::list<OutputBuffer> mOutputBuffers;
 
     C2_DO_NOT_COPY(C2SoftFlacEnc);
 };