• MTK平台Metadata的加载(1)——Metadata介绍


    (1)Metadata的分类

    Camera API2/HAL3 的核心为 per-frame control,为了达成这个目标产生了 metadata 的机制,metadata一共分成三类 constrol、dynamic 以及 static。

    • Control(request):当APK query出static metadata 后,可以从中作自己想要的控制。(每一帧都可以设定,会绑定对应
      的 image callback)。
    • Dynamic(result):当 Hal层收到 control metadata 后,设定进 ISP 最终产生对应的结果。
    • Static(charateristics):描述此logcial device 的规格与提供什么功能。
    • Template request:AOSP 定义的 high level scenario(ex:PREVIEW/VIDEO_RECORD/VIDEO_SNAPSHOT),并让 Ha 层回报各Scenario的预设 control metadata set,让 APK 可方便的预设值以方便后续控制操作。

    (2)Camera Metadata

    (A)Android Metadata

    //system/media/camera/src/camera_metadata.c
    
    struct camera_metadata {
          metadata_size_t          size;
          uint32_t                 version;
          uint32_t                 flags;
          metadata_size_t          entry_count;
          metadata_size_t          entry_capacity;
          metadata_uptrdiff_t      entries_start; // Offset from camera_metadata
          metadata_size_t          data_count;
          metadata_size_t          data_capacity;
          metadata_uptrdiff_t      data_start; // Offset from camera_metadata
          uint32_t                 padding;    // padding to 8 bytes boundary
          metadata_vendor_id_t     vendor_id;
    };
    

    (B)Mtk Metadata

    在定义 vendor tag时,为了避免直接修改 Android metadata tag 文件,Mtk 定义了自己的 metadata系统。
    IMetadata 是 Mtk camera hal 层用来存储 metadata 的容器,会用来存储 request、result 或者static meta 信息。

    //vendor/mediatek/proprietary/hardware/mtkcam/include/mtkcam/utils/metadata/IMetadata.h
    //vendor/mediatek/proprietary/hardware/mtkcam/utils/metadata/metadata/Metadata.cpp
    
    class IMetadata
    {
    		size_t                     		 		size() const;
            void                        		 		resize(const size_t size, uint8_t default_val = 0);
            size_t                      		 		append(const Memory &other);
            const uint8_t*           		array() const;
            uint8_t*                    			editArray();
            uint8_t                     			itemAt(size_t index) const;
            void                        				clear();
    
            // android support
            size_t                      				appendVector(const Memory &other);
            size_t                      				appendVector(const android::Vector<MUINT8> &v);
    		
    		virtual MBOOL                  			isEmpty() const;
    		virtual MUINT                   			count() const;
    		virtual MVOID                       			clear();
       		virtual android::status_t           remove(Tag_t tag);
    
        	virtual android::status_t           sort();
        	virtual android::status_t           update(Tag_t tag, IEntry const& entry);
        	virtual IEntry                     			 entryFor(Tag_t tag) const;
        	virtual IEntry                      			 entryAt(MUINT index) const;
        	virtual IEntry                      			 takeEntryFor(Tag_t tag);
        	virtual IEntry                      			 takeEntryAt(MUINT index);
        	virtual ssize_t                     	 		 flatten(void* buf, size_t buf_size) const;
        	virtual ssize_t                     			unflatten(void* buf, size_t buf_size);
        	virtual void                        				dump(int layer=0);
    
    		bool getEntry(const IMetadata* metadata, MUINT32 const tag, T& val, size_t index = 0);
    		android::status_t setEntry(IMetadata* metadata, MUINT32 const tag, T const& val);
    
    
    		class   IEntry
        	{
        		virtual MUINT32                 	tag() const;
            	virtual MINT32                  	type() const;
            	virtual const void*          	data() const;
            	virtual MBOOL                   	isEmpty() const;
            	virtual MUINT                   	count() const;
            	virtual MUINT                   	capacity() const;
            	virtual MBOOL                   	setCapacity(MUINT size);
            	virtual MUINT                   	setSize(MUINT size);
            	virtual MVOID                   		clear();
            	virtual android::status_t       removeAt(MUINT index);
            	template <typename T>  static int indexOf(const IEntry& entry, const T& target);
    
    
    			#define IMETADATA_IENTRY_OPS_DECLARATION(_T) \
            			virtual MVOID                   push_back(_T const& item, Type2Type<_T>); \
            			virtual MVOID                   replaceItemAt(MUINT index, _T const& item, Type2Type<_T>); \
            			virtual _T                     		itemAt(MUINT index, Type2Type<_T>) const; \
    
            			IMETADATA_IENTRY_OPS_DECLARATION(MUINT8)
            			IMETADATA_IENTRY_OPS_DECLARATION(MINT32)
            			IMETADATA_IENTRY_OPS_DECLARATION(MFLOAT)
            			IMETADATA_IENTRY_OPS_DECLARATION(MINT64)
            			IMETADATA_IENTRY_OPS_DECLARATION(MDOUBLE)
            			IMETADATA_IENTRY_OPS_DECLARATION(MRational)
            			IMETADATA_IENTRY_OPS_DECLARATION(MPoint)
            			IMETADATA_IENTRY_OPS_DECLARATION(MSize)
            			IMETADATA_IENTRY_OPS_DECLARATION(MRect)
            			IMETADATA_IENTRY_OPS_DECLARATION(IMetadata)
            			IMETADATA_IENTRY_OPS_DECLARATION(Memory)
    			#undef  IMETADATA_IENTRY_OPS_DECLARATION
        	}
    }
    

    那我们如何使用这些Metadata呢?

    //(1)向IMetadata 中填充对应 Tag 的 meta 数据
    MRect region1(MPoint(2,3),MSize(4,5));
    IMetadata::IEntry entryA(MTK_SCALER_CROP_REGION);
    entryA.push_back(region1,Type2Type<MRect>());
    IMetadata metadataA;
    metadataA.update(MTK_SCALER_CROP_REGION,entryA);
    
    //(2)替换已经填充到 IMetadata 中对应 Tag 的 meta 数据
    MRect region2(MPoint(7,8),MSize(9,10));
    IMetadata::IEntry entryB = metadataA.entryFor(MTK_SCALER_CROP_REGION);
    entryB. replaceItemAt(0, region2, Type2Type< MRect >());
    metadataA.update(MTK_SCALER_CROP_REGION,entryB);
    
    //(3)从 IMetadata 中获取对应 Tag 的 meta 数据
    IMetadata::IEntry entryC = metadataA.entryFor(MTK_SCALER_CROP_REGION);
    entryC.item(0, Type2Type<MRect>());
    

    (C)Android Tag与Mtk Tag的关系

    Mtk metadata tag 包含了所有的 Android Tag。Android Tag 都能在 Mtk metadata tag 中找到一一对应
    的 Tag,因此Mtk metadata tag 可以转换到对应的 Android metadata tag。

    //vendor/mediatek/proprietary/hardware/mtkcam/include/mtkcam/utils/metadata/client/TagMap.h
    
     #define ADD_ALL_MEMBERS \
         _IMP_TAGCONVERT_(    ANDROID_COLOR_CORRECTION_MODE  ,    MTK_COLOR_CORRECTION_MODE  )\
         _IMP_TAGCONVERT_(    ANDROID_COLOR_CORRECTION_TRANSFORM,    MTK_COLOR_CORRECTION_TRANSFORM)\
         _IMP_TAGCONVERT_(    ANDROID_COLOR_CORRECTION_GAINS ,    MTK_COLOR_CORRECTION_GAINS )\
         _IMP_TAGCONVERT_(    ANDROID_COLOR_CORRECTION_ABERRATION_MODE,    MTK_COLOR_CORRECTION_ABERRATION_MODE)\
         _IMP_TAGCONVERT_(    ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,    MTK_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES)\
         _IMP_TAGCONVERT_(    ANDROID_CONTROL_AE_ANTIBANDING_MODE ,    MTK_CONTROL_AE_ANTIBANDING_MODE )\
         _IMP_TAGCONVERT_(    ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,    MTK_CONTROL_AE_EXPOSURE_COMPENSATION)\
         _IMP_TAGCONVERT_(    ANDROID_CONTROL_AE_LOCK,    MTK_CONTROL_AE_LOCK)\
         _IMP_TAGCONVERT_(    ANDROID_CONTROL_AE_MODE,    MTK_CONTROL_AE_MODE)\
         _IMP_TAGCONVERT_(    ANDROID_CONTROL_AE_REGIONS,    MTK_CONTROL_AE_REGIONS)\
         _IMP_TAGCONVERT_(    ANDROID_CONTROL_AE_TARGET_FPS_RANGE,    MTK_CONTROL_AE_TARGET_FPS_RANGE)\
         _IMP_TAGCONVERT_(    ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,    MTK_CONTROL_AE_PRECAPTURE_TRIGGER)\
         _IMP_TAGCONVERT_(    ANDROID_CONTROL_AF_MODE,    MTK_CONTROL_AF_MODE)\
         _IMP_TAGCONVERT_(    ANDROID_CONTROL_AF_REGIONS,    MTK_CONTROL_AF_REGIONS)\
         _IMP_TAGCONVERT_(    ANDROID_CONTROL_AF_TRIGGER,    MTK_CONTROL_AF_TRIGGER)\
         _IMP_TAGCONVERT_(    ANDROID_CONTROL_AWB_LOCK,    MTK_CONTROL_AWB_LOCK)\
         _IMP_TAGCONVERT_(    ANDROID_CONTROL_AWB_MODE,    MTK_CONTROL_AWB_MODE)\
         _IMP_TAGCONVERT_(    ANDROID_CONTROL_AWB_REGIONS,    MTK_CONTROL_AWB_REGIONS)\
    	
    	//...
    

    (D)Android Tag与Mtk Tag的转换

    在 Camera Hal 层之上使用的是 Android 的 Camera metadata,而在 Camera Hal 层使用的是 Mtk Camera metadata。因此当 request metadata 从 App 层传递到 Hal 层时需要将 Android Camera metadata转换为 Mtk camera metadata。

    与之相反,result 与 static meta 则由 Mtk camera metadata 转换为 AndroidCamera metadata 并传递给 AP。

    IMetadataConvert.h 是用来进行转换的接口,在收到 App 的 request 时调用 convertFromHidl(上到下),
    再返回 result 或者 static metadata 时调用 convertToHidl 进行转换(下到上)

    //vendor/mediatek/proprietary/hardware/mtkcam/include/mtkcam/utils/metadata/IMetadataConverter.h
    //vendor/mediatek/proprietary/hardware/mtkcam/utils/metadata/conversion/MetadataConverter.cpp
    //vendor/mediatek/proprietary/hardware/mtkcam/utils/metadata/conversion/TypeConvert.androidMetadata.cpp
    //vendor/mediatek/proprietary/hardware/mtkcam/utils/metadata/conversion/TypeConvert.mtkMetadata.cpp
    
    class IMetadataConverter : public virtual android::RefBase
    {
    public:
        static  android::sp<IMetadataConverter>   createInstance(IMetadataTagSet const &pTagInfo);
    
        virtual MBOOL                   convertFromHidl(const void* src/*const ::android::hardware::hidl_vec* */, IMetadata& dst) = 0;
        virtual MBOOL                   convertToHidl(const IMetadata& src, void* dst/*::android::hardware::hidl_vec* */) = 0;
    
        virtual MBOOL                   convert(const camera_metadata* src, IMetadata& dst) const = 0;
        virtual MBOOL                   convert(const IMetadata& src, camera_metadata*& dst, size_t* pDstSize = nullptr) const = 0;
        
        virtual size_t                  	getCameraMetadataSize(const camera_metadata *metadata) const = 0;
        virtual void                    		freeCameraMetadata(camera_metadata *metadata) const = 0;
    
        virtual MVOID                   dump(const IMetadata &rMetadata, int frameNo = -1) const = 0;
        virtual MVOID                   dumpAll(const IMetadata &rMetadata, int frameNo = -1) const = 0;
    };
    
  • 相关阅读:
    Git常见问题
    QT子线程或自定义类操作访问主界面UI控件的几种方法
    git学习笔记之用命令行解决冲突
    硬件管理平台-硬件产品库-硬件项目
    DELL R730服务器开机报错:[XXX] usb 1-1-port4: disabled by hub (EMI?), re-enabling...
    第38节——useId——了解
    深入剖析Kubernetes
    cfssl使用方法重新整理说明
    【分类网络】GoogLeNet
    DB2分区表详解
  • 原文地址:https://blog.csdn.net/dongxianfei/article/details/124275722