codec2: use an index flag for split parameters

Bug: 124982277
Change-Id: I88dd8f568a5616f12cf6c176ab97fbfc89083962
diff --git a/media/codec2/core/include/C2Config.h b/media/codec2/core/include/C2Config.h
index 9f484a3..3820f90 100644
--- a/media/codec2/core/include/C2Config.h
+++ b/media/codec2/core/include/C2Config.h
@@ -117,7 +117,7 @@
 
     /* pipeline characteristics */
     kParamIndexMediaType,
-    kParamIndexDelayRequest,
+    __kParamIndexRESERVED_0,
     kParamIndexDelay,
     kParamIndexMaxReferenceAge,
     kParamIndexMaxReferenceCount,
@@ -151,6 +151,9 @@
     /* protected content */
     kParamIndexSecureMode,
 
+    // deprecated
+    kParamIndexDelayRequest = kParamIndexDelay | C2Param::CoreIndex::IS_REQUEST_FLAG,
+
     /* ------------------------------------ (trans/en)coders ------------------------------------ */
 
     kParamIndexBitrate = C2_PARAM_INDEX_CODER_PARAM_START,
@@ -779,22 +782,26 @@
  * outstanding input frames queued to the component, it shall produce output.
  */
 
-typedef C2PortParam<C2Tuning, C2Uint32Value, kParamIndexDelayRequest> C2PortRequestedDelayTuning;
-constexpr char C2_PARAMKEY_INPUT_DELAY_REQUEST[] = "input.delay.requested";
-constexpr char C2_PARAMKEY_OUTPUT_DELAY_REQUEST[] = "output.delay.requested";
+typedef C2PortParam<C2Tuning, C2Uint32Value, kParamIndexDelay | C2Param::CoreIndex::IS_REQUEST_FLAG>
+        C2PortRequestedDelayTuning;
+constexpr char C2_PARAMKEY_INPUT_DELAY_REQUEST[] = "input.delay"; // deprecated
+constexpr char C2_PARAMKEY_OUTPUT_DELAY_REQUEST[] = "output.delay"; // deprecated
 
-typedef C2GlobalParam<C2Tuning, C2Uint32Value, kParamIndexDelayRequest>
+typedef C2GlobalParam<C2Tuning, C2Uint32Value,
+                kParamIndexDelay | C2Param::CoreIndex::IS_REQUEST_FLAG>
         C2RequestedPipelineDelayTuning;
-constexpr char C2_PARAMKEY_PIPELINE_DELAY_REQUEST[] = "pipeline-delay.requested";
+constexpr char C2_PARAMKEY_PIPELINE_DELAY_REQUEST[] = "algo.delay"; // deprecated
 
 // read-only
-typedef C2PortParam<C2Tuning, C2Uint32Value, kParamIndexDelay> C2PortActualDelayTuning;
-constexpr char C2_PARAMKEY_INPUT_DELAY[] = "input.delay.actual";
-constexpr char C2_PARAMKEY_OUTPUT_DELAY[] = "output.delay.actual";
+typedef C2PortParam<C2Tuning, C2Uint32Value, kParamIndexDelay> C2PortDelayTuning;
+typedef C2PortDelayTuning C2PortActualDelayTuning; // deprecated
+constexpr char C2_PARAMKEY_INPUT_DELAY[] = "input.delay";
+constexpr char C2_PARAMKEY_OUTPUT_DELAY[] = "output.delay";
 
 // read-only
-typedef C2GlobalParam<C2Tuning, C2Uint32Value, kParamIndexDelay> C2ActualPipelineDelayTuning;
-constexpr char C2_PARAMKEY_PIPELINE_DELAY[] = "algo.delay.actual";
+typedef C2GlobalParam<C2Tuning, C2Uint32Value, kParamIndexDelay> C2PipelineDelayTuning;
+typedef C2PipelineDelayTuning C2ActualPipelineDelayTuning; // deprecated
+constexpr char C2_PARAMKEY_PIPELINE_DELAY[] = "algo.delay";
 
 /**
  * Reference characteristics.
diff --git a/media/codec2/core/include/C2Param.h b/media/codec2/core/include/C2Param.h
index d264bf3..cc8c17a 100644
--- a/media/codec2/core/include/C2Param.h
+++ b/media/codec2/core/include/C2Param.h
@@ -158,7 +158,8 @@
     struct CoreIndex {
     //public:
         enum : uint32_t {
-            IS_FLEX_FLAG = 0x00010000,
+            IS_FLEX_FLAG    = 0x00010000,
+            IS_REQUEST_FLAG = 0x00020000,
         };
 
     protected:
@@ -175,9 +176,9 @@
             DIR_INPUT      = 0x00000000,
             DIR_OUTPUT     = 0x10000000,
 
-            IS_STREAM_FLAG  = 0x02000000,
-            STREAM_ID_MASK  = 0x01FE0000,
-            STREAM_ID_SHIFT = 17,
+            IS_STREAM_FLAG  = 0x00100000,
+            STREAM_ID_MASK  = 0x03E00000,
+            STREAM_ID_SHIFT = 21,
             MAX_STREAM_ID   = STREAM_ID_MASK >> STREAM_ID_SHIFT,
             STREAM_MASK     = IS_STREAM_FLAG | STREAM_ID_MASK,
 
@@ -360,6 +361,10 @@
             mIndex = (mIndex & ~(DIR_MASK | IS_STREAM_FLAG)) | DIR_GLOBAL;
         }
 
+        inline void convertToRequest() {
+            mIndex = mIndex | IS_REQUEST_FLAG;
+        }
+
         /**
          * Sets the stream index.
          * \return true on success, false if could not set index (e.g. not a stream param).
@@ -476,6 +481,15 @@
         return copy;
     }
 
+    /// Returns managed clone of |orig| as a stream parameter at heap.
+    inline static std::unique_ptr<C2Param> CopyAsRequest(const C2Param &orig) {
+        std::unique_ptr<C2Param> copy = Copy(orig);
+        if (copy) {
+            copy->_mIndex.convertToRequest();
+        }
+        return copy;
+    }
+
 #if 0
     template<typename P, class=decltype(C2Param(P()))>
     P *As() { return P::From(this); }
diff --git a/media/codec2/sfplugin/ReflectedParamUpdater.cpp b/media/codec2/sfplugin/ReflectedParamUpdater.cpp
index 880d4a5..55b0ec9 100644
--- a/media/codec2/sfplugin/ReflectedParamUpdater.cpp
+++ b/media/codec2/sfplugin/ReflectedParamUpdater.cpp
@@ -205,6 +205,13 @@
         const std::shared_ptr<C2ParamReflector> &reflector, bool markVendor) {
     C2String paramName = desc->name();
 
+    // Do not reflect requested parameters
+    // TODO: split these once aliases are introduced into '.actual' and '.requested' and alias
+    // the name to '.actual'.
+    if (desc->index() & C2Param::CoreIndex::IS_REQUEST_FLAG) {
+        return;
+    }
+
     // prefix vendor parameters
     if (desc->index().isVendor() && markVendor) {
         paramName = "vendor." + paramName;
diff --git a/media/codec2/vndk/util/C2InterfaceHelper.cpp b/media/codec2/vndk/util/C2InterfaceHelper.cpp
index e447fbe..3bd709c 100644
--- a/media/codec2/vndk/util/C2InterfaceHelper.cpp
+++ b/media/codec2/vndk/util/C2InterfaceHelper.cpp
@@ -609,6 +609,9 @@
     // { depIx, paramIx } may be a suitable key
     std::map<size_t, std::pair<C2Param::Index, bool>> dependencies;
 
+    std::vector<std::unique_ptr<C2Param>> paramRequests;
+    std::vector<C2Param*> lateReadParams;
+
     // we cannot determine the last valid parameter, so add an extra
     // loop iteration after the last parameter
     for (size_t p_ix = 0; p_ix <= params.size(); ++p_ix) {
@@ -625,7 +628,27 @@
             }
 
             paramIx = p->index();
-            paramDepIx = getDependencyIndex_l(paramIx);
+
+            // convert parameter to request in case this is a split parameter
+            C2Param::Index requestParamIx = paramIx | C2Param::CoreIndex::IS_REQUEST_FLAG;
+
+            // setting a request directly is handled as normal
+            if (paramIx != requestParamIx) {
+                paramDepIx = getDependencyIndex_l(requestParamIx);
+                if (paramDepIx == SIZE_MAX) {
+                    // not a split parameter, handle it normally
+                    paramDepIx = getDependencyIndex_l(paramIx);
+                } else {
+                    // split parameter - replace with setting for the request - and queue to
+                    // read back actual value
+                    // TODO: read late params at the right time
+                    lateReadParams.emplace_back(p);
+                    std::unique_ptr<C2Param> request(C2Param::CopyAsRequest(*p));
+                    p = request.get();
+                    paramRequests.emplace_back(std::move(request));
+                }
+            }
+
             if (paramDepIx == SIZE_MAX) {
                 // unsupported parameter
                 paramNotFound = true;
@@ -715,6 +738,16 @@
         }
     }
 
+    // get late read parameters
+    for (C2Param *p : lateReadParams) {
+        std::shared_ptr<C2Param> value = _mFactory->getParamValue(p->index());
+        if (value) {
+            p->updateFrom(*value);
+        } else {
+            p->invalidate();
+        }
+    }
+
     return (paramCorrupted ? C2_CORRUPTED :
             paramBlocking ? C2_BLOCKING :
             paramTimedOut ? C2_TIMED_OUT :