当前位置: 首页 > news >正文

Linux驱动24 --- RkMedia 视频 API 使用

目录

一、名词解释

二、程序编译&执行


一、名词解释

mmap --- 内存映射

        一般用于无法直接操作的物理内存

        就将物理内存映射为一个虚拟内存

        操作虚拟内存就相当于操作物理内存

        CBR --- 固定码率 --- 最简单

        CBR 控制模式一般用于网络流媒体视频编码。CBR 的优点在于压缩速度非常快,并且码率很平稳不会出现码率跳变的情况

        VBR --- 可变码率

        VBR 的优点是它的尽可能保证整个图像编码质量,利用 VBR 编码的图像很少会出现马赛克、画面丢失的情况。但缺点同样也很明显,使用 VBR 编码出来的图像它体积是不固定的

        AVBR --- 混合码率

        AVBR 全称叫适配式可变码率控制方式,它的很多思想跟 VBR 基本上是一致的。但它比 VBR 强大的一点是这种控制方式能够自动检测当前编码场景是静止画面还是运动画面。若当前画面是静止画面则会主动降低码率、若当前画面是运动画面则会把码率主动提升。AVBR 适用于当前编码视频静止画面和运动画面频繁出现的场景,所以 AVBR 码率控制方式经常用在大型体育比赛上面。

        简单点理解 CBR --- I 帧间隔固定

二、程序编译&执行

修改 SDK 路径

        

        目前的目标:根据官方的例程,去完善自己的程序

//用来设置摄像头参数的 --- 必要的
rk_aiq_working_mode_t hdr_mode = RK_AIQ_WORKING_MODE_NORMAL;int fps = 30;SAMPLE_COMM_ISP_Init(s32CamId, hdr_mode, bMultictx, pIqfilesPath);SAMPLE_COMM_ISP_Run(s32CamId);SAMPLE_COMM_ISP_SetFrameRate(s32CamId, fps);
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();
RK_MPI_VI_SetChnAttr(s32CamId, 0, &vi_chn_attr);
RK_MPI_VI_EnableChn(s32CamId, 0);
RK_MPI_VENC_CreateChn(0, &venc_chn_attr);
RK_MPI_SYS_RegisterOutCb(&stEncChn, video_packet_cb);
RK_MPI_SYS_Bind(&stSrcChn, &stDestChn);
rtsp_del_demo(g_rtsplive);
RK_MPI_SYS_UnBind(&stSrcChn, &stDestChn);
RK_MPI_VENC_DestroyChn(0);
RK_MPI_VI_DisableChn(s32CamId, 0);
SAMPLE_COMM_ISP_Stop(s32CamId);

代码

#include "main.h"
#include <time.h>
//0.变量定义
RK_S32 s32CamId = 0;    //摄像头ID号
RK_BOOL bMultictx = RK_FALSE;   
RK_CHAR *pIqfilesPath = "/oem/etc/iqfiles";     //ISP配置文件rtsp_demo_handle g_rtsplive = NULL; //rtsp服务器的核心指针
rtsp_session_handle g_rtsp_session; //rtsp服务器配置RK_U32 Width = 1280;
RK_U32 Height = 720;int end_flag;
int time_count = 30 * 30;//30s的帧数,1s30帧
FILE *g_output_file;
int g_filesave; // 添加标志位,确保只保存一次文件
char filename[100] = {0};// 输出回调函数
void myoutcbfunc(MEDIA_BUFFER mb) 
{if(time_count){printf("time_count = %d\n", time_count);time_count--;}else{RK_MPI_MB_ReleaseBuffer(mb);//释放end_flag = 1;return;}/*回调函数中 --- 最核心的就是获取数据内容、获取数据大小*///1.一个是推流RK_MPI_MB_GetPtr(mb);RK_MPI_MB_GetSize(mb);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);//2.本地保存fwrite(RK_MPI_MB_GetPtr(mb), 1, RK_MPI_MB_GetSize(mb), g_output_file);RK_MPI_MB_ReleaseBuffer(mb);//释放}int main(void)
{// time_t tm = time(0);// struct tm *lm = localtime(&tm);// sprintf(filename,"%04d%02d%02d%02d%02d%02d.h264",lm->tm_year+1900,lm->tm_mon+1,lm->tm_mday,lm->tm_hour,lm->tm_min,lm->tm_sec);g_output_file = fopen("./9203.h264", "w");/*1.ISP的初始化 --- 必要内容没有参考文档,只能复制例程*/rk_aiq_working_mode_t hdr_mode = RK_AIQ_WORKING_MODE_NORMAL;int fps = 30;SAMPLE_COMM_ISP_Init(s32CamId, hdr_mode, bMultictx, pIqfilesPath);SAMPLE_COMM_ISP_Run(s32CamId);SAMPLE_COMM_ISP_SetFrameRate(s32CamId, fps);/*2.rtsp的初始化 --- 可有可无没有参考文档,只能复制例程*/g_rtsplive = create_rtsp_demo(554);     //推流的端口号//rtsp://192.168.66.88/live/main_stream --- 原本的//rtsp://192.168.66.88/xyd/9203 --- 可改g_rtsp_session = rtsp_new_session(g_rtsplive, "/live/main_stream");     //推流的路径 --- 可以自己修改/*重要内容 ---       rtsp_set_video --- RTSP_CODEC_ID_VIDEO_H264如果是音频需要换为   rtsp_set_audio --- RTSP_CODEC_ID_AUDIO_XXXX*/rtsp_set_video(g_rtsp_session, RTSP_CODEC_ID_VIDEO_H264, NULL, 0);/*重要内容 ---       rtsp_sync_video_ts如果是音频需要换为   rtsp_sync_audio_ts*/rtsp_sync_video_ts(g_rtsp_session, rtsp_get_reltime(), rtsp_get_ntptime());/*3.RkMedia相关配置 --- 必要内容有相关API文档进行说明*/RK_MPI_SYS_Init();//对于VI视频输入来说,管道号和通道号 填0即可VI_CHN_ATTR_S vi_pstChnAttr = {0};vi_pstChnAttr.enBufType = VI_CHN_BUF_TYPE_MMAP;vi_pstChnAttr.enPixFmt = IMAGE_TYPE_NV12;//输入视频的原始格式 --- 这里如果使用YUV色彩格式有问题 --- 最中使用的是NV12原因是例程使用的NV12vi_pstChnAttr.enWorkMode = VI_WORK_MODE_NORMAL;//VI通道工作模式vi_pstChnAttr.pcVideoNode = "rkispp_scale0";//节点路径vi_pstChnAttr.u32BufCnt = 3;//v4l2摄像头开发方式定义的缓冲区个数3~5vi_pstChnAttr.u32Height = Height;//高vi_pstChnAttr.u32Width = Width;//宽RK_MPI_VI_SetChnAttr(0, 0, &vi_pstChnAttr);RK_MPI_VI_EnableChn(0, 0);/*重要 --- venc通道,最终的整合需要2个编码器通道*/VENC_CHN_ATTR_S venc_stVencChnAttr = {0};venc_stVencChnAttr.stRcAttr.enRcMode = VENC_RC_MODE_H264CBR;//I帧间隔固定,比如固定间隔30帧venc_stVencChnAttr.stRcAttr.stH264Cbr.fr32DstFrameRateDen = 1;venc_stVencChnAttr.stRcAttr.stH264Cbr.fr32DstFrameRateNum = 30;venc_stVencChnAttr.stRcAttr.stH264Cbr.u32BitRate = Width * Height;venc_stVencChnAttr.stRcAttr.stH264Cbr.u32Gop = 30;//I帧间隔venc_stVencChnAttr.stRcAttr.stH264Cbr.u32SrcFrameRateDen = 1;//分母venc_stVencChnAttr.stRcAttr.stH264Cbr.u32SrcFrameRateNum = 30;//分子//编码器属性venc_stVencChnAttr.stVencAttr.enType = RK_CODEC_TYPE_H264;venc_stVencChnAttr.stVencAttr.imageType = IMAGE_TYPE_NV12;//输入图像格式venc_stVencChnAttr.stVencAttr.u32PicHeight = Height;venc_stVencChnAttr.stVencAttr.u32PicWidth = Width;//H264编码可以达到300倍以上venc_stVencChnAttr.stVencAttr.u32Profile = 77;//编码等级venc_stVencChnAttr.stVencAttr.u32VirHeight = Height;venc_stVencChnAttr.stVencAttr.u32VirWidth = Width;RK_MPI_VENC_CreateChn(0, &venc_stVencChnAttr);/*当前绑定的是VI0和VENC0通道后续绑定的是VI0和VENC1通道*/MPP_CHN_S v_pstSrcChn = {0}; MPP_CHN_S v_pstDestChn = {0};v_pstSrcChn.enModId = RK_ID_VI;//视频输入通道v_pstSrcChn.s32ChnId = 0;//VI通道v_pstSrcChn.s32DevId = 0;v_pstDestChn.enModId = RK_ID_VENC;//视频编码通道v_pstDestChn.s32ChnId = 0;//VENC通道v_pstDestChn.s32DevId = 0;RK_MPI_SYS_Bind(&v_pstSrcChn, &v_pstDestChn);//建立VI和VENC的联系RK_MPI_SYS_RegisterOutCb(&v_pstDestChn, myoutcbfunc);while(!end_flag){sleep(1);}/*3.RkMedia相关释放有相关API文档进行说明*/rtsp_del_demo(g_rtsplive);RK_MPI_SYS_UnBind(&v_pstSrcChn, &v_pstDestChn);RK_MPI_VENC_DestroyChn(0); //后续这个VENC要改为2个通道RK_MPI_VI_DisableChn(s32CamId, 0);SAMPLE_COMM_ISP_Stop(s32CamId);fclose(g_output_file); // 关闭文件return 0;
}
http://www.xdnf.cn/news/1248355.html

相关文章:

  • 前端保持和服务器时间同步的方法【使用vue3举例】
  • Tasks and Deadlines(Sorting and Searching)
  • Mysql-事务
  • Nginx入门:高性能Web服务器详解
  • 【图像算法 - 09】基于深度学习的烟雾检测:从算法原理到工程实现,完整实战指南
  • Claude Code实战体验:AI智能编程助手如何重塑开发工作流?
  • 2. JS 有哪些数据类型
  • Linux的NFS与Autofs配置指南
  • nodejs 编程基础01-NPM包管理
  • 最优化中常见的优化理论
  • Shader开发(七)创建第一个Shader项目
  • 游戏画面总是卡顿怎么办 告别延迟畅玩游戏
  • DDoS 防护的未来趋势AI 如何改变安全行业
  • MySQL 5.7 和 8.0 离线安装教程(图文版适合电脑小白)
  • C++返回值优化(RVO):高效返回对象的艺术
  • 【基础】第八篇 Java 位运算符详解:从基础到实战应用
  • Unknown initial character set index ‘255’,Kettle连接MySQL数据库常见错误及解决方案大全
  • nuxt学习笔记
  • 什么是mysql的垂直分表,理论依据是什么,如何使用?
  • LeetCode 刷题【31. 下一个排列】
  • Apache OFBiz Scrum 组件命令注入漏洞
  • 力扣148:排序链表
  • 不可变集合
  • 笔记学习杂记
  • nordic通过j-link rtt viewer打印日志
  • Linux网络编程:TCP初体验
  • 永磁同步电机的矢量控制
  • Python包安全工程实践:构建安全可靠的Python生态系统
  • Redis类型之String
  • Python深度学习:从入门到进阶