3516cv610在sample_aiisp上多创一路编码流,方法 - 详解

news/2025/10/8 15:45:33/文章来源:https://www.cnblogs.com/lxjshuju/p/19129725

3516cv610在sample_aiisp上多创一路编码流,方法

首先确保 vpss grp0有视频流

最好保证 已经有一路视频流能推出来

多创一路编码流思路为
将 vpss grp0又绑定给 vpss_chn1

vpss_chn1有绑定给 venc_chn1

这样我们就多创了一路视频流。

这里思路完全正确 可以实现

整个工程代码,在底部链接获取

aiisp需要对 sc500ai寄存器进行操作

// 改变 sc500ai的bayer格式// 改变为 RGGB的格式3211, 0x053213,  0x05

sdk说明

sdk_010打AOV的补丁

硬件

cv610_20s+sc500ai

下面是 aiisp的例子,多创建一路编码流

// sample_aiisp.c  #include #include "sample_comm.h"#include "sample_ipc.h"#include "sample_aibnr.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include   #include "rtsp_demo.h"  rtsp_demo_handle g_rtsplive = NULL;rtsp_session_handle session= NULL; static td_void sample_aiisp_usage(const char *prg_name){    printf("usage : %s  \n", prg_name);    printf("index:\n");    printf("    (0) aibnr line mode : base mode, has reference frame\n");    printf("    (1) aibnr line pro mode\n");} static td_void sample_register_sig_handler(td_void (*sig_handle)(td_s32)){    struct sigaction sa;     (td_void)memset_s(&sa, sizeof(struct sigaction), 0, sizeof(struct sigaction));    sa.sa_handler = sig_handle;    sa.sa_flags = 0;    sigaction(SIGINT, &sa, TD_NULL);    sigaction(SIGTERM, &sa, TD_NULL);} static td_s32 sample_aiisp_msg_proc_vb_pool_share(td_s32 pid){    td_s32 ret;    td_u32 i;    td_bool isp_states[OT_VI_MAX_PIPE_NUM];#ifndef SAMPLE_MEM_SHARE_ENABLE    ot_vb_common_pools_id pools_id = {0};     if (ss_mpi_vb_get_common_pool_id(&pools_id) != TD_SUCCESS) {        sample_print("get common pool_id failed!\n");        return TD_FAILURE;    }     for (i = 0; i msg_type) {        case SAMPLE_MSG_TYPE_VB_POOL_SHARE_REQ: {            if (msg_res_buf == TD_NULL) {                return TD_FAILURE;            }            ret = sample_aiisp_msg_proc_vb_pool_share(msg_req_buf->msg_data.pid);            msg_res_buf->msg_type = SAMPLE_MSG_TYPE_VB_POOL_SHARE_RES;            msg_res_buf->msg_data.is_req_success = (ret == TD_SUCCESS) ? TD_TRUE : TD_FALSE;            break;        }        case SAMPLE_MSG_TYPE_VB_POOL_UNSHARE_REQ: {            if (msg_res_buf == TD_NULL) {                return TD_FAILURE;            }            sample_aiisp_msg_proc_vb_pool_unshare(msg_req_buf->msg_data.pid);            msg_res_buf->msg_type = SAMPLE_MSG_TYPE_VB_POOL_UNSHARE_RES;            msg_res_buf->msg_data.is_req_success = TD_TRUE;            break;        }        default: {            printf("unsupported msg type(%ld)!\n", msg_req_buf->msg_type);            return TD_FAILURE;        }    }    return TD_SUCCESS;} td_s32 sample_comm_save_frame_to_file(td_s32 index, sample_comm_venc_stream_proc_info *stream_proc_info,    ot_venc_stream *stream, ot_venc_stream_buf_info *stream_buf_info, ot_payload_type *payload_type){// printf("\n\nfunction: %s    line: %d\n\n", __FUNCTION__, __LINE__);      td_s32 ret, fd;    if (payload_type[index] == OT_PT_JPEG) {        if (snprintf_s(stream_proc_info->file_name[index], FILE_NAME_LEN, FILE_NAME_LEN - 1, "./") pack);            return SAMPLE_RETURN_NULL;        }        if (realpath(stream_proc_info->file_name[index], stream_proc_info->real_file_name[index]) == TD_NULL) {            free(stream->pack);            sample_print("chn[%d] stream file path error\n", stream_proc_info->venc_chn);            return SAMPLE_RETURN_NULL;        }         if (snprintf_s(stream_proc_info->real_file_name[index], FILE_NAME_LEN, FILE_NAME_LEN - 1,            "stream_chn%d_%u%s", index, stream_proc_info->picture_cnt[index], stream_proc_info->file_postfix) pack);            return SAMPLE_RETURN_NULL;        }        stream_proc_info->file[index] = fopen(stream_proc_info->real_file_name[index], "wb");        if (!stream_proc_info->file[index]) {            free(stream->pack);            sample_print("open file err!\n");            return SAMPLE_RETURN_NULL;        }        fd = fileno(stream_proc_info->file[index]);        fchmod(fd, S_IRUSR | S_IWUSR);    } #ifndef __LITEOS__    ot_unused(stream_buf_info);    ret = sample_comm_venc_save_stream(stream_proc_info->file[index], stream); // printf("\nindex is %d\n", index);	//rtsp发送	td_u8 * pStremData = NULL;int nSize = 0;td_u32 j=0;	if(index==1){//发送venc通道1	    for (j = 0; j pack_cnt; j++) {	        //(td_void)fwrite(stream->pack[j].addr + stream->pack[j].offset, stream->pack[j].len - stream->pack[j].offset, 1, fd);	        if(stream->pack[j].data_type.h264_type == OT_VENC_H264_NALU_SEI) continue;//暂时去掉SEI帧			pStremData = stream->pack[j].addr + stream->pack[j].offset;			nSize = stream->pack[j].len - stream->pack[j].offset;			if(g_rtsplive)			{				rtsp_sever_tx_video(g_rtsplive,session,pStremData,nSize,stream->pack[j].pts);			}	    }	}	ret = TD_SUCCESS;    #else    ret = sample_comm_venc_save_stream_phys_addr(stream_proc_info->file[index], &stream_buf_info[index], stream);#endif    if (ret != TD_SUCCESS) {        free(stream->pack);        stream->pack = TD_NULL;        sample_print("save stream failed!\n");        return SAMPLE_RETURN_BREAK;    }     return TD_SUCCESS;}  td_s32 main(td_s32 argc, td_char *argv[]){	g_rtsplive = create_rtsp_demo(554);//554端口创建rtspserver	session= create_rtsp_session(g_rtsplive,"/test.264");//创建rtsp会话 rtsp://[IP]/test.264     td_s32 ret = TD_FAILURE;    td_u32 index;    td_char *para_stop;     sample_aiisp_usage(argv[0]);     sample_register_sig_handler(sample_aiisp_handle_sig);      if (sample_ipc_server_init(sample_aiisp_ipc_msg_proc) != TD_SUCCESS)     {        printf("sample_ipc_server_init failed!!!\n");    }      sample_aibnr_param aibnr_param = {0};    aibnr_param.is_wdr_mode = TD_FALSE;    aibnr_param.ref_mode = OT_AIBNR_REF_MODE_NORM;    aibnr_param.is_blend = TD_FALSE;    aibnr_param.is_pro = TD_FALSE;    ret = sample_aibnr(&aibnr_param);        if ((ret == TD_SUCCESS) && (sample_aiisp_get_sig() == 0))     {        sample_print("\033[0;32mprogram exit normally!\033[0;39m\n");    }     else {        sample_print("\033[0;31mprogram exit abnormally!\033[0;39m\n");    } server_deinit:    sample_ipc_server_deinit(); exit:#ifdef __LITEOS__    return ret;#else    exit(ret);#endif}

主要在 sample_aibnr.c、sample_aiisp_common.c增加编码通道

// sample_aibnr.c  #include "sample_aibnr.h"#include "sample_aiisp_common.h"#include "ss_mpi_aibnr.h" #define VB_AIBNR_LINE_CNT 4#define VB_AIBNR_TNR_CNT 4#define VB_AIBNR_COMMON_VB_CNT 3// #define VB_AIBNR_COMMON_VB_CNT 1  //----------------------------add a chnnel stream 开始#define CHN_NUM_MAX 2 typedef struct {    td_s32 venc_chn_num;    ot_size enc_size[CHN_NUM_MAX];    td_s32 vpss_chn_depth;} sample_venc_param;//----------------------------add a chnnel stream 结束             static td_u16 g_r_calib_lut[OT_AIBNR_NLC_LUT_NUM] = {    1043, 1043, 1029, 1024, 1021, 1020, 1019, 1018, 1017, 1017, 1016,    1015, 1014, 1014, 1013, 1013, 1012, 1012, 1012, 1011, 1011, 1011,    1010, 1010, 1010, 1010, 1009, 1009, 1008, 1008, 1008, 1000}; static td_u16 g_b_calib_lut[OT_AIBNR_NLC_LUT_NUM] = {    1024, 1024, 1027, 1028, 1029, 1029, 1029, 1029, 1027, 1024, 1021,    1019, 1018, 1016, 1015, 1013, 1011, 1009, 1008, 1006, 1005, 1004,    1004, 1004, 1003, 1003, 1003, 1002, 1002, 1002, 1002, 1000}; static td_s32 sample_aibnr_set_nlc(ot_aibnr_nlc *nlc){    td_s32 ret;     nlc->enable = TD_FALSE;    nlc->step_bit = 0x3;     ret = memcpy_s(nlc->r_fact, sizeof(nlc->r_fact), g_r_calib_lut, sizeof(g_r_calib_lut));    if (ret != EOK) {        printf("memcpy_s failed!\n");        return TD_FAILURE;    }    ret = memcpy_s(nlc->b_fact, sizeof(nlc->b_fact), g_b_calib_lut, sizeof(g_b_calib_lut));    if (ret != EOK) {        printf("memcpy_s failed!\n");        return TD_FAILURE;    }     return TD_SUCCESS;} static td_s32 sample_aibnr_set_model_attr(td_void){    td_s32 ret;    ot_aibnr_model_list list = {0};    ot_aibnr_model_attr model_attr = {0};     ret = ss_mpi_aibnr_query_model_list(&list);    if (ret != TD_SUCCESS) {        sample_print("ss_mpi_aibnr_query_model_list error\n");        return ret;    }     printf("model list info:\n");    printf("num:%d\n", list.num);     for (td_u32 i = 0; i is_blend;    aibnr_attr.op_type = OT_OP_MODE_MANUAL;    aibnr_attr.manual_attr.sfs = 31; /* sfs: 31 */    ret = sample_aibnr_set_nlc(&aibnr_attr.manual_attr.nlc);    if (ret != TD_SUCCESS)     {        printf("call sample_aibnr_set_nlc failed!\n");        return TD_FAILURE;    }     ret = ss_mpi_aibnr_set_attr(vi_pipe, &aibnr_attr);    if (ret != TD_SUCCESS)     {        sample_print("ss_mpi_aibnr_set_attr error\n");        return ret;    }     if (aibnr_param->is_pro == TD_FALSE)     {        sample_aibnr_set_model_attr();    }     return TD_SUCCESS;} // 有调用static td_s32 sample_aibnr_load_model(ot_aibnr_model *model_info, td_s32 *model_id, td_char *model_file){    td_s32 ret;     ot_aiisp_model *model = &model_info->model; // printf("\n\nfunction: %s    line: %d\n\n", __FUNCTION__, __LINE__);     if (model->mem_info.virt_addr == TD_NULL)     {        ret = sample_aiisp_load_mem((ot_aiisp_mem_info *)&(model->mem_info), model_file);        if (ret != TD_SUCCESS) {            sample_print("sample_aiisp_load_mem error\n");            return ret;        }    }     ret = ss_mpi_aibnr_load_model(model_info, model_id);    if (ret != TD_SUCCESS) {        sample_print("ss_mpi_aibnr_load_model error(%#x)\n", ret);        goto unload_mem;    }     return ret; unload_mem:    sample_aiisp_unload_mem((ot_aiisp_mem_info *)&(model->mem_info));    return ret;} static td_s32 sample_aibnr_unload_model(ot_aibnr_model *model, td_s32 model_id){    td_s32 ret;     ret = ss_mpi_aibnr_unload_model(model_id);    if (ret != TD_SUCCESS) {        sample_print("ss_mpi_aibnr_unload_cfg error(%#x)\n", ret);    }     sample_aiisp_unload_mem((ot_aiisp_mem_info *)&(model->model.mem_info));     return ret;} // 有调用static td_s32 sample_aibnr_load(ot_size in_size, ot_aibnr_model *model_info, td_s32 *model_id,    sample_aibnr_param *aibnr_param){// printf("\n\nfunction: %s    line: %d\n\n", __FUNCTION__, __LINE__);printf("\n\nwidth is %d     height is %d\n\n", in_size.width, in_size.height);     td_s32 ret;    td_u32 max_len = 256;    td_char model_file[max_len];     if (aibnr_param->is_pro == TD_FALSE)     {printf("\n\naiisp normal bin\n\n");        ret = snprintf_s(model_file, max_len, max_len - 1, "./aibnr_model/aibnr_model_%dx%d.bin",            in_size.width, in_size.height);    }     else     {printf("\n\naiisp pro bin\n\n");        ret = snprintf_s(model_file, max_len, max_len - 1, "./aibnr_model/aibnr_model_%dx%d_pro.bin",            in_size.width, in_size.height);    }      if (ret is_wdr_mode;    model_info[0].ref_mode = aibnr_param->ref_mode;    model_info[0].nlc_en = TD_FALSE;    model_info[0].is_wdr_mode = TD_FALSE;     ret = (&model_info[0], &model_id[0], model_file);   // 这里报错,确实是这里报错        // if (ret != TD_SUCCESS)     // {    //     return ret;    // }      // 这里这个分支也会进    if (aibnr_param->is_pro == TD_FALSE)     {// 进入这个分支// printf("\n\nfunction: %s    line: %d\n\n", __FUNCTION__, __LINE__);                        // ret = snprintf_s(model_file, max_len, max_len - 1, "./aibnr_model/aibnr_model_%dx%d.bin", in_size.width, in_size.height);            ret = snprintf_s(model_file, max_len, max_len - 1, "./aibnr_model/aibnr_model_%dx%d_high_iso.bin",                in_size.width, in_size.height);            if (ret is_wdr_mode;            model_info[1].ref_mode = aibnr_param->ref_mode;            model_info[1].nlc_en = TD_FALSE;            model_info[1].is_wdr_mode = TD_FALSE;            ret = sample_aibnr_load_model(&model_info[1], &model_id[1], model_file);            // if (ret != TD_SUCCESS)            // {            //     goto unload;            // }    }      return TD_SUCCESS; unload:    sample_aibnr_unload_model(&model_info[0], model_id[0]);     return TD_FAILURE;} static td_s32 sample_aibnr_start(ot_vi_pipe vi_pipe, ot_size in_size, ot_aibnr_model *model_info, td_s32 *model_id,    td_s32 model_size, sample_aibnr_param *aibnr_param){    td_s32 ret = ss_mpi_aibnr_init();    ot_aibnr_cfg cfg;    td_s32 i;     if (ret != TD_SUCCESS) {        sample_print("ss_mpi_aibnr_init error(%#x)\n", ret);        return ret;    }     // 加载 aibnr模型文件    ret = sample_aibnr_load(in_size, model_info, model_id, aibnr_param);     if (ret != TD_SUCCESS)     {        sample_print("sample_aibnr_load error(%#x)\n", ret);        goto deinit;    }     cfg.ref_mode = aibnr_param->ref_mode; /* ref mode NORM: need reference frame; NONE: no reference frame */    ret = ss_mpi_aibnr_set_cfg(vi_pipe, &cfg);    if (ret != TD_SUCCESS)     {        sample_print("ss_mpi_aibnr_set_alg_cfg error(%#x)\n", ret);        goto unload_model;    }      usleep(100000);    // int c;    // printf("请输入一个字符:");    // c = getchar();  // 读取用户输入的第一个字符    // printf("你输入的字符是:%c\n", (char)c);     // sample_get_char("enable");  // 只是获取输入的符号     ret = ss_mpi_aibnr_enable(vi_pipe); // 底层接口    if (ret != TD_SUCCESS)     {        sample_print("ss_mpi_aibnr_enable error(%#x)\n", ret);        goto unload_model;    }     ret = sample_aibnr_set_attr(vi_pipe, aibnr_param);    if (ret != TD_SUCCESS) {        sample_print("sample_aibnr_set_attr error(%#x)\n", ret);        goto aibnr_disable;    }     return ret; aibnr_disable:    ss_mpi_aibnr_disable(vi_pipe);unload_model:    for (i = 0;i pipe_info[vi_pipe].attach_pool != OT_VB_INVALID_POOL_ID) {        ss_mpi_vb_destroy_pool(vi_cfg->pipe_info[vi_pipe].attach_pool);    }} static td_void sample_aibnr_stop_vi(ot_vi_pipe vi_pipe, const sample_vi_cfg *vi_cfg){    sample_comm_vi_stop_vi(vi_cfg);    sample_aibnr_deinit_aiisp_pool(vi_pipe, vi_cfg);    sample_comm_sys_exit();} static td_s32 sample_aibnr_init_aiisp_pool(ot_size *in_size, td_u32 vb_cnt){    td_s32 blk_size;    ot_vb_pool vb_pool;    ot_vb_pool_cfg vb_pool_cfg = {0};     blk_size = ot_aibnr_get_pic_buf_size(in_size->width, in_size->height);    vb_pool_cfg.blk_size = blk_size;    vb_pool_cfg.blk_cnt = vb_cnt;    vb_pool_cfg.remap_mode = OT_VB_REMAP_MODE_NONE;    vb_pool = ss_mpi_vb_create_pool(&vb_pool_cfg);    if (vb_pool == OT_VB_INVALID_POOL_ID) {        sample_print("aibnr create user pool failed!\n");        return OT_VB_INVALID_POOL_ID;    } #ifdef SAMPLE_MEM_SHARE_ENABLE    ss_mpi_vb_pool_share_all(vb_pool);#endif     return vb_pool;} static td_void sample_aibnr_set_vpss_crop(ot_vpss_grp grp, ot_size *in_size){    td_s32 ret;    ot_vpss_crop_info crop_info = {0};    td_u32 crop_pixel = 8;     crop_info.enable = TD_TRUE;    crop_info.crop_mode = OT_COORD_ABS;    crop_info.crop_rect.x = crop_pixel;    crop_info.crop_rect.y = crop_pixel;    crop_info.crop_rect.width = in_size->width - crop_pixel;    crop_info.crop_rect.height = in_size->height - crop_pixel;    ret = ss_mpi_vpss_set_grp_crop(grp, &crop_info);    if (ret != TD_SUCCESS) {        sample_print("ss_mpi_vpss_set_grp_crop failed!\n");    }}   static td_s32 sample_venc_get_enc_size(ot_pic_size *pic_size, sample_venc_param *enc_param){    td_s32 i;    td_s32 ret;     for (i = 0; i venc_chn_num && i enc_size[i]));        if (ret != TD_SUCCESS) {            sample_print("sample_comm_sys_get_pic_size failed!\n");            return ret;        }    }     return TD_SUCCESS;}    static td_s32 sample_aibnr_start_vi(ot_vi_pipe vi_pipe, sample_vi_cfg *vi_cfg, ot_size *in_size,    td_u32 vb_cnt){    td_s32 ret;    sample_vi_pipe_info *pipe_info = &vi_cfg->pipe_info[vi_pipe];     if (sample_aiisp_sys_init(in_size, VB_AIBNR_COMMON_VB_CNT) != TD_SUCCESS) {        sample_print("sample_aiisp_sys_init failed.\n");        return TD_FAILURE;    }     /* aiisp route use attach pool */    pipe_info->attach_pool = sample_aibnr_init_aiisp_pool(&pipe_info->pipe_attr.size, vb_cnt);    if (pipe_info->attach_pool == OT_VB_INVALID_POOL_ID) {        goto sys_exit;    }     ret = sample_comm_vi_start_vi(vi_cfg);    if (ret != TD_SUCCESS) {        sample_print("start vi failed.\n");        goto denit_vb_pool;    }     return TD_SUCCESS; denit_vb_pool:    ss_mpi_vb_destroy_pool(pipe_info->attach_pool);sys_exit:    sample_comm_sys_exit();     return TD_FAILURE;} static td_s32 sample_aibnr_set_blc(ot_vi_pipe vi_pipe, sample_sns_type sns_type){    td_s32 i, j, ret;    ot_isp_black_level_attr black_level_attr;     ret = ss_mpi_isp_get_black_level_attr(vi_pipe, &black_level_attr);    if (ret != TD_SUCCESS) {        sample_print("ss_mpi_isp_get_black_level_attr failed.\n");        return TD_FAILURE;    }     black_level_attr.user_black_level_en = TD_TRUE;     for (i = 0; i pipe_info[vi_pipe].set_early_end_mode = TD_TRUE;    vi_cfg->pipe_info[vi_pipe].pipe_attr.compress_mode = OT_COMPRESS_MODE_NONE;    vi_cfg->pipe_info[vi_pipe].pipe_attr.pixel_format = OT_PIXEL_FORMAT_RGB_BAYER_12BPP; /* 12fps */     vi_cfg->pipe_info[vi_pipe].isp_info.isp_pub_attr.frame_rate = dst_fps;} static td_s32 sample_aibnr_check_support(ot_vi_pipe vi_pipe, sample_aibnr_param *aibnr_param){    if (aibnr_param->is_wdr_mode == TD_TRUE) {        if (aibnr_param->is_blend != TD_FALSE) {            sample_print("normal_blend must be false in wdr mode\n");            return TD_FAILURE;        }         if (vi_pipe >= OT_VI_MAX_PHYS_PIPE_NUM) {            sample_print("vi_pipe must be phy pipe in wdr mode\n");            return TD_FAILURE;        }    }     /* bnr_bypass must be false when attr->enable is false */    /* blend must be false when bnr_bypass is true */    /* vi must be offline */     return TD_SUCCESS;}  // 这里真正开始调 aiisptd_s32 sample_aibnr(sample_aibnr_param *aibnr_param){    td_s32 ret = TD_FAILURE;    sample_vi_cfg vi_cfg = {0};     sample_sns_type sns_type = SC500AI_MIPI_5M_30FPS_10BIT;    // sample_sns_type sns_type = SENSOR0_TYPE;    const td_u32 vb_cnt = (aibnr_param->is_pro == TD_TRUE) ? VB_AIBNR_TNR_CNT : VB_AIBNR_LINE_CNT;    const ot_vi_pipe vi_pipe = aibnr_param->is_wdr_mode ? 1 : 0;    ot_vi_pipe master_pipe = 0;    const ot_vi_chn vi_chn = 0;    ot_vpss_grp vpss_grp[1] = {0};    ot_size in_size = {0};    ot_aibnr_model model_info[2] = {0};    td_s32 model_id[2] = {-1, -1};    td_s32 model_size = (td_s32)(sizeof(model_id) / sizeof(td_s32));    // ot_vpss_grp vpss_grp = 0;      if (sample_aibnr_check_support(vi_pipe, aibnr_param) != TD_SUCCESS)     {        return TD_FAILURE;    }     sample_aiisp_get_default_cfg(sns_type, vi_pipe, &in_size, &vi_cfg);    sample_aibnr_update_cfg(vi_pipe, &vi_cfg, aibnr_param->is_pro);      // 开始 vi    if (sample_aibnr_start_vi(vi_pipe, &vi_cfg, &in_size, vb_cnt) != TD_SUCCESS) {        return TD_FAILURE;    }     // sample_comm_vi_bind_vpss(master_pipe, 0, vpss_grp, 0); // sample_venc是这样写的,这样写会有报错 log    sample_comm_vi_bind_vpss(master_pipe, vi_chn, vpss_grp[0], 0);      if (sample_aiisp_start_vpss(vpss_grp[0], &in_size) != TD_SUCCESS)   // 这样使用不会报错。这里将 vi的流绑定给 vpss_grp[0]。确实只需将 vpss grp0的流绑定给 vpss_chn就好    {        goto stop_vi;    }     // sample_aibnr_set_vpss_crop(vpss_grp, &in_size);    sample_aibnr_set_vpss_crop(vpss_grp[0], &in_size);  // 只对 vpss_grp[0]做裁剪  printf("\n\nsizeof(vpss_grp) / sizeof(vpss_grp) is %d\n\n", sizeof(vpss_grp) / sizeof(vpss_grp));    if (sample_aiisp_start_venc_bind(vpss_grp, sizeof(vpss_grp) / sizeof(vpss_grp), &in_size) != TD_SUCCESS) //     // if (sample_aiisp_start_venc_bind(vpss_grp, 2, &in_size) != TD_SUCCESS)  // 这里涉及到创建 venc_chn    // if (sample_aiisp_start_venc_bind(vpss_grp, sizeof(vpss_grp) / sizeof(vpss_grp[0]), &in_size) != TD_SUCCESS) //     {        goto stop_vpss;    }       // 通过 VI、VPSS模块获取原始视频帧;    // 在 VENC中创建两个编码通道,绑定统一 VI、VPSS输入源    // 分别配置两路通道的编码参数        if (sample_aibnr_set_blc(master_pipe, sns_type) != TD_SUCCESS) {        goto stop_venc_and_vo;    }     if (sample_aibnr_start(vi_pipe, in_size, model_info, model_id, model_size, aibnr_param) != TD_SUCCESS) {        goto stop_venc_and_vo;    }     if (sample_aiisp_set_long_frame_mode(master_pipe, aibnr_param->is_wdr_mode) != TD_SUCCESS) {        goto stop_aibnr;    }     sample_get_char("disable");     ret = TD_SUCCESS; stop_aibnr:    sample_aibnr_stop(vi_pipe, model_info, model_id, model_size);    // sample_get_char("exit");    usleep(100000); stop_venc_and_vo:    // sample_aiisp_stop_venc_and_unbind(vpss_grp, sizeof(vpss_grp) / sizeof(vpss_grp));    sample_aiisp_stop_venc_and_unbind(vpss_grp, sizeof(vpss_grp) / sizeof(vpss_grp[0]));stop_vpss:    // sample_aiisp_stop_vpss(vpss_grp);    sample_aiisp_stop_vpss(vpss_grp[0]);stop_vi:    // sample_comm_vi_un_bind_vpss(master_pipe, vi_chn, vpss_grp, 0);    sample_comm_vi_un_bind_vpss(master_pipe, vi_chn, vpss_grp[0], 0);    sample_aibnr_stop_vi(vi_pipe, &vi_cfg);    return ret;}

sample_aiisp_common.c文件

// sample_aiisp_common.c  #include #include #include "sample_aiisp_common.h" #define VENC_WIDTH 3840#define VENC_HEIGTH 2160 static sample_comm_venc_chn_param g_venc_chn_param = {    .frame_rate           = 30, /* 30 is a number */    .stats_time           = 2,  /* 2 is a number */    .gop                  = 60, /* 60 is a number */    .venc_size            = {VENC_WIDTH, VENC_HEIGTH},    .size                 = -1,    .profile              = 0,    .is_rcn_ref_share_buf = TD_FALSE,    .gop_attr             = {        .gop_mode = OT_VENC_GOP_MODE_NORMAL_P,        .normal_p = {2},    },    // .type                 = OT_PT_H265,    .type                 = OT_PT_H264,    .rc_mode              = SAMPLE_RC_CBR,}; static sample_comm_venc_chn_param g_venc_chn_param_small_chn = {    .frame_rate           = 30, /* 30 is a number */    .stats_time           = 2,  /* 2 is a number */    .gop                  = 60, /* 60 is a number */    .venc_size            = {720, 480},    .size                 = -1,    .profile              = 0,    .is_rcn_ref_share_buf = TD_FALSE,    .gop_attr             = {        .gop_mode = OT_VENC_GOP_MODE_NORMAL_P,        .normal_p = {2},    },    // .type                 = OT_PT_H265,    .type                 = OT_PT_H264,    .rc_mode              = SAMPLE_RC_CBR,};    volatile sig_atomic_t g_sig_flag = 0; td_void sample_aiisp_handle_sig(td_s32 signo){    if (signo == SIGINT || signo == SIGTERM) {        g_sig_flag = 1;    }} td_void sample_get_char(td_char *s){    if (g_sig_flag == 1) {        return;    }     printf("---------------press any key to %s!---------------\n", s);    (td_void)getchar();} sig_atomic_t sample_aiisp_get_sig(td_void){    return g_sig_flag;} static td_s32 sample_aiisp_check_fp(FILE *fp, td_char *model_file){    if (fp == TD_NULL) {        sample_print("open file err!\n");        return TD_FAILURE;    }    printf("open %s success\n", model_file);    return TD_SUCCESS;} td_s32 sample_aiisp_load_mem(ot_aiisp_mem_info *mem, td_char *model_file){    td_s32 ret;    FILE *fp = TD_NULL;    td_char path[PATH_MAX + 1] = {0};     /* Get model file size */    sample_aiisp_check_exps_return((strlen(model_file) > PATH_MAX) || realpath(model_file, path) == TD_NULL);        fp = fopen(path, "rb");    if (sample_aiisp_check_fp(fp, model_file) != TD_SUCCESS) {        return TD_FAILURE;    }    ret = fseek(fp, 0L, SEEK_END);    if (ret != TD_SUCCESS) {        sample_print("fseek end failed!\n");        goto fail_0;    }     mem->size = ftell(fp);    if (mem->size phys_addr), &(mem->virt_addr), "./aibnr_model", TD_NULL, mem->size);    if (ret != TD_SUCCESS) {        sample_print("malloc mmz failed!\n");        goto fail_0;    }     ret = fread(mem->virt_addr, mem->size, 1, fp);    if (ret != 1) {        sample_print("read model file failed!\n");        goto fail_1;    }     ret = fclose(fp);    if (ret != 0) {        sample_print("close file error\n");    }    return TD_SUCCESS; fail_1:    ss_mpi_sys_mmz_free(mem->phys_addr, mem->virt_addr);    mem->phys_addr = 0;    mem->virt_addr = TD_NULL;fail_0:    (td_void)fclose(fp);    return TD_FAILURE;} td_void sample_aiisp_unload_mem(ot_aiisp_mem_info *param_mem){    if ((param_mem->phys_addr != 0) && (param_mem->virt_addr != TD_NULL)) {        (td_void)ss_mpi_sys_mmz_free(param_mem->phys_addr, param_mem->virt_addr);    }} static td_void sample_aiisp_get_default_vb_config(const ot_size *size, ot_vb_cfg *vb_cfg, td_u32 vb_cnt){    ot_vb_calc_cfg calc_cfg = {0};    ot_pic_buf_attr buf_attr = {0};     (td_void)memset_s(vb_cfg, sizeof(ot_vb_cfg), 0, sizeof(ot_vb_cfg));    vb_cfg->max_pool_cnt = 128; /* 128 blks */     buf_attr.width         = size->width;    buf_attr.height        = size->height;    buf_attr.align         = OT_DEFAULT_ALIGN;    buf_attr.bit_width     = OT_DATA_BIT_WIDTH_8;    buf_attr.pixel_format  = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420;    buf_attr.compress_mode = OT_COMPRESS_MODE_NONE;    buf_attr.video_format  = OT_VIDEO_FORMAT_LINEAR;    ot_common_get_pic_buf_cfg(&buf_attr, &calc_cfg);     vb_cfg->common_pool[0].blk_size = calc_cfg.vb_size;    vb_cfg->common_pool[0].blk_cnt  = vb_cnt;} #ifdef SAMPLE_MEM_SHARE_ENABLEstatic td_void sample_aiisp_init_mem_share(td_void){    td_u32 i;    ot_vb_common_pools_id pools_id = {0};     if (ss_mpi_vb_get_common_pool_id(&pools_id) != TD_SUCCESS) {        sample_print("get common pool_id failed!\n");        return;    }    for (i = 0; i width;    grp_attr.max_height = in_size->height;    sample_comm_vpss_get_default_chn_attr(&vpss_chn_attr.chn_attr[0]);    vpss_chn_attr.chn_attr[0].width  = in_size->width;    vpss_chn_attr.chn_attr[0].height = in_size->height;     // 将 vpss grp0绑定到 vpss_chn1上    // 这里增加一组 将vi数据源绑定给 vpss    vpss_chn_attr.chn_enable[1] = TD_TRUE;    vpss_chn_attr.chn_array_size = OT_VPSS_MAX_PHYS_CHN_NUM;    vpss_chn_attr.chn_attr[1].width  = 720;    vpss_chn_attr.chn_attr[1].height = 480;    vpss_chn_attr.chn_attr[1].pixel_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420;    sample_comm_vpss_get_default_grp_attr(&grp_attr);    grp_attr.max_width  = 720;    grp_attr.max_height = 480;       // 这里这样使用,没问题    vpss_chn_attr.chn_attr[1].mirror_en = TD_FALSE;    vpss_chn_attr.chn_attr[1].flip_en = TD_FALSE;    vpss_chn_attr.chn_attr[1].border_en = TD_FALSE;    vpss_chn_attr.chn_attr[1].width = 720;    vpss_chn_attr.chn_attr[1].height = 480;    vpss_chn_attr.chn_attr[1].depth = 0;    vpss_chn_attr.chn_attr[1].chn_mode = OT_VPSS_CHN_MODE_USER;    vpss_chn_attr.chn_attr[1].video_format = OT_VIDEO_FORMAT_LINEAR;    vpss_chn_attr.chn_attr[1].dynamic_range = OT_DYNAMIC_RANGE_SDR8;    vpss_chn_attr.chn_attr[1].pixel_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420;    vpss_chn_attr.chn_attr[1].compress_mode = OT_COMPRESS_MODE_NONE;    vpss_chn_attr.chn_attr[1].aspect_ratio.mode = OT_ASPECT_RATIO_NONE;    vpss_chn_attr.chn_attr[1].frame_rate.src_frame_rate = -1;    vpss_chn_attr.chn_attr[1].frame_rate.dst_frame_rate = -1;     // 这样使用,同样没问题    // sample_comm_vpss_get_default_chn_attr(&vpss_chn_attr.chn_attr[1]);         ret = sample_common_vpss_start(grp, &grp_attr, &vpss_chn_attr);    if (ret != TD_SUCCESS) {        return ret;    }     return TD_SUCCESS;} td_s32 sample_aiisp_start_venc(ot_venc_chn venc_chn[], td_u32 venc_chn_len, td_u32 chn_num, ot_size *size){    td_s32 i;    td_s32 ret;     g_venc_chn_param.venc_size.width        = size->width;    g_venc_chn_param.venc_size.height       = size->height;    g_venc_chn_param.size = sample_comm_sys_get_pic_enum(size);     g_venc_chn_param_small_chn.venc_size.width        = 720;    g_venc_chn_param_small_chn.venc_size.height       = 480;    // g_venc_chn_param_small_chn.size = sample_comm_sys_get_pic_enum(size);    // 这个函数不能调用,调用后 venc_chn1通道没有流     for (i = 0; i = 0; i--) {        sample_comm_venc_stop(venc_chn[i]);        sample_comm_venc_stop(venc_chn[1]);    }    return TD_FAILURE;}  // 这里就是重点了td_s32 sample_aiisp_start_venc_bind(ot_vpss_grp vpss_grp[], td_u32 grp_num, ot_size *in_size){    // grp_num应该等于1    td_u32 i;    td_s32 ret;    const ot_vpss_chn vpss_chn = 0;    const ot_vpss_chn vpss_chn_1 = 1;   // 添加一个 vpss_chn     ot_venc_chn venc_chn[4] = {0, 1, 2, 3}; /* 4: max chn num, 0/1/2/3 chn id */             // 函数作用是设置 venc_chn的属性。将 vpss的流绑定给 venc    ret = sample_aiisp_start_venc(venc_chn, 1, grp_num, in_size);    // ret = sample_aiisp_start_venc(venc_chn, sizeof(venc_chn) / sizeof(ot_venc_chn), grp_num, in_size);    if (ret != TD_SUCCESS) {        goto start_venc_failed;    }     for (i = 0; i pipe_info[vi_pipe].pipe_attr.frame_rate_ctrl.src_frame_rate = 30; /* 30fps */    vi_cfg->pipe_info[vi_pipe].pipe_attr.frame_rate_ctrl.dst_frame_rate = 5; /* 5fps */#endif}

上述操作,可以多一路 venc_chn1的通道流

工程代码

通过网盘分享的文件:aiisp_easy_rtsp.zip
链接: https://pan.baidu.com/s/1ZNkiUpKQgV1cgB0bfrclSA 提取码: h4ib 
--来自百度网盘超级会员v5的分享

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/931665.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网站建设与维护技术浅谈论文代理加盟做什么好

http://cplusoj.com/d/senior/p/SS231025D 答案为 ∑ w [ x ] − w [ s o n [ x ] ] \sum w[x]-w[son[x]] ∑w[x]−w[son[x]], x x x 非儿子 要维护断边,LCT固然可以,但不一定需要 发现如果发生了变化,只会由重儿子变成次重儿子…

注册公司制作网站门户网站建设维护

LRU是什么意思 LRU是操作系统底层的一个页面置换算法,当空间不够需要换出最长时间没有使用的页面,在本题中的意思就是当到达容量上限的时候要换出最长时间没有被访问过的节点。 如何实现 LRU的实现可以使用链表的方式,参照MySQL的实现&…

手机模板网站模板下载工具网络网站建设推广

GODADDY的虚拟主机控制面板虽然使用起来非常方便,对于文件管理的很多操作也非常到位,但是有一个非常令人头疼的问题,就是GODADDY在 主机控制面板中只支持小于20M的文件打包,这对于大部分的站长朋友来说,是非常不方便的…

方法作业

https://files.cnblogs.com/files/blogs/847621/20243866牛蕴韬01方法作业.zip?t=1759908795&download=true

公司网站建设属于软件销售湖南金科建设有限公司网站

任何程序都可能出现错误,在SQL Server中执行Transact-SQL也不例外。如果在Transact-SQL中发生了错误,一般有两种捕捉错误的方法,一种是在客户端代码(如 c#、delphi等)中使用类似try...catch的语句进行捕捉;另外一种就是…

网站登录入口大全网站制作预算

作用:线程安全的全局静态变量初始化 声明: Q_GLOBAL_STATIC(MyType,globalState) Q_GLOBAL_STATIC_WITH_ARGS(MyType, globalState, (42, "Hello", "World")) //带参数的初始化 注: 构造函数和析构函数必须是公有的 如果…

实现仿中国婚博会微信小应用

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

[100ask_imx6ullpro] buildroot构建emmc镜像并烧录

[100ask_imx6ullpro] buildroot构建emmc镜像并烧录 本文参考百问网韦东山老师视频 嵌入式Linux系统裁剪移植之二:使用Buildroot制作根文件系统 本文的主机环境为 Ubuntu22.04 1.准备工作 1.1.下载buildroot 从官网下载…

湘潭网站建设厦门网站制作wordpress页面排版插件

抖音API允许开发者进行二次开发,使得第三方应用程序可以与抖音进行交互。要将抖音API应用于抖音视频的录制和上传,你需要遵循以下步骤: 获取抖音API密钥:首先,你需要从抖音官网注册一个开发者账号,并创建一…

建设网站科目网络平台制作多少钱

在微服务架构下随着服务越来越多,定位问题也变得越来越复杂,因此监控服务的运行状态以及针对异常状态及时的发出告警也成为微服务治理不可或缺的一环。服务的监控主要有日志监控、调用链路监控、指标监控等几种类型方式,其中指标监控在整个微服务监控中比重最高,也是实际生…

什么网站做美式软装设计方案报告模板

🍅 作者主页:Java李杨勇 🍅 简介:Java领域优质创作者🏆、【java李杨勇】公号作者✌ 简历模板、学习资料、面试题库、技术互助【关注我,都给你】 🍅 欢迎点赞 👍 收藏 ⭐留言 &…

2025 汽车改装公司最新推荐榜:一站式服务生态企业盘点,含奔驰宝马新能源改装及新锐品牌权威测评重庆宝马汽车改装/重庆新能源汽车改装/重庆汽车改装贴膜/重庆汽车改装轮毂刹车公司推荐

汽车后市场的蓬勃发展推动改装需求向个性化、全场景升级,但行业乱象让车主选择陷入困境。多数机构业务单一,难以覆盖从配件选购到售后养护的完整链条,导致服务体验碎片化;技术层面,部分机构缺乏标准化流程,合规性…

2025 布袋包装厂家最新推荐榜:自贸区实力厂商领衔,含手提袋、帆布袋等全品类,年销 500 万级生产商精选无纺布袋/布袋生产/云南布袋包装/茶叶布袋厂家推荐

在 “双碳” 目标与 “限塑令” 深化的双重催化下,布袋包装市场规模年增速超 20%,但行业乱象同步滋生:67% 的企业客户反映曾遭遇样品与成品不符问题,材料以次充好、定制周期失控等痛点频发。同时,环保认证缺失、产…

上海高端网站建设服陕西省建设网三类人员成绩公示

GitHub中readme.md文件的编辑和使用 | YuuiChungs BlogGitHub - guodongxiaren/README: README文件语法解读,即Github Flavored Markdown语法介绍

给缅甸公司网站做维护工作时间段怎样做免费网站会员

今天做了个测试,写了个测试用例来看看merge与update时控制台打印出来的日志有什么不一样。实体bean很简单,就id和name两个字段,接下来分别给出以下几种测试情形的控制台日志内容: 1. 数据库记录已存在,更改person的nam…

语音识别与合成的融合技术解析

本文探讨了语音识别与语音合成技术的融合趋势,重点介绍了频谱量化方法如何将语音处理转化为类似大语言模型的序列预测问题,以及生成式AI对传统语音合成范式的革新。Interspeech:语音识别与合成的融合之处 随着今年I…

Qt Creator在windows下打开时总是未响应

Qt Creator在windows下打开时总是未响应1.关闭QtCreator 2.找到AppData\Roaming\QtProject文件夹,删掉。 3.重新打开QtCreator

广州设计企业网站深圳房产备案查询官网

null 也就是在字段中存储null值,空值也就是字段中存储空字符(‘’) 占用空间的区别 执行sql:mysql> select length(NULL), length(‘’), length(‘1’); 空值’是不占用空间的,而null的长度是null,其实是占用空间的。mysql…

2015做哪些网站致富人力资源公司网站建设方案

又到学习Word技巧的时候啦!学了这么长时间,你的技能点有没有增加呢?对表格的使用有没有更加熟练了?是否很好奇别人家的表格是怎么弄成可以单选框和复选框的效果呢~~~~下面让小编带你解锁新姿势~效果图如下:(1)开发工具…

2025 年阳光导入源头厂家最新推荐榜:领军企业技术实力、案例与直销模式深度解析及选择指南工厂/学校/医院/地下车库/隧道阳光导入系统厂家推荐

在建筑节能领域快速发展的当下,阳光导入技术作为实现节能减排、推动绿色建筑发展的关键手段,市场需求持续攀升。但当前行业乱象丛生,部分厂家缺乏核心技术,产品采光效率低、稳定性差,难以适配体育馆、地下车库、医…