Merge changes I3c756d61,Id0f6cf61 into qt-dev

* changes:
  avcenc: add GOP support
  CCodec: add max B frames support
diff --git a/apex/ld.config.txt b/apex/ld.config.txt
index 87af5a1..a5937fd 100644
--- a/apex/ld.config.txt
+++ b/apex/ld.config.txt
@@ -127,3 +127,5 @@
 # namespace.sphal.link.platform.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
 namespace.sphal.link.platform.shared_libs = libEGL.so:libGLESv1_CM.so:libGLESv2.so:libGLESv3.so:libRS.so:libandroid_net.so:libc.so:libcgrouprc.so:libclang_rt.asan-aarch64-android.so:libclang_rt.asan-arm-android.so:libclang_rt.hwasan-aarch64-android.so:libclang_rt.asan-i686-android.so:libclang_rt.asan-x86_64-android.so:libdl.so:libft2.so:liblog.so:libm.so:libmediandk.so:libnativewindow.so:libneuralnetworks.so:libsync.so:libvndksupport.so:libvulkan.so
 
+# Add a link for libz.so which is llndk on devices where VNDK is not enforced.
+namespace.sphal.link.platform.shared_libs += libz.so
diff --git a/media/codec2/components/hevc/C2SoftHevcEnc.cpp b/media/codec2/components/hevc/C2SoftHevcEnc.cpp
index 9b93cf3..b129b1b 100644
--- a/media/codec2/components/hevc/C2SoftHevcEnc.cpp
+++ b/media/codec2/components/hevc/C2SoftHevcEnc.cpp
@@ -861,6 +861,22 @@
             return;
         }
     }
+
+    // handle dynamic config parameters
+    {
+        IntfImpl::Lock lock = mIntf->lock();
+        std::shared_ptr<C2StreamBitrateInfo::output> bitrate = mIntf->getBitrate_l();
+        lock.unlock();
+
+        if (bitrate != mBitrate) {
+            mBitrate = bitrate;
+            mEncParams.s_tgt_lyr_prms.as_tgt_params[0].ai4_tgt_bitrate[0] =
+                mBitrate->value;
+            mEncParams.s_tgt_lyr_prms.as_tgt_params[0].ai4_peak_bitrate[0] =
+                mBitrate->value << 1;
+        }
+    }
+
     ihevce_inp_buf_t s_encode_ip{};
     ihevce_out_buf_t s_encode_op{};
     uint64_t workIndex = work->input.ordinal.frameIndex.peekull();
diff --git a/media/codec2/components/opus/C2SoftOpusEnc.cpp b/media/codec2/components/opus/C2SoftOpusEnc.cpp
index 7b58c9b..2d110f7 100644
--- a/media/codec2/components/opus/C2SoftOpusEnc.cpp
+++ b/media/codec2/components/opus/C2SoftOpusEnc.cpp
@@ -205,15 +205,6 @@
         return C2_BAD_VALUE;
     }
 
-    // Get codecDelay
-    int32_t lookahead;
-    if (opus_multistream_encoder_ctl(mEncoder, OPUS_GET_LOOKAHEAD(&lookahead)) !=
-            OPUS_OK) {
-        ALOGE("failed to get lookahead");
-        return C2_BAD_VALUE;
-    }
-    mCodecDelay = lookahead * 1000000000ll / mSampleRate;
-
     // Set seek preroll to 80 ms
     mSeekPreRoll = 80000000;
     return C2_OK;
@@ -406,13 +397,26 @@
     if (!mHeaderGenerated) {
         uint8_t header[AOPUS_UNIFIED_CSD_MAXSIZE];
         memset(header, 0, sizeof(header));
+
+        // Get codecDelay
+        int32_t lookahead;
+        if (opus_multistream_encoder_ctl(mEncoder, OPUS_GET_LOOKAHEAD(&lookahead)) !=
+                OPUS_OK) {
+            ALOGE("failed to get lookahead");
+            mSignalledError = true;
+            work->result = C2_CORRUPTED;
+            return;
+        }
+        mCodecDelay = lookahead * 1000000000ll / mSampleRate;
+
         OpusHeader opusHeader;
+        memset(&opusHeader, 0, sizeof(opusHeader));
         opusHeader.channels = mChannelCount;
         opusHeader.num_streams = mChannelCount;
         opusHeader.num_coupled = 0;
         opusHeader.channel_mapping = ((mChannelCount > 8) ? 255 : (mChannelCount > 2));
         opusHeader.gain_db = 0;
-        opusHeader.skip_samples = 0;
+        opusHeader.skip_samples = lookahead;
         int headerLen = WriteOpusHeaders(opusHeader, mSampleRate, header,
             sizeof(header), mCodecDelay, mSeekPreRoll);
 
diff --git a/media/codec2/sfplugin/C2OMXNode.cpp b/media/codec2/sfplugin/C2OMXNode.cpp
index 6ae1c13..f0f62f6 100644
--- a/media/codec2/sfplugin/C2OMXNode.cpp
+++ b/media/codec2/sfplugin/C2OMXNode.cpp
@@ -50,14 +50,8 @@
 }  // namespace
 
 C2OMXNode::C2OMXNode(const std::shared_ptr<Codec2Client::Component> &comp)
-    : mComp(comp), mFrameIndex(0), mWidth(0), mHeight(0),
+    : mComp(comp), mFrameIndex(0), mWidth(0), mHeight(0), mUsage(0),
       mAdjustTimestampGapUs(0), mFirstInputFrame(true) {
-    // TODO: read from intf()
-    if (!strncmp(comp->getName().c_str(), "c2.android.", 11)) {
-        mUsage = GRALLOC_USAGE_SW_READ_OFTEN;
-    } else {
-        mUsage = GRALLOC_USAGE_HW_VIDEO_ENCODER;
-    }
 }
 
 status_t C2OMXNode::freeNode() {
@@ -103,13 +97,25 @@
 }
 
 status_t C2OMXNode::setParameter(OMX_INDEXTYPE index, const void *params, size_t size) {
-    // handle max/fixed frame duration control
-    if (index == (OMX_INDEXTYPE)OMX_IndexParamMaxFrameDurationForBitrateControl
-            && params != NULL
-            && size == sizeof(OMX_PARAM_U32TYPE)) {
-        // The incoming number is an int32_t contained in OMX_U32.
-        mAdjustTimestampGapUs = (int32_t)((OMX_PARAM_U32TYPE*)params)->nU32;
-        return OK;
+    if (params == NULL) {
+        return BAD_VALUE;
+    }
+    switch ((uint32_t)index) {
+        case OMX_IndexParamMaxFrameDurationForBitrateControl:
+            // handle max/fixed frame duration control
+            if (size != sizeof(OMX_PARAM_U32TYPE)) {
+                return BAD_VALUE;
+            }
+            // The incoming number is an int32_t contained in OMX_U32.
+            mAdjustTimestampGapUs = (int32_t)((OMX_PARAM_U32TYPE*)params)->nU32;
+            return OK;
+
+        case OMX_IndexParamConsumerUsageBits:
+            if (size != sizeof(OMX_U32)) {
+                return BAD_VALUE;
+            }
+            mUsage = *((OMX_U32 *)params);
+            return OK;
     }
     return ERROR_UNSUPPORTED;
 }
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index 0f958c9..f5a4d94 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -183,9 +183,11 @@
     GraphicBufferSourceWrapper(
             const sp<BGraphicBufferSource> &source,
             uint32_t width,
-            uint32_t height)
+            uint32_t height,
+            uint64_t usage)
         : mSource(source), mWidth(width), mHeight(height) {
         mDataSpace = HAL_DATASPACE_BT709;
+        mConfig.mUsage = usage;
     }
     ~GraphicBufferSourceWrapper() override = default;
 
@@ -193,6 +195,12 @@
         mNode = new C2OMXNode(comp);
         mNode->setFrameSize(mWidth, mHeight);
 
+        // Usage is queried during configure(), so setting it beforehand.
+        OMX_U32 usage = mConfig.mUsage & 0xFFFFFFFF;
+        (void)mNode->setParameter(
+                (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
+                &usage, sizeof(usage));
+
         // NOTE: we do not use/pass through color aspects from GraphicBufferSource as we
         // communicate that directly to the component.
         mSource->configure(mNode, mDataSpace);
@@ -364,7 +372,8 @@
 
         // color aspects (android._color-aspects)
 
-        // consumer usage
+        // consumer usage is queried earlier.
+
         ALOGD("ISConfig%s", status.str().c_str());
         return err;
     }
@@ -745,11 +754,8 @@
                 return BAD_VALUE;
             }
             if ((config->mDomain & Config::IS_ENCODER) && (config->mDomain & Config::IS_VIDEO)) {
-                C2Config::bitrate_mode_t mode = C2Config::BITRATE_VARIABLE;
-                if (msg->findInt32(KEY_BITRATE_MODE, &i32)) {
-                    mode = (C2Config::bitrate_mode_t) i32;
-                }
-                if (mode == BITRATE_MODE_CQ) {
+                int32_t mode = BITRATE_MODE_VBR;
+                if (msg->findInt32(KEY_BITRATE_MODE, &mode) && mode == BITRATE_MODE_CQ) {
                     if (!msg->findInt32(KEY_QUALITY, &i32)) {
                         ALOGD("quality is missing, which is required for video encoders in CQ.");
                         return BAD_VALUE;
@@ -818,6 +824,7 @@
                     config->mISConfig->mSuspended = true;
                 }
             }
+            config->mISConfig->mUsage = 0;
         }
 
         /*
@@ -897,8 +904,14 @@
                     indices.size(), params.size());
             return UNKNOWN_ERROR;
         }
-        if (usage && (usage.value & C2MemoryUsage::CPU_READ)) {
-            config->mInputFormat->setInt32("using-sw-read-often", true);
+        if (usage) {
+            if (usage.value & C2MemoryUsage::CPU_READ) {
+                config->mInputFormat->setInt32("using-sw-read-often", true);
+            }
+            if (config->mISConfig) {
+                C2AndroidMemoryUsage androidUsage(C2MemoryUsage(usage.value));
+                config->mISConfig->mUsage = androidUsage.asGrallocUsage();
+            }
         }
 
         // NOTE: we don't blindly use client specified input size if specified as clients
@@ -1089,10 +1102,12 @@
 
     sp<AMessage> inputFormat;
     sp<AMessage> outputFormat;
+    uint64_t usage = 0;
     {
         Mutexed<Config>::Locked config(mConfig);
         inputFormat = config->mInputFormat;
         outputFormat = config->mOutputFormat;
+        usage = config->mISConfig ? config->mISConfig->mUsage : 0;
     }
 
     sp<PersistentSurface> persistentSurface = CreateCompatibleInputSurface();
@@ -1116,7 +1131,7 @@
         int32_t height = 0;
         (void)outputFormat->findInt32("height", &height);
         err = setupInputSurface(std::make_shared<GraphicBufferSourceWrapper>(
-                persistentSurface->getBufferSource(), width, height));
+                persistentSurface->getBufferSource(), width, height, usage));
         bufferProducer = persistentSurface->getBufferProducer();
     }
 
@@ -1176,10 +1191,12 @@
 void CCodec::setInputSurface(const sp<PersistentSurface> &surface) {
     sp<AMessage> inputFormat;
     sp<AMessage> outputFormat;
+    uint64_t usage = 0;
     {
         Mutexed<Config>::Locked config(mConfig);
         inputFormat = config->mInputFormat;
         outputFormat = config->mOutputFormat;
+        usage = config->mISConfig ? config->mISConfig->mUsage : 0;
     }
     auto hidlTarget = surface->getHidlTarget();
     if (hidlTarget) {
@@ -1203,7 +1220,7 @@
         int32_t height = 0;
         (void)outputFormat->findInt32("height", &height);
         status_t err = setupInputSurface(std::make_shared<GraphicBufferSourceWrapper>(
-                surface->getBufferSource(), width, height));
+                surface->getBufferSource(), width, height, usage));
         if (err != OK) {
             ALOGE("Failed to set up input surface: %d", err);
             mCallback->onInputSurfaceDeclined(err);
diff --git a/media/codec2/sfplugin/CCodecConfig.cpp b/media/codec2/sfplugin/CCodecConfig.cpp
index 428f032..4c3fff7 100644
--- a/media/codec2/sfplugin/CCodecConfig.cpp
+++ b/media/codec2/sfplugin/CCodecConfig.cpp
@@ -358,14 +358,7 @@
         .limitTo(D::ENCODER & D::VIDEO & D::PARAM));
     add(ConfigMapper(KEY_BITRATE_MODE, C2_PARAMKEY_BITRATE_MODE, "value")
         .limitTo(D::ENCODER & D::CODED)
-        .withMapper([](C2Value v) -> C2Value {
-            int32_t value;
-            C2Config::bitrate_mode_t mode;
-            if (v.get(&value) && C2Mapper::map(value, &mode)) {
-                return mode;
-            }
-            return C2Value();
-        }));
+        .withC2Mappers<C2Config::bitrate_mode_t>());
     // remove when codecs switch to PARAMKEY and new modes
     deprecated(ConfigMapper(KEY_BITRATE_MODE, "coded.bitrate-mode", "value")
                .limitTo(D::ENCODER));
diff --git a/media/codec2/sfplugin/Codec2Buffer.cpp b/media/codec2/sfplugin/Codec2Buffer.cpp
index 0fd5731..c6cbad3 100644
--- a/media/codec2/sfplugin/Codec2Buffer.cpp
+++ b/media/codec2/sfplugin/Codec2Buffer.cpp
@@ -739,6 +739,7 @@
         ALOGD("ConstGraphicBlockBuffer::copy: set back buffer failed");
         return false;
     }
+    setRange(0, aBuffer->size());  // align size info
     converter.copyToMediaImage();
     setImageData(converter.imageData());
     mBufferRef = buffer;
diff --git a/media/codec2/sfplugin/InputSurfaceWrapper.h b/media/codec2/sfplugin/InputSurfaceWrapper.h
index 8341fd5..bb35763 100644
--- a/media/codec2/sfplugin/InputSurfaceWrapper.h
+++ b/media/codec2/sfplugin/InputSurfaceWrapper.h
@@ -78,6 +78,7 @@
         // IN PARAMS (CODEC WRAPPER)
         float mFixedAdjustedFps; // fixed fps via PTS manipulation
         float mMinAdjustedFps; // minimum fps via PTS manipulation
+        uint64_t mUsage; // consumer usage
     };
 
     /**
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index f54690d..527bb77 100755
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -1754,6 +1754,15 @@
                 // http://wiki.xiph.org/OggOpus#ID_Header
                 strncpy((char *)opusInfo, "OpusHead", 8);
 
+                // Version shall be 0 as per mp4 Opus Specific Box
+                // (https://opus-codec.org/docs/opus_in_isobmff.html#4.3.2)
+                if (opusInfo[8]) {
+                    return ERROR_MALFORMED;
+                }
+                // Force version to 1 as per OpusHead definition
+                // (http://wiki.xiph.org/OggOpus#ID_Header)
+                opusInfo[8] = 1;
+
                 // Read Opus Specific Box values
                 size_t opusOffset = 10;
                 uint16_t pre_skip = U16_AT(&opusInfo[opusOffset]);