1574 lines
		
	
	
		
			45 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1574 lines
		
	
	
		
			45 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
/**
 | 
						|
	@brief Source file of vendor ai net sample code.
 | 
						|
 | 
						|
	@file ai_op.c
 | 
						|
 | 
						|
	@ingroup ai_net_sample
 | 
						|
 | 
						|
	@note Nothing.
 | 
						|
 | 
						|
	Copyright Novatek Microelectronics Corp. 2020.  All rights reserved.
 | 
						|
*/
 | 
						|
 | 
						|
/*-----------------------------------------------------------------------------*/
 | 
						|
/* Including Files                                                             */
 | 
						|
/*-----------------------------------------------------------------------------*/
 | 
						|
#include <stdio.h>
 | 
						|
#include <unistd.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <string.h>
 | 
						|
#include <signal.h>
 | 
						|
#include "hdal.h"
 | 
						|
#include "hd_debug.h"
 | 
						|
#include "vendor_ai.h"
 | 
						|
#if defined(_BSP_NA51068_) || defined(_BSP_NA51090_)
 | 
						|
#include "vendor_common.h"
 | 
						|
#endif
 | 
						|
 | 
						|
// platform dependent
 | 
						|
#if defined(__LINUX)
 | 
						|
#include <pthread.h>			//for pthread API
 | 
						|
#define MAIN(argc, argv) 		int main(int argc, char** argv)
 | 
						|
#define GETCHAR()				getchar()
 | 
						|
#else
 | 
						|
#include <FreeRTOS_POSIX.h>	
 | 
						|
#include <FreeRTOS_POSIX/pthread.h> //for pthread API
 | 
						|
#include <kwrap/util.h>		//for sleep API
 | 
						|
#define sleep(x)    			vos_util_delay_ms(1000*(x))
 | 
						|
#define msleep(x)    			vos_util_delay_ms(x)
 | 
						|
#define usleep(x)   			vos_util_delay_us(x)
 | 
						|
#include <kwrap/examsys.h> 	//for MAIN(), GETCHAR() API
 | 
						|
#define MAIN(argc, argv) 		EXAMFUNC_ENTRY(ai_op, argc, argv)
 | 
						|
#define GETCHAR()				NVT_EXAMSYS_GETCHAR()
 | 
						|
#endif
 | 
						|
 | 
						|
#define DEBUG_MENU 		1
 | 
						|
 | 
						|
#define CHKPNT			printf("\033[37mCHK: %s, %s: %d\033[0m\r\n",__FILE__,__func__,__LINE__)
 | 
						|
#define DBGH(x)			printf("\033[0;35m%s=0x%08X\033[0m\r\n", #x, x)
 | 
						|
#define DBGD(x)			printf("\033[0;35m%s=%d\033[0m\r\n", #x, x)
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
#define NET_PATH_ID		UINT32
 | 
						|
 | 
						|
#define VENDOR_AI_CFG  				0x000f0000  //vendor ai config
 | 
						|
 | 
						|
#define AI_RGB_BUFSIZE(w, h)		(ALIGN_CEIL_4((w) * HD_VIDEO_PXLFMT_BPP(HD_VIDEO_PXLFMT_RGB888_PLANAR) / 8) * (h))
 | 
						|
 | 
						|
#define NET_VDO_SIZE_W	1920 //max for net
 | 
						|
#define NET_VDO_SIZE_H	1080 //max for net
 | 
						|
 | 
						|
#define SV_LENGTH 		10240
 | 
						|
#define SV_FEA_LENGTH 	256
 | 
						|
 | 
						|
#define SCALE_DIM_W 384
 | 
						|
#define SCALE_DIM_H 282
 | 
						|
 | 
						|
#define ALLOC_WORKBUF_BY_USER 1
 | 
						|
 | 
						|
typedef enum _AI_OP {
 | 
						|
    AI_OP_FC                             = 0,  //deprecated 
 | 
						|
	AI_OP_PREPROC_YUV2RGB                = 1,  
 | 
						|
	AI_OP_PREPROC_YUV2RGB_SCALE          = 2,
 | 
						|
	AI_OP_PREPROC_YUV2RGB_MEANSUB_PLANE  = 3,
 | 
						|
	AI_OP_PREPROC_YUV2RGB_MEANSUB_DC     = 4,
 | 
						|
	AI_OP_PREPROC_Y2Y_UV2UV				 = 5,
 | 
						|
	AI_OP_FC_LL_MODE                     = 6,
 | 
						|
	ENUM_DUMMY4WORD(AI_OP)
 | 
						|
} AI_OP;
 | 
						|
///////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
/*-----------------------------------------------------------------------------*/
 | 
						|
/* Type Definitions                                                            */
 | 
						|
/*-----------------------------------------------------------------------------*/
 | 
						|
 | 
						|
typedef struct _MEM_PARM {
 | 
						|
	uintptr_t pa;
 | 
						|
	uintptr_t va;
 | 
						|
	UINT32 size;
 | 
						|
	uintptr_t blk;
 | 
						|
} MEM_PARM;
 | 
						|
 | 
						|
 | 
						|
/*-----------------------------------------------------------------------------*/
 | 
						|
/* Global Functions                                                             */
 | 
						|
/*-----------------------------------------------------------------------------*/
 | 
						|
 | 
						|
#if defined(_BSP_NA51068_) || defined(_BSP_NA51090_)
 | 
						|
static HD_RESULT mem_get(MEM_PARM *mem_parm, UINT32 size, UINT32 id)
 | 
						|
{
 | 
						|
	HD_RESULT ret = HD_OK;
 | 
						|
 | 
						|
	if (size == 0) {
 | 
						|
		printf("mem_alloc fail, size = 0\r\n");
 | 
						|
		ret = HD_ERR_NG;
 | 
						|
		goto exit;
 | 
						|
	}
 | 
						|
 | 
						|
	mem_parm->size = size;
 | 
						|
	mem_parm->blk = hd_common_mem_get_block(HD_COMMON_MEM_CNN_POOL, mem_parm->size, DDR_ID0);
 | 
						|
	if (HD_COMMON_MEM_VB_INVALID_BLK == mem_parm->blk) {
 | 
						|
		printf("hd_common_mem_get_block fail\r\n");
 | 
						|
		ret = HD_ERR_NG;
 | 
						|
		goto exit;
 | 
						|
	}
 | 
						|
	mem_parm->pa = hd_common_mem_blk2pa(mem_parm->blk);
 | 
						|
	if (mem_parm->pa == 0) {
 | 
						|
		printf("hd_common_mem_blk2pa fail, blk = %#lx\r\n", mem_parm->blk);
 | 
						|
		hd_common_mem_release_block(mem_parm->blk);
 | 
						|
		ret = HD_ERR_NG;
 | 
						|
		goto exit;
 | 
						|
	}
 | 
						|
	/* Must use "HD_COMMON_MEM_MEM_TYPE_CACHE", or it will cause the cpu layer to perform inefficiently */
 | 
						|
	mem_parm->va = (UINTPTR)hd_common_mem_mmap(HD_COMMON_MEM_MEM_TYPE_CACHE, mem_parm->pa, mem_parm->size);
 | 
						|
	if (mem_parm->va == 0) {
 | 
						|
		ret = HD_ERR_NG;
 | 
						|
		goto exit;
 | 
						|
	}
 | 
						|
 | 
						|
exit:
 | 
						|
	return ret;
 | 
						|
}
 | 
						|
 | 
						|
static HD_RESULT mem_rel(MEM_PARM *mem_parm)
 | 
						|
{
 | 
						|
	HD_RESULT ret = HD_OK;
 | 
						|
 | 
						|
	if (mem_parm->va) {
 | 
						|
		ret = hd_common_mem_munmap((void *)mem_parm->va, mem_parm->size);
 | 
						|
		if (ret != HD_OK) {
 | 
						|
			printf("hd_common_mem_munmap fail\n");
 | 
						|
		}
 | 
						|
	}
 | 
						|
	ret = hd_common_mem_release_block(mem_parm->blk);
 | 
						|
	if (ret != HD_OK) {
 | 
						|
		printf("hd_common_mem_release_block fail\n");
 | 
						|
	}
 | 
						|
 | 
						|
	return ret;
 | 
						|
}
 | 
						|
static HD_RESULT mem_alloc(MEM_PARM *mem_parm, CHAR* name, UINT32 size)
 | 
						|
{
 | 
						|
	return mem_get(mem_parm, size, 0);
 | 
						|
}
 | 
						|
 | 
						|
static HD_RESULT mem_free(MEM_PARM *mem_parm)
 | 
						|
{
 | 
						|
	return mem_rel(mem_parm);
 | 
						|
}
 | 
						|
#else
 | 
						|
static HD_RESULT mem_alloc(MEM_PARM *mem_parm, CHAR* name, UINT32 size)
 | 
						|
{
 | 
						|
	HD_RESULT ret = HD_OK;
 | 
						|
	UINT32 pa   = 0;
 | 
						|
	void  *va   = NULL;
 | 
						|
 | 
						|
	//alloc private pool
 | 
						|
	ret = hd_common_mem_alloc(name, &pa, (void**)&va, size, DDR_ID0);
 | 
						|
	if (ret!= HD_OK) {
 | 
						|
		return ret;
 | 
						|
	}
 | 
						|
 | 
						|
	mem_parm->pa   = pa;
 | 
						|
	mem_parm->va   = (UINT32)va;
 | 
						|
	mem_parm->size = size;
 | 
						|
	mem_parm->blk  = (UINT32)-1;
 | 
						|
 | 
						|
	return HD_OK;
 | 
						|
}
 | 
						|
 | 
						|
static HD_RESULT mem_free(MEM_PARM *mem_parm)
 | 
						|
{
 | 
						|
	HD_RESULT ret = HD_OK;
 | 
						|
	
 | 
						|
	//free private pool
 | 
						|
	ret =  hd_common_mem_free(mem_parm->pa, (void *)mem_parm->va);
 | 
						|
	if (ret!= HD_OK) {
 | 
						|
		return ret;
 | 
						|
	}
 | 
						|
	
 | 
						|
	mem_parm->pa = 0;
 | 
						|
	mem_parm->va = 0;
 | 
						|
	mem_parm->size = 0;
 | 
						|
	mem_parm->blk = (UINT32)-1;
 | 
						|
 | 
						|
	return HD_OK;
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
static INT32 mem_save(MEM_PARM *mem_parm, const CHAR *filename)
 | 
						|
{
 | 
						|
	FILE *fd;
 | 
						|
	UINT32 size = 0;
 | 
						|
 | 
						|
	fd = fopen(filename, "wb");
 | 
						|
 | 
						|
	if (!fd) {
 | 
						|
		printf("ERR: cannot open %s for write!\r\n", filename);
 | 
						|
		return -1;
 | 
						|
	}
 | 
						|
 | 
						|
	size = (INT32)fwrite((VOID *)mem_parm->va, 1, mem_parm->size, fd);
 | 
						|
	if (size != mem_parm->size) {
 | 
						|
		printf("ERR: write %s with size %ld < wanted %ld?\r\n", filename, size, mem_parm->size);
 | 
						|
	} else {
 | 
						|
		printf("write %s with %ld bytes.\r\n", filename, mem_parm->size);
 | 
						|
	}
 | 
						|
 | 
						|
	if (fd) {
 | 
						|
		fclose(fd);
 | 
						|
	}
 | 
						|
 | 
						|
	return size;
 | 
						|
}
 | 
						|
 | 
						|
static VOID mem_fill(MEM_PARM *mem_parm, int mode)
 | 
						|
{
 | 
						|
    UINT32 i = 0;
 | 
						|
 | 
						|
	if (mode == 0) {
 | 
						|
		// clear
 | 
						|
		memset((VOID *)mem_parm->va, 1, mem_parm->size); 
 | 
						|
	} else {
 | 
						|
	    // struct timeval time_temp;
 | 
						|
	    // gettimeofday(&time_temp, NULL);
 | 
						|
	    // srand((time_temp.tv_sec - time_temp.tv_sec) * 1000000 + (time_temp.tv_usec - time_temp.tv_usec));
 | 
						|
	    // for(i = 0; i < mem_parm->size; i++)
 | 
						|
	    // {
 | 
						|
	    //     ((UINT8 *)mem_parm->va)[i] = rand() & 0xff;
 | 
						|
	    // }
 | 
						|
	    for(i = 0; i < mem_parm->size; i++) {
 | 
						|
	        ((INT8 *)mem_parm->va)[i] = (i & 0x07);
 | 
						|
	    }
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
static INT32 mem_load(MEM_PARM *mem_parm, const CHAR *filename)
 | 
						|
{
 | 
						|
	FILE *fd;
 | 
						|
	INT32 size = 0;
 | 
						|
 | 
						|
	fd = fopen(filename, "rb");
 | 
						|
 | 
						|
	if (!fd) {
 | 
						|
		printf("cannot read %s\r\n", filename);
 | 
						|
		size = -1;
 | 
						|
		goto exit;
 | 
						|
	}
 | 
						|
 | 
						|
	fseek(fd, 0, SEEK_END);
 | 
						|
	size = ftell(fd);
 | 
						|
	fseek(fd, 0, SEEK_SET);
 | 
						|
 | 
						|
	// check "ai_in_buf" enough or not
 | 
						|
	if (mem_parm->size < (UINT32)size) {
 | 
						|
		printf("ERROR: ai_in_buf(%u) is not enough, input file(%u)\r\n", mem_parm->size, (UINT32)size);
 | 
						|
		size = -1;
 | 
						|
		goto exit;
 | 
						|
	}
 | 
						|
	
 | 
						|
	if (size < 0) {
 | 
						|
		printf("getting %s size failed\r\n", filename);
 | 
						|
		goto exit;
 | 
						|
	} else if ((INT32)fread((VOID *)mem_parm->va, 1, size, fd) != size) {
 | 
						|
		printf("read size < %ld\r\n", size);
 | 
						|
		size = -1;
 | 
						|
		goto exit;
 | 
						|
	}
 | 
						|
	mem_parm->size = size;
 | 
						|
 | 
						|
	// we use cpu to read memory, which needs to deal cache flush.
 | 
						|
	if(hd_common_mem_flush_cache((VOID *)mem_parm->va, mem_parm->size) != HD_OK) {
 | 
						|
        printf("flush cache failed.\r\n");
 | 
						|
    }
 | 
						|
 | 
						|
exit:
 | 
						|
	if (fd) {
 | 
						|
		fclose(fd);
 | 
						|
	}
 | 
						|
 | 
						|
	return size;
 | 
						|
}
 | 
						|
 | 
						|
/*-----------------------------------------------------------------------------*/
 | 
						|
/* Input Functions                                                             */
 | 
						|
/*-----------------------------------------------------------------------------*/
 | 
						|
typedef struct _NET_IN_CONFIG {
 | 
						|
 | 
						|
	CHAR input_filename[256];
 | 
						|
	UINT32 w;
 | 
						|
	UINT32 h;
 | 
						|
	UINT32 c;
 | 
						|
	UINT32 loff;
 | 
						|
	UINT32 fmt;
 | 
						|
	
 | 
						|
} NET_IN_CONFIG;
 | 
						|
 | 
						|
typedef struct _NET_IN {
 | 
						|
 | 
						|
	NET_IN_CONFIG in_cfg;
 | 
						|
	//MEM_PARM input_mem;
 | 
						|
	UINT32 in_id;
 | 
						|
	//VENDOR_AI_BUF src_img;
 | 
						|
		
 | 
						|
} NET_IN;
 | 
						|
 | 
						|
static NET_IN *g_in = NULL;
 | 
						|
 | 
						|
static HD_RESULT input_init(void)
 | 
						|
{
 | 
						|
	HD_RESULT ret = HD_OK;
 | 
						|
	int  i;
 | 
						|
	
 | 
						|
	for (i = 0; i < 16; i++) {
 | 
						|
		NET_IN* p_net = g_in + i;
 | 
						|
		p_net->in_id = i;
 | 
						|
	}
 | 
						|
	return ret;
 | 
						|
}
 | 
						|
 | 
						|
static HD_RESULT input_uninit(void)
 | 
						|
{
 | 
						|
	HD_RESULT ret = HD_OK;
 | 
						|
	return ret;
 | 
						|
}
 | 
						|
 | 
						|
static INT32 input_mem_config(NET_PATH_ID net_path, HD_COMMON_MEM_INIT_CONFIG* p_mem_cfg, void* p_cfg, INT32 i)
 | 
						|
{
 | 
						|
	return i;
 | 
						|
}
 | 
						|
 | 
						|
static HD_RESULT input_set_config(NET_PATH_ID net_path, NET_IN_CONFIG* p_in_cfg)
 | 
						|
{
 | 
						|
	HD_RESULT ret = HD_OK;
 | 
						|
	NET_IN* p_in = g_in + net_path;
 | 
						|
	UINT32 proc_id = p_in->in_id;
 | 
						|
	
 | 
						|
	memcpy((void*)&p_in->in_cfg, (void*)p_in_cfg, sizeof(NET_IN_CONFIG));
 | 
						|
	printf("proc_id(%u) set in_cfg: file(%s), buf=(%u,%u,%u,%u,%08x)\r\n", 
 | 
						|
		proc_id,
 | 
						|
		p_in->in_cfg.input_filename,
 | 
						|
		p_in->in_cfg.w,
 | 
						|
		p_in->in_cfg.h,
 | 
						|
		p_in->in_cfg.c,
 | 
						|
		p_in->in_cfg.loff,
 | 
						|
		p_in->in_cfg.fmt);
 | 
						|
	
 | 
						|
	return ret;
 | 
						|
}
 | 
						|
 | 
						|
/*-----------------------------------------------------------------------------*/
 | 
						|
/* Network Functions                                                             */
 | 
						|
/*-----------------------------------------------------------------------------*/
 | 
						|
 | 
						|
static HD_RESULT network_init(void)
 | 
						|
{
 | 
						|
	HD_RESULT ret = HD_OK;
 | 
						|
	
 | 
						|
	ret = hd_videoproc_init();
 | 
						|
	if (ret != HD_OK) {
 | 
						|
		printf("hd_videoproc_init fail=%d\n", ret);
 | 
						|
		return ret;
 | 
						|
	}
 | 
						|
	ret = vendor_ai_init();
 | 
						|
	if (ret != HD_OK) {
 | 
						|
		printf("vendor_ai_init fail=%d\n", ret);
 | 
						|
		return ret;
 | 
						|
	}
 | 
						|
 | 
						|
	return ret;
 | 
						|
}
 | 
						|
 | 
						|
static HD_RESULT network_uninit(void)
 | 
						|
{
 | 
						|
	HD_RESULT ret = HD_OK;
 | 
						|
	
 | 
						|
	ret = hd_videoproc_uninit();
 | 
						|
	if (ret != HD_OK) {
 | 
						|
		printf("hd_videoproc_uninit fail=%d\n", ret);
 | 
						|
	}
 | 
						|
	ret = vendor_ai_uninit();
 | 
						|
	if (ret != HD_OK) {
 | 
						|
		printf("vendor_ai_uninit fail=%d\n", ret);
 | 
						|
	}
 | 
						|
	
 | 
						|
	return ret;
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////////////////////////
 | 
						|
typedef struct _OP_PROC {
 | 
						|
 | 
						|
	UINT32 proc_id;
 | 
						|
    int op_opt;
 | 
						|
	MEM_PARM input_mem;
 | 
						|
	MEM_PARM weight_mem;
 | 
						|
	MEM_PARM output_mem;
 | 
						|
#if ALLOC_WORKBUF_BY_USER
 | 
						|
	MEM_PARM work_mem;
 | 
						|
#endif
 | 
						|
		
 | 
						|
} OP_PROC;
 | 
						|
 | 
						|
static OP_PROC *g_op = NULL;
 | 
						|
 | 
						|
static HD_RESULT op_init(void)
 | 
						|
{
 | 
						|
	HD_RESULT ret = HD_OK;
 | 
						|
	int  i;	
 | 
						|
	for (i = 0; i < 16; i++) {
 | 
						|
		OP_PROC* p_op = g_op + i;
 | 
						|
		p_op->proc_id = i;
 | 
						|
	}
 | 
						|
	return ret;
 | 
						|
}
 | 
						|
 | 
						|
static HD_RESULT op_uninit(void)
 | 
						|
{
 | 
						|
	HD_RESULT ret = HD_OK;
 | 
						|
	return ret;
 | 
						|
}
 | 
						|
 | 
						|
static HD_RESULT operator_set_config(NET_PATH_ID net_path, int in_op_opt)
 | 
						|
{
 | 
						|
	HD_RESULT ret = HD_OK;
 | 
						|
	OP_PROC* p_op = g_op + net_path;
 | 
						|
    p_op->op_opt = in_op_opt;
 | 
						|
	return ret;
 | 
						|
}
 | 
						|
 | 
						|
static HD_RESULT operator_alloc_out_buf(NET_PATH_ID op_path, NET_PATH_ID in_path)
 | 
						|
{
 | 
						|
	HD_RESULT ret = HD_OK;
 | 
						|
	OP_PROC* p_op = g_op + op_path;
 | 
						|
	NET_IN* p_in = g_in + in_path;
 | 
						|
	UINT32 proc_id = p_op->proc_id;
 | 
						|
	
 | 
						|
	// alloc result buff
 | 
						|
    switch (p_op->op_opt) {
 | 
						|
	    case AI_OP_FC: //VENDOR_AI_OP_FC
 | 
						|
	    case AI_OP_FC_LL_MODE:
 | 
						|
        {
 | 
						|
	        ret = mem_alloc(&p_op->output_mem, "user_out_buf", SV_LENGTH*4);
 | 
						|
	        if (ret != HD_OK) {
 | 
						|
	       	    printf("proc_id(%u) alloc out_buf fail\r\n", proc_id);
 | 
						|
	      	    return HD_ERR_FAIL;
 | 
						|
	        }
 | 
						|
            else {
 | 
						|
                printf("proc_id(%u) alloc out_buf OK, size = %d\r\n", proc_id, SV_LENGTH*4);
 | 
						|
            }
 | 
						|
    	    mem_fill(&p_op->output_mem, 1); 
 | 
						|
	        mem_save(&p_op->output_mem, "/mnt/sd/user_out_ori.bin");
 | 
						|
    	}
 | 
						|
        break;
 | 
						|
		case AI_OP_PREPROC_YUV2RGB_SCALE:
 | 
						|
		{
 | 
						|
			ret = mem_alloc(&p_op->output_mem, "user_out_buf", AI_RGB_BUFSIZE(SCALE_DIM_W, SCALE_DIM_H));
 | 
						|
			if (ret != HD_OK) {
 | 
						|
	        	printf("proc_id(%lu) alloc out_buf fail\r\n", proc_id);
 | 
						|
	        	return HD_ERR_FAIL;
 | 
						|
	        }
 | 
						|
            else {
 | 
						|
                printf("proc_id(%lu) alloc out_buf OK, size = %d\r\n", proc_id, AI_RGB_BUFSIZE(SCALE_DIM_W, SCALE_DIM_H));
 | 
						|
            }
 | 
						|
		}
 | 
						|
		break;
 | 
						|
		case AI_OP_PREPROC_YUV2RGB:
 | 
						|
		case AI_OP_PREPROC_YUV2RGB_MEANSUB_PLANE:
 | 
						|
		case AI_OP_PREPROC_YUV2RGB_MEANSUB_DC:
 | 
						|
		case AI_OP_PREPROC_Y2Y_UV2UV:
 | 
						|
        {
 | 
						|
			if(p_op->op_opt == AI_OP_PREPROC_YUV2RGB_SCALE) {
 | 
						|
            	ret = mem_alloc(&p_op->output_mem, "user_out_buf", AI_RGB_BUFSIZE(SCALE_DIM_W, SCALE_DIM_H));
 | 
						|
				if (ret != HD_OK) {
 | 
						|
	        		printf("proc_id(%u) alloc out_buf fail\r\n", proc_id);
 | 
						|
	        		return HD_ERR_FAIL;
 | 
						|
	        	}
 | 
						|
            	else {
 | 
						|
                	printf("proc_id(%u) alloc out_buf OK, size = %d\r\n", proc_id, AI_RGB_BUFSIZE(SCALE_DIM_W, SCALE_DIM_H));
 | 
						|
            	}
 | 
						|
			}
 | 
						|
			else {
 | 
						|
				ret = mem_alloc(&p_op->output_mem, "user_out_buf", AI_RGB_BUFSIZE(p_in->in_cfg.w, p_in->in_cfg.h));
 | 
						|
				if (ret != HD_OK) {
 | 
						|
	        		printf("proc_id(%u) alloc out_buf fail\r\n", proc_id);
 | 
						|
	        		return HD_ERR_FAIL;
 | 
						|
	        	}
 | 
						|
				else {
 | 
						|
                	printf("proc_id(%u) alloc out_buf OK, size = %d\r\n", proc_id, AI_RGB_BUFSIZE(p_in->in_cfg.w, p_in->in_cfg.h));
 | 
						|
            	}
 | 
						|
			}
 | 
						|
        }
 | 
						|
        break;
 | 
						|
        default:
 | 
						|
        break;
 | 
						|
    }
 | 
						|
	return ret;
 | 
						|
}
 | 
						|
 | 
						|
#if ALLOC_WORKBUF_BY_USER
 | 
						|
static HD_RESULT operator_alloc_work_buf(NET_PATH_ID op_path)
 | 
						|
{
 | 
						|
	HD_RESULT ret = HD_OK;
 | 
						|
	OP_PROC* p_op = g_op + op_path;
 | 
						|
	UINT32 proc_id = p_op->proc_id;
 | 
						|
	VENDOR_AI_OP_CFG_MAX wmax;
 | 
						|
 | 
						|
	switch (p_op->op_opt) {
 | 
						|
		case AI_OP_FC: 
 | 
						|
        {
 | 
						|
			wmax.op = VENDOR_AI_OP_FC;
 | 
						|
			ret = vendor_ai_op_get(proc_id, VENDOR_AI_OP_PARAM_CFG_MAX, &wmax);
 | 
						|
			if (ret != HD_OK) {
 | 
						|
		   	    printf("proc_id(%u) get work_buf fail\r\n", proc_id);
 | 
						|
		  	    return HD_ERR_FAIL;
 | 
						|
		    }
 | 
						|
			else {
 | 
						|
				printf("proc_id(%u) work_buf size = %lu\r\n", proc_id, wmax.size);
 | 
						|
			}
 | 
						|
		}
 | 
						|
		break;
 | 
						|
		case AI_OP_PREPROC_YUV2RGB:
 | 
						|
		case AI_OP_PREPROC_YUV2RGB_SCALE:
 | 
						|
		case AI_OP_PREPROC_YUV2RGB_MEANSUB_PLANE:
 | 
						|
		case AI_OP_PREPROC_YUV2RGB_MEANSUB_DC:
 | 
						|
		case AI_OP_PREPROC_Y2Y_UV2UV:
 | 
						|
		{
 | 
						|
			wmax.op = VENDOR_AI_OP_PREPROC;
 | 
						|
			ret = vendor_ai_op_get(proc_id, VENDOR_AI_OP_PARAM_CFG_MAX, &wmax);
 | 
						|
			if (ret != HD_OK) {
 | 
						|
		   	    printf("proc_id(%u) get work_buf fail\r\n", proc_id);
 | 
						|
		  	    return HD_ERR_FAIL;
 | 
						|
		    }
 | 
						|
			else {
 | 
						|
				printf("proc_id(%u) work_buf size = %lu\r\n", proc_id, wmax.size);
 | 
						|
			}
 | 
						|
		}
 | 
						|
		break;
 | 
						|
		case AI_OP_FC_LL_MODE:
 | 
						|
		{
 | 
						|
			wmax.op = VENDOR_AI_OP_LIST;
 | 
						|
			wmax.max_param[0] = SV_LENGTH;
 | 
						|
			ret = vendor_ai_op_get(proc_id, VENDOR_AI_OP_PARAM_CFG_MAX, &wmax);
 | 
						|
			if (ret != HD_OK) {
 | 
						|
		   	    printf("proc_id(%u) get work_buf fail\r\n", proc_id);
 | 
						|
		  	    return HD_ERR_FAIL;
 | 
						|
		    }
 | 
						|
			else {
 | 
						|
				printf("proc_id(%u) work_buf size = %lu\r\n", proc_id, wmax.size);
 | 
						|
			}
 | 
						|
		}
 | 
						|
		break;
 | 
						|
	}
 | 
						|
	
 | 
						|
	// alloc work buff
 | 
						|
    ret = mem_alloc(&p_op->work_mem, "op_work_buf", wmax.size);
 | 
						|
    if (ret != HD_OK) {
 | 
						|
   	    printf("proc_id(%u) alloc work_buf fail\r\n", proc_id);
 | 
						|
  	    return HD_ERR_FAIL;
 | 
						|
    }
 | 
						|
            
 | 
						|
	return ret;
 | 
						|
}
 | 
						|
 | 
						|
static HD_RESULT operator_free_work_buf(NET_PATH_ID op_path)
 | 
						|
{
 | 
						|
	HD_RESULT ret = HD_OK;
 | 
						|
	OP_PROC* p_op = g_op + op_path;
 | 
						|
	
 | 
						|
	// free work buff
 | 
						|
	mem_free(&p_op->work_mem);
 | 
						|
	
 | 
						|
	return ret;
 | 
						|
}
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
static HD_RESULT operator_free_out_buf(NET_PATH_ID op_path)
 | 
						|
{
 | 
						|
	HD_RESULT ret = HD_OK;
 | 
						|
	OP_PROC* p_op = g_op + op_path;
 | 
						|
	
 | 
						|
	// free result buff
 | 
						|
	mem_free(&p_op->output_mem);
 | 
						|
	
 | 
						|
	return ret;
 | 
						|
}
 | 
						|
 | 
						|
static HD_RESULT operator_open(NET_PATH_ID op_path, NET_PATH_ID in_path)
 | 
						|
{
 | 
						|
	HD_RESULT ret = HD_OK;
 | 
						|
	OP_PROC* p_op = g_op + op_path;
 | 
						|
	NET_IN* p_in = g_in + in_path;
 | 
						|
	UINT32 proc_id = p_op->proc_id;
 | 
						|
	VENDOR_AI_OP_CFG_WORKBUF wbuf = {0};
 | 
						|
 | 
						|
	// alloc buffer
 | 
						|
	switch (p_op->op_opt) {
 | 
						|
		case AI_OP_FC: 
 | 
						|
		case AI_OP_FC_LL_MODE:
 | 
						|
        {
 | 
						|
	        ret = mem_alloc(&p_op->input_mem, "user_in_buf", SV_FEA_LENGTH);
 | 
						|
	        if (ret != HD_OK) {
 | 
						|
	        	printf("proc_id(%u) alloc in_buf fail\r\n", proc_id);
 | 
						|
	        	return HD_ERR_FAIL;
 | 
						|
	        }
 | 
						|
	        ret = mem_alloc(&p_op->weight_mem, "user_weight_buf", SV_LENGTH*SV_FEA_LENGTH);
 | 
						|
	        if (ret != HD_OK) {
 | 
						|
	        	printf("proc_id(%u) alloc weight_buf fail\r\n", proc_id);
 | 
						|
	        	return HD_ERR_FAIL;
 | 
						|
	        }
 | 
						|
 | 
						|
	        // fill buffer
 | 
						|
	        mem_fill(&p_op->input_mem, 1); 
 | 
						|
	        mem_fill(&p_op->weight_mem, 1); 
 | 
						|
	        // save buffer
 | 
						|
	        mem_save(&p_op->input_mem, "/mnt/sd/user_in.bin"); 
 | 
						|
	        mem_save(&p_op->weight_mem, "/mnt/sd/user_weight.bin");
 | 
						|
		}
 | 
						|
        break;
 | 
						|
		case AI_OP_PREPROC_YUV2RGB:
 | 
						|
		case AI_OP_PREPROC_YUV2RGB_SCALE:
 | 
						|
		case AI_OP_PREPROC_YUV2RGB_MEANSUB_PLANE:
 | 
						|
		case AI_OP_PREPROC_YUV2RGB_MEANSUB_DC:
 | 
						|
		case AI_OP_PREPROC_Y2Y_UV2UV:
 | 
						|
        {
 | 
						|
			if(p_op->op_opt == AI_OP_PREPROC_YUV2RGB_MEANSUB_PLANE)
 | 
						|
            	ret = mem_alloc(&p_op->input_mem, "user_in_buf", 2*AI_RGB_BUFSIZE(p_in->in_cfg.w, p_in->in_cfg.h));
 | 
						|
			else
 | 
						|
				ret = mem_alloc(&p_op->input_mem, "user_in_buf", AI_RGB_BUFSIZE(p_in->in_cfg.w, p_in->in_cfg.h));
 | 
						|
			if (ret != HD_OK) {
 | 
						|
	    	    printf("proc_id(%lu) alloc in_buf fail\r\n", proc_id);
 | 
						|
	    	    return HD_ERR_FAIL;
 | 
						|
	        }
 | 
						|
            
 | 
						|
            INT32 file_len;
 | 
						|
            file_len = mem_load(&p_op->input_mem, p_in->in_cfg.input_filename);
 | 
						|
	        if (file_len < 0) {
 | 
						|
		        printf("load buf(%s) fail\r\n", p_in->in_cfg.input_filename);
 | 
						|
		        return HD_ERR_NG;
 | 
						|
	        }
 | 
						|
        	printf("load buf(%s) ok, size = %d\r\n", p_in->in_cfg.input_filename, file_len);
 | 
						|
        }
 | 
						|
        break;
 | 
						|
        default:
 | 
						|
        {
 | 
						|
            printf("Unknown op_opt");
 | 
						|
	        return HD_ERR_LIMIT;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
	}
 | 
						|
 | 
						|
	// open
 | 
						|
	ret = vendor_ai_op_open(op_path);
 | 
						|
	
 | 
						|
#if ALLOC_WORKBUF_BY_USER
 | 
						|
	//alloc work buffer
 | 
						|
	ret = operator_alloc_work_buf(op_path);
 | 
						|
 | 
						|
	//set work buffer
 | 
						|
	wbuf.pa = (&p_op->work_mem)->pa;
 | 
						|
	wbuf.va = (&p_op->work_mem)->va;
 | 
						|
	wbuf.size = (&p_op->work_mem)->size;
 | 
						|
	switch (p_op->op_opt) {
 | 
						|
		case AI_OP_FC: 
 | 
						|
        {
 | 
						|
			wbuf.op = VENDOR_AI_OP_FC;
 | 
						|
		}
 | 
						|
		break;
 | 
						|
		case AI_OP_PREPROC_YUV2RGB:
 | 
						|
		case AI_OP_PREPROC_YUV2RGB_SCALE:
 | 
						|
		case AI_OP_PREPROC_YUV2RGB_MEANSUB_PLANE:
 | 
						|
		case AI_OP_PREPROC_YUV2RGB_MEANSUB_DC:
 | 
						|
		case AI_OP_PREPROC_Y2Y_UV2UV:
 | 
						|
        {
 | 
						|
			wbuf.op = VENDOR_AI_OP_PREPROC;
 | 
						|
		}
 | 
						|
		break;
 | 
						|
		case AI_OP_FC_LL_MODE:
 | 
						|
        {
 | 
						|
			wbuf.op = VENDOR_AI_OP_LIST;
 | 
						|
		}
 | 
						|
		break;
 | 
						|
	}
 | 
						|
	ret = vendor_ai_op_set(proc_id, VENDOR_AI_OP_PARAM_CFG_WORKBUF, &wbuf);
 | 
						|
#endif
 | 
						|
	
 | 
						|
	//start
 | 
						|
	ret = vendor_ai_op_start(op_path);
 | 
						|
	return ret;
 | 
						|
}
 | 
						|
 | 
						|
static HD_RESULT operator_close(NET_PATH_ID op_path)
 | 
						|
{
 | 
						|
	HD_RESULT ret = HD_OK;
 | 
						|
	OP_PROC* p_op = g_op + op_path;
 | 
						|
 | 
						|
	//stop
 | 
						|
	ret = vendor_ai_op_stop(op_path);
 | 
						|
 | 
						|
#if ALLOC_WORKBUF_BY_USER
 | 
						|
	//free work buf
 | 
						|
	ret = operator_free_work_buf(op_path);
 | 
						|
#endif
 | 
						|
 | 
						|
	// close	
 | 
						|
	ret = vendor_ai_op_close(op_path);
 | 
						|
    // free buffer
 | 
						|
	switch (p_op->op_opt) {
 | 
						|
		case AI_OP_FC: //VENDOR_AI_OP_FC
 | 
						|
		case AI_OP_FC_LL_MODE:
 | 
						|
        {
 | 
						|
			mem_free(&p_op->input_mem);
 | 
						|
			mem_free(&p_op->weight_mem);
 | 
						|
		}
 | 
						|
        break;
 | 
						|
		case AI_OP_PREPROC_YUV2RGB:
 | 
						|
		case AI_OP_PREPROC_YUV2RGB_SCALE:
 | 
						|
		case AI_OP_PREPROC_YUV2RGB_MEANSUB_PLANE:
 | 
						|
		case AI_OP_PREPROC_YUV2RGB_MEANSUB_DC:
 | 
						|
		case AI_OP_PREPROC_Y2Y_UV2UV:
 | 
						|
        {
 | 
						|
            mem_free(&p_op->input_mem);
 | 
						|
        }
 | 
						|
        break;
 | 
						|
        default:
 | 
						|
        break;
 | 
						|
	}
 | 
						|
	return ret;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
typedef struct _VIDEO_LIVEVIEW {
 | 
						|
 | 
						|
    // (1) input 
 | 
						|
	NET_IN_CONFIG net_in_cfg;
 | 
						|
	NET_PATH_ID in_path;
 | 
						|
    
 | 
						|
 | 
						|
	// (2) operator	
 | 
						|
	NET_PATH_ID op_path;
 | 
						|
    int net_op_opt;
 | 
						|
	pthread_t  op_thread_id;
 | 
						|
	UINT32 op_start;
 | 
						|
	UINT32 op_exit;
 | 
						|
	UINT32 op_oneshot;
 | 
						|
 | 
						|
} VIDEO_LIVEVIEW;
 | 
						|
 | 
						|
static HD_RESULT init_module(void)
 | 
						|
{
 | 
						|
	HD_RESULT ret;
 | 
						|
    if ((ret = op_init()) != HD_OK)
 | 
						|
		return ret;
 | 
						|
	if ((ret = input_init()) != HD_OK)
 | 
						|
		return ret;
 | 
						|
	if ((ret = network_init()) != HD_OK)
 | 
						|
		return ret;
 | 
						|
	return HD_OK;
 | 
						|
}
 | 
						|
 | 
						|
static HD_RESULT open_module(VIDEO_LIVEVIEW *p_stream)
 | 
						|
{
 | 
						|
	HD_RESULT ret;
 | 
						|
	if ((ret = operator_open(p_stream->op_path, p_stream->in_path)) != HD_OK)
 | 
						|
		return ret;
 | 
						|
	return HD_OK;
 | 
						|
}
 | 
						|
 | 
						|
static HD_RESULT close_module(VIDEO_LIVEVIEW *p_stream)
 | 
						|
{
 | 
						|
	HD_RESULT ret;
 | 
						|
	if ((ret = operator_close(p_stream->op_path)) != HD_OK)
 | 
						|
		return ret;
 | 
						|
	return HD_OK;
 | 
						|
}
 | 
						|
 | 
						|
static HD_RESULT exit_module(void)
 | 
						|
{
 | 
						|
	HD_RESULT ret;
 | 
						|
	if ((ret = op_uninit()) != HD_OK)
 | 
						|
		return ret;
 | 
						|
	if ((ret = input_uninit()) != HD_OK)
 | 
						|
		return ret;
 | 
						|
    if ((ret = network_uninit()) != HD_OK)
 | 
						|
		return ret;
 | 
						|
	return HD_OK;
 | 
						|
}
 | 
						|
///////////////////////////////////////////////////////////////////////////////
 | 
						|
static VOID *operator_user_thread(VOID *arg);
 | 
						|
 | 
						|
static HD_RESULT operator_user_start(VIDEO_LIVEVIEW *p_stream)
 | 
						|
{
 | 
						|
	HD_RESULT ret = HD_OK;
 | 
						|
 | 
						|
	p_stream->op_start = 0;
 | 
						|
	p_stream->op_exit = 0;
 | 
						|
	p_stream->op_oneshot = 0;
 | 
						|
	
 | 
						|
	ret = pthread_create(&p_stream->op_thread_id, NULL, operator_user_thread, (VOID*)(p_stream));
 | 
						|
	if (ret < 0) {
 | 
						|
		return HD_ERR_FAIL;
 | 
						|
	}
 | 
						|
 | 
						|
	p_stream->op_start = 1;
 | 
						|
	p_stream->op_exit = 0;
 | 
						|
	p_stream->op_oneshot = 0;
 | 
						|
	
 | 
						|
	return ret;
 | 
						|
}
 | 
						|
 | 
						|
static HD_RESULT operator_user_oneshot(VIDEO_LIVEVIEW *p_stream)
 | 
						|
{
 | 
						|
	HD_RESULT ret = HD_OK;
 | 
						|
	p_stream->op_oneshot = 1;
 | 
						|
	return ret;
 | 
						|
}
 | 
						|
 | 
						|
static HD_RESULT operator_user_stop(VIDEO_LIVEVIEW *p_stream)
 | 
						|
{
 | 
						|
	HD_RESULT ret = HD_OK;
 | 
						|
	p_stream->op_exit = 1;
 | 
						|
	
 | 
						|
	pthread_join(p_stream->op_thread_id, NULL);
 | 
						|
 | 
						|
	return ret;
 | 
						|
}
 | 
						|
 | 
						|
static VOID *operator_user_thread(VOID *arg)
 | 
						|
{
 | 
						|
	HD_RESULT ret = HD_OK;
 | 
						|
	
 | 
						|
	VIDEO_LIVEVIEW *p_stream = (VIDEO_LIVEVIEW*)arg;
 | 
						|
	OP_PROC* p_op = g_op + p_stream->op_path;
 | 
						|
	NET_IN* p_in = g_in + p_stream->in_path;
 | 
						|
 | 
						|
	printf("\r\n");
 | 
						|
	while (p_stream->op_start == 0) sleep(1);
 | 
						|
 | 
						|
	printf("\r\n");
 | 
						|
	ret = operator_alloc_out_buf(p_stream->op_path, p_stream->in_path);
 | 
						|
	if (HD_OK != ret) {
 | 
						|
		printf("proc_id(%u) alloc output fail !!\n", p_stream->op_path);
 | 
						|
		goto skip;
 | 
						|
	}
 | 
						|
	
 | 
						|
	printf("\r\n");
 | 
						|
    
 | 
						|
    switch (p_op->op_opt) {
 | 
						|
		case AI_OP_FC: 
 | 
						|
        {
 | 
						|
	        while (p_stream->op_exit == 0) {
 | 
						|
 | 
						|
	        	if (p_stream->op_oneshot) {
 | 
						|
            
 | 
						|
 | 
						|
	                // 2. flush input
 | 
						|
	        		ret = hd_common_mem_flush_cache((VOID *)(&p_op->input_mem)->va, (&p_op->input_mem)->size);
 | 
						|
                    if(HD_OK != ret) {
 | 
						|
                        printf("flush cache failed.\n");
 | 
						|
                    }
 | 
						|
	        		ret = hd_common_mem_flush_cache((VOID *)(&p_op->weight_mem)->va, (&p_op->weight_mem)->size);
 | 
						|
                    if(HD_OK != ret) {
 | 
						|
                        printf("flush cache failed.\n");
 | 
						|
                    }
 | 
						|
	        		ret = hd_common_mem_flush_cache((VOID *)(&p_op->output_mem)->va, (&p_op->output_mem)->size);
 | 
						|
                    if(HD_OK != ret) {
 | 
						|
                        printf("flush cache failed.\n");
 | 
						|
                    }
 | 
						|
		        	// 3. run OP
 | 
						|
		        	{
 | 
						|
		        		/*
 | 
						|
		        		The code below is the flow of using FC 
 | 
						|
		        		suppose the input feature size is 256 bytes (defined as SV_FEA_LENGTH)
 | 
						|
		        		and the desired output length is 10240 (defined as SV_LENGTH)
 | 
						|
		        		the following sample will transpose the input 256 bytes feature (1 byte per element) into 10240*4 bytes feature (4 bytes per element)
 | 
						|
		        		
 | 
						|
		        		fc_init_param is for setting parameter of FC
 | 
						|
			        	user should set input/output/weight address
 | 
						|
			        	*/
 | 
						|
			        	VENDOR_AI_BUF src[2] = {0};
 | 
						|
			        	VENDOR_AI_BUF dest[1] = {0};
 | 
						|
			        	MEM_PARM* in_buf = &p_op->input_mem;
 | 
						|
			        	MEM_PARM* out_buf = &p_op->output_mem;
 | 
						|
			        	MEM_PARM* weight_buf = &p_op->weight_mem;
 | 
						|
		        		//pprintf("input addr pa = 0x%08X\n", (unsigned int)(in_buf->pa));
 | 
						|
			        	//pprintf("output addr pa = 0x%08X\n", (unsigned int)(out_buf->pa));
 | 
						|
			        	//pprintf("weight addr pa = 0x%08X\n", (unsigned int)(weight_buf->pa));
 | 
						|
				        
 | 
						|
		          		//set src1 as 1d tensor
 | 
						|
			        	src[0].sign = MAKEFOURCC('A','B','U','F');
 | 
						|
			        	src[0].ddr_id = 0;
 | 
						|
			        	src[0].va = in_buf->va; //< input address	 (size = SV_FEA_LENGTH bytes)
 | 
						|
			        	src[0].pa = in_buf->pa;
 | 
						|
			        	src[0].size = SV_FEA_LENGTH;
 | 
						|
			        	src[0].fmt = HD_VIDEO_PXLFMT_AI_SFIXED8(0); //fixpoint s7.0
 | 
						|
			        	src[0].width = SV_FEA_LENGTH;
 | 
						|
			        	src[0].height = 1;
 | 
						|
			        	src[0].channel = 1;
 | 
						|
			        	src[0].batch_num = 1;
 | 
						|
			        	
 | 
						|
		        		//set src2 as 2d tensor
 | 
						|
		        		src[1].sign = MAKEFOURCC('A','B','U','F');
 | 
						|
		        		src[1].ddr_id = 0;
 | 
						|
		        		src[1].va = weight_buf->va; //< sv weight address (size = SV_LENGTH*SV_FEA_LENGTH bytes)
 | 
						|
		        		src[1].pa = weight_buf->pa;
 | 
						|
		        		src[1].size = SV_FEA_LENGTH*SV_LENGTH;
 | 
						|
		        		src[1].fmt = HD_VIDEO_PXLFMT_AI_SFIXED8(0); //fixpoint s7.0
 | 
						|
			        	src[1].width = SV_FEA_LENGTH;
 | 
						|
			        	src[1].height = SV_LENGTH;
 | 
						|
			        	src[1].channel = 1;
 | 
						|
			        	src[1].batch_num = 1;
 | 
						|
		        		
 | 
						|
		        		//set dest as 1d tensor
 | 
						|
			        	dest[0].sign = MAKEFOURCC('A','B','U','F');
 | 
						|
		        		dest[0].ddr_id = 0;
 | 
						|
			        	dest[0].va = out_buf->va; //< output address	 (size = SV_LENGTH*4 bytes)
 | 
						|
			        	dest[0].pa = out_buf->pa;
 | 
						|
			        	dest[0].size = SV_LENGTH*4;
 | 
						|
			        	dest[0].fmt = HD_VIDEO_PXLFMT_AI_SFIXED32(0); //fixpoint s31.0
 | 
						|
			        	dest[0].width = SV_LENGTH;
 | 
						|
			        	dest[0].height = 1;
 | 
						|
			        	dest[0].channel = 1;
 | 
						|
			        	dest[0].batch_num = 1;
 | 
						|
 | 
						|
			        	ret = vendor_ai_op_proc(p_stream->op_path, VENDOR_AI_OP_FC, NULL, 2, src, 1, dest);
 | 
						|
		        	}
 | 
						|
		        	if (ret != 0) {
 | 
						|
		        		printf("op inference fail\n");
 | 
						|
		        		return 0;
 | 
						|
		        	}
 | 
						|
        
 | 
						|
		        	p_stream->op_oneshot = FALSE;
 | 
						|
		                	
 | 
						|
		        	printf("inference done!\n");
 | 
						|
		        	ret = hd_common_mem_flush_cache((VOID *)(&p_op->output_mem)->va, (&p_op->output_mem)->size);
 | 
						|
                  if(HD_OK != ret) {
 | 
						|
                        printf("flush cache failed.\n");
 | 
						|
                    }
 | 
						|
        
 | 
						|
		        	mem_save(&p_op->output_mem, "/mnt/sd/op_user_out.bin"); 
 | 
						|
        
 | 
						|
		        }
 | 
						|
		        usleep(100);
 | 
						|
	        }
 | 
						|
		}
 | 
						|
        break;
 | 
						|
		case AI_OP_FC_LL_MODE: 
 | 
						|
        {
 | 
						|
	        while (p_stream->op_exit == 0) {
 | 
						|
 | 
						|
	        	if (p_stream->op_oneshot) {
 | 
						|
            
 | 
						|
 | 
						|
	                // 2. flush input
 | 
						|
	        		ret = hd_common_mem_flush_cache((VOID *)(&p_op->input_mem)->va, (&p_op->input_mem)->size);
 | 
						|
                    if(HD_OK != ret) {
 | 
						|
                        printf("flush cache failed.\n");
 | 
						|
                    }
 | 
						|
	        		ret = hd_common_mem_flush_cache((VOID *)(&p_op->weight_mem)->va, (&p_op->weight_mem)->size);
 | 
						|
                    if(HD_OK != ret) {
 | 
						|
                        printf("flush cache failed.\n");
 | 
						|
                    }
 | 
						|
	        		ret = hd_common_mem_flush_cache((VOID *)(&p_op->output_mem)->va, (&p_op->output_mem)->size);
 | 
						|
                    if(HD_OK != ret) {
 | 
						|
                        printf("flush cache failed.\n");
 | 
						|
                    }
 | 
						|
		        	// 3. run OP
 | 
						|
		        	{
 | 
						|
		        		/*
 | 
						|
		        		The code below is the flow of using FC 
 | 
						|
		        		suppose the input feature size is 256 bytes (defined as SV_FEA_LENGTH)
 | 
						|
		        		and the desired output length is 10240 (defined as SV_LENGTH)
 | 
						|
		        		the following sample will transpose the input 256 bytes feature (1 byte per element) into 10240*4 bytes feature (4 bytes per element)
 | 
						|
		        		
 | 
						|
		        		fc_init_param is for setting parameter of FC
 | 
						|
			        	user should set input/output/weight address
 | 
						|
			        	*/
 | 
						|
			        	VENDOR_AI_BUF src[2] = {0};
 | 
						|
			        	VENDOR_AI_BUF dest[1] = {0};
 | 
						|
			        	MEM_PARM* in_buf = &p_op->input_mem;
 | 
						|
			        	MEM_PARM* out_buf = &p_op->output_mem;
 | 
						|
			        	MEM_PARM* weight_buf = &p_op->weight_mem;
 | 
						|
		        		//pprintf("input addr pa = 0x%08X\n", (unsigned int)(in_buf->pa));
 | 
						|
			        	//pprintf("output addr pa = 0x%08X\n", (unsigned int)(out_buf->pa));
 | 
						|
			        	//pprintf("weight addr pa = 0x%08X\n", (unsigned int)(weight_buf->pa));
 | 
						|
				        
 | 
						|
		          		//set src1 as 1d tensor
 | 
						|
			        	src[0].sign = MAKEFOURCC('A','B','U','F');
 | 
						|
			        	src[0].ddr_id = 0;
 | 
						|
			        	src[0].va = in_buf->va; //< input address	 (size = SV_FEA_LENGTH bytes)
 | 
						|
			        	src[0].pa = in_buf->pa; //must 4 bytes align!
 | 
						|
			        	src[0].size = SV_FEA_LENGTH;
 | 
						|
			        	src[0].fmt = HD_VIDEO_PXLFMT_AI_SFIXED8(0); //fixpoint s7.0
 | 
						|
			        	src[0].width = SV_FEA_LENGTH;
 | 
						|
			        	src[0].height = 1;
 | 
						|
			        	src[0].channel = 1;
 | 
						|
			        	src[0].batch_num = 1;
 | 
						|
			        	
 | 
						|
		        		//set src2 as 2d tensor
 | 
						|
		        		src[1].sign = MAKEFOURCC('A','B','U','F');
 | 
						|
		        		src[1].ddr_id = 0;
 | 
						|
		        		src[1].va = weight_buf->va; //< sv weight address (size = SV_LENGTH*SV_FEA_LENGTH bytes)
 | 
						|
		        		src[1].pa = weight_buf->pa; //must 4 bytes align!
 | 
						|
		        		src[1].size = SV_FEA_LENGTH*SV_LENGTH;
 | 
						|
		        		src[1].fmt = HD_VIDEO_PXLFMT_AI_SFIXED8(0); //fixpoint s7.0
 | 
						|
			        	src[1].width = SV_FEA_LENGTH;
 | 
						|
			        	src[1].height = SV_LENGTH;
 | 
						|
			        	src[1].channel = 1;
 | 
						|
			        	src[1].batch_num = 1;
 | 
						|
		        		
 | 
						|
		        		//set dest as 1d tensor
 | 
						|
			        	dest[0].sign = MAKEFOURCC('A','B','U','F');
 | 
						|
		        		dest[0].ddr_id = 0;
 | 
						|
			        	dest[0].va = out_buf->va; //< output address	 (size = SV_LENGTH*4 bytes)
 | 
						|
			        	dest[0].pa = out_buf->pa; //must 4 bytes align!
 | 
						|
			        	dest[0].size = SV_LENGTH*4;
 | 
						|
			        	dest[0].fmt = HD_VIDEO_PXLFMT_AI_SFIXED32(0); //fixpoint s31.0
 | 
						|
			        	dest[0].width = SV_LENGTH;
 | 
						|
			        	dest[0].height = 1;
 | 
						|
			        	dest[0].channel = 1;
 | 
						|
			        	dest[0].batch_num = 1;
 | 
						|
 | 
						|
						ret = vendor_ai_op_add(p_stream->op_path, VENDOR_AI_OP_LIST, NULL, 2, src, 1, dest);
 | 
						|
						if (ret != HD_OK) {
 | 
						|
					   	    printf("proc_id(%u) vendor_ai_op_add fail\r\n", p_stream->op_path);
 | 
						|
					    }
 | 
						|
						
 | 
						|
						ret = hd_common_mem_flush_cache((VOID *)(&p_op->work_mem)->va, (&p_op->work_mem)->size);
 | 
						|
                    	if(HD_OK != ret) {
 | 
						|
                        	printf("flush cache failed.\n");
 | 
						|
                    	}
 | 
						|
						
 | 
						|
			        	ret = vendor_ai_op_proc(p_stream->op_path, VENDOR_AI_OP_LIST, NULL, 0, NULL, 0, NULL);
 | 
						|
						if (ret != HD_OK) {
 | 
						|
					   	    printf("proc_id(%u) vendor_ai_op_proc for run fc ll fail\r\n", p_stream->op_path);
 | 
						|
    					}
 | 
						|
						
 | 
						|
		        	}
 | 
						|
        
 | 
						|
		        	p_stream->op_oneshot = FALSE;
 | 
						|
		                	
 | 
						|
		        	printf("inference done!\n");
 | 
						|
		        	ret = hd_common_mem_flush_cache((VOID *)(&p_op->output_mem)->va, (&p_op->output_mem)->size);
 | 
						|
                  if(HD_OK != ret) {
 | 
						|
                        printf("flush cache failed.\n");
 | 
						|
                    }
 | 
						|
        
 | 
						|
		        	mem_save(&p_op->output_mem, "/mnt/sd/op_user_out.bin"); 
 | 
						|
        
 | 
						|
		        }
 | 
						|
		        usleep(100);
 | 
						|
	        }		
 | 
						|
		}
 | 
						|
        break;
 | 
						|
		/*current support preproc function
 | 
						|
		[format]
 | 
						|
		Y -> Y
 | 
						|
		UV -> UV
 | 
						|
		RGB -> RGB
 | 
						|
		YUV -> RGB
 | 
						|
		[param]
 | 
						|
		meansub plane mode: (using p_out_sub in VENDOR_AI_OP_PREPROC_PARAM) 
 | 
						|
		meansub dc mode: (using p_out_sub in VENDOR_AI_OP_PREPROC_PARAM)
 | 
						|
		Bilinear Scaling down: (using scale_dim in VENDOR_AI_OP_PREPROC_PARAM)
 | 
						|
		*/
 | 
						|
        case AI_OP_PREPROC_YUV2RGB:
 | 
						|
		case AI_OP_PREPROC_YUV2RGB_SCALE:
 | 
						|
		case AI_OP_PREPROC_YUV2RGB_MEANSUB_PLANE:
 | 
						|
		case AI_OP_PREPROC_YUV2RGB_MEANSUB_DC: 
 | 
						|
        {
 | 
						|
            while (p_stream->op_exit == 0) {
 | 
						|
 | 
						|
	        	if (p_stream->op_oneshot) {
 | 
						|
                    ret = hd_common_mem_flush_cache((VOID *)(&p_op->input_mem)->va, (&p_op->input_mem)->size);
 | 
						|
                    if(HD_OK != ret) {
 | 
						|
                        printf("flush cache failed.\n");
 | 
						|
                    }
 | 
						|
                    ret = hd_common_mem_flush_cache((VOID *)(&p_op->output_mem)->va, (&p_op->output_mem)->size);
 | 
						|
                    if(HD_OK != ret) {
 | 
						|
                        printf("flush cache failed.\n");
 | 
						|
                    }
 | 
						|
                    // 3. run OP
 | 
						|
		        	{
 | 
						|
                        VENDOR_AI_BUF src[2] = {0};
 | 
						|
			        	VENDOR_AI_BUF dest[3] = {0};
 | 
						|
			        	MEM_PARM* in_buf = &p_op->input_mem;
 | 
						|
			        	MEM_PARM* out_buf = &p_op->output_mem;
 | 
						|
                        NET_IN_CONFIG in_cfg = p_in->in_cfg;
 | 
						|
                        VENDOR_AI_OP_PREPROC_PARAM p_parm = {0};
 | 
						|
 | 
						|
                        //set src1 as 1d tensor
 | 
						|
						src[0].sign = MAKEFOURCC('A','B','U','F');
 | 
						|
						src[0].ddr_id = 0;
 | 
						|
						src[0].va = in_buf->va; //< input address	 
 | 
						|
						src[0].pa = in_buf->pa; //must 2 bytes align!
 | 
						|
						src[0].size = in_cfg.loff * in_cfg.h;
 | 
						|
						src[0].fmt = HD_VIDEO_PXLFMT_Y8;
 | 
						|
						src[0].width = in_cfg.w;
 | 
						|
						src[0].height = in_cfg.h;
 | 
						|
						src[0].line_ofs = in_cfg.loff;
 | 
						|
						src[0].channel = 1;
 | 
						|
						src[0].batch_num = 1;
 | 
						|
 | 
						|
                        //set src2 as 1d tensor
 | 
						|
						src[1].sign = MAKEFOURCC('A','B','U','F');
 | 
						|
						src[1].ddr_id = 0;
 | 
						|
						src[1].va = in_buf->va + src[0].size; //< input address	 
 | 
						|
						src[1].pa = in_buf->pa + src[0].size; //must 2 bytes align!
 | 
						|
						src[1].size = in_cfg.loff * in_cfg.h;
 | 
						|
						src[1].fmt = HD_VIDEO_PXLFMT_UV; 
 | 
						|
						src[1].width = in_cfg.w;
 | 
						|
						src[1].height = in_cfg.h;
 | 
						|
						src[1].line_ofs = in_cfg.loff;
 | 
						|
						src[1].channel = 1;
 | 
						|
						src[1].batch_num = 1;
 | 
						|
 | 
						|
						if(p_op->op_opt == AI_OP_PREPROC_YUV2RGB_SCALE) {
 | 
						|
							//set dest1 as 1d tensor
 | 
						|
							dest[0].sign = MAKEFOURCC('A','B','U','F');
 | 
						|
							dest[0].ddr_id = 0;
 | 
						|
							dest[0].va = out_buf->va; //< output address	 
 | 
						|
							dest[0].pa = out_buf->pa;
 | 
						|
							dest[0].size = SCALE_DIM_W * SCALE_DIM_H;
 | 
						|
							dest[0].fmt = HD_VIDEO_PXLFMT_R8;
 | 
						|
							dest[0].width = SCALE_DIM_W;
 | 
						|
							dest[0].height = SCALE_DIM_H;
 | 
						|
							dest[0].line_ofs = SCALE_DIM_W;
 | 
						|
							dest[0].channel = 1;
 | 
						|
							dest[0].batch_num = 1;
 | 
						|
 | 
						|
							//set dest2 as 1d tensor
 | 
						|
							dest[1].sign = MAKEFOURCC('A','B','U','F');
 | 
						|
							dest[1].ddr_id = 0;
 | 
						|
							dest[1].va = out_buf->va + dest[0].size; //< output address	 
 | 
						|
							dest[1].pa = out_buf->pa + dest[0].size;
 | 
						|
							dest[1].size = SCALE_DIM_W * SCALE_DIM_H;
 | 
						|
							dest[1].fmt = HD_VIDEO_PXLFMT_G8;
 | 
						|
							dest[1].width = SCALE_DIM_W;
 | 
						|
							dest[1].height = SCALE_DIM_H;
 | 
						|
							dest[1].line_ofs = SCALE_DIM_W;
 | 
						|
							dest[1].channel = 1;
 | 
						|
							dest[1].batch_num = 1;
 | 
						|
 | 
						|
							//set dest3 as 1d tensor
 | 
						|
							dest[2].sign = MAKEFOURCC('A','B','U','F');
 | 
						|
							dest[2].ddr_id = 0;
 | 
						|
							dest[2].va = out_buf->va + 2*dest[0].size; //< output address		 
 | 
						|
							dest[2].pa = out_buf->pa + 2*dest[0].size;
 | 
						|
							dest[2].size = SCALE_DIM_W * SCALE_DIM_H;
 | 
						|
							dest[2].fmt = HD_VIDEO_PXLFMT_B8;
 | 
						|
							dest[2].width = SCALE_DIM_W;
 | 
						|
							dest[2].height = SCALE_DIM_H;
 | 
						|
							dest[2].line_ofs = SCALE_DIM_W;
 | 
						|
							dest[2].channel = 1;
 | 
						|
							dest[2].batch_num = 1;
 | 
						|
						}
 | 
						|
						else {
 | 
						|
							//set dest1 as 1d tensor
 | 
						|
							dest[0].sign = MAKEFOURCC('A','B','U','F');
 | 
						|
							dest[0].ddr_id = 0;
 | 
						|
							dest[0].va = out_buf->va; //< output address	 
 | 
						|
							dest[0].pa = out_buf->pa;
 | 
						|
							dest[0].size = in_cfg.loff * in_cfg.h;
 | 
						|
							dest[0].fmt = HD_VIDEO_PXLFMT_R8;
 | 
						|
							dest[0].width = in_cfg.w;
 | 
						|
							dest[0].height = in_cfg.h;
 | 
						|
							dest[0].line_ofs = in_cfg.w;
 | 
						|
							dest[0].channel = 1;
 | 
						|
							dest[0].batch_num = 1;
 | 
						|
 | 
						|
							//set dest2 as 1d tensor
 | 
						|
							dest[1].sign = MAKEFOURCC('A','B','U','F');
 | 
						|
							dest[1].ddr_id = 0;
 | 
						|
							dest[1].va = out_buf->va + dest[0].size; //< output address	 
 | 
						|
							dest[1].pa = out_buf->pa + dest[0].size;
 | 
						|
							dest[1].size = in_cfg.loff * in_cfg.h;
 | 
						|
							dest[1].fmt = HD_VIDEO_PXLFMT_G8;
 | 
						|
							dest[1].width = in_cfg.w;
 | 
						|
							dest[1].height = in_cfg.h;
 | 
						|
							dest[1].line_ofs = in_cfg.w;
 | 
						|
							dest[1].channel = 1;
 | 
						|
							dest[1].batch_num = 1;
 | 
						|
 | 
						|
							//set dest3 as 1d tensor
 | 
						|
							dest[2].sign = MAKEFOURCC('A','B','U','F');
 | 
						|
							dest[2].ddr_id = 0;
 | 
						|
							dest[2].va = out_buf->va + 2*dest[0].size; //< output address		 
 | 
						|
							dest[2].pa = out_buf->pa + 2*dest[0].size;
 | 
						|
							dest[2].size = in_cfg.loff * in_cfg.h;
 | 
						|
							dest[2].fmt = HD_VIDEO_PXLFMT_B8;
 | 
						|
							dest[2].width = in_cfg.w;
 | 
						|
							dest[2].height = in_cfg.h;
 | 
						|
							dest[2].line_ofs = in_cfg.w;
 | 
						|
							dest[2].channel = 1;
 | 
						|
							dest[2].batch_num = 1;
 | 
						|
						}
 | 
						|
 | 
						|
                        // set func parameter
 | 
						|
 | 
						|
						//scale
 | 
						|
						if (p_op->op_opt == AI_OP_PREPROC_YUV2RGB_SCALE) {
 | 
						|
							p_parm.scale_dim.w = SCALE_DIM_W;
 | 
						|
							p_parm.scale_dim.h = SCALE_DIM_H;
 | 
						|
						}				
 | 
						|
						
 | 
						|
                        // plane mode
 | 
						|
                        if (p_op->op_opt == AI_OP_PREPROC_YUV2RGB_MEANSUB_PLANE) {
 | 
						|
							memset((VOID *)(in_buf->va + src[0].size*3), 0x80808080, src[0].size*3);   //clear buffer for sub
 | 
						|
							ret = hd_common_mem_flush_cache((VOID *)(in_buf->va + src[0].size*3), src[0].size*3);
 | 
						|
							if(HD_OK != ret) {
 | 
						|
								printf("flush cache failed.\n");
 | 
						|
							}
 | 
						|
							p_parm.p_out_sub.pa = in_buf->pa + 3*src[0].size;
 | 
						|
							p_parm.p_out_sub.va = in_buf->va + 3*src[0].size;                       
 | 
						|
							p_parm.p_out_sub.width = in_cfg.w;
 | 
						|
							p_parm.p_out_sub.height = in_cfg.h;
 | 
						|
							p_parm.p_out_sub.line_ofs = in_cfg.w*3;
 | 
						|
                        }
 | 
						|
 | 
						|
						// dc mode
 | 
						|
						if (p_op->op_opt == AI_OP_PREPROC_YUV2RGB_MEANSUB_DC) {                 
 | 
						|
							p_parm.out_sub_color[0] = 128;
 | 
						|
							p_parm.out_sub_color[1] = 127;
 | 
						|
							p_parm.out_sub_color[2] = 126;
 | 
						|
						}
 | 
						|
         
 | 
						|
                        ret = vendor_ai_op_proc(p_stream->op_path, VENDOR_AI_OP_PREPROC, &p_parm, 2, src, 3, dest);
 | 
						|
 | 
						|
                    }
 | 
						|
                    if (ret != 0) {
 | 
						|
		        		printf("op inference fail\n");
 | 
						|
		        		return 0;
 | 
						|
		        	}
 | 
						|
        
 | 
						|
		        	p_stream->op_oneshot = FALSE;
 | 
						|
		                	
 | 
						|
		        	printf("inference done!\n");
 | 
						|
		        	ret = hd_common_mem_flush_cache((VOID *)(&p_op->output_mem)->va, (&p_op->output_mem)->size);
 | 
						|
                    if(HD_OK != ret) {
 | 
						|
                        printf("flush cache failed.\n");
 | 
						|
                    }
 | 
						|
 | 
						|
                    mem_save(&p_op->output_mem, "/mnt/sd/op_user_out.bin");
 | 
						|
					
 | 
						|
 | 
						|
	        	}
 | 
						|
                usleep(100);
 | 
						|
            }
 | 
						|
        }
 | 
						|
        break;
 | 
						|
		case AI_OP_PREPROC_Y2Y_UV2UV: 
 | 
						|
        {
 | 
						|
            while (p_stream->op_exit == 0) {
 | 
						|
 | 
						|
	        	if (p_stream->op_oneshot) {
 | 
						|
                    ret = hd_common_mem_flush_cache((VOID *)(&p_op->input_mem)->va, (&p_op->input_mem)->size);
 | 
						|
                    if(HD_OK != ret) {
 | 
						|
                        printf("flush cache failed.\n");
 | 
						|
                    }
 | 
						|
                    ret = hd_common_mem_flush_cache((VOID *)(&p_op->output_mem)->va, (&p_op->output_mem)->size);
 | 
						|
                    if(HD_OK != ret) {
 | 
						|
                        printf("flush cache failed.\n");
 | 
						|
                    }
 | 
						|
                    // 3. run OP
 | 
						|
		        	
 | 
						|
                        VENDOR_AI_BUF src[2] = {0};
 | 
						|
			        	VENDOR_AI_BUF dest[2] = {0};
 | 
						|
			        	MEM_PARM* in_buf = &p_op->input_mem;
 | 
						|
			        	MEM_PARM* out_buf = &p_op->output_mem;
 | 
						|
                        NET_IN_CONFIG in_cfg = p_in->in_cfg;
 | 
						|
                        VENDOR_AI_OP_PREPROC_PARAM p_parm = {0};
 | 
						|
 | 
						|
                        //set src1 as 1d tensor
 | 
						|
						src[0].sign = MAKEFOURCC('A','B','U','F');
 | 
						|
						src[0].ddr_id = 0;
 | 
						|
						src[0].va = in_buf->va; //< input address	 
 | 
						|
						src[0].pa = in_buf->pa;
 | 
						|
						src[0].size = in_cfg.loff * in_cfg.h;
 | 
						|
						src[0].fmt = HD_VIDEO_PXLFMT_Y8;
 | 
						|
						src[0].width = in_cfg.w;
 | 
						|
						src[0].height = in_cfg.h;
 | 
						|
						src[0].line_ofs = in_cfg.loff;
 | 
						|
						src[0].channel = 1;
 | 
						|
						src[0].batch_num = 1;
 | 
						|
 | 
						|
                        //set src2 as 1d tensor
 | 
						|
						src[1].sign = MAKEFOURCC('A','B','U','F');
 | 
						|
						src[1].ddr_id = 0;
 | 
						|
						src[1].va = in_buf->va + src[0].size; //< input address	 
 | 
						|
						src[1].pa = in_buf->pa + src[0].size; //must 2 bytes align!
 | 
						|
						src[1].size = in_cfg.loff * in_cfg.h;
 | 
						|
						src[1].fmt = HD_VIDEO_PXLFMT_UV; 
 | 
						|
						src[1].width = in_cfg.w/2;
 | 
						|
						src[1].height = in_cfg.h/2;
 | 
						|
						src[1].line_ofs = in_cfg.w;
 | 
						|
						src[1].channel = 1;
 | 
						|
						src[1].batch_num = 1;
 | 
						|
 | 
						|
						//set dest1 as 1d tensor
 | 
						|
						dest[0].sign = MAKEFOURCC('A','B','U','F');
 | 
						|
						dest[0].ddr_id = 0;
 | 
						|
						dest[0].va = out_buf->va; //< output address	 
 | 
						|
						dest[0].pa = out_buf->pa;
 | 
						|
						dest[0].size = SCALE_DIM_W * SCALE_DIM_H;
 | 
						|
						dest[0].fmt = HD_VIDEO_PXLFMT_Y8;
 | 
						|
						dest[0].width = SCALE_DIM_W;
 | 
						|
						dest[0].height = SCALE_DIM_H;
 | 
						|
						dest[0].line_ofs = SCALE_DIM_W;
 | 
						|
						dest[0].channel = 1;
 | 
						|
						dest[0].batch_num = 1;
 | 
						|
 | 
						|
						//set dest2 as 1d tensor
 | 
						|
						dest[1].sign = MAKEFOURCC('A','B','U','F');
 | 
						|
						dest[1].ddr_id = 0;
 | 
						|
						dest[1].va = out_buf->va + dest[0].size; //< output address	 
 | 
						|
						dest[1].pa = out_buf->pa + dest[0].size;
 | 
						|
						dest[1].size = SCALE_DIM_W * SCALE_DIM_H / 2;
 | 
						|
						dest[1].fmt = HD_VIDEO_PXLFMT_UV;
 | 
						|
						dest[1].width = SCALE_DIM_W/2;
 | 
						|
						dest[1].height = SCALE_DIM_H/2;
 | 
						|
						dest[1].line_ofs = SCALE_DIM_W;
 | 
						|
						dest[1].channel = 1;
 | 
						|
						dest[1].batch_num = 1;
 | 
						|
 | 
						|
                        // set func parameter
 | 
						|
                        
 | 
						|
						//scale
 | 
						|
						p_parm.scale_dim.w = SCALE_DIM_W;
 | 
						|
						p_parm.scale_dim.h = SCALE_DIM_H;	 
 | 
						|
         
 | 
						|
                        ret = vendor_ai_op_proc(p_stream->op_path, VENDOR_AI_OP_PREPROC, &p_parm, 1, src, 1, dest);
 | 
						|
 | 
						|
						p_parm.scale_dim.w = SCALE_DIM_W/2;
 | 
						|
						p_parm.scale_dim.h = SCALE_DIM_H/2;
 | 
						|
						
 | 
						|
						ret = vendor_ai_op_proc(p_stream->op_path, VENDOR_AI_OP_PREPROC, &p_parm, 1, src+1, 1, dest+1);
 | 
						|
 | 
						|
                    
 | 
						|
                    if (ret != 0) {
 | 
						|
		        		printf("op inference fail\n");
 | 
						|
		        		return 0;
 | 
						|
		        	}
 | 
						|
        
 | 
						|
		        	p_stream->op_oneshot = FALSE;
 | 
						|
		                	
 | 
						|
		        	printf("inference done!\n");
 | 
						|
		        	ret = hd_common_mem_flush_cache((VOID *)(&p_op->output_mem)->va, (&p_op->output_mem)->size);
 | 
						|
                    if(HD_OK != ret) {
 | 
						|
                        printf("flush cache failed.\n");
 | 
						|
                    }
 | 
						|
 | 
						|
                    mem_save(&p_op->output_mem, "/mnt/sd/op_user_out.bin");
 | 
						|
 | 
						|
	        	}
 | 
						|
                usleep(100);
 | 
						|
            }	
 | 
						|
		}
 | 
						|
		break;
 | 
						|
        default:
 | 
						|
        break;
 | 
						|
    }
 | 
						|
	
 | 
						|
	ret = operator_free_out_buf(p_stream->op_path);
 | 
						|
	if (HD_OK != ret) {
 | 
						|
		printf("proc_id(%u) free output fail !!\n", p_stream->op_path);
 | 
						|
		goto skip;
 | 
						|
	}
 | 
						|
skip:
 | 
						|
	
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
/*-----------------------------------------------------------------------------*/
 | 
						|
/* Interface Functions                                                         */
 | 
						|
/*-----------------------------------------------------------------------------*/
 | 
						|
MAIN(argc, argv)
 | 
						|
{
 | 
						|
	VIDEO_LIVEVIEW stream[2] = {0}; //0: net proc, 1: op path
 | 
						|
	HD_COMMON_MEM_INIT_CONFIG mem_cfg = {0};
 | 
						|
    INT32 idx;
 | 
						|
	HD_RESULT ret;
 | 
						|
	INT key;
 | 
						|
 | 
						|
	NET_IN_CONFIG in_cfg = {
 | 
						|
		.input_filename = "/mnt/sd/jpg/YUV420_SP_W512H376.bin",
 | 
						|
		.w = 512,
 | 
						|
		.h = 376,
 | 
						|
		.c = 2,
 | 
						|
		.loff = 512,
 | 
						|
		.fmt = HD_VIDEO_PXLFMT_YUV420
 | 
						|
	};
 | 
						|
 | 
						|
    if(argc < 2){
 | 
						|
		printf("usage : ai_op (op_opt)\n"
 | 
						|
			   "op-opt:\n"
 | 
						|
			   "0 FC\n"
 | 
						|
			   "1 PREPROC (YUV2RGB)\n"
 | 
						|
			   "2 PREPROC (YUV2RGB & scale)\n"
 | 
						|
			   "3 PREPROC (YUV2RGB & meansub_plane)\n"
 | 
						|
			   "4 PREPROC (YUV2RGB & meansub_dc)\n"
 | 
						|
			   "5 PREPROC (Y2Y_UV2UV)\n"
 | 
						|
			   "6 FC (LL MODE)\n");
 | 
						|
		return -1;
 | 
						|
	}
 | 
						|
 | 
						|
	idx = 1;
 | 
						|
 | 
						|
	// parse operator config
 | 
						|
	if (argc > idx) {
 | 
						|
		sscanf(argv[idx++], "%d", &stream[0].net_op_opt);
 | 
						|
	}		
 | 
						|
	
 | 
						|
	printf("\r\n\r\n");
 | 
						|
 | 
						|
	// malloc for g_in & g_op
 | 
						|
	g_in  = (NET_IN *)malloc(sizeof(NET_IN)*16);
 | 
						|
	g_op  = (OP_PROC *)malloc(sizeof(OP_PROC)*16);
 | 
						|
	if ((g_in == NULL) || (g_op == NULL)) {
 | 
						|
		printf("fail to malloc g_in/g_op\n");
 | 
						|
		goto exit;
 | 
						|
	}
 | 
						|
 | 
						|
	stream[0].op_path = 1;
 | 
						|
    stream[0].in_path = 1;
 | 
						|
 | 
						|
	if (stream[0].net_op_opt == AI_OP_FC)
 | 
						|
		printf("Run FC!\r\n");
 | 
						|
	else if (stream[0].net_op_opt == AI_OP_PREPROC_YUV2RGB)
 | 
						|
		printf("Run PREPROC (YUV2RGB)!\r\n");
 | 
						|
	else if (stream[0].net_op_opt == AI_OP_PREPROC_YUV2RGB_SCALE)
 | 
						|
		printf("Run PREPROC (YUV2RGB & scale)!\r\n");
 | 
						|
	else if (stream[0].net_op_opt == AI_OP_PREPROC_YUV2RGB_MEANSUB_PLANE)
 | 
						|
		printf("Run PREPROC (YUV2RGB & meansub_plane)!\r\n");
 | 
						|
	else if (stream[0].net_op_opt == AI_OP_PREPROC_YUV2RGB_MEANSUB_DC)
 | 
						|
		printf("Run PREPROC (YUV2RGB & meansub_dc)!\r\n");
 | 
						|
	else if (stream[0].net_op_opt == AI_OP_PREPROC_Y2Y_UV2UV)
 | 
						|
		printf("Run PREPROC (Y2Y_UV2UV)!\r\n");
 | 
						|
	else if (stream[0].net_op_opt == AI_OP_FC_LL_MODE)
 | 
						|
		printf("Run FC (LL MODE)!\r\n");
 | 
						|
	else {
 | 
						|
		printf("Unknown op-opt = %d",stream[0].net_op_opt);
 | 
						|
		return -1;
 | 
						|
	}
 | 
						|
	
 | 
						|
	// init hdal
 | 
						|
	ret = hd_common_init(0);
 | 
						|
	if (ret != HD_OK) {
 | 
						|
		printf("hd_common_init fail=%d\n", ret);
 | 
						|
		goto exit;
 | 
						|
	}
 | 
						|
    
 | 
						|
#if defined(_BSP_NA51055_) || defined(_BSP_NA51089_)
 | 
						|
	// set project config for AI
 | 
						|
	hd_common_sysconfig(0, (1<<16), 0, VENDOR_AI_CFG); //enable AI engine
 | 
						|
#else
 | 
						|
	ret = vendor_common_clear_pool_blk(HD_COMMON_MEM_CNN_POOL, 0);
 | 
						|
	if (ret != HD_OK) {
 | 
						|
		printf("vendor_common_clear_pool_blk fail=%d\n", ret);
 | 
						|
		goto exit;
 | 
						|
	}
 | 
						|
#endif
 | 
						|
 | 
						|
	// init mem
 | 
						|
	if(stream[0].net_op_opt != AI_OP_FC && stream[0].net_op_opt != AI_OP_FC_LL_MODE) { //for preproc
 | 
						|
		INT32 idx = 0; // mempool index
 | 
						|
		input_mem_config(stream[0].in_path, &mem_cfg, 0, idx);
 | 
						|
	}
 | 
						|
    
 | 
						|
#if defined(_BSP_NA51055_) || defined(_BSP_NA51089_)
 | 
						|
	ret = hd_common_mem_init(&mem_cfg);
 | 
						|
	if (HD_OK != ret) {
 | 
						|
		printf("hd_common_mem_init err: %d\r\n", ret);
 | 
						|
		goto exit;
 | 
						|
	}
 | 
						|
#endif
 | 
						|
	
 | 
						|
	// init all modules
 | 
						|
	ret = init_module();
 | 
						|
	if (ret != HD_OK) {
 | 
						|
		printf("init fail=%d\n", ret);
 | 
						|
		goto exit;
 | 
						|
	}
 | 
						|
 | 
						|
    if(stream[0].net_op_opt != AI_OP_FC && stream[0].net_op_opt != AI_OP_FC_LL_MODE) { //for preproc
 | 
						|
        // set open config
 | 
						|
	    ret = input_set_config(stream[0].in_path, &in_cfg);
 | 
						|
	    if (HD_OK != ret) {
 | 
						|
	    	printf("proc_id(%u) input_set_config fail=%d\n", stream[0].in_path, ret);
 | 
						|
		    goto exit;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
 | 
						|
    // set operator config
 | 
						|
    ret = operator_set_config(stream[0].op_path, stream[0].net_op_opt);
 | 
						|
    if (HD_OK != ret) {
 | 
						|
	    printf("proc_id(%u) operator_set_config fail=%d\n", stream[0].in_path, ret);
 | 
						|
		goto exit;
 | 
						|
	}
 | 
						|
 | 
						|
	// open video_liveview modules
 | 
						|
	ret = open_module(&stream[0]);
 | 
						|
	if (ret != HD_OK) {
 | 
						|
		printf("open fail=%d\n", ret);
 | 
						|
		goto exit;
 | 
						|
	}
 | 
						|
 | 
						|
// start
 | 
						|
	operator_user_start(&stream[0]);
 | 
						|
 | 
						|
	printf("Enter q to quit\n");
 | 
						|
	printf("Enter r to run once\n");
 | 
						|
	do {
 | 
						|
		key = GETCHAR();
 | 
						|
		if (key == 'r') {
 | 
						|
		
 | 
						|
			operator_user_oneshot(&stream[0]);
 | 
						|
			continue;
 | 
						|
		}
 | 
						|
		if (key == 'q' || key == 0x3) {
 | 
						|
 | 
						|
			break;
 | 
						|
		}
 | 
						|
	} while(1);
 | 
						|
 | 
						|
	// stop
 | 
						|
	operator_user_stop(&stream[0]);
 | 
						|
 | 
						|
exit:
 | 
						|
	// close video_liveview modules
 | 
						|
	ret = close_module(&stream[0]);
 | 
						|
	if (ret != HD_OK) {
 | 
						|
		printf("close fail=%d\n", ret);
 | 
						|
	}
 | 
						|
 | 
						|
	// uninit all modules
 | 
						|
	ret = exit_module();
 | 
						|
	if (ret != HD_OK) {
 | 
						|
		printf("exit fail=%d\n", ret);
 | 
						|
	}
 | 
						|
 | 
						|
 | 
						|
#if defined(_BSP_NA51055_) || defined(_BSP_NA51089_)
 | 
						|
	// uninit memory
 | 
						|
	ret = hd_common_mem_uninit();
 | 
						|
	if (ret != HD_OK) {
 | 
						|
		printf("mem fail=%d\n", ret);
 | 
						|
	}
 | 
						|
#endif
 | 
						|
 | 
						|
	// uninit hdal
 | 
						|
	ret = hd_common_uninit();
 | 
						|
	if (ret != HD_OK) {
 | 
						|
		printf("common fail=%d\n", ret);
 | 
						|
	}
 | 
						|
 | 
						|
	// free g_in & g_op
 | 
						|
	if (g_in)  free(g_in);
 | 
						|
	if (g_op)  free(g_op);
 | 
						|
 | 
						|
	return ret;
 | 
						|
}
 |