音视频开发

通过多线程分别获取高分辨率(1920 * 1080)和低分辨率(1280 * 720)

初始化VI模块

 

初始化HIGH VENC模块

初始化LOW VENC模块

初始化RGA模块

绑定 VI和HIGH VENC

绑定 VI和RGA

创建线程

HIGH VENC处理

RGA处理

LOW VENC处理

销毁 

 

QP原理的讲解

QP参数调节,指的是量化参数调节。它主要是来调节图像的细节,最终达到调节画面质量的作用。QP值和比特率成反比,QP值越小,码率越高,画面质量越好;反之QP值越大,码率越低,画面质量越低,而且随着视频源复杂度,这种反比的关系会更加明显。但是要注意的是,在设置QP值的时候会容易造成码率的波动,有时候画面质量提升了会导致码率大幅度提升,所以在提升画面质量的时候也需要考虑码率的情况。在编码中,亮度的QP最大值是51、色度的QP最大值是39,在真正开发中调节亮度的QP值为主。

QP调节一般由QStep、MinQp、MaxQp这三个参数进行调节

QStep

QStep指的是量化步长,QStep随着QP的增加而增加。每当QP值增加6,QStep增加一倍。在一般的编码器,H264/H265采用的是标量量化技术,用数学表达式就是:FQ = round(y/QStep)(FQ是量化的值、y是输入样本点编码、QStep是量化步长、round是取整函数)。QP值越小,整体画面越精细,否则越粗糙;QP的取值范围是[0,51],当值为0的时候表示画面最精细,当值为51的时候画面最粗糙。

minqp

设置最小量化器,限制最好的图像质量(重点在静止画面),当QP达到这个值的时候,数值不会变。这就会使得在静止场景下,码率到达一定数量后不会进行调整。minqp越小,静止时候码率越大,质量越好,minQp取值范围是[0,48]。下面就是利用minQp做静止画面调节的细节。

 maxqp

设置最大量化器,最大QP值,限制最差的画面(重点在运动的时候),maxQp越小,运动时候码率就越大,质量相对越好。同样道理,当运动情况下到达一定码率后就不会调整,取值范围是[8,51]。下面就是利用maxQp做运动画面调节的细节。

RV1126多线程分别获取QP的VENC数据和普通VENC数据

步骤流程

VI模块初始化

普通VENC初始化

量化QP的VENC初始化

绑定VI和VENC

设置VENC模块的QP量化参数

绑定VI和QP量化的VENC模块 

创建线程

 

通过GOP模式调节画面质量

普通GOP模式

普通GOP模式是最常见的GOP模式,它的特点就是两个I帧间隔固定的GOPSIZE,而GOPSIZE里面都是P帧或者B帧。比方说上图,GOPSIZE=5,相当于每隔5个P帧或者B帧插入一个I帧;普通的GOP模式通常适用于普通场景,比方说视频场景比较单一,没有那种运动画面、静止画面频繁切换的场景。 

智能SMARTP的GOP模式

在SMART的GOP模式下,会分成两种I帧,一种是普通的I帧另外一种是虚拟I帧。普通的I帧主要是检测画面的静止区域,当检测到视频里面有静止画面的时候,编码器会利用长参考帧大幅度降低码率,静止画面降低码率能够有效防止画面的呼吸效应出现。

而在运动区域,则利用短参考帧进行运动估计,并插入Virtual I帧(虚拟I帧就是SMARTP)。在插入虚拟I帧的时候,可以最大拉长I帧间隔让它其提高在运动场景下的码率能够得到足够的提高,画面质量能够得到很好的改善;SMARTP模式常使用在静止画面和运动画面经常切换的场景,尤其是体育赛事。

 

TSVC的GOP模式

多层时域指的是编码层可以划分为多个层级,RV1126提供了RK_MPI_MB_GetTsvcLevel获取层数,并通过层数来定制码流。举个例子,TSVC技术可以将一个普通的H264码流分割成不同的帧率、分辨率和视频质量的层数。一般而言,TSVC技术会根据目前的编码的网络情况把视频码流分割成一个基础层和多个视频增强层,基础层为开发者提供最基本的视频质量、帧率和分辨率。基础层可以作为一个独立的层进行解码,而增强层的信息则依赖于基础层进行解码;总体来说,解码端接受的增强层数量越大,解码的视频质量就会越好。TSVC模式主要运用在网络环境不好的情况,如弱网环境、或者移动场景下比较多。

RV1126多线程获取SMARTP的GOP模式数据和普通GOP模式数据

代码显示

#include <assert.h>
#include <fcntl.h>
#include <getopt.h>
#include <pthread.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include "rkmedia_api.h"#define PIPE_ID 0
#define VI_CHN_ID 0#define COMMON_GOP_VENC_CHN 0
#define SMARTP_GOP_VENC_CHN 1//获取每一帧COMMON_GOP的编码数据
void  * get_common_gop_thread(void * args)
{pthread_detach(pthread_self());FILE * common_gop_h264 = fopen("test_common_gop.h264", "w+");MEDIA_BUFFER mb = NULL;while (1){mb = RK_MPI_SYS_GetMediaBuffer(RK_ID_VENC, COMMON_GOP_VENC_CHN, -1);if(!mb){printf("Get COMMON_GOP VENC break.......\n");break;}printf("Get COMMON_GOP VENC Success.......\n");fwrite(RK_MPI_MB_GetPtr(mb), RK_MPI_MB_GetSize(mb), 1, common_gop_h264);RK_MPI_MB_ReleaseBuffer(mb);}return NULL;
}//获取每一帧SMARTP_GOP的编码数据
void  * get_smartp_gop_thread(void * args)
{pthread_detach(pthread_self());FILE * smartp_gop_h264 = fopen("test_smartp_gop.h264", "w+");MEDIA_BUFFER mb = NULL;while (1){mb = RK_MPI_SYS_GetMediaBuffer(RK_ID_VENC, SMARTP_GOP_VENC_CHN, -1);if(!mb){printf("Get SMARTP_GOP VENC break.......\n");break;}printf("Get SMARTP_GOP VENC Success.......\n");fwrite(RK_MPI_MB_GetPtr(mb), RK_MPI_MB_GetSize(mb), 1, smartp_gop_h264);RK_MPI_MB_ReleaseBuffer(mb);}return NULL;
}int main()
{int ret;RK_MPI_SYS_Init();// VI Init......VI_CHN_ATTR_S vi_chn_attr;vi_chn_attr.pcVideoNode = "rkispp_scale0";    // 设置视频设备节点路径vi_chn_attr.u32Width = 1920;                  // 设置分辨率的宽度vi_chn_attr.u32Height = 1080;                 // 设置分辨率的高度vi_chn_attr.enPixFmt = IMAGE_TYPE_NV12;       // 设置图像类型vi_chn_attr.enBufType = VI_CHN_BUF_TYPE_MMAP; // 设置VI获取类型vi_chn_attr.u32BufCnt = 3;                    // 设置缓冲数量vi_chn_attr.enWorkMode = VI_WORK_MODE_NORMAL; // 设置VI工作类型ret = RK_MPI_VI_SetChnAttr(PIPE_ID, VI_CHN_ID, &vi_chn_attr);if (ret){printf("VI_CHN_ATTR Set Failed.....\n");return -1;}else{printf("VI_CHN_ATTR Set Success.....\n");}ret |= RK_MPI_VI_EnableChn(PIPE_ID, VI_CHN_ID);if (ret){printf("VI_CHN_ATTR Enable Failed.....\n");return -1;}else{printf("VI_CHN_ATTR Enable Success.....\n");}// Common_Gop Venc ParameterVENC_CHN_ATTR_S common_gop_venc_attr;common_gop_venc_attr.stVencAttr.enType = RK_CODEC_TYPE_H264;  // 设置编码器类型common_gop_venc_attr.stVencAttr.imageType = IMAGE_TYPE_NV12;  // 设置编码图像类型common_gop_venc_attr.stVencAttr.u32PicWidth = 1920;           // 设置编码分辨率宽度common_gop_venc_attr.stVencAttr.u32PicHeight = 1080;          // 设置编码分辨率高度common_gop_venc_attr.stVencAttr.u32VirWidth = 1920;           // 设置编码分辨率虚宽common_gop_venc_attr.stVencAttr.u32VirHeight = 1080;          // 设置编码分辨率虚高common_gop_venc_attr.stVencAttr.u32Profile = 66;              // 设置编码等级common_gop_venc_attr.stVencAttr.enRotation = VENC_ROTATION_0; // 设置编码的旋转角度//********* 设置码率控制属性  *******************//common_gop_venc_attr.stRcAttr.enRcMode = VENC_RC_MODE_H264CBR;    // 设置H264的CBR码率控制模式common_gop_venc_attr.stRcAttr.stH264Cbr.u32Gop = 25;              // 设置GOP关键帧间隔common_gop_venc_attr.stRcAttr.stH264Cbr.u32SrcFrameRateNum = 25;  // 设置源帧率分子common_gop_venc_attr.stRcAttr.stH264Cbr.u32SrcFrameRateDen = 1;   // 设置源帧率分母common_gop_venc_attr.stRcAttr.stH264Cbr.fr32DstFrameRateNum = 25; // 设置目标帧率分子common_gop_venc_attr.stRcAttr.stH264Cbr.fr32DstFrameRateDen = 1;  // 设置目标帧率分母common_gop_venc_attr.stRcAttr.stH264Cbr.u32BitRate = 8388608;     // 设置码率大小ret = RK_MPI_VENC_CreateChn(COMMON_GOP_VENC_CHN, &common_gop_venc_attr);if (ret){printf("Set Common_Gop Venc Attr Failed.....\n");}else{printf("Set Common_Gop Venc Attr Success.....\n");}// Common_Gop Venc ParameterVENC_CHN_ATTR_S smartp_gop_venc_attr;smartp_gop_venc_attr.stVencAttr.enType = RK_CODEC_TYPE_H264;  // 设置编码器类型smartp_gop_venc_attr.stVencAttr.imageType = IMAGE_TYPE_NV12;  // 设置编码图像类型smartp_gop_venc_attr.stVencAttr.u32PicWidth = 1920;           // 设置编码分辨率宽度smartp_gop_venc_attr.stVencAttr.u32PicHeight = 1080;          // 设置编码分辨率高度smartp_gop_venc_attr.stVencAttr.u32VirWidth = 1920;           // 设置编码分辨率虚宽smartp_gop_venc_attr.stVencAttr.u32VirHeight = 1080;          // 设置编码分辨率虚高smartp_gop_venc_attr.stVencAttr.u32Profile = 66;              // 设置编码等级smartp_gop_venc_attr.stVencAttr.enRotation = VENC_ROTATION_0; // 设置编码的旋转角度//********* 设置码率控制属性  *******************//smartp_gop_venc_attr.stRcAttr.enRcMode = VENC_RC_MODE_H264CBR;    // 设置H264的CBR码率控制模式smartp_gop_venc_attr.stRcAttr.stH264Cbr.u32Gop = 25;              // 设置GOP关键帧间隔smartp_gop_venc_attr.stRcAttr.stH264Cbr.u32SrcFrameRateNum = 25;  // 设置源帧率分子smartp_gop_venc_attr.stRcAttr.stH264Cbr.u32SrcFrameRateDen = 1;   // 设置源帧率分母smartp_gop_venc_attr.stRcAttr.stH264Cbr.fr32DstFrameRateNum = 25; // 设置目标帧率分子smartp_gop_venc_attr.stRcAttr.stH264Cbr.fr32DstFrameRateDen = 1;  // 设置目标帧率分母smartp_gop_venc_attr.stRcAttr.stH264Cbr.u32BitRate = 8388608;     // 设置码率大小ret = RK_MPI_VENC_CreateChn(SMARTP_GOP_VENC_CHN, &smartp_gop_venc_attr);if (ret){printf("Set SMARTP_Gop Venc Attr Failed.....\n");}else{printf("Set SMARTP_Gop Venc Attr Success.....\n");}VENC_GOP_ATTR_S venc_gop_attr_s;venc_gop_attr_s.enGopMode = VENC_GOPMODE_SMARTP;//设置GOP模式为SMARTP模式venc_gop_attr_s.u32GopSize = 25;//设置短参考帧间隔是25venc_gop_attr_s.u32BgInterval = 25 * 5;//venc_gop_attr_s.s32IPQpDelta = 6;//设置I帧和P帧的差值是6venc_gop_attr_s.s32ViQpDelta = 6;//设置虚拟I帧和P帧的差值是6ret = RK_MPI_VENC_SetGopMode(SMARTP_GOP_VENC_CHN,&venc_gop_attr_s);if (ret){printf("Set SMARTP_GOP_MODE Failed.....\n");}else{printf("Set SMARTP_GOP_MODE Success.....\n");}MPP_CHN_S vi_chn_s;vi_chn_s.enModId = RK_ID_VI;vi_chn_s.s32ChnId = VI_CHN_ID;MPP_CHN_S common_gop_venc_chn_s;common_gop_venc_chn_s.enModId = RK_ID_VENC;common_gop_venc_chn_s.s32ChnId = COMMON_GOP_VENC_CHN;MPP_CHN_S smartp_gop_venc_chn_s;smartp_gop_venc_chn_s.enModId = RK_ID_VENC;smartp_gop_venc_chn_s.s32ChnId = SMARTP_GOP_VENC_CHN;ret = RK_MPI_SYS_Bind(&vi_chn_s, &common_gop_venc_chn_s); //绑定VI和COMMON_GOP的VENC节点if (ret){printf("Bind Vi And Common_Gop Failed.....\n");}else{printf("Bind Vi And Common_Gop Success.....\n");}ret = RK_MPI_SYS_Bind(&vi_chn_s, &smartp_gop_venc_chn_s);  //绑定VI和SMARTP_GOP的VENC节点if (ret){printf("Bind Vi And Smartp_Gop Failed.....\n");}else{printf("Bind Vi And Smartp_Gop Success.....\n");}pthread_t common_gop_pid, smartp_gop_pid;pthread_create(&common_gop_pid, NULL, get_common_gop_thread, NULL);pthread_create(&common_gop_pid, NULL, get_smartp_gop_thread, NULL);while (1){sleep(2);}RK_MPI_SYS_UnBind(&vi_chn_s, &common_gop_venc_chn_s);RK_MPI_SYS_UnBind(&vi_chn_s, &smartp_gop_venc_chn_s);RK_MPI_VENC_DestroyChn(COMMON_GOP_VENC_CHN);RK_MPI_VENC_DestroyChn(SMARTP_GOP_VENC_CHN);RK_MPI_VI_DisableChn(PIPE_ID, VI_CHN_ID);return 0;
}

 OSD原理的讲解 

OSD(on-screen-display)中文名称是屏幕菜单调节显示方式,它的作用是对屏幕显示器做各种工作指标,包括:色彩、几何图形等进行调整,从而使得整个显示器得到最佳的状,最常见的OSD调试就是在屏幕上添加水印、LOGO。OSD技术广泛运用在PC个人电脑、电视机顶盒、ETC屏幕显示等等,后来随着网络技术的发展OSD调节也从屏幕发展到了编码图层的叠加,换言之在编码图层也可以通过OSD的叠加方法显示出自定义的图层。

实现过程

1.视频信号处理

OSD叠加的第一个步骤,就是要对视频信号进行处理。这种信号处理就是要从模拟信号转换成数字信号,转换完成之后需要通过芯片对数字信号进行后处理工作,包括:去噪、锐化等等。

2.OSD图像的生成
视频数据经过数字信号处理后,就可以对其进行OSD图像的生成。OSD的图像包含很多种类型,比方说LOGO图形、文字、图标等,而生成OSD图像的方式一般分为软件模式和硬件模式。硬件模式是利用专门的OSD处理芯片,通过硬件的图像合成器将OSD图像和视频信号合成,整个过程CPU不去进行处理;软件模式是通过软件的图像处理算法生成OSD图像,整个过程CPU都参与处理,常用的OSD生成的框架有:OPENCV、 FFMPEG等。

3.OSD图像的叠加

最后一步就是把OSD的图像进行叠加,所谓叠加就是把OSD图像和视频信号结合在一起。OSD信号叠加一般分为两种一种是上方叠加、另外一种是下方叠加,上方叠加相当于把OSD图像显示在视频的顶部、下方叠加相当于把OSD图像显示在视频的底部。OSD叠加的原理也非常简单,就是把OSD图像的像素点和视频信号的像素点进行合成,并且在合成的过程中可以通过调整位置、大小等参数显示出来。

RV1126的OSD模块讲解 

在RV1126开发OSD模块的时候,一般要使用下面的结构体分别是OSD_REGION_INFO_SBITMAP_S。OSD_REGION_INFO_S主要作用是是在编码图像里面划分一个OSD区域,相当于在编码图像中空出一块空间给OSD图层来用,BITMAP_S的作用是向OSD图层以位图的形式把具体的内容显示出来,下面是OSD_REGION_INFO和Bitmap的关系:

SDL_TTF库渲染文字并保存

运行时报的错误

上面这个错误是缺少了libSDL_ttf-2.0.so.0的库,此时要把libSDL_ttf-2.0.so.0放在/usr/lib下面

上面这个错误是缺少了libSDL-1.2.so.0的库,此时要把libSDL-1.2.so.0放在/usr/lib下面

RV1126的OSD模块和SDL_TTF结合输出H264文件

 

#include <assert.h>
#include <fcntl.h>
#include <getopt.h>
#include <pthread.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>// #include "common/sample_common.h"
#include "rkmedia_api.h"#include <stdio.h>
#include "SDL.h"
#include "SDL_ttf.h"
#include <time.h>#define CAMERA_PATH "rkispp_scale0"
#define CAMERA_ID 0
#define CAMERA_CHN 0
#define VENC_CHN 0//对某个数值进行对齐
static int get_align16_value(int input_value, int align)
{int handle_value = 0;if (align && (input_value % align))handle_value = (input_value/ align + 1) * align;return handle_value;
}void * bitmap_osd_handle_thread(void * args)
{pthread_detach(pthread_self());int ret ;TTF_Font * ttf_font;char *pstr = "2019-11-21 15:40:29";SDL_Surface * text_surface;SDL_Surface * convert_text_surface;SDL_PixelFormat * pixel_format;//TTF模块的初始化ret = TTF_Init();if(ret < 0){printf("TTF_Init Failed...\n");}//打开TTF的字库ttf_font = TTF_OpenFont("./fzlth.ttf", 48);if(ttf_font == NULL){printf("TTF_OpenFont Failed...\n");}//SDL_COLOR黑色,RGB(0,0,0)SDL_Color sdl_color;sdl_color.r = 0;sdl_color.g = 0;sdl_color.b = 0;text_surface = TTF_RenderText_Solid(ttf_font, pstr, sdl_color); 渲染文字//ARGB_8888pixel_format = (SDL_PixelFormat *)malloc(sizeof(SDL_PixelFormat));pixel_format->BitsPerPixel = 32;  //每个像素所占的比特位数 pixel_format->BytesPerPixel = 4; //每个像素所占的字节数 pixel_format->Amask = 0XFF000000;//ARGB的A掩码,A位0xffpixel_format->Rmask = 0X00FF0000;//ARGB的R掩码,R位0xffpixel_format->Gmask = 0X0000FF00;//ARGB的G掩码,G位0xffpixel_format->Bmask = 0X000000FF;//ARGB的B掩码,B位0xffconvert_text_surface = SDL_ConvertSurface(text_surface, pixel_format, 0);if(convert_text_surface == NULL){printf("convert_text_surface failed...\n");}BITMAP_S bitmap;//Bitmap位图结构体bitmap.u32Width = get_align16_value(convert_text_surface->w, 16);//Bitmap的宽度bitmap.u32Height = get_align16_value(convert_text_surface->h, 16);//Bitmap的高度bitmap.enPixelFormat = PIXEL_FORMAT_ARGB_8888;像素格式ARGB8888bitmap.pData = malloc((bitmap.u32Width) * (bitmap.u32Height) * pixel_format->BytesPerPixel); bitmap的data的分配大小memcpy(bitmap.pData, convert_text_surface->pixels, (convert_text_surface->w) * (convert_text_surface->h) *pixel_format->BytesPerPixel);bitmap的data赋值OSD_REGION_INFO_S rgn_info; //OSD_RGN_INFO结构体rgn_info.enRegionId = REGION_ID_0; //rgn的区域IDrgn_info.u32Width = bitmap.u32Width ; //osd的长度rgn_info.u32Height = bitmap.u32Height ; //osd的高度rgn_info.u32PosX = 128; //Osd的X轴方向rgn_info.u32PosY = 128; //Osd的Y轴方向rgn_info.u8Enable = 1; 使能OSD模块,1是使能,0为禁止。rgn_info.u8Inverse = 0; //禁止翻转ret = RK_MPI_VENC_RGN_SetBitMap(VENC_CHN, &rgn_info, &bitmap);  //设置OSD位图if(ret){printf("RK_MPI_VENC_RGN_SetBitMap failed...\n");}else{printf("RK_MPI_VENC_RGN_SetBitMap Success...\n");}return NULL;
}void * get_h264_data_thread(void * args)
{pthread_detach(pthread_self());FILE *h264_file = fopen("test_osd_venc.h264", "w+");MEDIA_BUFFER mb ;while (1){mb = RK_MPI_SYS_GetMediaBuffer(RK_ID_VENC, VENC_CHN, -1);if(!mb){printf("RK_MPI_SYS_GetMediaBuffer failed...\n");break;}printf("Get osd buffer success.....\n");fwrite(RK_MPI_MB_GetPtr(mb), RK_MPI_MB_GetSize(mb), 1, h264_file);RK_MPI_MB_ReleaseBuffer(mb);}return NULL;
}int main()
{int ret;VI_CHN_ATTR_S vi_chn_attr;vi_chn_attr.pcVideoNode = CAMERA_PATH;        //设置视频设备节点路径vi_chn_attr.u32Width = 1920;                  //设置分辨率的宽度vi_chn_attr.u32Height = 1080;                 //设置分辨率的高度vi_chn_attr.enPixFmt = IMAGE_TYPE_NV12;       //设置图像类型vi_chn_attr.enBufType = VI_CHN_BUF_TYPE_MMAP; //设置VI获取类型vi_chn_attr.u32BufCnt = 3;                    //设置缓冲数量vi_chn_attr.enWorkMode = VI_WORK_MODE_NORMAL; //设置VI工作类型ret = RK_MPI_VI_SetChnAttr(CAMERA_ID, CAMERA_CHN, &vi_chn_attr);if (ret){printf("Vi Set Attr Failed.....\n");return 0;}else{printf("Vi Set Attr Success.....\n");}ret = RK_MPI_VI_EnableChn(CAMERA_ID, CAMERA_CHN); // if (ret){printf("Vi Enable Attr Failed.....\n");return 0;}else{printf("Vi Enable Attr Success.....\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.stVencAttr.imageType = IMAGE_TYPE_NV12;//设置编码图像类型venc_chn_attr.stVencAttr.u32PicWidth = 1920;//设置编码分辨率宽度venc_chn_attr.stVencAttr.u32PicHeight = 1080;//设置编码分辨率高度venc_chn_attr.stVencAttr.u32VirWidth = 1920;//设置编码分辨率虚宽venc_chn_attr.stVencAttr.u32VirHeight = 1080;//设置编码分辨率虚高venc_chn_attr.stVencAttr.u32Profile = 77;//设置编码等级venc_chn_attr.stRcAttr.enRcMode = VENC_RC_MODE_H264CBR;//设置H264的CBR码率控制模式venc_chn_attr.stRcAttr.stH264Cbr.u32Gop = 25;venc_chn_attr.stRcAttr.stH264Cbr.u32BitRate = 2000000; // 2Mbvenc_chn_attr.stRcAttr.stH264Cbr.fr32DstFrameRateDen = 1;//设置源帧率分母venc_chn_attr.stRcAttr.stH264Cbr.fr32DstFrameRateNum = 25;//设置源帧率分子venc_chn_attr.stRcAttr.stH264Cbr.u32SrcFrameRateDen = 1;//设置目标帧率分母venc_chn_attr.stRcAttr.stH264Cbr.u32SrcFrameRateNum = 25;//设置目标帧率分子ret = RK_MPI_VENC_CreateChn(0, &venc_chn_attr);  //VENC模块的初始化if (ret){printf("ERROR: create VENC[0] error! ret=%d\n", ret);return 0;}else{printf("VENC SUCCESS\n");}ret = RK_MPI_VENC_RGN_Init(VENC_CHN, NULL);//RGN模块的初始化if(ret){printf("Create VENC_RGN Failed .....\n");return 0;}else{printf("Create VENC_RGN Success .....\n");}MPP_CHN_S vi_chn_s;MPP_CHN_S venc_chn_s;vi_chn_s.enModId = RK_ID_VI;vi_chn_s.s32ChnId = 0;venc_chn_s.enModId = RK_ID_VENC;venc_chn_s.s32ChnId = 0;ret = RK_MPI_SYS_Bind(&vi_chn_s, &venc_chn_s); VI模块节点和VENC节点绑定if(ret){printf("RK_MPI_SYS_Bind Failed .....\n");}else{printf("RK_MPI_SYS_Bind Success .....\n");}pthread_t bitmap_pid, venc_pid;pthread_create(&bitmap_pid, NULL, bitmap_osd_handle_thread, NULL); //创建OSD叠加线程pthread_create(&venc_pid, NULL, get_h264_data_thread, NULL);   //获取H264码流线程while (1){sleep(2);}RK_MPI_SYS_UnBind(&vi_chn_s, &venc_chn_s);RK_MPI_VENC_DestroyChn(VENC_CHN);RK_MPI_VI_DisableChn(CAMERA_ID, CAMERA_CHN);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/403745.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【后端记录】修复MySql的错误修改的数据记录【binlog修复】

前言 今天入门后端的时候&#xff0c;不小心改了非预期的数据&#xff0c;因为还没学到事务&#xff0c;所以恢复数据还比较麻烦&#xff0c;站在巨人的肩膀上还是解决了&#xff0c;原文连接在下面 https://blog.csdn.net/qq_42874315/article/details/140480570 解决办法 原…

【自动驾驶】控制算法(二)三大坐标系与车辆运动学模型

写在前面&#xff1a; &#x1f31f; 欢迎光临 清流君 的博客小天地&#xff0c;这里是我分享技术与心得的温馨角落。&#x1f4dd; 个人主页&#xff1a;清流君_CSDN博客&#xff0c;期待与您一同探索 移动机器人 领域的无限可能。 &#x1f50d; 本文系 清流君 原创之作&…

第37讲:Cephfs文件系统的正确使用姿势

文章目录 1.Cephfs文件系统简介2.Cephfs文件系统细节介绍2.1.Cephfs文件系统多客户端隔离挂载2.2.Ceph集群中多个Cephfs如何单独使用 3.挂载多个Cephfs文件系统4.Cephfs文件系统多客户端隔离挂载实战4.1.创建一个Cephfs文件系统4.2.将Cephfs文件系统挂载到本地路径4.3.在Cephfs…

java:IDEA修改java版本的几个不同的地方

文章目录 项目JDK设置&#xff08;Project SDK&#xff09;项目模块级JDK设置&#xff08;Module SDK&#xff09;IDE级别的JDK设置Maven配置文件编译器&#xff08;Java Compiler&#xff09;构建工具配置文件&#xff08;如build.gradle或pom.xml&#xff09;.idea/misc.xml文…

Chrome快捷键提高效率

浏览效率提高快捷建 快速切换标签页 Ctrl 数字&#xff08;1或者2&#xff09;&#xff0c;标签页数字从左到右为顺序&#xff0c;1开始。快速切换标签页。 Ctrl1 到 Ctrl8 切换到标签栏中指定位置编号所对应的标签页 Ctrl9切换到最后一个标签页 CtrlTab 或 CtrlPgDown 切…

EasyCVR视频汇聚平台构建远程安防监控:5大亮点解析,助力安防无死角

随着科技的飞速发展&#xff0c;远程安防监控系统已经成为现代社会中不可或缺的一部分&#xff0c;无论是在小区、公共场所还是工业领域&#xff0c;安防监控都发挥着至关重要的作用。而EasyCVR作为一款功能强大的视频监控综合管理平台&#xff0c;其在构建远程安防监控系统方面…

英伟达开源 Nemotron-4-4B:小型模型,大能量

前沿科技速递&#x1f680; 在人工智能领域&#xff0c;语言模型已经成为推动自然语言处理&#xff08;NLP&#xff09;进步的关键力量。然而&#xff0c;随着模型规模的不断扩大&#xff0c;训练和部署这些大型语言模型&#xff08;LLM&#xff09;的资源成本也在急剧增加。为…

WUP-MY-LABEL-PRINTER 旻佑热敏打印机标签打印uniapp插件使用说明

插件地址&#xff1a;WUP-MY-LABEL-PRINTER 旻佑热敏打印机标签打印安卓库 简介 本插件主要用于旻佑热敏打印机打印标签&#xff0c;不支持票据打印。适用于旻佑的各型支持标签打印的热敏打印机。本插件开发时使用的打印机型号为MY-805嵌入式面板打印机&#xff0c;其他型号请…

uni-app--》打造个性化壁纸预览应用平台(二)

&#x1f3d9;️作者简介&#xff1a;大家好&#xff0c;我是亦世凡华、渴望知识储备自己的一名前端工程师 &#x1f304;个人主页&#xff1a;亦世凡华、 &#x1f306;系列专栏&#xff1a;uni-app &#x1f307;座右铭&#xff1a;人生亦可燃烧&#xff0c;亦可腐败&#xf…

深度学习的量化和剪枝

一&#xff1a;背景 如果要将深度学习的AI模型部署到受限设备&#xff08;FPGA&#xff09;上&#xff0c;往往需要更小的存储需求和最低的计算复杂度。当然&#xff0c;还得保持一定的性能&#xff08;下降在能够接受的范围&#xff09;。受限设备资源的环境&#xff0c;一般是…

数据结构与算法--插入排序与选择排序

文章目录 回顾提要排序基本概念排序的分类排序算法的稳定性排序算法的性能指标内排序 排序方法直接插入排序直接插入排序的要点直接插入排序的实现直接插入排序性能分析直接插入排序的适用情景 简单选择排序简单选择排序的要点简单选择排序的执行过程简单选择排序的实现简单选择…

分布式锁:Mysql实现,Redis实现,Zookeeper实现

目录 前置知识 Mysql实现分布式锁 1.get_lock函数 Java代码实现&#xff1a; 2.for update尾缀 Java代码实现&#xff1a; 3.自己定义锁表 Java代码实现&#xff1a; 4.时间戳列实现乐观锁 Java代码实现&#xff1a; Redis实现分布式锁 Zookeeper实现分布式锁&#…

完整搭建windows下mysql8.0源码编译调试环境!

背景&#xff1a; 前段时间一直在看mysql相关的博客&#xff0c;所以对源码起了浓厚的兴趣&#xff0c;所以尝试通过vmware和vscode在windosw环境中搭建一套编译调试的环境~ 看了一下网上的搭建教程基本杂乱无章&#xff0c;想要从零跟着搭建出一个完善的调试环境也不是易事&…

Leetcode3232. 判断是否可以赢得数字游戏

Every day a Leetcode 题目来源&#xff1a;3232. 判断是否可以赢得数字游戏 解法1&#xff1a;3232. 判断是否可以赢得数字游戏 用一个 sum1 统计个位数的和&#xff0c;sum2 统计十位数的和。 只要 sum1 和 sum2 不相等&#xff0c;Alice 拿大的就能赢得这场游戏。 代码…

Maven的依赖范围

依赖的jar包&#xff0c;默认情况下&#xff0c;可以在任何地方使用&#xff0c;可以通过scope来设置作用范围 作用范围&#xff1a; 主程序范围有效&#xff08;main文件夹范围内&#xff09;测试程序范围有效&#xff08;test文件夹范围内&#xff09;是否参与打包运行&…

一次日志记录中使用fastjson涉及到ByteBuffer的教训

背景 目前本人在公司负责的模块中&#xff0c;有一个模块是负责数据同步的&#xff0c;主要是将我们数据产线使用的 AWS Dynamodb 同步的我们的测试QA 的环境的 MongoDB 的库中&#xff0c;去年开始也提供了使用 EMR 批量同步的功能&#xff0c;但是有时候业务也需要少量的数据…

【OpenCV_python】凸包检测 轮廓特征 直方图均衡化 模板匹配 霍夫变换

凸包特征检测 凸包就是图像的最小外接多边形&#xff0c;通过图像的轮廓点&#xff0c;找到距离最远的两个点的直线&#xff0c;根据直线找到距离最远的下一个点&#xff0c;直到所有的点被包围在多边形内 读取图像二值化找图像的轮廓获取凸包点的坐标绘制凸包点 convexHull 获…

程序员如何写PLC程序

PLC是可编程逻辑控制器的简称&#xff0c;常用的编程语言是IEC61131-3&#xff08;梯形图、结构化文本、指令表、功能块、顺序功能图&#xff09;和西门子的SCL。程序员常用的编程语言是JS、Java、Python、C/C、Go等。PLC广泛采用编程工具有codesys、博图等。程序员常用的编程工…

敏捷架构在数字时代的应用:从理论到实践的全面指南

在数字化转型和技术变革的浪潮中&#xff0c;企业面临着不断提升敏捷性和应对复杂环境的挑战。敏捷架构在数字时代的应用不仅从理论层面阐述了敏捷架构的基本原理&#xff0c;还为企业提供了详细的实践指南&#xff0c;帮助企业从理论走向实际操作。本文将从理论与实践的双重视…

STM32——CAN通讯基础知识

CAN 协议简介 CAN 是控制器局域网络 (Controller Area Network) 的简称&#xff0c;它是由研发和生产汽车电子产品著称的德国 BOSCH 公司开发的&#xff0c;并最终成为国际标准(ISO11519以及ISO11898),是国际上应用最广泛的现场总线之一。差异点如下&#xff1a; 高速CAN可以达…