首先感谢阅读,如果您也对TDA4相关的开发感兴趣,我们这边有个学习交流微信群,可以入群和大家一起交流学习。
资历较浅,水平有限,如遇错误,请大家多指正!
保持开源精神,共同分享、进步!
博主WX : AIR_12 我会拉你入群。
链接:TDA4 相关专栏 链接:TDA4 Demo Gitee开源库
欢迎大家加入,一起维护这个开源库,给更多的朋友提供帮助。
在TDA4平台开发的时候,经常会遇到 ObjectArray 相关的内容。经过较长时间的使用和实际测试,现在将相关经验总结如下,希望对大家有所帮助!
ObjectArray:个人理解这就类似于是C++中的一个容器,可以在这个Array里面放置各种各样的数据类型,如:Image、Reference等等,其中最常用的就是image了。
一、创建一个ObjectArray:vxCreateObjectArray
vxCreateObjectArray(vx_context context, //在此context中创建ObjectArray
vx_reference exemplar, //创建ObjectArray的依据、参考,就是创建此种类型的array
vx_size count); //创建的Array里面包含此类型数据的个数。
如:
/* Create Input OpenVx object */
vx_image image = vxCreateImage(context, 1920, 1080, VX_DF_IMAGE_NV12); //创建一个1080P的NV12格式的图片
status = vxGetStatus((vx_reference)image ); //查询创建图片的状态
if(status == VX_SUCCESS)
{
vx_object_array image_arr = vxCreateObjectArray(context, (vx_reference)image, 8); //以image为参考,创建具有8个相同属性对象的array,8个对象都是1080P 的NV12 图像
vxReleaseImage(&image); //释放这个临时文件 image
}
二、查询一个ObjectArray里对象的属性:vxQueryObjectArray
当我们遇到一个ObjectArray 时,如果不知道内部的对象属性可以调用这个函数查询如下内容:
ObjectArray内部对象的数据类型、ObjectArray内部对象的数量。
vxQueryObjectArray( vx_object_array arr, //需要查询的arr对象
vx_enum attribute, //需要查询的操作枚举,可查询内部对象数据类型或者对象个数
void *ptr, //传出参数,如果是查询对象类型,则返回对象类型的枚举值;如果查询的是对象个数,则返回内部对象的数量
vx_size size); //传出参数的字节数量,根据查询内容不同而不同。见示例。
1、查询Array内部对象的属性
vx_enum actual_item_type = VX_TYPE_INVALID;
vx_status status = vxQueryObjectArray((vx_object_array)image_arr, //被查询的array
VX_OBJECT_ARRAY_ITEMTYPE, //需要查询的数据类型
&actual_item_type, //传出参数,array对象的数据类型
sizeof(vx_enum)); //传出参数的大小
当然查询image_arr,得到的类型,是 “VX_TYPE_DF_IMAGE”,知道是图像类型以后,就可以按照图像的相关操作,去查询图像的属性了。
详情,请参阅这篇博客:[TI TDA4 J721E]TIOVX Image图像相关操作(修正版)
查询以后,会得到actual_item_type,这是一个枚举的类型,一共有以下这些属性可以被查询到。
/*! \brief The type enumeration lists all the known types in OpenVX.
* \ingroup group_basic_features
*/
enum vx_type_e {
VX_TYPE_INVALID = 0x000,/*!< \brief An invalid type value. When passed an error must be returned. */
VX_TYPE_CHAR = 0x001,/*!< \brief A <tt>\ref vx_char</tt>. */
VX_TYPE_INT8 = 0x002,/*!< \brief A <tt>\ref vx_int8</tt>. */
VX_TYPE_UINT8 = 0x003,/*!< \brief A <tt>\ref vx_uint8</tt>. */
VX_TYPE_INT16 = 0x004,/*!< \brief A <tt>\ref vx_int16</tt>. */
VX_TYPE_UINT16 = 0x005,/*!< \brief A <tt>\ref vx_uint16</tt>. */
VX_TYPE_INT32 = 0x006,/*!< \brief A <tt>\ref vx_int32</tt>. */
VX_TYPE_UINT32 = 0x007,/*!< \brief A <tt>\ref vx_uint32</tt>. */
VX_TYPE_INT64 = 0x008,/*!< \brief A <tt>\ref vx_int64</tt>. */
VX_TYPE_UINT64 = 0x009,/*!< \brief A <tt>\ref vx_uint64</tt>. */
VX_TYPE_FLOAT32 = 0x00A,/*!< \brief A <tt>\ref vx_float32</tt>. */
VX_TYPE_FLOAT64 = 0x00B,/*!< \brief A <tt>\ref vx_float64</tt>. */
VX_TYPE_ENUM = 0x00C,/*!< \brief A <tt>\ref vx_enum</tt>. Equivalent in size to a <tt>\ref vx_int32</tt>. */
VX_TYPE_SIZE = 0x00D,/*!< \brief A <tt>\ref vx_size</tt>. */
VX_TYPE_DF_IMAGE = 0x00E,/*!< \brief A <tt>\ref vx_df_image</tt>. */
#if defined(EXPERIMENTAL_PLATFORM_SUPPORTS_16_FLOAT)
VX_TYPE_FLOAT16 = 0x00F,/*!< \brief A <tt>\ref vx_float16</tt>. */
#endif
VX_TYPE_BOOL = 0x010,/*!< \brief A <tt>\ref vx_bool</tt>. */
/* add new scalar types here */
VX_TYPE_SCALAR_MAX, /*!< \brief A floating value for comparison between OpenVX scalars and OpenVX structs. */
VX_TYPE_RECTANGLE = 0x020,/*!< \brief A <tt>\ref vx_rectangle_t</tt>. */
VX_TYPE_KEYPOINT = 0x021,/*!< \brief A <tt>\ref vx_keypoint_t</tt>. */
VX_TYPE_COORDINATES2D = 0x022,/*!< \brief A <tt>\ref vx_coordinates2d_t</tt>. */
VX_TYPE_COORDINATES3D = 0x023,/*!< \brief A <tt>\ref vx_coordinates3d_t</tt>. */
VX_TYPE_USER_STRUCT_START = 0x100,/*!< \brief A user-defined struct base index.*/
VX_TYPE_VENDOR_STRUCT_START = 0x400,/*!< \brief A vendor-defined struct base index.*/
VX_TYPE_KHRONOS_OBJECT_START = 0x800,/*!< \brief A Khronos defined object base index. */
VX_TYPE_VENDOR_OBJECT_START = 0xC00,/*!< \brief A vendor defined object base index. */
VX_TYPE_KHRONOS_STRUCT_MAX = (vx_enum)VX_TYPE_USER_STRUCT_START - 1,/*!< \brief A value for comparison between Khronos defined structs and user structs. */
VX_TYPE_USER_STRUCT_END = (vx_enum)VX_TYPE_VENDOR_STRUCT_START - 1,/*!< \brief A value for comparison between user structs and vendor structs. */
VX_TYPE_VENDOR_STRUCT_END = (vx_enum)VX_TYPE_KHRONOS_OBJECT_START - 1,/*!< \brief A value for comparison between vendor structs and Khronos defined objects. */
VX_TYPE_KHRONOS_OBJECT_END = (vx_enum)VX_TYPE_VENDOR_OBJECT_START - 1,/*!< \brief A value for comparison between Khronos defined objects and vendor structs. */
VX_TYPE_VENDOR_OBJECT_END = 0xFFF,/*!< \brief A value used for bound checking of vendor objects */
VX_TYPE_REFERENCE = 0x800,/*!< \brief A <tt>\ref vx_reference</tt>. */
VX_TYPE_CONTEXT = 0x801,/*!< \brief A <tt>\ref vx_context</tt>. */
VX_TYPE_GRAPH = 0x802,/*!< \brief A <tt>\ref vx_graph</tt>. */
VX_TYPE_NODE = 0x803,/*!< \brief A <tt>\ref vx_node</tt>. */
VX_TYPE_KERNEL = 0x804,/*!< \brief A <tt>\ref vx_kernel</tt>. */
VX_TYPE_PARAMETER = 0x805,/*!< \brief A <tt>\ref vx_parameter</tt>. */
VX_TYPE_DELAY = 0x806,/*!< \brief A <tt>\ref vx_delay</tt>. */
VX_TYPE_LUT = 0x807,/*!< \brief A <tt>\ref vx_lut</tt>. */
VX_TYPE_DISTRIBUTION = 0x808,/*!< \brief A <tt>\ref vx_distribution</tt>. */
VX_TYPE_PYRAMID = 0x809,/*!< \brief A <tt>\ref vx_pyramid</tt>. */
VX_TYPE_THRESHOLD = 0x80A,/*!< \brief A <tt>\ref vx_threshold</tt>. */
VX_TYPE_MATRIX = 0x80B,/*!< \brief A <tt>\ref vx_matrix</tt>. */
VX_TYPE_CONVOLUTION = 0x80C,/*!< \brief A <tt>\ref vx_convolution</tt>. */
VX_TYPE_SCALAR = 0x80D,/*!< \brief A <tt>\ref vx_scalar</tt>. when needed to be completely generic for kernel validation. */
VX_TYPE_ARRAY = 0x80E,/*!< \brief A <tt>\ref vx_array</tt>. */
VX_TYPE_IMAGE = 0x80F,/*!< \brief A <tt>\ref vx_image</tt>. */
VX_TYPE_REMAP = 0x810,/*!< \brief A <tt>\ref vx_remap</tt>. */
VX_TYPE_ERROR = 0x811,/*!< \brief An error object which has no type. */
VX_TYPE_META_FORMAT = 0x812,/*!< \brief A <tt>\ref vx_meta_format</tt>. */
VX_TYPE_OBJECT_ARRAY = 0x813,/*!< \brief A <tt>\ref vx_object_array</tt>. */
/* \todo add new object types here */
};
2、查询Array内部对象的个数
vxQueryObjectArray( input, //等待查询的array
VX_OBJECT_ARRAY_NUMITEMS, //查询对象数量操作
&num_items, //传出参数,传出内部对象的个数
sizeof(num_items)); //传出参数的数据长度
如:查询input_arr里面的对象个数,则得到的值是 num_items = 8;
vx_size num_items;
vx_status status = vxQueryObjectArray((vx_object_array)input_arr, //等待查询的array
VX_OBJECT_ARRAY_NUMITEMS, //进行容量大小的查询操作
&num_items, //传出参数,整型数据
sizeof(vx_size))); //传出数据的字节数
三、从ObjectArray里获取一个对象:vxGetObjectArrayItem
vx_reference vxGetObjectArrayItem( vx_object_array arr, //源array
vx_uint32 index); //需要获取的地址索引
如:从image_arr中获取到第四个位置上的对象,如下代码。
vx_image image = (vx_image)vxGetObjectArrayItem(image_arr, 3);
vxReleaseImage(&image ); //释放图像
注意,有意思的地方来了。
通过vxGetObjectArrayItem获取到的对象,在没有进行release之前,只要对这个image进行操作,那么在对应的array位置上的对象,也会随之被更改。也就相当于取出了这个对象的指针,然后操作指针指向的内容。比如:
vx_image image = (vx_image)vxGetObjectArrayItem(obj->output_image_arr, 0); //获取图像
status = app_create_graph_display(obj->graph, &obj->displayobj, image); //使用图像创建显示node
vxReleaseImage(&image); //释放临时图像
这个实例,就是从array里面创建了一个临时图像,然后作为disp node的输入。
这样操作以后,Display node 就会以array的第一个元素作为输入,显示出来了。
PS:创建的临时图像一定要记得release,否则会有内存泄露的风险!!!
四、释放ObjectArray:vxReleaseObjectArray
vx_status vxReleaseObjectArray(vx_object_array *arr);
比较简单,直接使用即可释放array占用的内存。
【声明】
【欢迎转载转发,请注明出处。原创比较辛苦,请尊重原创,祝大家学习愉快!】
【博主专注嵌入式开发,具有多年嵌入式软、硬件开发经验,欢迎大家学习交流!】
【如有嵌入式相关项目需求,欢迎私信】