首页 > 技术知识 > 正文

首先, 根据文档, 接好摄像头, 我这个硬件是旧版本的, 两条线, 记住, 镜头朝上, fpc的金手指朝上, 如果发现接好电又开不了机, 说明接反了, 赶紧拔下来.

rv1126接2053_2593双目推流-rv1190

然后下载固件, 刷这个固件

rv1126接2053_2593双目推流-rv11901

基于rkmedia_vi_double_cameras_test.c 这个例程, 进行修改

// Copyright 2020 Fuzhou Rockchip Electronics Co., Ltd. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include <assert.h> #include <fcntl.h> #include <signal.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <unistd.h> #include “common/sample_common.h” #include “librtsp/rtsp_demo.h” #include “rkmedia_api.h” #include <rga/RgaApi.h> #include <rga/rga.h> rtsp_demo_handle g_rtsplive = NULL; static rtsp_session_handle g_rtsp_session; static int video_width = 1920; static int video_height = 1080; static int disp_width = 3840; // 720; static int disp_height = 1080; // 1280; static bool quit = false; static void sigterm_handler(int sig) { fprintf(stderr, “signal %d\n”, sig); quit = true; } void video_packet_cb(MEDIA_BUFFER mb) { static RK_S32 packet_cnt = 0; if (quit) return; printf(“#Get packet-%d, size %zu\n”, packet_cnt, RK_MPI_MB_GetSize(mb)); if (g_rtsplive && g_rtsp_session) { rtsp_tx_video(g_rtsp_session, RK_MPI_MB_GetPtr(mb), RK_MPI_MB_GetSize(mb), RK_MPI_MB_GetTimestamp(mb)); rtsp_do_event(g_rtsplive); } RK_MPI_MB_ReleaseBuffer(mb); packet_cnt++; } int main(void) { int ret = 0; // int ui = 1; char *iq_dir = “/oem/etc/iqfiles”; // int ch; // CODEC_TYPE_E enCodecType = RK_CODEC_TYPE_H264; // 初始化isp, device 0跟1 ret = SAMPLE_COMM_ISP_Init(0, RK_AIQ_WORKING_MODE_NORMAL, RK_TRUE, iq_dir); if (ret) return -1; SAMPLE_COMM_ISP_Run(0); ret = SAMPLE_COMM_ISP_Init(1, RK_AIQ_WORKING_MODE_NORMAL, RK_TRUE, iq_dir); if (ret) return -1; SAMPLE_COMM_ISP_Run(1); SAMPLE_COMM_ISP_SetFrameRate(0, 30); SAMPLE_COMM_ISP_SetFrameRate(1, 30); // init rtsp g_rtsplive = create_rtsp_demo(554); g_rtsp_session = rtsp_new_session(g_rtsplive, “/live/main_stream”); rtsp_set_video(g_rtsp_session, RTSP_CODEC_ID_VIDEO_H264, NULL, 0); rtsp_sync_video_ts(g_rtsp_session, rtsp_get_reltime(), rtsp_get_ntptime()); RK_MPI_SYS_Init(); VI_CHN_ATTR_S vi_chn_attr; memset(&vi_chn_attr, 0, sizeof(vi_chn_attr)); vi_chn_attr.pcVideoNode = “rkispp_scale0”; vi_chn_attr.u32BufCnt = 3; vi_chn_attr.u32Width = video_width; vi_chn_attr.u32Height = video_height; vi_chn_attr.enPixFmt = IMAGE_TYPE_NV12; vi_chn_attr.enWorkMode = VI_WORK_MODE_NORMAL; ret = RK_MPI_VI_SetChnAttr(0, 0, &vi_chn_attr); ret |= RK_MPI_VI_EnableChn(0, 0); if (ret) { printf(“Create vi[0] failed! ret=%d\n”, ret); return -1; } memset(&vi_chn_attr, 0, sizeof(vi_chn_attr)); vi_chn_attr.pcVideoNode = “rkispp_scale0”; vi_chn_attr.u32BufCnt = 3; vi_chn_attr.u32Width = video_width; vi_chn_attr.u32Height = video_height; vi_chn_attr.enPixFmt = IMAGE_TYPE_NV12; vi_chn_attr.enWorkMode = VI_WORK_MODE_NORMAL; ret = RK_MPI_VI_SetChnAttr(1, 1, &vi_chn_attr); ret |= RK_MPI_VI_EnableChn(1, 1); if (ret) { printf(“Create vi[1] failed! ret=%d\n”, ret); return -1; } printf(“>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> create vi 0 & 1 done\n”); // pipe[0]: vi[0] // pipe[1]: vi[1] RK_U8 u8LayoutHor = 2; RK_U8 u8LayoutVer = 1; RK_U16 u16ChnCnt = u8LayoutHor * u8LayoutVer; VMIX_DEV_INFO_S stDevInfo; stDevInfo.enImgType = IMAGE_TYPE_NV12; stDevInfo.u16ChnCnt = u16ChnCnt; stDevInfo.u16Fps = 30; stDevInfo.u32ImgWidth = disp_width; stDevInfo.u32ImgHeight = disp_height; stDevInfo.bEnBufPool = RK_TRUE; stDevInfo.u16BufPoolCnt = 6; stDevInfo.stChnInfo[0].stInRect.s32X = 0; stDevInfo.stChnInfo[0].stInRect.s32Y = 0; stDevInfo.stChnInfo[0].stInRect.u32Width = video_width; stDevInfo.stChnInfo[0].stInRect.u32Height = video_height; stDevInfo.stChnInfo[0].stOutRect.s32X = 0; stDevInfo.stChnInfo[0].stOutRect.s32Y = 0; stDevInfo.stChnInfo[0].stOutRect.u32Width = video_width; stDevInfo.stChnInfo[0].stOutRect.u32Height = video_height; stDevInfo.stChnInfo[1].stInRect.s32X = 0; stDevInfo.stChnInfo[1].stInRect.s32Y = 0; stDevInfo.stChnInfo[1].stInRect.u32Width = video_width; stDevInfo.stChnInfo[1].stInRect.u32Height = video_height; stDevInfo.stChnInfo[1].stOutRect.s32X = 1920; stDevInfo.stChnInfo[1].stOutRect.s32Y = 0; stDevInfo.stChnInfo[1].stOutRect.u32Width = video_width; stDevInfo.stChnInfo[1].stOutRect.u32Height = video_height; ret = RK_MPI_VMIX_CreateDev(0, &stDevInfo); if (ret) { printf(“Init VMIX device failed! ret=%d\n”, ret); return -1; } printf(“>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> create vmix done\n”); // 绑定通道 for (RK_U16 i = 0; i < 2; i++) { ret = RK_MPI_VMIX_EnableChn(0, i); if (ret) { printf(“Enable VM[0]:Chn[%d] failed! ret=%d\n”, i, ret); return -1; } } printf(“>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> bind vmix done\n”); // 创建编码通道 VENC_CHN_ATTR_S venc_chn_attr; memset(&venc_chn_attr, 0, sizeof(venc_chn_attr)); venc_chn_attr.stVencAttr.enType = RK_CODEC_TYPE_H264; venc_chn_attr.stRcAttr.enRcMode = VENC_RC_MODE_H264CBR; venc_chn_attr.stRcAttr.stH264Cbr.u32Gop = 30; venc_chn_attr.stRcAttr.stH264Cbr.u32BitRate = disp_width * disp_height; // frame rate: in 30/1, out 30/1. venc_chn_attr.stRcAttr.stH264Cbr.fr32DstFrameRateDen = 1; venc_chn_attr.stRcAttr.stH264Cbr.fr32DstFrameRateNum = 30; venc_chn_attr.stRcAttr.stH264Cbr.u32SrcFrameRateDen = 1; venc_chn_attr.stRcAttr.stH264Cbr.u32SrcFrameRateNum = 30; venc_chn_attr.stVencAttr.imageType = IMAGE_TYPE_NV12; venc_chn_attr.stVencAttr.u32PicWidth = disp_width; venc_chn_attr.stVencAttr.u32PicHeight = disp_height; venc_chn_attr.stVencAttr.u32VirWidth = disp_width; venc_chn_attr.stVencAttr.u32VirHeight = disp_height; venc_chn_attr.stVencAttr.u32Profile = 77; ret = RK_MPI_VENC_CreateChn(0, &venc_chn_attr); if (ret) { printf(“ERROR: create VENC[0] error! ret=%d\n”, ret); return 0; } MPP_CHN_S stEncChn; stEncChn.enModId = RK_ID_VENC; stEncChn.s32DevId = 0; stEncChn.s32ChnId = 0; ret = RK_MPI_SYS_RegisterOutCb(&stEncChn, video_packet_cb); // 注册回调 if (ret) { printf(“ERROR: register output callback for VENC[0] error! ret=%d\n”, ret); return 0; } printf(“>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> create venc done\n”); MPP_CHN_S stSrcChn; MPP_CHN_S stDestChn; #if 0 // 绑定vmix到venc MPP_CHN_S stSrcChn; stSrcChn.enModId = RK_ID_VMIX; stSrcChn.s32DevId = 0; stSrcChn.s32ChnId = 0; stDestChn.enModId = RK_ID_VENC; stDestChn.s32DevId = 0; stDestChn.s32ChnId = 0; ret = RK_MPI_SYS_Bind(&stSrcChn, &stDestChn); if (ret) { printf(“ERROR: Bind VMIX[0] and VENC[0] error! ret=%d\n”, ret); return 0; } printf(“%s initial finish\n”, __func__); signal(SIGINT, sigterm_handler); // 创建输出设备vo VO_CHN_ATTR_S stVoAttr = {0}; stVoAttr.pcDevNode = “/dev/dri/card0”; stVoAttr.emPlaneType = VO_PLANE_OVERLAY; stVoAttr.enImgType = IMAGE_TYPE_NV12; stVoAttr.u16Zpos = 0; stVoAttr.stImgRect.s32X = 0; stVoAttr.stImgRect.s32Y = 0; stVoAttr.stImgRect.u32Width = disp_width; stVoAttr.stImgRect.u32Height = disp_height; stVoAttr.stDispRect.s32X = 0; stVoAttr.stDispRect.s32Y = 0; stVoAttr.stDispRect.u32Width = disp_width; stVoAttr.stDispRect.u32Height = disp_height; ret = RK_MPI_VO_CreateChn(0, &stVoAttr); if (ret) { printf(“Create vo[0] failed! ret=%d\n”, ret); return -1; } // VO[1] for primary plane memset(&stVoAttr, 0, sizeof(stVoAttr)); stVoAttr.pcDevNode = “/dev/dri/card0”; stVoAttr.emPlaneType = VO_PLANE_PRIMARY; stVoAttr.enImgType = IMAGE_TYPE_RGB888; stVoAttr.u16Zpos = ui; stVoAttr.stImgRect.s32X = 0; stVoAttr.stImgRect.s32Y = 0; stVoAttr.stImgRect.u32Width = disp_width; stVoAttr.stImgRect.u32Height = disp_height; stVoAttr.stDispRect.s32X = 0; stVoAttr.stDispRect.s32Y = 0; stVoAttr.stDispRect.u32Width = disp_width; stVoAttr.stDispRect.u32Height = disp_height; ret = RK_MPI_VO_CreateChn(1, &stVoAttr); if (ret) { printf(“Create vo[1] failed! ret=%d\n”, ret); return -1; } #endif printf(“#Bind VMX[0] to VO[0]….\n”); stSrcChn.enModId = RK_ID_VMIX; stSrcChn.s32DevId = 0; stSrcChn.s32ChnId = 0; // invalid stDestChn.enModId = RK_ID_VENC; stDestChn.s32DevId = 0; stDestChn.s32ChnId = 0; ret = RK_MPI_SYS_Bind(&stSrcChn, &stDestChn); if (ret) { printf(“Bind VMX[0] to vo[0] failed! ret=%d\n”, ret); return -1; } for (RK_U16 i = 0; i < 2; i++) { printf(“#Bind VI[%u] to VM[0]:Chn[%u]….\n”, i, i); stSrcChn.enModId = RK_ID_VI; stSrcChn.s32DevId = i; stSrcChn.s32ChnId = i; stDestChn.enModId = RK_ID_VMIX; stDestChn.s32DevId = 0; stDestChn.s32ChnId = i; ret = RK_MPI_SYS_Bind(&stSrcChn, &stDestChn); if (ret) { printf(“Bind vi[%u] to vmix[0]:Chn[%u] failed! ret=%d\n”, i, i, ret); return -1; } // RK_MPI_SYS_DumpChn(RK_ID_VMIX); // getchar(); } printf(“%s initial finish\n”, __func__); signal(SIGINT, sigterm_handler); while (!quit) { usleep(500000); } printf(“%s exit!\n”, __func__); if (g_rtsplive) rtsp_del_demo(g_rtsplive); printf(“#UnBind VMX[0] to VO[0]….\n”); stSrcChn.enModId = RK_ID_VMIX; stSrcChn.s32DevId = 0; stSrcChn.s32ChnId = 0; // invalid stDestChn.enModId = RK_ID_VENC; stDestChn.s32DevId = 0; stDestChn.s32ChnId = 0; ret = RK_MPI_SYS_UnBind(&stSrcChn, &stDestChn); if (ret) { printf(“UnBind VMX[0] to vo[0] failed! ret=%d\n”, ret); return -1; } // destroy venc before vi ret = RK_MPI_VENC_DestroyChn(0); if (ret) { printf(“ERROR: Destroy VENC[0] error! ret=%d\n”, ret); return 0; } for (RK_U16 i = 0; i < 2; i++) { printf(“#UnBind VI[%u] to VM[0]:Chn[%u]….\n”, i, i); stSrcChn.enModId = RK_ID_VI; stSrcChn.s32DevId = i; stSrcChn.s32ChnId = i; stDestChn.enModId = RK_ID_VMIX; stDestChn.s32DevId = 0; stDestChn.s32ChnId = i; ret = RK_MPI_SYS_UnBind(&stSrcChn, &stDestChn); if (ret) { printf(“UnBind vi[%u] to vmix[0]:Chn[%u] failed! ret=%d\n”, i, i, ret); return -1; } } // RK_MPI_VO_DestroyChn(0); // RK_MPI_VO_DestroyChn(1); // destroy venc before vi ret = RK_MPI_VENC_DestroyChn(0); if (ret) { printf(“ERROR: Destroy VENC[0] error! ret=%d\n”, ret); return 0; } for (RK_U16 i = 0; i < u16ChnCnt; i++) { ret = RK_MPI_VMIX_DisableChn(0, i); if (ret) printf(“Disable VIMX[0]:Chn[%u] failed! ret=%d\n”, i, ret); } ret = RK_MPI_VMIX_DestroyDev(0); if (ret) { printf(“DeInit VIMX[0] failed! ret=%d\n”, ret); } RK_MPI_VI_DisableChn(0, 0); RK_MPI_VI_DisableChn(1, 1); SAMPLE_COMM_ISP_Stop(0); SAMPLE_COMM_ISP_Stop(1); return 0; }
<

修改CMakeLists.txt, 添加rtsp的依赖

#————————– # rkmedia_vi_double_cameras_rtsp #————————– link_directories(${PROJECT_SOURCE_DIR}/librtsp/) add_executable(rkmedia_vi_double_cameras_rtsp rkmedia_vi_double_cameras_rtsp.c ${COMMON_SRC}) add_dependencies(rkmedia_vi_double_cameras_rtsp easymedia) target_link_libraries(rkmedia_vi_double_cameras_rtsp easymedia ${THIRD_MEDIA} rtsp) target_include_directories(rkmedia_vi_double_cameras_rtsp PRIVATE ${CMAKE_SOURCE_DIR}/include) install(TARGETS rkmedia_vi_double_cameras_rtsp RUNTIME DESTINATION “bin”)

编译之后push过去.

vlc拿到的流, 地址是192.168.100.75/live/main_stream

rv1126接2053_2593双目推流-rv11902

猜你喜欢