Codec2: clean up base vs. baseIndex confusion

- rename baseIndex to coreIndex
- define ParamIndex
- change names of macros defining base structs from '_NO_BASE' to
  'BASE'
- fix creating flexible params from base structs and add unit tests
  to verify

Bug: 64121714
Test: unittest
Change-Id: I95c237a4328e5313604588b695e2fd117001dda3
diff --git a/media/libstagefright/codec2/include/C2Config.h b/media/libstagefright/codec2/include/C2Config.h
index b1ac8bc..d4294c4 100644
--- a/media/libstagefright/codec2/include/C2Config.h
+++ b/media/libstagefright/codec2/include/C2Config.h
@@ -41,7 +41,7 @@
 enum name : type { __VA_ARGS__ }; \
 DEFINE_C2_ENUM_VALUE_CUSTOM_HELPER(name, type, names, __VA_ARGS__)
 
-enum C2ParamIndexKind : uint32_t {
+enum C2ParamIndexKind : C2Param::ParamIndex {
     /// domain
     kParamIndexDomain,
 
@@ -231,13 +231,10 @@
     int32_t mWidth;     ///< video width
     int32_t mHeight;    ///< video height
 
-    DEFINE_C2STRUCT_NO_BASE(VideoSize)
-} C2_PACK;
-
-DESCRIBE_C2STRUCT(VideoSize, {
+    DEFINE_AND_DESCRIBE_BASE_C2STRUCT(VideoSize)
     C2FIELD(mWidth, "width")
     C2FIELD(mHeight, "height")
-})
+};
 
 // video size for video decoder [OUT]
 typedef C2StreamParam<C2Info, C2VideoSizeStruct, kParamIndexVideoSize> C2VideoSizeStreamInfo;
diff --git a/media/libstagefright/codec2/include/C2Param.h b/media/libstagefright/codec2/include/C2Param.h
index 753c665..02403c5 100644
--- a/media/libstagefright/codec2/include/C2Param.h
+++ b/media/libstagefright/codec2/include/C2Param.h
@@ -71,7 +71,7 @@
  *     an error for the specific setting, but should continue to apply other settings.
  *     TODO: this currently may result in unintended results.
  *
- * **NOTE:** unlike OMX, params are not versioned. Instead, a new struct with new base index
+ * **NOTE:** unlike OMX, params are not versioned. Instead, a new struct with new param index
  * SHALL be added as new versions are required.
  *
  * The proper subtype (Setting, Info or Param) is incorporated into the class type. Define structs
@@ -104,7 +104,7 @@
     // layout:
     //
     //      +------+-----+---+------+--------+----|------+--------------+
-    //      | kind | dir | - |stream|streamID|flex|vendor|  base index  |
+    //      | kind | dir | - |stream|streamID|flex|vendor|  core index  |
     //      +------+-----+---+------+--------+----+------+--------------+
     //  bit: 31..30 29.28       25   24 .. 17  16    15   14    ..     0
     //
@@ -121,6 +121,19 @@
     };
 
     /**
+     * Parameter index is associated with each parameter. It is used to identify and distinguish
+     * global parameters, and also parameters on a given port or stream. They must be unique for the
+     * set of global parameters, as well as for the set of parameters on each port or each stream,
+     * but the same parameter index can be used for parameters on different streams or ports, as
+     * well as for global parameters and port/stream parameters.
+     *
+     * Parameter index is also used to describe the layout of the parameter structures. Multiple
+     * parameter types can share the same layout, but the layout for all parameters with the same
+     * parameter index across all components must be identical.
+     */
+    typedef uint32_t ParamIndex;
+
+    /**
      * base index (including the vendor extension bit) is a global index for
      * C2 parameter structs. (e.g. the same indices cannot be reused for different
      * structs for different components).
@@ -149,7 +162,7 @@
             kFlexibleFlag  = 0x00010000,
             kVendorFlag    = 0x00008000,
             kParamMask     = 0x0000FFFF,
-            kBaseMask      = kParamMask | kFlexibleFlag,
+            kCoreMask      = kParamMask | kFlexibleFlag,
         };
 
     public:
@@ -170,11 +183,12 @@
         /// returns true iff this is a flexible parameter (with variable size)
         inline bool isFlexible() const { return mIndex & kFlexibleFlag; }
 
-        /// returns the base type: the index for the underlying struct
-        inline unsigned int baseIndex() const { return mIndex & kBaseMask; }
+        /// returns the core parameter type (index) for the underlying struct.
+        /// This is the combination of the parameter index and the flexible flag.
+        inline unsigned int coreIndex() const { return mIndex & kCoreMask; }
 
-        /// returns the param index for the underlying struct
-        inline unsigned int paramIndex() const { return mIndex & kParamMask; }
+        /// returns the parameter index for the underlying struct
+        inline ParamIndex paramIndex() const { return mIndex & kParamMask; }
 
         DEFINE_FIELD_BASED_COMPARISON_OPERATORS(BaseIndex, mIndex)
 
@@ -450,8 +464,8 @@
     friend struct _C2ParamInspector; // for testing
 
     /// returns the base type: the index for the underlying struct (for testing
-    /// as this can be gotten by the baseIndex enum)
-    inline uint32_t _baseIndex() const { return _mIndex.baseIndex(); }
+    /// as this can be gotten by the coreIndex enum)
+    inline uint32_t _coreIndex() const { return _mIndex.coreIndex(); }
 
     /// returns true iff |o| has the same size and index as this. This performs the
     /// basic check for equality.
@@ -711,7 +725,7 @@
                         ///< however, bytes cannot be individually addressed by clients.
 
         // complex types
-        STRUCT_FLAG = 0x10000, ///< structs. Marked with this flag in addition to their baseIndex.
+        STRUCT_FLAG = 0x10000, ///< structs. Marked with this flag in addition to their coreIndex.
     };
 
     typedef std::pair<C2String, C2Value::Primitive> named_value_type;
@@ -802,12 +816,12 @@
         return getType(&underlying);
     }
 
-    // verify C2Struct by having a fieldList and a baseIndex.
+    // verify C2Struct by having a fieldList and a coreIndex.
     template<typename T,
-             class=decltype(T::baseIndex + 1), class=decltype(T::fieldList)>
+             class=decltype(T::coreIndex + 1), class=decltype(T::fieldList)>
     inline static Type getType(T*) {
         static_assert(!std::is_base_of<C2Param, T>::value, "cannot use C2Params as fields");
-        return (Type)(T::baseIndex | STRUCT_FLAG);
+        return (Type)(T::coreIndex | STRUCT_FLAG);
     }
 };
 
@@ -832,7 +846,7 @@
 struct C2StructDescriptor {
 public:
     /// Returns the parameter type
-    inline C2Param::BaseIndex baseIndex() const { return _mType.baseIndex(); }
+    inline C2Param::BaseIndex coreIndex() const { return _mType.coreIndex(); }
 
     // Returns the number of fields in this param (not counting any recursive fields).
     // Must be at least 1 for valid params.
@@ -849,7 +863,7 @@
 
     template<typename T>
     inline C2StructDescriptor(T*)
-        : C2StructDescriptor(T::baseIndex, T::fieldList) { }
+        : C2StructDescriptor(T::coreIndex, T::fieldList) { }
 
     inline C2StructDescriptor(
             C2Param::BaseIndex type,
@@ -914,24 +928,30 @@
 };
 
 /// \ingroup internal
-/// Define a structure without baseIndex.
-#define DEFINE_C2STRUCT_NO_BASE(name) \
+/// Define a structure without coreIndex.
+#define DEFINE_BASE_C2STRUCT(name) \
 public: \
     typedef C2##name##Struct _type; /**< type name shorthand */ \
     const static std::initializer_list<const C2FieldDescriptor> fieldList; /**< structure fields */
 
-/// Define a structure with matching baseIndex.
+/// Define a structure with matching coreIndex.
 #define DEFINE_C2STRUCT(name) \
 public: \
-    enum : uint32_t { baseIndex = kParamIndex##name }; \
-    DEFINE_C2STRUCT_NO_BASE(name)
+    enum : uint32_t { coreIndex = kParamIndex##name }; \
+    DEFINE_BASE_C2STRUCT(name)
 
-/// Define a flexible structure with matching baseIndex.
+/// Define a flexible structure without coreIndex.
+#define DEFINE_BASE_FLEX_C2STRUCT(name, flexMember) \
+public: \
+    FLEX(C2##name##Struct, flexMember) \
+    DEFINE_BASE_C2STRUCT(name)
+
+/// Define a flexible structure with matching coreIndex.
 #define DEFINE_FLEX_C2STRUCT(name, flexMember) \
 public: \
     FLEX(C2##name##Struct, flexMember) \
-    enum : uint32_t { baseIndex = kParamIndex##name | C2Param::BaseIndex::_kFlexibleFlag }; \
-    DEFINE_C2STRUCT_NO_BASE(name)
+    enum : uint32_t { coreIndex = kParamIndex##name | C2Param::BaseIndex::_kFlexibleFlag }; \
+    DEFINE_BASE_C2STRUCT(name)
 
 #ifdef __C2_GENERATE_GLOBAL_VARS__
 /// \ingroup internal
@@ -1037,17 +1057,30 @@
 #define C2SOLE_FIELD(member, name) \
   C2FieldDescriptor(&_type::member, name, 0)
 
-/// Define a structure with matching baseIndex and start describing its fields.
+/// Define a structure with matching coreIndex and start describing its fields.
 /// This must be at the end of the structure definition.
 #define DEFINE_AND_DESCRIBE_C2STRUCT(name) \
     DEFINE_C2STRUCT(name) } C2_PACK; \
     const std::initializer_list<const C2FieldDescriptor> C2##name##Struct::fieldList = {
 
-/// Define a flexible structure with matching baseIndex and start describing its fields.
+/// Define a flexible structure with matching coreIndex and start describing its fields.
 /// This must be at the end of the structure definition.
 #define DEFINE_AND_DESCRIBE_FLEX_C2STRUCT(name, flexMember) \
     DEFINE_FLEX_C2STRUCT(name, flexMember) } C2_PACK; \
     const std::initializer_list<const C2FieldDescriptor> C2##name##Struct::fieldList = {
+
+/// Define a base structure (with no coreIndex) and start describing its fields.
+/// This must be at the end of the structure definition.
+#define DEFINE_AND_DESCRIBE_BASE_C2STRUCT(name) \
+    DEFINE_BASE_C2STRUCT(name) } C2_PACK; \
+    const std::initializer_list<const C2FieldDescriptor> C2##name##Struct::fieldList = {
+
+/// Define a flexible base structure (with no coreIndex) and start describing its fields.
+/// This must be at the end of the structure definition.
+#define DEFINE_AND_DESCRIBE_BASE_FLEX_C2STRUCT(name, flexMember) \
+    DEFINE_BASE_FLEX_C2STRUCT(name, flexMember) } C2_PACK; \
+    const std::initializer_list<const C2FieldDescriptor> C2##name##Struct::fieldList = {
+
 #else
 /// \if 0
 /* Alternate declaration of field definitions in case no field list is to be generated.
@@ -1056,14 +1089,22 @@
 #define C2FIELD(member, name)
 /// \deprecated
 #define C2SOLE_FIELD(member, name)
-/// Define a structure with matching baseIndex and start describing its fields.
+/// Define a structure with matching coreIndex and start describing its fields.
 /// This must be at the end of the structure definition.
 #define DEFINE_AND_DESCRIBE_C2STRUCT(name) \
     DEFINE_C2STRUCT(name) }  C2_PACK; namespace ignored {
-/// Define a flexible structure with matching baseIndex and start describing its fields.
+/// Define a flexible structure with matching coreIndex and start describing its fields.
 /// This must be at the end of the structure definition.
 #define DEFINE_AND_DESCRIBE_FLEX_C2STRUCT(name, flexMember) \
     DEFINE_FLEX_C2STRUCT(name, flexMember) } C2_PACK; namespace ignored {
+/// Define a base structure (with no coreIndex) and start describing its fields.
+/// This must be at the end of the structure definition.
+#define DEFINE_AND_DESCRIBE_BASE_C2STRUCT(name) \
+    DEFINE_BASE_C2STRUCT(name) } C2_PACK; namespace ignored {
+/// Define a flexible base structure (with no coreIndex) and start describing its fields.
+/// This must be at the end of the structure definition.
+#define DEFINE_AND_DESCRIBE_BASE_FLEX_C2STRUCT(name, flexMember) \
+    DEFINE_BASE_FLEX_C2STRUCT(name, flexMember) } C2_PACK; namespace ignored {
 /// \endif
 #endif
 
@@ -1080,7 +1121,8 @@
     /**
      *  Describes a parameter structure.
      *
-     *  \param[in] paramIndex the base index of the parameter structure
+     *  \param[in] coreIndex the base index of the parameter structure containing at least the
+     *  core index
      *
      *  \return the description of the parameter structure
      *  \retval nullptr if the parameter is not supported by this reflector
@@ -1093,7 +1135,7 @@
      *  descriptions, but we want to conserve memory if client only wants the description
      *  of a few indices.
      */
-    virtual std::unique_ptr<C2StructDescriptor> describe(C2Param::BaseIndex paramIndex) = 0;
+    virtual std::unique_ptr<C2StructDescriptor> describe(C2Param::BaseIndex coreIndex) = 0;
 
 protected:
     virtual ~C2ParamReflector() = default;
diff --git a/media/libstagefright/codec2/include/C2ParamDef.h b/media/libstagefright/codec2/include/C2ParamDef.h
index f369617..8656629 100644
--- a/media/libstagefright/codec2/include/C2ParamDef.h
+++ b/media/libstagefright/codec2/include/C2ParamDef.h
@@ -59,35 +59,35 @@
                         || decltype(_C2Comparable_impl::__testNE<S>(0))::value> {
 };
 
-///  Helper class that checks if a type has a baseIndex constant.
-struct C2_HIDE _C2BaseIndexHelper_impl
+///  Helper class that checks if a type has a coreIndex constant.
+struct C2_HIDE _C2CoreIndexHelper_impl
 {
-    template<typename S, int=S::baseIndex>
-    static std::true_type __testBaseIndex(int);
+    template<typename S, int=S::coreIndex>
+    static std::true_type __testCoreIndex(int);
     template<typename>
-    static std::false_type __testBaseIndex(...);
+    static std::false_type __testCoreIndex(...);
 };
 
-/// Helper template that verifies a type's baseIndex and creates it if the type does not have one.
-template<typename S, int BaseIndex,
-        bool HasBase=decltype(_C2BaseIndexHelper_impl::__testBaseIndex<S>(0))::value>
-struct C2_HIDE C2BaseIndexOverride {
-    // TODO: what if we allow structs without baseIndex?
-    static_assert(BaseIndex == S::baseIndex, "baseIndex differs from structure");
+/// Helper template that verifies a type's coreIndex and creates it if the type does not have one.
+template<typename S, int CoreIndex,
+        bool HasBase=decltype(_C2CoreIndexHelper_impl::__testCoreIndex<S>(0))::value>
+struct C2_HIDE C2CoreIndexOverride {
+    // TODO: what if we allow structs without coreIndex?
+    static_assert(CoreIndex == S::coreIndex, "coreIndex differs from structure");
 };
 
-/// Specialization for types without a baseIndex.
-template<typename S, int BaseIndex>
-struct C2_HIDE C2BaseIndexOverride<S, BaseIndex, false> {
+/// Specialization for types without a coreIndex.
+template<typename S, int CoreIndex>
+struct C2_HIDE C2CoreIndexOverride<S, CoreIndex, false> {
 public:
     enum : uint32_t {
-        baseIndex = BaseIndex, ///< baseIndex override.
+        coreIndex = CoreIndex, ///< coreIndex override.
     };
 };
 
-/// Helper template that adds a baseIndex to a type if it does not have one.
-template<typename S, int BaseIndex>
-struct C2_HIDE C2AddBaseIndex : public S, public C2BaseIndexOverride<S, BaseIndex> {};
+/// Helper template that adds a coreIndex to a type if it does not have one.
+template<typename S, int CoreIndex>
+struct C2_HIDE C2AddCoreIndex : public S, public C2CoreIndexOverride<S, CoreIndex> {};
 
 /**
  * \brief Helper class to check struct requirements for parameters.
@@ -96,7 +96,7 @@
  *  - verify default constructor, no virtual methods, and no equality operators.
  *  - expose typeIndex, and non-flex flexSize.
  */
-template<typename S, int BaseIndex, unsigned TypeIndex>
+template<typename S, int CoreIndex, unsigned TypeIndex>
 struct C2_HIDE C2StructCheck {
     static_assert(
             std::is_default_constructible<S>::value, "C2 structure must have default constructor");
@@ -105,7 +105,7 @@
 
 public:
     enum : uint32_t {
-        typeIndex = BaseIndex | TypeIndex
+        typeIndex = CoreIndex | TypeIndex
     };
 
 protected:
@@ -161,17 +161,19 @@
  * \brief Helper class to check flexible struct requirements and add common operations.
  *
  * Features:
- *  - expose baseIndex and fieldList (this is normally inherited from the struct, but flexible
+ *  - expose coreIndex and fieldList (this is normally inherited from the struct, but flexible
  *    structs cannot be base classes and thus inherited from)
  *  - disable copy assignment and construction (TODO: this is already done in the FLEX macro for the
  *    flexible struct, so may not be needed here)
  */
-template<typename S, int BaseIndex, unsigned TypeIndex>
-struct C2_HIDE C2FlexStructCheck : public C2StructCheck<S, BaseIndex, TypeIndex> {
+template<typename S, int ParamIndex, unsigned TypeIndex>
+struct C2_HIDE C2FlexStructCheck :
+// add flexible flag as C2StructCheck defines typeIndex
+        public C2StructCheck<S, ParamIndex | C2Param::BaseIndex::_kFlexibleFlag, TypeIndex> {
 public:
     enum : uint32_t {
         /// \hideinitializer
-        baseIndex = BaseIndex | C2Param::BaseIndex::_kFlexibleFlag, ///< flexible struct base-index
+        coreIndex = ParamIndex | C2Param::BaseIndex::_kFlexibleFlag, ///< flexible struct core-index
     };
 
     const static std::initializer_list<const C2FieldDescriptor> fieldList; // TODO assign here
@@ -181,8 +183,8 @@
 
 protected:
     // cannot copy flexible params
-    C2FlexStructCheck(const C2FlexStructCheck<S, BaseIndex, TypeIndex> &) = delete;
-    C2FlexStructCheck& operator= (const C2FlexStructCheck<S, BaseIndex, TypeIndex> &) = delete;
+    C2FlexStructCheck(const C2FlexStructCheck<S, ParamIndex, TypeIndex> &) = delete;
+    C2FlexStructCheck& operator= (const C2FlexStructCheck<S, ParamIndex, TypeIndex> &) = delete;
 
     // constants used for helper methods
     enum : uint32_t {
@@ -215,8 +217,9 @@
 
 // TODO: this probably does not work.
 /// Expose fieldList from subClass;
-template<typename S, int BaseIndex, unsigned TypeIndex>
-const std::initializer_list<const C2FieldDescriptor> C2FlexStructCheck<S, BaseIndex, TypeIndex>::fieldList = S::fieldList;
+template<typename S, int ParamIndex, unsigned TypeIndex>
+const std::initializer_list<const C2FieldDescriptor>
+C2FlexStructCheck<S, ParamIndex, TypeIndex>::fieldList = S::fieldList;
 
 /// Define From() cast operators for params.
 #define DEFINE_CAST_OPERATORS(_type) \
@@ -299,7 +302,7 @@
  * Global-parameter template.
  *
  * Base template to define a global setting/tuning or info based on a structure and
- * an optional BaseIndex. Global parameters are not tied to a port (input or output).
+ * an optional ParamIndex. Global parameters are not tied to a port (input or output).
  *
  * Parameters wrap structures by prepending a (parameter) header. The fields of the wrapped
  * structure can be accessed directly, and constructors and potential public methods are also
@@ -307,13 +310,14 @@
  *
  * \tparam T param type C2Setting, C2Tuning or C2Info
  * \tparam S wrapped structure
- * \tparam BaseIndex optional base-index override. Must be specified for common/reused structures.
+ * \tparam ParamIndex optional parameter index override. Must be specified for base/reused
+ * structures.
  */
-template<typename T, typename S, int BaseIndex=S::baseIndex, class Flex=void>
-struct C2_HIDE C2GlobalParam : public T, public S, public C2BaseIndexOverride<S, BaseIndex>,
-        public C2StructCheck<S, BaseIndex, T::indexFlags | T::Type::kDirGlobal> {
+template<typename T, typename S, int ParamIndex=S::coreIndex, class Flex=void>
+struct C2_HIDE C2GlobalParam : public T, public S, public C2CoreIndexOverride<S, ParamIndex>,
+        public C2StructCheck<S, ParamIndex, T::indexFlags | T::Type::kDirGlobal> {
 private:
-    typedef C2GlobalParam<T, S, BaseIndex> _type;
+    typedef C2GlobalParam<T, S, ParamIndex> _type;
 
 public:
     /// Wrapper around base structure's constructor.
@@ -327,21 +331,22 @@
  * Global-parameter template for flexible structures.
  *
  * Base template to define a global setting/tuning or info based on a flexible structure and
- * an optional BaseIndex. Global parameters are not tied to a port (input or output).
+ * an optional ParamIndex. Global parameters are not tied to a port (input or output).
  *
  * \tparam T param type C2Setting, C2Tuning or C2Info
  * \tparam S wrapped flexible structure
- * \tparam BaseIndex optional base-index override. Must be specified for common/reused structures.
+ * \tparam ParamIndex optional parameter index override. Must be specified for base/reused
+ *         structures.
  *
  * Parameters wrap structures by prepending a (parameter) header. The fields and methods of flexible
  * structures can be accessed via the m member variable; however, the constructors of the structure
  * are wrapped directly. (This is because flexible types cannot be subclassed.)
  */
-template<typename T, typename S, int BaseIndex>
-struct C2_HIDE C2GlobalParam<T, S, BaseIndex, IF_FLEXIBLE(S)>
-    : public T, public C2FlexStructCheck<S, BaseIndex, T::indexFlags | T::Type::kDirGlobal> {
+template<typename T, typename S, int ParamIndex>
+struct C2_HIDE C2GlobalParam<T, S, ParamIndex, IF_FLEXIBLE(S)>
+    : public T, public C2FlexStructCheck<S, ParamIndex, T::indexFlags | T::Type::kDirGlobal> {
 private:
-    typedef C2GlobalParam<T, S, BaseIndex> _type;
+    typedef C2GlobalParam<T, S, ParamIndex> _type;
 
     /// Wrapper around base structure's constructor.
     template<typename ...Args>
@@ -359,12 +364,13 @@
  * Port-parameter template.
  *
  * Base template to define a port setting/tuning or info based on a structure and
- * an optional BaseIndex. Port parameters are tied to a port (input or output), but not to a
+ * an optional ParamIndex. Port parameters are tied to a port (input or output), but not to a
  * specific stream.
  *
  * \tparam T param type C2Setting, C2Tuning or C2Info
  * \tparam S wrapped structure
- * \tparam BaseIndex optional base-index override. Must be specified for common/reused structures.
+ * \tparam ParamIndex optional parameter index override. Must be specified for base/reused
+ *         structures.
  *
  * Parameters wrap structures by prepending a (parameter) header. The fields of the wrapped
  * structure can be accessed directly, and constructors and potential public methods are also
@@ -373,11 +379,11 @@
  * There are 3 flavors of port parameters: unspecified, input and output. Parameters with
  * unspecified port expose a setPort method, and add an initial port parameter to the constructor.
  */
-template<typename T, typename S, int BaseIndex=S::baseIndex, class Flex=void>
-struct C2_HIDE C2PortParam : public T, public S, public C2BaseIndexOverride<S, BaseIndex>,
-        private C2StructCheck<S, BaseIndex, T::indexFlags | T::Index::kDirUndefined> {
+template<typename T, typename S, int ParamIndex=S::coreIndex, class Flex=void>
+struct C2_HIDE C2PortParam : public T, public S, public C2CoreIndexOverride<S, ParamIndex>,
+        private C2StructCheck<S, ParamIndex, T::indexFlags | T::Index::kDirUndefined> {
 private:
-    typedef C2PortParam<T, S, BaseIndex> _type;
+    typedef C2PortParam<T, S, ParamIndex> _type;
 
 public:
     /// Default constructor.
@@ -392,8 +398,8 @@
     DEFINE_CAST_OPERATORS(_type)
 
     /// Specialization for an input port parameter.
-    struct input : public T, public S, public C2BaseIndexOverride<S, BaseIndex>,
-            public C2StructCheck<S, BaseIndex, T::indexFlags | T::Index::kDirInput> {
+    struct input : public T, public S, public C2CoreIndexOverride<S, ParamIndex>,
+            public C2StructCheck<S, ParamIndex, T::indexFlags | T::Index::kDirInput> {
         /// Wrapper around base structure's constructor.
         template<typename ...Args>
         inline input(const Args(&... args)) : T(sizeof(_type), input::typeIndex), S(args...) { }
@@ -403,8 +409,8 @@
     };
 
     /// Specialization for an output port parameter.
-    struct output : public T, public S, public C2BaseIndexOverride<S, BaseIndex>,
-            public C2StructCheck<S, BaseIndex, T::indexFlags | T::Index::kDirOutput> {
+    struct output : public T, public S, public C2CoreIndexOverride<S, ParamIndex>,
+            public C2StructCheck<S, ParamIndex, T::indexFlags | T::Index::kDirOutput> {
         /// Wrapper around base structure's constructor.
         template<typename ...Args>
         inline output(const Args(&... args)) : T(sizeof(_type), output::typeIndex), S(args...) { }
@@ -417,12 +423,13 @@
  * Port-parameter template for flexible structures.
  *
  * Base template to define a port setting/tuning or info based on a flexible structure and
- * an optional BaseIndex. Port parameters are tied to a port (input or output), but not to a
+ * an optional ParamIndex. Port parameters are tied to a port (input or output), but not to a
  * specific stream.
  *
  * \tparam T param type C2Setting, C2Tuning or C2Info
  * \tparam S wrapped flexible structure
- * \tparam BaseIndex optional base-index override. Must be specified for common/reused structures.
+ * \tparam ParamIndex optional parameter index override. Must be specified for base/reused
+ *         structures.
  *
  * Parameters wrap structures by prepending a (parameter) header. The fields and methods of flexible
  * structures can be accessed via the m member variable; however, the constructors of the structure
@@ -431,11 +438,11 @@
  * There are 3 flavors of port parameters: unspecified, input and output. Parameters with
  * unspecified port expose a setPort method, and add an initial port parameter to the constructor.
  */
-template<typename T, typename S, int BaseIndex>
-struct C2_HIDE C2PortParam<T, S, BaseIndex, IF_FLEXIBLE(S)>
-    : public T, public C2FlexStructCheck<S, BaseIndex, T::indexFlags | T::Type::kDirUndefined> {
+template<typename T, typename S, int ParamIndex>
+struct C2_HIDE C2PortParam<T, S, ParamIndex, IF_FLEXIBLE(S)>
+    : public T, public C2FlexStructCheck<S, ParamIndex, T::indexFlags | T::Type::kDirUndefined> {
 private:
-    typedef C2PortParam<T, S, BaseIndex> _type;
+    typedef C2PortParam<T, S, ParamIndex> _type;
 
     /// Default constructor for basic allocation: new(flexCount) P.
     inline C2PortParam(size_t flexCount) : T(_type::calcSize(flexCount), _type::typeIndex) { }
@@ -455,8 +462,8 @@
     DEFINE_CAST_OPERATORS(_type)
 
     /// Specialization for an input port parameter.
-    struct input : public T, public C2BaseIndexOverride<S, BaseIndex>,
-            public C2FlexStructCheck<S, BaseIndex, T::indexFlags | T::Index::kDirInput> {
+    struct input : public T,
+            public C2FlexStructCheck<S, ParamIndex, T::indexFlags | T::Index::kDirInput> {
     private:
         /// Wrapper around base structure's constructor while also specifying port/direction.
         template<typename ...Args>
@@ -471,8 +478,8 @@
     };
 
     /// Specialization for an output port parameter.
-    struct output : public T, public C2BaseIndexOverride<S, BaseIndex>,
-            public C2FlexStructCheck<S, BaseIndex, T::indexFlags | T::Index::kDirOutput> {
+    struct output : public T,
+            public C2FlexStructCheck<S, ParamIndex, T::indexFlags | T::Index::kDirOutput> {
     private:
         /// Wrapper around base structure's constructor while also specifying port/direction.
         template<typename ...Args>
@@ -491,12 +498,13 @@
  * Stream-parameter template.
  *
  * Base template to define a stream setting/tuning or info based on a structure and
- * an optional BaseIndex. Stream parameters are tied to a specific stream on a port (input or
+ * an optional ParamIndex. Stream parameters are tied to a specific stream on a port (input or
  * output).
  *
  * \tparam T param type C2Setting, C2Tuning or C2Info
  * \tparam S wrapped structure
- * \tparam BaseIndex optional base-index override. Must be specified for common/reused structures.
+ * \tparam ParamIndex optional paramter index override. Must be specified for base/reused
+ *         structures.
  *
  * Parameters wrap structures by prepending a (parameter) header. The fields of the wrapped
  * structure can be accessed directly, and constructors and potential public methods are also
@@ -507,12 +515,12 @@
  * parameters with unspecified port expose a setPort method, and add an additional initial port
  * parameter to the constructor.
  */
-template<typename T, typename S, int BaseIndex=S::baseIndex, class Flex=void>
-struct C2_HIDE C2StreamParam : public T, public S, public C2BaseIndexOverride<S, BaseIndex>,
-        private C2StructCheck<S, BaseIndex,
+template<typename T, typename S, int ParamIndex=S::coreIndex, class Flex=void>
+struct C2_HIDE C2StreamParam : public T, public S, public C2CoreIndexOverride<S, ParamIndex>,
+        private C2StructCheck<S, ParamIndex,
                 T::indexFlags | T::Index::kStreamFlag | T::Index::kDirUndefined> {
 private:
-    typedef C2StreamParam<T, S, BaseIndex> _type;
+    typedef C2StreamParam<T, S, ParamIndex> _type;
 
 public:
     /// Default constructor. Port/direction and stream-ID is undefined.
@@ -531,8 +539,8 @@
     DEFINE_CAST_OPERATORS(_type)
 
     /// Specialization for an input stream parameter.
-    struct input : public T, public S, public C2BaseIndexOverride<S, BaseIndex>,
-            public C2StructCheck<S, BaseIndex,
+    struct input : public T, public S, public C2CoreIndexOverride<S, ParamIndex>,
+            public C2StructCheck<S, ParamIndex,
                     T::indexFlags | T::Index::kStreamFlag | T::Type::kDirInput> {
         /// Default constructor. Stream-ID is undefined.
         inline input() : T(sizeof(_type), input::typeIndex) { }
@@ -547,8 +555,8 @@
     };
 
     /// Specialization for an output stream parameter.
-    struct output : public T, public S, public C2BaseIndexOverride<S, BaseIndex>,
-            public C2StructCheck<S, BaseIndex,
+    struct output : public T, public S, public C2CoreIndexOverride<S, ParamIndex>,
+            public C2StructCheck<S, ParamIndex,
                     T::indexFlags | T::Index::kStreamFlag | T::Type::kDirOutput> {
         /// Default constructor. Stream-ID is undefined.
         inline output() : T(sizeof(_type), output::typeIndex) { }
@@ -567,12 +575,13 @@
  * Stream-parameter template for flexible structures.
  *
  * Base template to define a stream setting/tuning or info based on a flexible structure and
- * an optional BaseIndex. Stream parameters are tied to a specific stream on a port (input or
+ * an optional ParamIndex. Stream parameters are tied to a specific stream on a port (input or
  * output).
  *
  * \tparam T param type C2Setting, C2Tuning or C2Info
  * \tparam S wrapped flexible structure
- * \tparam BaseIndex optional base-index override. Must be specified for common/reused structures.
+ * \tparam ParamIndex optional parameter index override. Must be specified for base/reused
+ *         structures.
  *
  * Parameters wrap structures by prepending a (parameter) header. The fields and methods of flexible
  * structures can be accessed via the m member variable; however, the constructors of the structure
@@ -583,13 +592,13 @@
  * parameters with unspecified port expose a setPort method, and add an additional initial port
  * parameter to the constructor.
  */
-template<typename T, typename S, int BaseIndex>
-struct C2_HIDE C2StreamParam<T, S, BaseIndex, IF_FLEXIBLE(S)>
-    : public T, public C2BaseIndexOverride<S, BaseIndex>,
-      private C2FlexStructCheck<S, BaseIndex,
+template<typename T, typename S, int ParamIndex>
+struct C2_HIDE C2StreamParam<T, S, ParamIndex, IF_FLEXIBLE(S)>
+    : public T,
+      public C2FlexStructCheck<S, ParamIndex,
               T::indexFlags | T::Index::kStreamFlag | T::Index::kDirUndefined> {
 private:
-    typedef C2StreamParam<T, S> _type;
+    typedef C2StreamParam<T, S, ParamIndex> _type;
     /// Default constructor. Port/direction and stream-ID is undefined.
     inline C2StreamParam(size_t flexCount) : T(_type::calcSize(flexCount), _type::typeIndex, 0u) { }
     /// Wrapper around base structure's constructor while also specifying port/direction and
@@ -611,8 +620,8 @@
     DEFINE_CAST_OPERATORS(_type)
 
     /// Specialization for an input stream parameter.
-    struct input : public T, public C2BaseIndexOverride<S, BaseIndex>,
-            public C2FlexStructCheck<S, BaseIndex,
+    struct input : public T,
+            public C2FlexStructCheck<S, ParamIndex,
                     T::indexFlags | T::Index::kStreamFlag | T::Type::kDirInput> {
     private:
         /// Default constructor. Stream-ID is undefined.
@@ -633,8 +642,8 @@
     };
 
     /// Specialization for an output stream parameter.
-    struct output : public T, public C2BaseIndexOverride<S, BaseIndex>,
-            public C2FlexStructCheck<S, BaseIndex,
+    struct output : public T,
+            public C2FlexStructCheck<S, ParamIndex,
                     T::indexFlags | T::Index::kStreamFlag | T::Type::kDirOutput> {
     private:
         /// Default constructor. Stream-ID is undefined.
@@ -659,7 +668,7 @@
 
 /**
  * \ingroup internal
- * A structure template encapsulating a single element with default constructors and no base-index.
+ * A structure template encapsulating a single element with default constructors and no core-index.
  */
 template<typename T>
 struct C2SimpleValueStruct {
@@ -668,7 +677,7 @@
     inline C2SimpleValueStruct() = default;
     // Constructor with an initial value.
     inline C2SimpleValueStruct(T value) : mValue(value) {}
-    DEFINE_C2STRUCT_NO_BASE(SimpleValue)
+    DEFINE_BASE_C2STRUCT(SimpleValue)
 };
 
 // TODO: move this and next to some generic place
@@ -757,7 +766,7 @@
 
 /**
  * Specialization for a flexible blob and string arrays. A structure template encapsulating a single
- * flexible array member with default flexible constructors and no base-index. This type cannot be
+ * flexible array member with default flexible constructors and no core-index. This type cannot be
  * constructed on its own as it's size is 0.
  *
  * \internal This is different from C2SimpleArrayStruct<T[]> simply because its member has the name
@@ -770,7 +779,7 @@
     T mValue[];
 
     inline C2SimpleValueStruct() = default;
-    DEFINE_C2STRUCT_NO_BASE(SimpleValue)
+    DEFINE_BASE_C2STRUCT(SimpleValue)
     FLEX(C2SimpleValueStruct, mValue)
 
 private:
@@ -792,7 +801,7 @@
 
 /**
  * A structure template encapsulating a single flexible array element of a specific type (T) with
- * default constructors and no base-index. This type cannot be constructed on its own as it's size
+ * default constructors and no core-index. This type cannot be constructed on its own as it's size
  * is 0. Instead, it is meant to be used as a parameter, e.g.
  *
  *   typedef C2StreamParam<C2Info, C2SimpleArrayStruct<C2MyFancyStruct>,
@@ -806,8 +815,8 @@
     T mValues[]; ///< array member
     /// Default constructor
     inline C2SimpleArrayStruct() = default;
-    DEFINE_C2STRUCT_NO_BASE(SimpleArray)
-    FLEX(C2SimpleArrayStruct, mValues)
+    DEFINE_BASE_FLEX_C2STRUCT(SimpleArray, mValues)
+    //FLEX(C2SimpleArrayStruct, mValues)
 
 private:
     /// Construct from a C2MemoryBlock.
diff --git a/media/libstagefright/codec2/tests/C2Param_test.cpp b/media/libstagefright/codec2/tests/C2Param_test.cpp
index 83f67d5..0e71b2a 100644
--- a/media/libstagefright/codec2/tests/C2Param_test.cpp
+++ b/media/libstagefright/codec2/tests/C2Param_test.cpp
@@ -93,9 +93,9 @@
 struct C2SizeStruct {
     int32_t mNumber;
     int32_t mHeight;
-    enum : uint32_t { baseIndex = kParamIndexSize };                        // <= needed for C2FieldDescriptor
+    enum : uint32_t { coreIndex = kParamIndexSize };                        // <= needed for C2FieldDescriptor
     const static std::initializer_list<const C2FieldDescriptor> fieldList;  // <= needed for C2FieldDescriptor
-    const static FD::Type TYPE = (FD::Type)(baseIndex | FD::STRUCT_FLAG);
+    const static FD::Type TYPE = (FD::Type)(coreIndex | FD::STRUCT_FLAG);
 };
 
 DEFINE_NO_NAMED_VALUES_FOR(C2SizeStruct)
@@ -121,7 +121,7 @@
     bool mYesNo[100];
 
     const static std::initializer_list<const C2FieldDescriptor> fieldList;
-    // enum : uint32_t { baseIndex = kParamIndexTest };
+    // enum : uint32_t { coreIndex = kParamIndexTest };
     // typedef C2TestStruct_A _type;
 } __attribute__((packed));
 
@@ -296,7 +296,7 @@
     int32_t mFlex[];
 
     const static std::initializer_list<const C2FieldDescriptor> fieldList;
-    // enum : uint32_t { baseIndex = kParamIndexTestFlex, flexSize = 4 };
+    // enum : uint32_t { coreIndex = kParamIndexTestFlex, flexSize = 4 };
     // typedef C2TestStruct_FlexS32 _type;
     // typedef int32_t flexType;
 };
@@ -310,7 +310,7 @@
     int32_t mFlex[];
 
     const static std::initializer_list<const C2FieldDescriptor> fieldList;
-    // enum : uint32_t { baseIndex = kParamIndexTestFlexEnd, flexSize = 4 };
+    // enum : uint32_t { coreIndex = kParamIndexTestFlexEnd, flexSize = 4 };
     // typedef C2TestStruct_FlexEnd _type;
     // typedef int32_t flexType;
 };
@@ -365,7 +365,7 @@
     int64_t mFlexSigned64[];
 
     const static std::initializer_list<const C2FieldDescriptor> fieldList;
-    // enum : uint32_t { baseIndex = kParamIndexTestFlexS64, flexSize = 8 };
+    // enum : uint32_t { coreIndex = kParamIndexTestFlexS64, flexSize = 8 };
     // typedef C2TestStruct_FlexS64 _type;
     // typedef int64_t flexType;
 };
@@ -379,7 +379,7 @@
     int64_t mSigned64Flex[];
 
     const static std::initializer_list<const C2FieldDescriptor> fieldList;
-    // enum : uint32_t { baseIndex = C2TestStruct_FlexEndS64, flexSize = 8 };
+    // enum : uint32_t { coreIndex = C2TestStruct_FlexEndS64, flexSize = 8 };
     // typedef C2TestStruct_FlexEndS64 _type;
     // typedef int64_t flexType;
 };
@@ -426,7 +426,7 @@
     C2SizeStruct mFlexSize[];
 
     const static std::initializer_list<const C2FieldDescriptor> fieldList;
-    // enum : uint32_t { baseIndex = kParamIndexTestFlexSize, flexSize = 8 };
+    // enum : uint32_t { coreIndex = kParamIndexTestFlexSize, flexSize = 8 };
     // typedef C2TestStruct_FlexSize _type;
     // typedef C2SizeStruct flexType;
 };
@@ -440,7 +440,7 @@
     C2SizeStruct mSizeFlex[];
 
     const static std::initializer_list<const C2FieldDescriptor> fieldList;
-    // enum : uint32_t { baseIndex = C2TestStruct_FlexEndSize, flexSize = 8 };
+    // enum : uint32_t { coreIndex = C2TestStruct_FlexEndSize, flexSize = 8 };
     // typedef C2TestStruct_FlexEndSize _type;
     // typedef C2SizeStruct flexType;
 };
@@ -471,6 +471,29 @@
     C2FIELD(mFlexSize, "flex")
 }) // ; optional
 
+struct C2TestBaseFlexEndSizeStruct {
+    int32_t mSigned32;
+    C2SizeStruct mFlexSize[];
+    C2TestBaseFlexEndSizeStruct() {}
+
+    DEFINE_BASE_FLEX_C2STRUCT(TestBaseFlexEndSize, mFlexSize)
+} C2_PACK;
+
+DESCRIBE_C2STRUCT(TestBaseFlexEndSize, {
+    C2FIELD(mSigned32, "s32")
+    C2FIELD(mFlexSize, "flex")
+}) // ; optional
+
+struct C2TestBaseFlexEndSize2Struct {
+    int32_t mSigned32;
+    C2SizeStruct mFlexSize[];
+    C2TestBaseFlexEndSize2Struct() {}
+
+    DEFINE_AND_DESCRIBE_BASE_FLEX_C2STRUCT(TestBaseFlexEndSize2, mFlexSize)
+    C2FIELD(mSigned32, "s32")
+    C2FIELD(mFlexSize, "flex")
+};
+
 template<>
 std::vector<std::vector<const C2FieldDescriptor>>
 //std::initializer_list<std::initializer_list<const C2FieldDescriptor>>
@@ -480,6 +503,8 @@
         C2TestStruct_FlexEndSize::fieldList,
         C2TestFlexSizeStruct::fieldList,
         C2TestFlexEndSizeStruct::fieldList,
+        C2TestBaseFlexEndSizeStruct::fieldList,
+        C2TestBaseFlexEndSize2Struct::fieldList,
     };
 }
 
@@ -498,6 +523,9 @@
     EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId(&((C2TestFlexEndSizeStruct*)0)->mSigned32));
     EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId(&((C2TestFlexEndSizeStruct*)0)->mFlexSize));
 
+    EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId(&((C2TestBaseFlexEndSizeStruct*)0)->mSigned32));
+    EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId(&((C2TestBaseFlexEndSizeStruct*)0)->mFlexSize));
+
     // member pointer constructor
     EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::mSigned32));
     EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::mSigned64));
@@ -512,6 +540,9 @@
     EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId((C2TestFlexEndSizeStruct*)0, &C2TestFlexEndSizeStruct::mSigned32));
     EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId((C2TestFlexEndSizeStruct*)0, &C2TestFlexEndSizeStruct::mFlexSize));
 
+    EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId((C2TestBaseFlexEndSizeStruct*)0, &C2TestBaseFlexEndSizeStruct::mSigned32));
+    EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId((C2TestBaseFlexEndSizeStruct*)0, &C2TestBaseFlexEndSizeStruct::mFlexSize));
+
     // member pointer sans type pointer
     EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId(&C2TestStruct_A::mSigned32));
     EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId(&C2TestStruct_A::mSigned64));
@@ -526,8 +557,12 @@
     EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId(&C2TestFlexEndSizeStruct::mSigned32));
     EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId(&C2TestFlexEndSizeStruct::mFlexSize));
 
+    EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId(&C2TestBaseFlexEndSizeStruct::mSigned32));
+    EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId(&C2TestBaseFlexEndSizeStruct::mFlexSize));
+
     typedef C2GlobalParam<C2Info, C2TestAStruct> C2TestAInfo;
     typedef C2GlobalParam<C2Info, C2TestFlexEndSizeStruct> C2TestFlexEndSizeInfo;
+    typedef C2GlobalParam<C2Info, C2TestBaseFlexEndSizeStruct, kParamIndexTestFlexEndSize> C2TestFlexEndSizeInfoFromBase;
 
     // pointer constructor in C2Param
     EXPECT_EQ(_C2FieldId(8, 4), _C2FieldId(&((C2TestAInfo*)0)->mSigned32));
@@ -543,6 +578,9 @@
     EXPECT_EQ(_C2FieldId(8, 4), _C2FieldId(&((C2TestFlexEndSizeInfo*)0)->m.mSigned32));
     EXPECT_EQ(_C2FieldId(12, 8), _C2FieldId(&((C2TestFlexEndSizeInfo*)0)->m.mFlexSize));
 
+    EXPECT_EQ(_C2FieldId(8, 4), _C2FieldId(&((C2TestFlexEndSizeInfoFromBase*)0)->m.mSigned32));
+    EXPECT_EQ(_C2FieldId(12, 8), _C2FieldId(&((C2TestFlexEndSizeInfoFromBase*)0)->m.mFlexSize));
+
     // member pointer in C2Param
     EXPECT_EQ(_C2FieldId(8, 4), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::mSigned32));
     EXPECT_EQ(_C2FieldId(12, 8), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::mSigned64));
@@ -558,6 +596,8 @@
     // EXPECT_EQ(_C2FieldId(8, 4), _C2FieldId(&C2TestFlexEndSizeInfo::m.mSigned32));
     // EXPECT_EQ(_C2FieldId(12, 8), _C2FieldId(&C2TestFlexEndSizeInfo::m.mFlexSize));
 
+    // EXPECT_EQ(_C2FieldId(8, 4), _C2FieldId(&C2TestFlexEndSizeInfoFromBase::m.mSigned32));
+    // EXPECT_EQ(_C2FieldId(12, 8), _C2FieldId(&C2TestFlexEndSizeInfoFromBase::m.mFlexSize));
 
 
 }
@@ -636,6 +676,10 @@
     typedef C2GlobalParam<C2Info, C2TestFlexEndSizeStruct> C2TestFlexEndSizeInfo;
     static_assert(offsetof(C2TestFlexEndSizeInfo, m.mSigned32) == 8, "offset should be 8");
     static_assert(offsetof(C2TestFlexEndSizeInfo, m.mFlexSize) == 12, "offset should be 12");
+
+    typedef C2GlobalParam<C2Info, C2TestBaseFlexEndSizeStruct, kParamIndexTestFlexEndSize> C2TestFlexEndSizeInfoFromBase;
+    static_assert(offsetof(C2TestFlexEndSizeInfoFromBase, m.mSigned32) == 8, "offset should be 8");
+    static_assert(offsetof(C2TestFlexEndSizeInfoFromBase, m.mFlexSize) == 12, "offset should be 12");
 }
 
 /* ===================================== PARAM USAGE TESTS ===================================== */
@@ -649,6 +693,15 @@
     C2FIELD(mNumber, "number")
 };
 
+struct C2NumberBaseStruct {
+    int32_t mNumber;
+    C2NumberBaseStruct() {}
+    C2NumberBaseStruct(int32_t _number) : mNumber(_number) {}
+
+    DEFINE_AND_DESCRIBE_BASE_C2STRUCT(NumberBase)
+    C2FIELD(mNumber, "number")
+};
+
 struct C2NumbersStruct {
     int32_t mNumbers[];
     C2NumbersStruct() {}
@@ -691,7 +744,7 @@
 
 struct C2NumbersStruct {
     int32_t mNumbers[];
-    enum { baseIndex = kParamIndexNumber };
+    enum { coreIndex = kParamIndexNumber };
     const static std::initializer_list<const C2FieldDescriptor> fieldList;
     C2NumbersStruct() {}
 
@@ -725,7 +778,7 @@
 
         C2Param::Index index(paramType);
         switch (paramType) {
-        case C2NumberConfig::baseIndex:
+        case C2NumberConfig::coreIndex:
             return std::unique_ptr<C2ParamDescriptor>(new C2ParamDescriptor{
                 true /* isRequired */,
                 "number",
@@ -774,19 +827,21 @@
 
 struct _C2ParamInspector {
     static void StaticTest();
+    static void StaticFromBaseTest();
     static void StaticFlexTest();
+    static void StaticFlexFromBaseTest();
 };
 
 // TEST_F(_C2ParamInspector, StaticTest) {
 void _C2ParamInspector::StaticTest() {
     typedef C2Param::Index I;
 
-    // C2NumberStruct: baseIndex = kIndex                          (args)
-    static_assert(C2NumberStruct::baseIndex == kParamIndexNumber, "bad index");
+    // C2NumberStruct: coreIndex = kIndex                          (args)
+    static_assert(C2NumberStruct::coreIndex == kParamIndexNumber, "bad index");
     static_assert(sizeof(C2NumberStruct) == 4, "bad size");
 
     // C2NumberTuning:             kIndex | tun | global           (args)
-    static_assert(C2NumberTuning::baseIndex == kParamIndexNumber, "bad index");
+    static_assert(C2NumberTuning::coreIndex == kParamIndexNumber, "bad index");
     static_assert(C2NumberTuning::typeIndex == (kParamIndexNumber | I::kTypeTuning | I::kDirGlobal), "bad index");
     static_assert(sizeof(C2NumberTuning) == 12, "bad size");
 
@@ -798,11 +853,11 @@
     static_assert(sizeof(C2NumberPortTuning) == 12, "bad size");
     // C2NumberPortTuning::input:  kIndex | tun | port | input     (args)
     // C2NumberPortTuning::output: kIndex | tun | port | output    (args)
-    static_assert(C2NumberPortTuning::input::baseIndex ==
+    static_assert(C2NumberPortTuning::input::coreIndex ==
                   kParamIndexNumber, "bad index");
     static_assert(C2NumberPortTuning::input::typeIndex ==
                   (kParamIndexNumber | I::kTypeTuning | I::kDirInput), "bad index");
-    static_assert(C2NumberPortTuning::output::baseIndex ==
+    static_assert(C2NumberPortTuning::output::coreIndex ==
                   kParamIndexNumber, "bad index");
     static_assert(C2NumberPortTuning::output::typeIndex ==
                   (kParamIndexNumber | I::kTypeTuning | I::kDirOutput), "bad index");
@@ -819,11 +874,11 @@
     static_assert(sizeof(C2NumberStreamTuning) == 12u, "bad size");
     // C2NumberStreamTuning::input kIndex | tun | str | input      (int, args)
     // C2NumberStreamTuning::output kIx   | tun | str | output     (int, args)
-    static_assert(C2NumberStreamTuning::input::baseIndex ==
+    static_assert(C2NumberStreamTuning::input::coreIndex ==
                   kParamIndexNumber, "bad index");
     static_assert(C2NumberStreamTuning::input::typeIndex ==
                   (kParamIndexNumber | I::kTypeTuning | I::kDirInput | I::kStreamFlag), "bad index");
-    static_assert(C2NumberStreamTuning::output::baseIndex ==
+    static_assert(C2NumberStreamTuning::output::coreIndex ==
                   kParamIndexNumber, "bad index");
     static_assert(C2NumberStreamTuning::output::typeIndex ==
                   (kParamIndexNumber | I::kTypeTuning | I::kDirOutput | I::kStreamFlag), "bad index");
@@ -837,15 +892,80 @@
     static_assert(offsetof(C2NumberStreamTuning::output, mNumber) == 8, "bad offset");
 }
 
+void _C2ParamInspector::StaticFromBaseTest() {
+    enum { kParamIndexMy = 3102 };
+    typedef C2NumberBaseStruct C2MyStruct;
+    typedef C2GlobalParam<C2Setting, C2MyStruct, kParamIndexMy> C2MySetting;
+    typedef   C2PortParam<C2Setting, C2MyStruct, kParamIndexMy> C2MyPortSetting;
+    typedef C2StreamParam<C2Setting, C2MyStruct, kParamIndexMy> C2MyStreamSetting;
+
+    typedef C2Param::Index I;
+
+    // C2MyStruct has no coreIndex
+    //static_assert(C2MyStruct::coreIndex == kParamIndexMy, "bad index");
+    static_assert(sizeof(C2MyStruct) == 4, "bad size");
+
+    // C2MySetting:             kIndex | tun | global           (args)
+    static_assert(C2MySetting::coreIndex == kParamIndexMy, "bad index");
+    static_assert(C2MySetting::typeIndex == (kParamIndexMy | I::kTypeSetting | I::kDirGlobal), "bad index");
+    static_assert(sizeof(C2MySetting) == 12, "bad size");
+
+    static_assert(offsetof(C2MySetting, _mSize) == 0, "bad size");
+    static_assert(offsetof(C2MySetting, _mIndex) == 4, "bad offset");
+    static_assert(offsetof(C2MySetting, mNumber) == 8, "bad offset");
+
+    // C2MyPortSetting:         kIndex | tun | port             (bool, args)
+    static_assert(sizeof(C2MyPortSetting) == 12, "bad size");
+    // C2MyPortSetting::input:  kIndex | tun | port | input     (args)
+    // C2MyPortSetting::output: kIndex | tun | port | output    (args)
+    static_assert(C2MyPortSetting::input::coreIndex ==
+                  kParamIndexMy, "bad index");
+    static_assert(C2MyPortSetting::input::typeIndex ==
+                  (kParamIndexMy | I::kTypeSetting | I::kDirInput), "bad index");
+    static_assert(C2MyPortSetting::output::coreIndex ==
+                  kParamIndexMy, "bad index");
+    static_assert(C2MyPortSetting::output::typeIndex ==
+                  (kParamIndexMy | I::kTypeSetting | I::kDirOutput), "bad index");
+    static_assert(sizeof(C2MyPortSetting::input) == 12, "bad size");
+    static_assert(sizeof(C2MyPortSetting::output) == 12, "bad size");
+    static_assert(offsetof(C2MyPortSetting::input, _mSize) == 0, "bad size");
+    static_assert(offsetof(C2MyPortSetting::input, _mIndex) == 4, "bad offset");
+    static_assert(offsetof(C2MyPortSetting::input, mNumber) == 8, "bad offset");
+    static_assert(offsetof(C2MyPortSetting::output, _mSize) == 0, "bad size");
+    static_assert(offsetof(C2MyPortSetting::output, _mIndex) == 4, "bad offset");
+    static_assert(offsetof(C2MyPortSetting::output, mNumber) == 8, "bad offset");
+
+    // C2MyStreamSetting:       kIndex | tun | str              (bool, uint, args)
+    static_assert(sizeof(C2MyStreamSetting) == 12u, "bad size");
+    // C2MyStreamSetting::input kIndex | tun | str | input      (int, args)
+    // C2MyStreamSetting::output kIx   | tun | str | output     (int, args)
+    static_assert(C2MyStreamSetting::input::coreIndex ==
+                  kParamIndexMy, "bad index");
+    static_assert(C2MyStreamSetting::input::typeIndex ==
+                  (kParamIndexMy | I::kTypeSetting | I::kDirInput | I::kStreamFlag), "bad index");
+    static_assert(C2MyStreamSetting::output::coreIndex ==
+                  kParamIndexMy, "bad index");
+    static_assert(C2MyStreamSetting::output::typeIndex ==
+                  (kParamIndexMy | I::kTypeSetting | I::kDirOutput | I::kStreamFlag), "bad index");
+    static_assert(sizeof(C2MyStreamSetting::input) == 12u, "bad size");
+    static_assert(sizeof(C2MyStreamSetting::output) == 12u, "bad size");
+    static_assert(offsetof(C2MyStreamSetting::input, _mSize) == 0, "bad size");
+    static_assert(offsetof(C2MyStreamSetting::input, _mIndex) == 4, "bad offset");
+    static_assert(offsetof(C2MyStreamSetting::input, mNumber) == 8, "bad offset");
+    static_assert(offsetof(C2MyStreamSetting::output, _mSize) == 0, "bad size");
+    static_assert(offsetof(C2MyStreamSetting::output, _mIndex) == 4, "bad offset");
+    static_assert(offsetof(C2MyStreamSetting::output, mNumber) == 8, "bad offset");
+}
+
 void _C2ParamInspector::StaticFlexTest() {
     typedef C2Param::Index I;
 
-    // C2NumbersStruct: baseIndex = kIndex                          (args)
-    static_assert(C2NumbersStruct::baseIndex == (I::kFlexibleFlag | kParamIndexNumbers), "bad index");
+    // C2NumbersStruct: coreIndex = kIndex                          (args)
+    static_assert(C2NumbersStruct::coreIndex == (I::kFlexibleFlag | kParamIndexNumbers), "bad index");
     static_assert(sizeof(C2NumbersStruct) == 0, "bad size");
 
     // C2NumbersTuning:             kIndex | tun | global           (args)
-    static_assert(C2NumbersTuning::baseIndex == (I::kFlexibleFlag | kParamIndexNumbers), "bad index");
+    static_assert(C2NumbersTuning::coreIndex == (I::kFlexibleFlag | kParamIndexNumbers), "bad index");
     static_assert(C2NumbersTuning::typeIndex == (I::kFlexibleFlag | kParamIndexNumbers | I::kTypeTuning | I::kDirGlobal), "bad index");
     static_assert(sizeof(C2NumbersTuning) == 8, "bad size");
 
@@ -857,11 +977,11 @@
     static_assert(sizeof(C2NumbersPortTuning) == 8, "bad size");
     // C2NumbersPortTuning::input:  kIndex | tun | port | input     (args)
     // C2NumbersPortTuning::output: kIndex | tun | port | output    (args)
-    static_assert(C2NumbersPortTuning::input::baseIndex ==
+    static_assert(C2NumbersPortTuning::input::coreIndex ==
                   (I::kFlexibleFlag | kParamIndexNumbers), "bad index");
     static_assert(C2NumbersPortTuning::input::typeIndex ==
                   (I::kFlexibleFlag | kParamIndexNumbers | I::kTypeTuning | I::kDirInput), "bad index");
-    static_assert(C2NumbersPortTuning::output::baseIndex ==
+    static_assert(C2NumbersPortTuning::output::coreIndex ==
                   (I::kFlexibleFlag | kParamIndexNumbers), "bad index");
     static_assert(C2NumbersPortTuning::output::typeIndex ==
                   (I::kFlexibleFlag | kParamIndexNumbers | I::kTypeTuning | I::kDirOutput), "bad index");
@@ -878,11 +998,11 @@
     static_assert(sizeof(C2NumbersStreamTuning) == 8, "bad size");
     // C2NumbersStreamTuning::input kIndex | tun | str | input      (int, args)
     // C2NumbersStreamTuning::output kIx   | tun | str | output     (int, args)
-    static_assert(C2NumbersStreamTuning::input::baseIndex ==
+    static_assert(C2NumbersStreamTuning::input::coreIndex ==
                   (I::kFlexibleFlag | kParamIndexNumbers), "bad index");
     static_assert(C2NumbersStreamTuning::input::typeIndex ==
                   (I::kFlexibleFlag | kParamIndexNumbers | I::kTypeTuning | I::kDirInput | I::kStreamFlag), "bad index");
-    static_assert(C2NumbersStreamTuning::output::baseIndex ==
+    static_assert(C2NumbersStreamTuning::output::coreIndex ==
                   (I::kFlexibleFlag | kParamIndexNumbers), "bad index");
     static_assert(C2NumbersStreamTuning::output::typeIndex ==
                   (I::kFlexibleFlag | kParamIndexNumbers | I::kTypeTuning | I::kDirOutput | I::kStreamFlag), "bad index");
@@ -896,6 +1016,80 @@
     static_assert(offsetof(C2NumbersStreamTuning::output, m.mNumbers) == 8, "bad offset");
 }
 
+template<bool, unsigned ...N>
+struct _print_as_warning { };
+
+template<unsigned ...N>
+struct _print_as_warning<true, N...> : std::true_type { };
+
+#define static_assert_equals(a, b, msg) \
+static_assert(_print_as_warning<(a) == (b), a, b>::value, msg)
+
+void _C2ParamInspector::StaticFlexFromBaseTest() {
+    enum { kParamIndexMy = 1203 };
+    typedef C2TestBaseFlexEndSizeStruct C2MyStruct;
+    typedef C2GlobalParam<C2Info, C2MyStruct, kParamIndexMy> C2MyInfo;
+    typedef   C2PortParam<C2Info, C2MyStruct, kParamIndexMy> C2MyPortInfo;
+    typedef C2StreamParam<C2Info, C2MyStruct, kParamIndexMy> C2MyStreamInfo;
+
+    typedef C2Param::Index I;
+
+    // C2MyStruct has no coreIndex
+    //static_assert(C2MyStruct::coreIndex == (I::kFlexibleFlag | kParamIndexMy), "bad index");
+    static_assert(sizeof(C2MyStruct) == 4, "bad size");
+
+    // C2MyInfo:             kIndex | tun | global           (args)
+    static_assert_equals(C2MyInfo::coreIndex, (I::kFlexibleFlag | kParamIndexMy), "bad index");
+    static_assert_equals(C2MyInfo::typeIndex, (I::kFlexibleFlag | kParamIndexMy | I::kTypeInfo | I::kDirGlobal), "bad index");
+    static_assert(sizeof(C2MyInfo) == 12, "bad size");
+
+    static_assert(offsetof(C2MyInfo, _mSize) == 0, "bad size");
+    static_assert(offsetof(C2MyInfo, _mIndex) == 4, "bad offset");
+    static_assert(offsetof(C2MyInfo, m.mSigned32) == 8, "bad offset");
+
+    // C2MyPortInfo:         kIndex | tun | port             (bool, args)
+    static_assert(sizeof(C2MyPortInfo) == 12, "bad size");
+    // C2MyPortInfo::input:  kIndex | tun | port | input     (args)
+    // C2MyPortInfo::output: kIndex | tun | port | output    (args)
+    static_assert(C2MyPortInfo::input::coreIndex ==
+                  (I::kFlexibleFlag | kParamIndexMy), "bad index");
+    static_assert(C2MyPortInfo::input::typeIndex ==
+                  (I::kFlexibleFlag | kParamIndexMy | I::kTypeInfo | I::kDirInput), "bad index");
+    static_assert(C2MyPortInfo::output::coreIndex ==
+                  (I::kFlexibleFlag | kParamIndexMy), "bad index");
+    static_assert(C2MyPortInfo::output::typeIndex ==
+                  (I::kFlexibleFlag | kParamIndexMy | I::kTypeInfo | I::kDirOutput), "bad index");
+    static_assert(sizeof(C2MyPortInfo::input) == 12, "bad size");
+    static_assert(sizeof(C2MyPortInfo::output) == 12, "bad size");
+    static_assert(offsetof(C2MyPortInfo::input, _mSize) == 0, "bad size");
+    static_assert(offsetof(C2MyPortInfo::input, _mIndex) == 4, "bad offset");
+    static_assert(offsetof(C2MyPortInfo::input, m.mSigned32) == 8, "bad offset");
+    static_assert(offsetof(C2MyPortInfo::output, _mSize) == 0, "bad size");
+    static_assert(offsetof(C2MyPortInfo::output, _mIndex) == 4, "bad offset");
+    static_assert(offsetof(C2MyPortInfo::output, m.mSigned32) == 8, "bad offset");
+
+    // C2MyStreamInfo:       kIndex | tun | str              (bool, uint, args)
+    static_assert(sizeof(C2MyStreamInfo) == 12, "bad size");
+    // C2MyStreamInfo::input kIndex | tun | str | input      (int, args)
+    // C2MyStreamInfo::output kIx   | tun | str | output     (int, args)
+    static_assert(C2MyStreamInfo::input::coreIndex ==
+                  (I::kFlexibleFlag | kParamIndexMy), "bad index");
+    static_assert(C2MyStreamInfo::input::typeIndex ==
+                  (I::kFlexibleFlag | kParamIndexMy | I::kTypeInfo | I::kDirInput | I::kStreamFlag), "bad index");
+    static_assert(C2MyStreamInfo::output::coreIndex ==
+                  (I::kFlexibleFlag | kParamIndexMy), "bad index");
+    static_assert(C2MyStreamInfo::output::typeIndex ==
+                  (I::kFlexibleFlag | kParamIndexMy | I::kTypeInfo | I::kDirOutput | I::kStreamFlag), "bad index");
+    static_assert(sizeof(C2MyStreamInfo::input) == 12, "bad size");
+    static_assert(sizeof(C2MyStreamInfo::output) == 12, "bad size");
+    static_assert(offsetof(C2MyStreamInfo::input, _mSize) == 0, "bad size");
+    static_assert(offsetof(C2MyStreamInfo::input, _mIndex) == 4, "bad offset");
+    static_assert(offsetof(C2MyStreamInfo::input, m.mSigned32) == 8, "bad offset");
+    static_assert(offsetof(C2MyStreamInfo::output, _mSize) == 0, "bad size");
+    static_assert(offsetof(C2MyStreamInfo::output, _mIndex) == 4, "bad offset");
+    static_assert(offsetof(C2MyStreamInfo::output, m.mSigned32) == 8, "bad offset");
+}
+
 TEST_F(C2ParamTest, ParamOpsTest) {
     const C2NumberStruct str(100);
     C2NumberStruct bstr;
@@ -904,10 +1098,10 @@
         EXPECT_EQ(100, str.mNumber);
         bstr.mNumber = 100;
 
-        C2Param::BaseIndex index = C2NumberStruct::baseIndex;
+        C2Param::BaseIndex index = C2NumberStruct::coreIndex;
         EXPECT_FALSE(index.isVendor());
         EXPECT_FALSE(index.isFlexible());
-        EXPECT_EQ(index.baseIndex(), kParamIndexNumber);
+        EXPECT_EQ(index.coreIndex(), kParamIndexNumber);
         EXPECT_EQ(index.paramIndex(), kParamIndexNumber);
     }
 
@@ -941,15 +1135,15 @@
         EXPECT_EQ(tun, btun);
 
         // index
-        EXPECT_EQ(C2Param::Type(tun.type()).baseIndex(), C2NumberStruct::baseIndex);
+        EXPECT_EQ(C2Param::Type(tun.type()).coreIndex(), C2NumberStruct::coreIndex);
         EXPECT_EQ(C2Param::Type(tun.type()).paramIndex(), kParamIndexNumber);
         EXPECT_EQ(tun.type(), C2NumberTuning::typeIndex);
         EXPECT_EQ(tun.stream(), ~0u);
 
-        C2Param::BaseIndex index = C2NumberTuning::baseIndex;
+        C2Param::BaseIndex index = C2NumberTuning::coreIndex;
         EXPECT_FALSE(index.isVendor());
         EXPECT_FALSE(index.isFlexible());
-        EXPECT_EQ(index.baseIndex(), kParamIndexNumber);
+        EXPECT_EQ(index.coreIndex(), kParamIndexNumber);
         EXPECT_EQ(index.paramIndex(), kParamIndexNumber);
 
         C2Param::Type type = C2NumberTuning::typeIndex;
@@ -1095,22 +1289,22 @@
         EXPECT_TRUE(inp1 == boutp1);
 
         // index
-        EXPECT_EQ(C2Param::Type(inp1.type()).baseIndex(), C2NumberStruct::baseIndex);
+        EXPECT_EQ(C2Param::Type(inp1.type()).coreIndex(), C2NumberStruct::coreIndex);
         EXPECT_EQ(C2Param::Type(inp1.type()).paramIndex(), kParamIndexNumber);
         EXPECT_EQ(inp1.type(), C2NumberPortTuning::input::typeIndex);
         EXPECT_EQ(inp1.stream(), ~0u);
 
-        EXPECT_EQ(C2Param::Type(inp2.type()).baseIndex(), C2NumberStruct::baseIndex);
+        EXPECT_EQ(C2Param::Type(inp2.type()).coreIndex(), C2NumberStruct::coreIndex);
         EXPECT_EQ(C2Param::Type(inp2.type()).paramIndex(), kParamIndexNumber);
         EXPECT_EQ(inp2.type(), C2NumberPortTuning::input::typeIndex);
         EXPECT_EQ(inp2.stream(), ~0u);
 
-        EXPECT_EQ(C2Param::Type(outp1.type()).baseIndex(), C2NumberStruct::baseIndex);
+        EXPECT_EQ(C2Param::Type(outp1.type()).coreIndex(), C2NumberStruct::coreIndex);
         EXPECT_EQ(C2Param::Type(outp1.type()).paramIndex(), kParamIndexNumber);
         EXPECT_EQ(outp1.type(), C2NumberPortTuning::output::typeIndex);
         EXPECT_EQ(outp1.stream(), ~0u);
 
-        EXPECT_EQ(C2Param::Type(outp2.type()).baseIndex(), C2NumberStruct::baseIndex);
+        EXPECT_EQ(C2Param::Type(outp2.type()).coreIndex(), C2NumberStruct::coreIndex);
         EXPECT_EQ(C2Param::Type(outp2.type()).paramIndex(), kParamIndexNumber);
         EXPECT_EQ(outp2.type(), C2NumberPortTuning::output::typeIndex);
         EXPECT_EQ(outp2.stream(), ~0u);
@@ -1118,13 +1312,13 @@
         C2Param::BaseIndex index = C2NumberPortTuning::input::typeIndex;
         EXPECT_FALSE(index.isVendor());
         EXPECT_FALSE(index.isFlexible());
-        EXPECT_EQ(index.baseIndex(), kParamIndexNumber);
+        EXPECT_EQ(index.coreIndex(), kParamIndexNumber);
         EXPECT_EQ(index.paramIndex(), kParamIndexNumber);
 
         index = C2NumberPortTuning::output::typeIndex;
         EXPECT_FALSE(index.isVendor());
         EXPECT_FALSE(index.isFlexible());
-        EXPECT_EQ(index.baseIndex(), kParamIndexNumber);
+        EXPECT_EQ(index.coreIndex(), kParamIndexNumber);
         EXPECT_EQ(index.paramIndex(), kParamIndexNumber);
 
         C2Param::Type type = C2NumberPortTuning::input::typeIndex;
@@ -1315,32 +1509,32 @@
         EXPECT_TRUE(ins1 == bouts1);
 
         // index
-        EXPECT_EQ(C2Param::Type(ins1.type()).baseIndex(), C2NumberStruct::baseIndex);
+        EXPECT_EQ(C2Param::Type(ins1.type()).coreIndex(), C2NumberStruct::coreIndex);
         EXPECT_EQ(C2Param::Type(ins1.type()).paramIndex(), kParamIndexNumber);
         EXPECT_EQ(ins1.type(), C2NumberStreamTuning::input::typeIndex);
 
-        EXPECT_EQ(C2Param::Type(ins2.type()).baseIndex(), C2NumberStruct::baseIndex);
+        EXPECT_EQ(C2Param::Type(ins2.type()).coreIndex(), C2NumberStruct::coreIndex);
         EXPECT_EQ(C2Param::Type(ins2.type()).paramIndex(), kParamIndexNumber);
         EXPECT_EQ(ins2.type(), C2NumberStreamTuning::input::typeIndex);
 
-        EXPECT_EQ(C2Param::Type(outs1.type()).baseIndex(), C2NumberStruct::baseIndex);
+        EXPECT_EQ(C2Param::Type(outs1.type()).coreIndex(), C2NumberStruct::coreIndex);
         EXPECT_EQ(C2Param::Type(outs1.type()).paramIndex(), kParamIndexNumber);
         EXPECT_EQ(outs1.type(), C2NumberStreamTuning::output::typeIndex);
 
-        EXPECT_EQ(C2Param::Type(outs2.type()).baseIndex(), C2NumberStruct::baseIndex);
+        EXPECT_EQ(C2Param::Type(outs2.type()).coreIndex(), C2NumberStruct::coreIndex);
         EXPECT_EQ(C2Param::Type(outs2.type()).paramIndex(), kParamIndexNumber);
         EXPECT_EQ(outs2.type(), C2NumberStreamTuning::output::typeIndex);
 
         C2Param::BaseIndex index = C2NumberStreamTuning::input::typeIndex;
         EXPECT_FALSE(index.isVendor());
         EXPECT_FALSE(index.isFlexible());
-        EXPECT_EQ(index.baseIndex(), kParamIndexNumber);
+        EXPECT_EQ(index.coreIndex(), kParamIndexNumber);
         EXPECT_EQ(index.paramIndex(), kParamIndexNumber);
 
         index = C2NumberStreamTuning::output::typeIndex;
         EXPECT_FALSE(index.isVendor());
         EXPECT_FALSE(index.isFlexible());
-        EXPECT_EQ(index.baseIndex(), kParamIndexNumber);
+        EXPECT_EQ(index.coreIndex(), kParamIndexNumber);
         EXPECT_EQ(index.paramIndex(), kParamIndexNumber);
 
         C2Param::Type type = C2NumberStreamTuning::input::typeIndex;
@@ -1420,11 +1614,11 @@
     }
 }
 
-void StaticTestAddBaseIndex() {
+void StaticTestAddCoreIndex() {
     struct nobase {};
-    struct base { enum : uint32_t { baseIndex = 1 }; };
-    static_assert(C2AddBaseIndex<nobase, 2>::baseIndex == 2, "should be 2");
-    static_assert(C2AddBaseIndex<base, 1>::baseIndex == 1, "should be 1");
+    struct base { enum : uint32_t { coreIndex = 1 }; };
+    static_assert(C2AddCoreIndex<nobase, 2>::coreIndex == 2, "should be 2");
+    static_assert(C2AddCoreIndex<base, 1>::coreIndex == 1, "should be 1");
 }
 
 class TestFlexHelper {
@@ -1464,10 +1658,10 @@
 //        EXPECT_EQ(100, str->m.mNumbers[0]);
         (void)&bstr.mNumbers[0];
 
-        C2Param::BaseIndex index = C2NumbersStruct::baseIndex;
+        C2Param::BaseIndex index = C2NumbersStruct::coreIndex;
         EXPECT_FALSE(index.isVendor());
         EXPECT_TRUE(index.isFlexible());
-        EXPECT_EQ(index.baseIndex(), kParamIndexNumbers | C2Param::BaseIndex::_kFlexibleFlag);
+        EXPECT_EQ(index.coreIndex(), kParamIndexNumbers | C2Param::BaseIndex::_kFlexibleFlag);
         EXPECT_EQ(index.paramIndex(), kParamIndexNumbers);
     }
 
@@ -1504,15 +1698,15 @@
         EXPECT_EQ(*tun, *btun);
 
         // index
-        EXPECT_EQ(C2Param::Type(tun->type()).baseIndex(), C2NumbersStruct::baseIndex);
+        EXPECT_EQ(C2Param::Type(tun->type()).coreIndex(), C2NumbersStruct::coreIndex);
         EXPECT_EQ(C2Param::Type(tun->type()).paramIndex(), kParamIndexNumbers);
         EXPECT_EQ(tun->type(), C2NumbersTuning::typeIndex);
         EXPECT_EQ(tun->stream(), ~0u);
 
-        C2Param::BaseIndex index = C2NumbersTuning::baseIndex;
+        C2Param::BaseIndex index = C2NumbersTuning::coreIndex;
         EXPECT_FALSE(index.isVendor());
         EXPECT_TRUE(index.isFlexible());
-        EXPECT_EQ(index.baseIndex(), kParamIndexNumbers | C2Param::BaseIndex::_kFlexibleFlag);
+        EXPECT_EQ(index.coreIndex(), kParamIndexNumbers | C2Param::BaseIndex::_kFlexibleFlag);
         EXPECT_EQ(index.paramIndex(), kParamIndexNumbers);
 
         C2Param::Type type = C2NumbersTuning::typeIndex;
@@ -1673,22 +1867,22 @@
         EXPECT_TRUE(*inp1 == *boutp1);
 
         // index
-        EXPECT_EQ(C2Param::Type(inp1->type()).baseIndex(), C2NumbersStruct::baseIndex);
+        EXPECT_EQ(C2Param::Type(inp1->type()).coreIndex(), C2NumbersStruct::coreIndex);
         EXPECT_EQ(C2Param::Type(inp1->type()).paramIndex(), kParamIndexNumbers);
         EXPECT_EQ(inp1->type(), C2NumbersPortTuning::input::typeIndex);
         EXPECT_EQ(inp1->stream(), ~0u);
 
-        EXPECT_EQ(C2Param::Type(inp2->type()).baseIndex(), C2NumbersStruct::baseIndex);
+        EXPECT_EQ(C2Param::Type(inp2->type()).coreIndex(), C2NumbersStruct::coreIndex);
         EXPECT_EQ(C2Param::Type(inp2->type()).paramIndex(), kParamIndexNumbers);
         EXPECT_EQ(inp2->type(), C2NumbersPortTuning::input::typeIndex);
         EXPECT_EQ(inp2->stream(), ~0u);
 
-        EXPECT_EQ(C2Param::Type(outp1->type()).baseIndex(), C2NumbersStruct::baseIndex);
+        EXPECT_EQ(C2Param::Type(outp1->type()).coreIndex(), C2NumbersStruct::coreIndex);
         EXPECT_EQ(C2Param::Type(outp1->type()).paramIndex(), kParamIndexNumbers);
         EXPECT_EQ(outp1->type(), C2NumbersPortTuning::output::typeIndex);
         EXPECT_EQ(outp1->stream(), ~0u);
 
-        EXPECT_EQ(C2Param::Type(outp2->type()).baseIndex(), C2NumbersStruct::baseIndex);
+        EXPECT_EQ(C2Param::Type(outp2->type()).coreIndex(), C2NumbersStruct::coreIndex);
         EXPECT_EQ(C2Param::Type(outp2->type()).paramIndex(), kParamIndexNumbers);
         EXPECT_EQ(outp2->type(), C2NumbersPortTuning::output::typeIndex);
         EXPECT_EQ(outp2->stream(), ~0u);
@@ -1696,13 +1890,13 @@
         C2Param::BaseIndex index = C2NumbersPortTuning::input::typeIndex;
         EXPECT_FALSE(index.isVendor());
         EXPECT_TRUE(index.isFlexible());
-        EXPECT_EQ(index.baseIndex(), kParamIndexNumbers | C2Param::BaseIndex::_kFlexibleFlag);
+        EXPECT_EQ(index.coreIndex(), kParamIndexNumbers | C2Param::BaseIndex::_kFlexibleFlag);
         EXPECT_EQ(index.paramIndex(), kParamIndexNumbers);
 
         index = C2NumbersPortTuning::output::typeIndex;
         EXPECT_FALSE(index.isVendor());
         EXPECT_TRUE(index.isFlexible());
-        EXPECT_EQ(index.baseIndex(), kParamIndexNumbers | C2Param::BaseIndex::_kFlexibleFlag);
+        EXPECT_EQ(index.coreIndex(), kParamIndexNumbers | C2Param::BaseIndex::_kFlexibleFlag);
         EXPECT_EQ(index.paramIndex(), kParamIndexNumbers);
 
         C2Param::Type type = C2NumbersPortTuning::input::typeIndex;
@@ -1910,32 +2104,32 @@
         EXPECT_TRUE(*ins1 == *bouts1);
 
         // index
-        EXPECT_EQ(C2Param::Type(ins1->type()).baseIndex(), C2NumbersStruct::baseIndex);
+        EXPECT_EQ(C2Param::Type(ins1->type()).coreIndex(), C2NumbersStruct::coreIndex);
         EXPECT_EQ(C2Param::Type(ins1->type()).paramIndex(), kParamIndexNumbers);
         EXPECT_EQ(ins1->type(), C2NumbersStreamTuning::input::typeIndex);
 
-        EXPECT_EQ(C2Param::Type(ins2->type()).baseIndex(), C2NumbersStruct::baseIndex);
+        EXPECT_EQ(C2Param::Type(ins2->type()).coreIndex(), C2NumbersStruct::coreIndex);
         EXPECT_EQ(C2Param::Type(ins2->type()).paramIndex(), kParamIndexNumbers);
         EXPECT_EQ(ins2->type(), C2NumbersStreamTuning::input::typeIndex);
 
-        EXPECT_EQ(C2Param::Type(outs1->type()).baseIndex(), C2NumbersStruct::baseIndex);
+        EXPECT_EQ(C2Param::Type(outs1->type()).coreIndex(), C2NumbersStruct::coreIndex);
         EXPECT_EQ(C2Param::Type(outs1->type()).paramIndex(), kParamIndexNumbers);
         EXPECT_EQ(outs1->type(), C2NumbersStreamTuning::output::typeIndex);
 
-        EXPECT_EQ(C2Param::Type(outs2->type()).baseIndex(), C2NumbersStruct::baseIndex);
+        EXPECT_EQ(C2Param::Type(outs2->type()).coreIndex(), C2NumbersStruct::coreIndex);
         EXPECT_EQ(C2Param::Type(outs2->type()).paramIndex(), kParamIndexNumbers);
         EXPECT_EQ(outs2->type(), C2NumbersStreamTuning::output::typeIndex);
 
         C2Param::BaseIndex index = C2NumbersStreamTuning::input::typeIndex;
         EXPECT_FALSE(index.isVendor());
         EXPECT_TRUE(index.isFlexible());
-        EXPECT_EQ(index.baseIndex(), kParamIndexNumbers | C2Param::BaseIndex::_kFlexibleFlag);
+        EXPECT_EQ(index.coreIndex(), kParamIndexNumbers | C2Param::BaseIndex::_kFlexibleFlag);
         EXPECT_EQ(index.paramIndex(), kParamIndexNumbers);
 
         index = C2NumbersStreamTuning::output::typeIndex;
         EXPECT_FALSE(index.isVendor());
         EXPECT_TRUE(index.isFlexible());
-        EXPECT_EQ(index.baseIndex(), kParamIndexNumbers | C2Param::BaseIndex::_kFlexibleFlag);
+        EXPECT_EQ(index.coreIndex(), kParamIndexNumbers | C2Param::BaseIndex::_kFlexibleFlag);
         EXPECT_EQ(index.paramIndex(), kParamIndexNumbers);
 
         C2Param::Type type = C2NumbersStreamTuning::input::typeIndex;
@@ -2284,8 +2478,8 @@
         MyParamReflector(const MyComponentInstance *i) : instance(i) { }
 
         virtual std::unique_ptr<C2StructDescriptor> describe(C2Param::BaseIndex paramIndex) {
-            switch (paramIndex.baseIndex()) {
-            case decltype(instance->mDomainInfo)::baseIndex:
+            switch (paramIndex.coreIndex()) {
+            case decltype(instance->mDomainInfo)::coreIndex:
             default:
                 return std::unique_ptr<C2StructDescriptor>(new C2StructDescriptor{
                     instance->mDomainInfo.type(),
@@ -2460,7 +2654,7 @@
 void dumpStruct(const C2StructDescriptor &sd) {
     using namespace std;
     cout << "struct ";
-    dumpType(sd.baseIndex());
+    dumpType(sd.coreIndex());
     cout << " {" << endl;
     //C2FieldDescriptor &f;
     for (const C2FieldDescriptor &f : sd) {
diff --git a/media/libstagefright/codec2/vndk/include/util/C2ParamUtils.h b/media/libstagefright/codec2/vndk/include/util/C2ParamUtils.h
index edae303..5f09889 100644
--- a/media/libstagefright/codec2/vndk/include/util/C2ParamUtils.h
+++ b/media/libstagefright/codec2/vndk/include/util/C2ParamUtils.h
@@ -278,7 +278,7 @@
 C2_HIDE
 void addC2Params(std::list<const C2FieldDescriptor> &fields, _C2Tuple<T, Params...> *)
 {
-    //C2Param::index_t index = T::baseIndex;
+    //C2Param::index_t index = T::coreIndex;
     //(void)index;
     fields.insert(fields.end(), T::fieldList);
     addC2Params(fields, (_C2Tuple<Params...> *)nullptr);
diff --git a/media/libstagefright/codecs/avcdec/C2SoftAvcDec.cpp b/media/libstagefright/codecs/avcdec/C2SoftAvcDec.cpp
index 3aa8c38..5f55e1e 100644
--- a/media/libstagefright/codecs/avcdec/C2SoftAvcDec.cpp
+++ b/media/libstagefright/codecs/avcdec/C2SoftAvcDec.cpp
@@ -209,15 +209,15 @@
 }  // namespace
 
 #define CASE(member) \
-    case decltype(component->member)::baseIndex: \
+    case decltype(component->member)::coreIndex: \
         return std::unique_ptr<C2StructDescriptor>(new C2StructDescriptor( \
                 static_cast<decltype(component->member) *>(nullptr)))
 
 class C2SoftAvcDecIntf::ParamReflector : public C2ParamReflector {
 public:
-    virtual std::unique_ptr<C2StructDescriptor> describe(C2Param::BaseIndex paramIndex) override {
+    virtual std::unique_ptr<C2StructDescriptor> describe(C2Param::BaseIndex coreIndex) override {
         constexpr C2SoftAvcDecIntf *component = nullptr;
-        switch (paramIndex.baseIndex()) {
+        switch (coreIndex.coreIndex()) {
         CASE(mDomainInfo);
         CASE(mInputStreamCount);
         CASE(mInputStreamFormat);
@@ -226,7 +226,7 @@
         CASE(mMaxVideoSizeHint);
 
         // port mime configs are stored as unique_ptr.
-        case C2PortMimeConfig::baseIndex:
+        case C2PortMimeConfig::coreIndex:
             return std::unique_ptr<C2StructDescriptor>(new C2StructDescriptor(
                     static_cast<C2PortMimeConfig *>(nullptr)));
         }