技术专栏
rv1126接2053_2593双目推流
首先, 根据文档, 接好摄像头, 我这个硬件是旧版本的, 两条线, 记住, 镜头朝上, fpc的金手指朝上, 如果发现接好电又开不了机, 说明接反了, 赶紧拔下来.
然后下载固件, 刷这个固件
基于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
声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
红包
点赞
收藏
评论
打赏
- 分享
- 举报
评论
0个
手气红包
暂无数据
相关专栏
-
浏览量:2466次2023-04-28 17:07:50
-
浏览量:1216次2024-01-09 17:35:19
-
浏览量:3545次2023-04-19 17:17:55
-
浏览量:1544次2024-01-04 17:26:55
-
浏览量:791次2023-12-13 14:01:46
-
浏览量:221次2024-10-18 13:07:07
-
浏览量:2529次2023-06-28 17:22:40
-
浏览量:7150次2023-01-11 16:49:09
-
浏览量:3359次2023-03-24 16:30:17
-
2022-11-10 10:36:09
-
浏览量:6225次2022-10-24 14:44:33
-
浏览量:1326次2024-05-16 12:25:25
-
浏览量:960次2023-08-30 18:37:06
-
浏览量:1612次2023-12-29 17:51:55
-
浏览量:729次2024-01-02 09:46:50
-
浏览量:3983次2021-06-18 16:05:42
-
浏览量:3026次2022-05-17 17:19:48
-
浏览量:797次2023-12-11 11:37:59
-
浏览量:1247次2023-08-31 16:23:55
置顶时间设置
结束时间
删除原因
-
广告/SPAM
-
恶意灌水
-
违规内容
-
文不对题
-
重复发帖
打赏作者
Marc
您的支持将鼓励我继续创作!
打赏金额:
¥1
¥5
¥10
¥50
¥100
支付方式:
微信支付
打赏成功!
感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~
举报反馈
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明
审核成功
发布时间设置
发布时间:
请选择发布时间设置
是否关联周任务-专栏模块
审核失败
失败原因
请选择失败原因
备注
请输入备注