当前位置: 首页 > 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.lryc.cn/news/610530.html

相关文章:

  • 技术文章推荐|解析 ESA 零售交易方案(技术分析+案例拆解)
  • 基于k8s环境下的pulsar常用命令(下)
  • JavaWeb02——基础标签及样式(黑马视频笔记)
  • 203.移除链表元素 707.设计链表 206.反转链表
  • 8.5 位|归并|递归
  • 腾讯云CodeBuddy AI IDE+CloudBase AI ToolKit打造理财小助手网页
  • C++ - 基于多设计模式下的同步异步日志系统(11w字)
  • 使用ProxySql实现MySQL的读写分离
  • 【模电笔记】—— 直流稳压电源——整流、滤波电路
  • C++返回值优化(RVO):高效返回对象的艺术
  • LINUX 85 SHElL if else 前瞻 实例
  • 解锁n8n:开启自动化工作流的无限可能
  • 数据挖掘,到底是在挖掘什么?
  • Leetcode-2080区间内查询数字的频率
  • 417页PDF | 2025年“人工智能+”行业标杆案例荟萃
  • 机器学习——集成学习(Ensemble Learning)详解:原理、方法与实战应用
  • 深度拆解Dify:开源LLM开发平台的架构密码与技术突围
  • 服务器端口连通性的测试工具和方法
  • ApacheCon Asia 2025 中国开源年度报告:Apache Doris 国内第一
  • Spring Boot 整合 Thymeleaf
  • 全球氨运输罐行业发展现状及趋势分析报告
  • makefile的使用与双向链表
  • Docker Compose管理新范式:可视化控制台结合cpolar提升容器编排效率?
  • Docker使用的常见问题
  • 解决微信小程序中camera组件被view事件穿透触发对焦以及camera的bindtap事件
  • 性能优化篇:SQL数据库查表速度优化
  • JAVA无人共享球杆柜系统球杆柜租赁系统源码支持微信小程序
  • TortoiseGit配置SSH Key或Putty Key
  • W3D引擎游戏开发----从入门到精通【22】
  • 微信小程序功能实现:页面导航与跳转