Firefly1126中RKMedia中多路视频流rknn检测配置
Firefly1126中RKMedia中多路视频流rknn检测配置
1,对于SDK目录下的app内的rkmedia_demo进行配置编译(路径为:/sdk/app/firefly_rkmedia_demo),具体过程参考如下博客:
https://www.cnblogs.com/kxqblog/p/16142999.html
2,在同一目录下新建一个名为rkmedia_localfile_vdec_venc_rtsp_test.cc的文件。
3,在同一目录下的CMakeList.txt中为新文件加入如下配置:
#---------------------------------------------
# rkmedia_localfile_vdec_venc_rtsp_test
#---------------------------------------------
add_executable(rkmedia_localfile_vdec_venc_rtsp_test ${CMAKE_SOURCE_DIR}/rkmedia_localfile_vdec_venc_rtsp_test.cc)
target_link_libraries(rkmedia_localfile_vdec_venc_rtsp_test ${COMMON_DEPENDENT_LIBS} ${FIREFLY_RTSP_LIB} ${ROCKCHIP_RTSP_LIB})
install(TARGETS rkmedia_localfile_vdec_venc_rtsp_test RUNTIME DESTINATION "bin")
在其中添加rkmedia_rtspget_vdec_venc_rtsp_test.cc代码,若能在终端下直接编译成功,以上添加配置工作则成功完成。
在编译过程中出现以下错误:
错误1:
arm-linux-gnueabihf-g++: error: larcsoft_face_engine: No such file or directory
解决办法:
同一代码下的build.sh文件中LIBCP下larcsoft_face_engine没有加上-字符,加上即可解决问题。
4,修改代码
代码修改中注意以下几点:
1.代码主要参考rkmedia_rtspget_vedc_venc_rtsp.cc与sdk/external/rkmedia/examples/rkmedia_venc_local_file_test.c文件,对于rkmedia_rtspget_vedc_venc_rtsp.cc,由于没有合适的拉流源作为输入,在本代码rkmedia_localfile_vdec_venc_rtsp_test.cc中将拉流源替换为文件输入作为解决方案,实现视频的解码,AI识别,编码,推流过程。
2.修改点主要是在rkmedia_rtspget_vedc_venc_rtsp.cc文件中用到了VO模块用于绑定输出,需要将有关的模块一并注释删除,具体详见代码中演示。主要添加与修改了以下部分:
注释掉有关ffrtspget拉流的代码,本例采用本地文件进行测试,:
// static void *rtspgetbuff(void *data) {
// ffrtspGet(*(FFRTSPGet *)data);
// }
等
将其中FFRKMedia_Vdec_Send函数改为:
static void* FFRKMedia_Vdec_Send(void *arg){//unsigned framesize,int cur_chn
main_stream_data *arg_data = (struct main_stream_data *)arg;
FILE *infile = fopen(cfg.session_cfg[arg_data->number].videourl, "rb");
if (!infile) {
fprintf(stderr, "Could not open %s\n", cfg.session_cfg[arg_data->number].videourl);
return 0;
}
int data_size;
int read_size;
int u32Loop=1;//xunhuan
int ret;
data_size = INBUF_SIZE;
// fseek(infile, 0, SEEK_END);
// data_size = ftell(infile);//帧模式直接读取文件大小
// fseek(infile, 0, SEEK_SET);
while (g_flag_run) {
MEDIA_BUFFER mb = RK_MPI_MB_CreateBuffer(data_size, RK_FALSE, 0);
RETRY:
/* read raw data from the input file */
read_size = fread(RK_MPI_MB_GetPtr(mb), 1, data_size, infile);
if (!read_size || feof(infile)) {
if (u32Loop) {
fseek(infile, 0, SEEK_SET);
goto RETRY;
} else {
RK_MPI_MB_ReleaseBuffer(mb);
break;
}
}
RK_MPI_MB_SetSize(mb, read_size);
printf("#Send packet(%p, %zuBytes) to VDEC[%d].\n", RK_MPI_MB_GetPtr(mb),
RK_MPI_MB_GetSize(mb),cfg.session_cfg[arg_data->number].stVdecChn.s32ChnId);
ret = RK_MPI_SYS_SendMediaBuffer(RK_ID_VDEC,cfg.session_cfg[arg_data->number].stVdecChn.s32ChnId, mb);
RK_MPI_MB_ReleaseBuffer(mb);
usleep(30 * 1000);
}
fclose(infile);
return NULL;
}
并在Main函数中加入获取本地文件的线程:
pthread_create(&localfile_thread[i],NULL,FFRKMedia_Vdec_Send,&main_data1[i]);
pthread_t localfile_thread[MAXFFRTSPChn];
pthread_join(localfile_thread[i], NULL);
3.准备工作,将待检测视频转换为h.264码流
利用ffmpeg使用以下指令转换:
ffmpeg -i AnimalVideo.mp4 -codec copy -bsf: h264_mp4toannexb -f h264 AnimalVideo0.264
将待检测视频流转换完毕后,再复制一份后上传到开发板下某一目录待用。
##修改后ffrtsp-nn.cfg,其中video_type只能为264或265文件,而fps,width,height根据文件属性进行修改
video_type=6 video_fps=30 width=1920 height=1080 image_type=4 port=8554 video_url=./AnimalVideo0.264
video_type=6 video_fps=30 width=1920 height=1080 image_type=4 port=8555 video_url=./AnimalVideo1.264
输入以下命令执行程序:
./rkmedia_localfile_vdec_venc_rtsp_test -c ./localfile-nn.cfg -p /usr/share/rknn_model/ssd_inception_v2_rv1109_rv1126.rknn -l /usr/share/rknn_model/coco_labels_list.txt -b /usr/share/rknn_model/box_priors.txt
拉流指令:
vlc rtsp://192.168.137.10:8554/H264_stream_0
vlc rtsp://192.168.137.10:8555/H264_stream_1
之后成功的显示拉流视频如下:
后续记录:
其中遇到的问题有二:
第一个问题是最后的拉视频流时不时卡顿,推测是代码中每次读取的本地文件流数据比较小导致的,但是增大后,双会报以下错误,此问题还没有解决,留待以后测试。
[RKMEDIA][VDEC][Info]:Failed to put a packet to MPP (ret = -1)
#Send packet(0x8fb04b08, 8192Bytes) to VDEC[0].
[RKMEDIA][VDEC][Info]:Failed to put a packet to MPP (ret = -1)
#Send packet(0x91505f68, 8192Bytes) to VDEC[1].
[RKMEDIA][VDEC][Info]:Failed to put a packet to MPP (ret = -1)
第二个问题是能够显示拉流视频时,调试端打印以下信息,其中,有个错误不知道是为什么发生的,并且ctrl+C也不能成功退出进程。