how to use vxAddUserKernel

Hi every one,

I followed OpenVX tutorial and at the exercise 3 I want to use vxAddUserKernel instead of vxAddKernel.
for this purpose I defined median_blur_validator function to checks input and output parameters as bellow but I got VX_ERROR_INVALID_PARAMETERS error.
what is wrong ?

vx_status VX_CALLBACK median_blur_validator(vx_node node, const vx_reference
		parameters[ ], vx_uint32 index, vx_meta_format metas[])
{

    if( index == 0 )
    {

        vx_df_image format = VX_DF_IMAGE_VIRT;
        ERROR_CHECK_STATUS( vxQueryImage( ( vx_image )parameters[ index ], VX_IMAGE_ATTRIBUTE_FORMAT, &format, sizeof( format ) ) );
        if( format != VX_DF_IMAGE_U8 )
        {
            return VX_ERROR_INVALID_FORMAT;
        }
    }
    else if( index == 1 )
    {
        vx_uint32 width = 0, height = 0;
        vx_image input = NULL;
        vx_parameter parameter = (vx_parameter) parameters[ index ] ;
        ERROR_CHECK_STATUS( vxQueryParameter( parameter, VX_PARAMETER_ATTRIBUTE_REF, &input, sizeof( input ) ) );
        ERROR_CHECK_STATUS( vxReleaseParameter( &parameter ) );
        ERROR_CHECK_OBJECT( input );
        ERROR_CHECK_STATUS( vxQueryImage( input, VX_IMAGE_ATTRIBUTE_WIDTH,  &width,  sizeof( width ) ) );
        ERROR_CHECK_STATUS( vxQueryImage( input, VX_IMAGE_ATTRIBUTE_HEIGHT, &height, sizeof( height ) ) );
        ERROR_CHECK_STATUS( vxReleaseImage( &input ) );

        vx_df_image format = VX_DF_IMAGE_U8;
        ERROR_CHECK_STATUS( vxSetMetaFormatAttribute( metas[0], VX_IMAGE_ATTRIBUTE_FORMAT, &format, sizeof( format ) ) );
        ERROR_CHECK_STATUS( vxSetMetaFormatAttribute( metas[0], VX_IMAGE_ATTRIBUTE_WIDTH,  &width,  sizeof( width ) ) );
        ERROR_CHECK_STATUS( vxSetMetaFormatAttribute( metas[0], VX_IMAGE_ATTRIBUTE_HEIGHT, &height, sizeof( height ) ) );
    }
    else if( index == 2 )
    {
        // parameters #2 -- scalar of type VX_TYPE_INT32
        vx_enum type = VX_TYPE_INVALID;
        ERROR_CHECK_STATUS( vxQueryScalar( ( vx_scalar )parameters[ index ], VX_SCALAR_ATTRIBUTE_TYPE, &type, sizeof( type ) ) );
//        ERROR_CHECK_STATUS( vxReleaseScalar( ( vx_scalar * )&ref ) );
        if( type != VX_TYPE_INT32 )
        {
            return VX_ERROR_INVALID_TYPE;
        }
    }
    else
    {
        // invalid input parameter
        return VX_ERROR_INVALID_PARAMETERS;
    }

    return VX_SUCCESS;
}

The third parameter of the validator function is not an “index”, but “num” - the number of elements in “parameters” array.
The function is called only once during validation stage and must check all input parameters and fill all output “metas” in one call.
Also “parameters” array holds actual reference to node’s arguments (ie. images, scalars, etc.), not “vx_parameter” objects.

The correct version of the validator function:


vx_status VX_CALLBACK median_blur_validator(vx_node node, const vx_reference parameters[ ], vx_uint32 num, vx_meta_format metas[])
{
    vx_df_image format = VX_DF_IMAGE_VIRT;
    ERROR_CHECK_STATUS( vxQueryImage((vx_image)parameters[0], VX_IMAGE_FORMAT, &format, sizeof(format)) );
    if( format != VX_DF_IMAGE_U8 )
    {
        return VX_ERROR_INVALID_FORMAT;
    }

    // Copy meta-data of 1st parameter to 2nd parameter
    ERROR_CHECK_STATUS( vxSetMetaFormatFromReference(metas[1], parameters[0]) );

    vx_enum type = VX_TYPE_INVALID;
    ERROR_CHECK_STATUS( vxQueryScalar((vx_scalar)parameters[2], VX_SCALAR_ATTRIBUTE_TYPE, &type, sizeof(type)) );
    if( type != VX_TYPE_INT32 )
    {
        return VX_ERROR_INVALID_TYPE;
    }
 
    return VX_SUCCESS;
}