3516cv610在sample_aiisp上多創一路編碼流,方法

3516cv610在sample_aiisp上多創一路編碼流,方法

首先確保 vpss grp0有視頻流

最好保證 已經有一路視頻流能推出來

多創一路編碼流思路為
將 vpss grp0又綁定給 vpss_chn1

vpss_chn1有綁定給 venc_chn1

這樣我們就多創了一路視頻流。

這里思路完全正確 可以實現

整個工程代碼,在底部鏈接獲取

aiisp需要對 sc500ai寄存器進行操作

// 改變 sc500ai的bayer格式
// 改變為 RGGB的格式
3211, 0x05
3213,  0x05

sdk說明

sdk_010打AOV的補丁

硬件

cv610_20s+sc500ai

下面是 aiisp的例子,多創建一路編碼流

// sample_aiisp.c#include <signal.h>
#include "sample_comm.h"
#include "sample_ipc.h"
#include "sample_aibnr.h"#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <poll.h>
#include <sys/time.h>
#include <sys/select.h>
#include <fcntl.h>
#include <errno.h>
#include <pthread.h>
#include <math.h>
#include <unistd.h>
#include <signal.h>
#include <sys/prctl.h>
#include <limits.h>#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 <index> \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_ENABLEot_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 < pools_id.pool_cnt; ++i) {if (ss_mpi_vb_pool_share(pools_id.pool[i], pid) != TD_SUCCESS) {sample_print("vb pool share failed!\n");return TD_FAILURE;}}
#endifret = sample_comm_vi_get_isp_run_state(isp_states, OT_VI_MAX_PIPE_NUM);if (ret != TD_SUCCESS) {sample_print("get isp states fail\n");return TD_FAILURE;}for (i = 0; i < OT_VI_MAX_PIPE_NUM; i++) {if (!isp_states[i]) {continue;}ret = ss_mpi_isp_mem_share(i, pid);if (ret != TD_SUCCESS) {sample_print("ss_mpi_isp_mem_share vi_pipe %u, pid %d fail\n", i, pid);}}return TD_SUCCESS;
}static td_void sample_aiisp_msg_proc_vb_pool_unshare(td_s32 pid)
{td_s32 ret;td_u32 i;td_bool isp_states[OT_VI_MAX_PIPE_NUM];
#ifndef SAMPLE_MEM_SHARE_ENABLEot_vb_common_pools_id pools_id = {0};if (ss_mpi_vb_get_common_pool_id(&pools_id) == TD_SUCCESS) {for (i = 0; i < pools_id.pool_cnt; ++i) {ret = ss_mpi_vb_pool_unshare(pools_id.pool[i], pid);if (ret != TD_SUCCESS) {sample_print("ss_mpi_vb_pool_unshare vi_pipe %u, pid %d fail\n", pools_id.pool[i], pid);}}}
#endifret = sample_comm_vi_get_isp_run_state(isp_states, OT_VI_MAX_PIPE_NUM);if (ret != TD_SUCCESS) {sample_print("get isp states fail\n");return;}for (i = 0; i < OT_VI_MAX_PIPE_NUM; i++) {if (!isp_states[i]) {continue;}ret = ss_mpi_isp_mem_unshare(i, pid);if (ret != TD_SUCCESS) {sample_print("ss_mpi_isp_mem_unshare vi_pipe %u, pid %d fail\n", i, pid);}}
}static td_s32 sample_aiisp_ipc_msg_proc(const sample_ipc_msg_req_buf *msg_req_buf,td_bool *is_need_fb, sample_ipc_msg_res_buf *msg_res_buf)
{td_s32 ret;if (msg_req_buf == TD_NULL || is_need_fb == TD_NULL) {return TD_FAILURE;}/* need feedback default */*is_need_fb = TD_TRUE;switch ((sample_msg_type)msg_req_buf->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, "./") < 0) {free(stream->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) < 0) {free(stream->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通道1for (j = 0; j < stream->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;#elseret = sample_comm_venc_save_stream_phys_addr(stream_proc_info->file[index], &stream_buf_info[index], stream);
#endifif (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端口創建rtspserversession= create_rtsp_session(g_rtsplive,"/test.264");//創建rtsp會話 rtsp://[IP]/test.264td_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;
#elseexit(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 2typedef 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 < list.num && i < OT_AIISP_MAX_MODEL_NUM; i++) {printf("id:%d  is wdr:%d\n", list.info[i].id, list.info[i].is_wdr_mode);}//---------------------aibnr模型0// sample_get_char("select model 0");model_attr.op_type = OT_OP_MODE_MANUAL;model_attr.manual_id = 0;ss_mpi_aibnr_set_model_attr(0, &model_attr);//---------------------------aibnr模型1// sample_get_char("select model 1");// model_attr.op_type = OT_OP_MODE_MANUAL;// model_attr.manual_id = 1;// ss_mpi_aibnr_set_model_attr(0, &model_attr);//-------------------------模型auto mode// sample_get_char("set auto mode");// model_attr.op_type = OT_OP_MODE_AUTO;// for (td_u32 i = 0; i < OT_AIISP_AUTO_ISO_NUM; i++) {//     model_attr.auto_id[i] = 1;//     if (i < 0x2) {//         model_attr.auto_id[i] = 0;//     }// }// ss_mpi_aibnr_set_model_attr(0, &model_attr);return TD_SUCCESS;
}static td_s32 sample_aibnr_set_attr(ot_vi_pipe vi_pipe, sample_aibnr_param *aibnr_param)
{td_s32 ret;ot_aibnr_attr aibnr_attr;ret = ss_mpi_aibnr_get_attr(vi_pipe, &aibnr_attr);if (ret != TD_SUCCESS) {sample_print("ss_mpi_aibnr_get_attr error\n");return ret;}aibnr_attr.enable = TD_TRUE;aibnr_attr.bnr_bypass = TD_FALSE;aibnr_attr.blend = aibnr_param->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 < 0) {printf("set name failed!\n");return ret;}model_info[0].model.preempted_en = TD_FALSE;model_info[0].model.image_size.width  = in_size.width;model_info[0].model.image_size.height = in_size.height;model_info[0].is_wdr_mode = aibnr_param->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 < 0) {printf("set name failed!\n");goto unload;}model_info[1].model.preempted_en = TD_FALSE;model_info[1].model.image_size.width  = in_size.width;model_info[1].model.image_size.height = in_size.height;model_info[1].is_wdr_mode = aibnr_param->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 < model_size; i++) {if (model_id[i] != -1) {sample_aibnr_unload_model(&model_info[i], model_id[i]);}}deinit:ss_mpi_aibnr_exit();return ret;
}static td_s32 sample_aibnr_unload(ot_vi_pipe vi_pipe, ot_aibnr_model *model, td_s32 *model_id, td_s32 model_size)
{td_s32 return_value = TD_SUCCESS;td_s32 ret;td_s32 i;for (i = 0; i < model_size; i++) {if (model_id[i] != -1) {ret = sample_aibnr_unload_model(&model[i], model_id[i]);if (ret != TD_SUCCESS) {return_value = ret;}}}return return_value;
}static td_s32 sample_aibnr_stop(ot_vi_pipe vi_pipe, ot_aibnr_model *model, td_s32 *model_id, td_s32 model_size)
{td_s32 ret1;td_s32 ret2;ret1 = ss_mpi_aibnr_disable(vi_pipe);if (ret1 != TD_SUCCESS) {sample_print("ss_mpi_aibnr_disable false error(%#x)\n", ret1);}ret2 = sample_aibnr_unload(vi_pipe, model, model_id, model_size);if (ret2 != TD_SUCCESS) {sample_print("sample_aibnr_unload_exit false error(%#x)\n", ret2);}ss_mpi_aibnr_exit();if ((ret1 != TD_SUCCESS) || (ret2 != TD_SUCCESS)) {return TD_FAILURE;}return TD_SUCCESS;
}static td_void sample_aibnr_deinit_aiisp_pool(ot_vi_pipe vi_pipe, const sample_vi_cfg *vi_cfg)
{if (vi_cfg->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_ENABLEss_mpi_vb_pool_share_all(vb_pool);
#endifreturn 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 < enc_param->venc_chn_num && i < CHN_NUM_MAX; i++) {ret = sample_comm_sys_get_pic_size(pic_size[i], &(enc_param->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 < OT_ISP_WDR_MAX_FRAME_NUM; i++) {for (j = 0; j < OT_ISP_BAYER_CHN_NUM; j++) {black_level_attr.user_black_level[i][j] = 1200; /* user_black_level of aibnr default as 1200 */}}ret = ss_mpi_isp_set_black_level_attr(vi_pipe, &black_level_attr);if (ret != TD_SUCCESS) {sample_print("ss_mpi_isp_set_black_level_attr failed.\n");return TD_FAILURE;}return TD_SUCCESS;
}static td_void sample_aibnr_update_cfg(ot_vi_pipe vi_pipe, sample_vi_cfg *vi_cfg, td_bool is_pro)
{td_u32 dst_fps = (is_pro == TD_TRUE) ? 5 : 12;  /* 5\12fps */vi_cfg->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;
}// 這里真正開始調 aiisp
td_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);// 開始 viif (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是這樣寫的,這樣寫會有報錯 logsample_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 <signal.h>
#include <limits.h>
#include "sample_aiisp_common.h"#define VENC_WIDTH 3840
#define VENC_HEIGTH 2160static 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 <= 0) {sample_print("ftell failed!\n");goto fail_0;}ret = fseek(fp, 0L, SEEK_SET);if (ret != TD_SUCCESS) {sample_print("fseek set failed!\n");goto fail_0;}/* malloc model file mem */ret = ss_mpi_sys_mmz_alloc(&(mem->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_ENABLE
static 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 < pools_id.pool_cnt; ++i) {ss_mpi_vb_pool_share_all(pools_id.pool[i]);}
}
#endiftd_s32 sample_aiisp_sys_init(ot_size *in_size, td_u32 vb_cnt)
{td_s32 ret;ot_vb_cfg vb_cfg = {0};td_u32 supplement_config;ot_vi_vpss_mode_type mode_type = OT_VI_OFFLINE_VPSS_ONLINE;sample_aiisp_get_default_vb_config(in_size, &vb_cfg, vb_cnt);supplement_config = OT_VB_SUPPLEMENT_BNR_MOT_MASK;ret = sample_comm_sys_init_with_vb_supplement(&vb_cfg, supplement_config);if (ret != TD_SUCCESS) {return TD_FAILURE;}#ifdef SAMPLE_MEM_SHARE_ENABLEsample_aiisp_init_mem_share();
#endifret = sample_comm_vi_set_vi_vpss_mode(mode_type, OT_VI_AIISP_MODE_DEFAULT);if (ret != TD_SUCCESS) {return TD_FAILURE;}return TD_SUCCESS;
}td_s32 sample_aiisp_start_vpss(ot_vpss_grp grp, ot_size *in_size)
{td_s32 ret;ot_vpss_grp_attr grp_attr = {0};sample_vpss_chn_attr vpss_chn_attr = {0};vpss_chn_attr.chn_enable[0] = TD_TRUE;vpss_chn_attr.chn_array_size = OT_VPSS_MAX_PHYS_CHN_NUM;sample_comm_vpss_get_default_grp_attr(&grp_attr);grp_attr.max_width  = in_size->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數據源綁定給 vpssvpss_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 < (td_s32)chn_num && i < (td_s32)venc_chn_len; i++) {ret = sample_comm_venc_start(venc_chn[0], &g_venc_chn_param);if (ret != TD_SUCCESS) {goto exit;}// 小的 venc_chn分辨率綁定vpss視頻源ret = sample_comm_venc_start(venc_chn[1], &g_venc_chn_param_small_chn);if (ret != TD_SUCCESS) {goto exit;}}// 獲取視頻流// 改為2,就多創建了一路碼流。是創了兩個 h264文件,但 index=1是一直沒打印的ret = sample_comm_venc_start_get_stream(venc_chn, 2);// ret = sample_comm_venc_start_get_stream(venc_chn, chn_num);if (ret != TD_SUCCESS) {goto exit;}return TD_SUCCESS;exit:for (i = i - 1; 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應該等于1td_u32 i;td_s32 ret;const ot_vpss_chn vpss_chn = 0;const ot_vpss_chn vpss_chn_1 = 1;   // 添加一個 vpss_chnot_venc_chn venc_chn[4] = {0, 1, 2, 3}; /* 4: max chn num, 0/1/2/3 chn id */// 函數作用是設置 venc_chn的屬性。將 vpss的流綁定給 vencret = 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 < grp_num; i++) {// 經檢驗 i等于 0sample_comm_vpss_bind_venc(vpss_grp[i], vpss_chn, venc_chn[i]);// 這里需將 vpss_chn1綁定給 venc嗎,需要sample_comm_vpss_bind_venc(vpss_grp[0], vpss_chn_1, venc_chn[1]);}return TD_SUCCESS;start_venc_failed:return TD_FAILURE;
}td_void sample_aiisp_stop_vpss(ot_vpss_grp grp)
{td_bool chn_enable[OT_VPSS_MAX_PHYS_CHN_NUM] = {TD_TRUE, TD_FALSE, TD_FALSE};sample_common_vpss_stop(grp, chn_enable, OT_VPSS_MAX_PHYS_CHN_NUM);
}td_void sample_aiisp_stop_venc(ot_venc_chn venc_chn[], td_u32 venc_chn_len, td_u32 chn_num)
{td_u32 i;sample_comm_venc_stop_get_stream(chn_num);for (i = 0; i < chn_num && i < venc_chn_len; i++) {sample_comm_venc_stop(venc_chn[i]);}
}td_void sample_aiisp_stop_venc_and_unbind(ot_vpss_grp vpss_grp[], td_u32 grp_num)
{td_u32 i;const ot_vpss_chn vpss_chn = 0;ot_venc_chn venc_chn[4] = {0, 1, 2, 3}; /* 4: max chn num, 0/1/2/3 chn id */for (i = 0; i < grp_num; i++) {sample_comm_vpss_un_bind_venc(vpss_grp[i], vpss_chn, venc_chn[i]);}sample_aiisp_stop_venc(venc_chn, sizeof(venc_chn) / sizeof(ot_venc_chn), grp_num);
}td_s32 sample_aiisp_set_long_frame_mode(ot_vi_pipe vi_pipe, td_bool is_wdr_mode)
{td_s32 ret;ot_isp_exposure_attr exp_attr = {0};ot_isp_wdr_fs_attr fswdr_attr = {0};if (is_wdr_mode == TD_FALSE) {return TD_SUCCESS;}sample_get_char("set long frame mode");ret = ss_mpi_isp_get_exposure_attr(vi_pipe, &exp_attr);if (ret != TD_SUCCESS) {printf("ss_mpi_isp_get_exposure_attr error[0x%x]\n", ret);return TD_FAILURE;}exp_attr.auto_attr.fswdr_mode = OT_ISP_FSWDR_LONG_FRAME_MODE;ret = ss_mpi_isp_set_exposure_attr(vi_pipe, &exp_attr);if (ret != TD_SUCCESS) {printf("ss_mpi_isp_set_exposure_attr error[0x%x]\n", ret);return TD_FAILURE;}ret = ss_mpi_isp_get_fswdr_attr(vi_pipe, &fswdr_attr);if (ret != TD_SUCCESS) {printf("ss_mpi_isp_get_fswdr_attr error[0x%x]\n", ret);return TD_FAILURE;}fswdr_attr.wdr_merge_mode = OT_ISP_MERGE_WDR_MODE;ret = ss_mpi_isp_set_fswdr_attr(vi_pipe, &fswdr_attr);if (ret != TD_SUCCESS) {printf("ss_mpi_isp_set_fswdr_attr error[0x%x]\n", ret);return TD_FAILURE;}return ret;
}td_void sample_aiisp_get_default_cfg(sample_sns_type sns_type, ot_vi_pipe vi_pipe,ot_size *size, sample_vi_cfg *vi_cfg)
{sample_comm_vi_get_size_by_sns_type(sns_type, size);sample_comm_vi_get_default_vi_cfg(sns_type, vi_cfg);#ifdef OT_FPGAvi_cfg->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.pswp.cn/news/907859.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/907859.shtml
英文地址,請注明出處:http://en.pswp.cn/news/907859.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【燒腦算法】不定長滑動窗口:從動態調整到精準匹配以靈活特性實現高效破題

目錄 求最長/最大 2730. 找到最長的半重復子字符串 2779. 數組的最大美麗值 1838. 最高頻元素的頻數 2516. 每種字符至少取 K 個 2831. 找出最長等值子數組 求最短/最小 1234. 替換子串得到平衡字符串 2875. 無限數組的最短子數組 76. 最小覆蓋子串 632. 最小區間 …

第七十篇 從餐廳后廚到電影院選座:生活場景拆解Java并發編程核心

目錄 一、并發基礎&#xff1a;餐廳后廚的協作藝術1.1 廚師與線程&#xff08;Thread&#xff09;1.2 共享資源競爭&#xff1a;唯一的炒鍋1.3 線程狀態轉換&#xff1a;廚師工作流 二、線程同步&#xff1a;電影院選座中的鎖機制2.1 同步鎖&#xff08;synchronized&#xff0…

嵌入式學習--江協stm32day1

失蹤人口回歸了&#xff0c;stm32的學習比起51要慢一些&#xff0c;因為涉及插線&#xff0c;可能存在漏插&#xff0c;不牢固等問題。 相對于51直接對寄存器的設置&#xff0c;stm32因為是32位修改起來比較麻煩&#xff0c;江協課程是基于標準庫的&#xff0c;是對封裝函數進…

vue+elementUi+axios實現分頁(MyBatis、Servlet)

vueelementUiaxios實現分頁 文章目錄 vueelementUiaxios實現分頁1.代碼實現【HTML】**【Servlet層】****【Service層】****【Dao層】** 2.總結步驟3.實現要點4.注意事項4.注意事項 注&#xff1a;此項目 前端為 html、 后端采用 mybatis、servlet實現 1.代碼實現 【HTML】…

vue-10( 動態路由匹配和路由參數)

動態路由匹配和路由參數 動態路由匹配是 Vue Router 的一個強大功能&#xff0c;它允許你創建靈活且可重用的路由。您可以使用參數來捕獲 URL 的動態段&#xff0c;而不是為每個可能的值定義特定路由。這在處理具有唯一標識符的資源&#xff08;如用戶配置文件、產品詳細信息或…

劫持進程注入

劫持進程注入和遠程線程注入的區別就是 遠程線程注入是向一個正在運行中的進程注入 而劫持進程注入則是自己打開一個進程(以掛起的方式) 然后再進行注入的操作 這樣做的原因是當進程在掛起的狀態時他的所有線程都是處于未啟用的階段 這樣就可以避免目標進程的反注入線程的…

uni-app學習筆記二十--pages.json頁面路由pages設置

uni-app 通過 pages 節點配置應用由哪些頁面組成&#xff0c;pages 節點接收一個數組&#xff0c;數組每個項都是一個對象&#xff0c;其屬性值如下&#xff1a; 屬性類型默認值描述pathString配置頁面路徑styleObject配置頁面窗口表現&#xff0c;配置項參考下方 pageStylene…

VScode編譯調試debug,gpu的cuda程序,Nsight

進行下面操作的前提是&#xff0c;我們的環境已經能跑簡單的CUDA程序了。 一、安裝Nsight 二、創建launch.json文件 {"version": "0.2.0","configurations": [{"name": "CUDA C: Launch","type": "cuda-gdb…

鏈表題解——合并兩個有序鏈表【LeetCode】

1. 算法思路 這段代碼的核心思想是 合并兩個有序鏈表。具體步驟如下&#xff1a; 初始化哨兵節點&#xff1a; 創建一個哨兵節點 dummy&#xff0c;用于簡化鏈表操作&#xff0c;避免處理頭節點的特殊情況。使用指針 cur 指向 dummy&#xff0c;用于構建新的鏈表。 遍歷兩個鏈…

K8S集群主機網絡端口不通問題排查

一、環境&#xff1a; k8s: v1.23.6 docker: 20.10.14 問題和故障現象&#xff1a;devops主機集群主機節點到端口8082不通&#xff08;網絡策略已經申請&#xff0c;并且網絡策略已經實施完畢&#xff09;&#xff0c;而且網絡實施人員再次確認&#xff0c;網絡策…

qemu安裝risc-V 64

參考這篇文章https://developer.aliyun.com/article/1323996&#xff0c;其中在wsl下面安裝可能會報錯環境變量中有空格。 # clean_path.sh#!/bin/bash# 備份舊 PATH OLD_PATH"$PATH"# 過濾掉包含空格、制表符、換行的路徑 CLEAN_PATH"" IFS: read -ra PA…

python爬蟲:RoboBrowser 的詳細使用

更多內容請見: 爬蟲和逆向教程-專欄介紹和目錄 文章目錄 一、RoboBrowser概述1.1 RoboBrowser 介紹1.2 安裝 RoboBrowser1.3 與類似工具比較二、基本用法2.1 創建瀏覽器對象并訪問網頁2.2 查找元素2.3 填寫和提交表單三、高級功能3.1 處理文件上傳3.2 處理JavaScript重定向3.3…

CTFSHOW-WEB-36D杯

給你shell 這道題對我這個新手還是有難度的&#xff0c;花了不少時間。首先f12看源碼&#xff0c;看到?view_source&#xff0c;點進去看源碼 <?php //Its no need to use scanner. Of course if you want, but u will find nothing. error_reporting(0); include "…

CentOS_7.9 2U物理服務器上部署系統簡易操作步驟

近期單位網站革新&#xff0c;鑒于安全加固&#xff0c;計劃將原有Windows環境更新到Linux-CentOS 7.9&#xff0c;這版本也沒的說&#xff08;絕&#xff09;了&#xff08;版&#xff09;官方停止更新&#xff0c;但無論如何還是被sisi的牽掛著這一大批人&#xff0c;畢竟從接…

LVS-DR高可用-Keepalived

目錄 Keepalved雙機熱備 核心概念 關鍵組件 工作流程 實例環境 配置keepalived Web服務器配置 Keepalved雙機熱備 Keepalived雙機熱備是一種基于VRRP&#xff08;Virtual Router Redundancy Protocol&#xff0c;虛擬路由冗余協議&#xff09;實現的高可用性解決方案&am…

Polar編譯碼(SCL譯碼)和LDPC編譯碼(BP譯碼)的matlab性能仿真,并對比香農限

目錄 1.算法仿真效果 2.算法涉及理論知識概要 2.1香農極限 2.2 Polar碼編譯碼原理與SCL譯碼 2.3 LDPC碼編譯碼原理與BP譯碼 3.MATLAB核心程序 4.完整算法代碼文件獲得 1.算法仿真效果 matlab2024b仿真結果如下&#xff08;完整代碼運行后無水印&#xff09;&#xff1a…

AI 產品的 MVP 構建邏輯:Prompt 工程 ≠ 產品工程?(實戰增補篇)

一. 系統思維&#xff1a;產品工程的全局把控&#xff08;實戰增補篇&#xff09; 1. 某智能風控系統的彈性架構實踐 某消費金融公司在開發「30 秒極速貸」產品時&#xff0c;面臨兩大挑戰&#xff1a; Prompt 優化困境&#xff1a;傳統風控模型依賴 “提取用戶信用報告關鍵…

Unity程序集

對于Unity的程序集&#xff0c;具體內容可以參考Unity官方文檔&#xff0c;程序集定義 - 預定義程序集 比如Unity的默認程序集&#xff0c;Assembly-CSharp.dll&#xff0c;還有其他的比如 Assembly-CSharp-Editor.dll&#xff0c;Assembly-CSharp-firstpass.dll 沒有指定或…

【架構藝術】平衡技術架構設計和預期的產品形態

近期筆者因為工作原因&#xff0c;開始啟動team內部部分技術項目的重構。在事情啟動的過程中&#xff0c;內部對于這件事情的定性和投入有一些爭論&#xff0c;但最終還是敲定了下來。其中部分爭論點主要在于產品形態&#xff0c;因為事情涉及到跨部門合作&#xff0c;所以產品…

React和原生事件的區別

一、核心差異對比表 維度原生事件React 事件綁定語法HTML 屬性&#xff08;onclick&#xff09;或 DOM API&#xff08;addEventListener&#xff09;JSX 中使用駝峰式屬性&#xff08;onClick&#xff09;綁定位置直接綁定到具體 DOM 元素統一委托到根節點&#xff08;React …