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也不能成功退出進程。