RV1126 NO.14:通过多线程获取VENC的H264码流数据

前言:RV1126进行CMOS摄像头采集,并进行VENC的视频编码处理,最终获取到H264码流。

一.RV1126 VI模块采集并进行VENC编码的流程

RV1126多线程采集VI模块编码VENC并保存到文件,一般分为四个步骤:分别是初始化VI模块、初始化VENC模块、绑定VI和VENC模块、多线程获取每一帧H264码流数据

1.1. ​​​​​​​初始化VI模块:

VI模块的初始化实际上就是对VI_CHN_ATTR_S的参数进行设置、然后调用RK_MPI_VI_SetChnAttr设置VI模块并使能RK_MPI_VI_EnableChn,伪代码如下:

VI_CHN_ATTR_S  vi_chn_attr;//(这里是设置VI的属性)

ret = RK_MPI_VI_SetChnAttr(CAMERA_ID, 0, &vi_chn_attr);
ret |= RK_MPI_VI_EnableChn(CAMERA_ID, 0);

 

1.2.​​​​​​​​​​​​​​初始化VENC模块:

VENC模块的初始化实际上就是对VENC_CHN_ATTR_S的参数进行设置、然后调用RK_MPI_VENC_CreateChn创建编码器伪代码如下:

VENC_CHN_ATTR_S venc_chn_attr;
venc_chn_attr.stVencAttr.enType = RK_CODEC_TYPE_H264;//(这里是设置VENC的属性)
ret = RK_MPI_VENC_CreateChn(0, &venc_chn_attr);

1.3.​​​​​​​​​​​​​​绑定VI节点和VENC节点:

绑定VI节点和VENC节点,使其两个模块能够关联起来,使用的API是RK_MPI_SYS_Bind关于这个API的定义,之前说过了,这里不在阐述。伪代码如下:

MPP_CHN_S vi_chn_s;
vi_chn_s.enModId = RK_ID_VI;
vi_chn_s.s32ChnId = 0;

MPP_CHN_S venc_chn_s;
venc_chn_s.enModId = RK_ID_VENC;
venc_chn_s.s32ChnId = 0;

ret = RK_MPI_SYS_Bind(&vi_chn_s, &venc_chn_s);

1.4.​​​​​​​开启多线程采集VENC的数据

开启一个线程去采集每一帧VENC模块的数据,使用的API是RK_MPI_SYS_GetMediaBuffer, 模块ID是RK_ID_VENC,通道号ID是VENC创建的ID号这个API的具体作用已经在之前的获取VI数据的课程里面已经讲解过,我们直接上伪代码

while(1)

{

  .........................

  mb = RK_MPI_SYS_GetMediaBuffer(RK_ID_VENC, s32_chn_id, -1);

  fwrite(RK_MPI_MB_GetPtr(mb), RK_MPI_MB_GetSize(mb), 1, h264_file);

.......................

}

接下来看完整代码演示:

#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"

#define CAMERA_PATH "rkispp_scale0"
#define CAMERA_ID 0
#define CAMERA_CHN 0
#define VENC_CHN 0

void * get_h264_venc_thread(void * args)
{
    pthread_detach(pthread_self());
    FILE * h264_file = fopen("test_camera.h264", "w+");
    MEDIA_BUFFER mb;

    while (1)
    {
        mb = RK_MPI_SYS_GetMediaBuffer(RK_ID_VENC, VENC_CHN, -1);
        if(!mb)
        {
            printf("Get Venc Mb Break.....\n");
            break;
        }

        printf("Get H264 One Frame.......\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 argc, char *argv[])
{
    int ret;
    VI_CHN_ATTR_S vi_chn_attr;
    vi_chn_attr.pcVideoNode = CAMERA_PATH; //Path
    vi_chn_attr.u32Width = 1920; //Width
    vi_chn_attr.u32Height = 1080; //Height
    vi_chn_attr.enPixFmt = IMAGE_TYPE_NV12; //ImageType
    vi_chn_attr.enBufType = VI_CHN_BUF_TYPE_MMAP;//BufType
    vi_chn_attr.u32BufCnt = 3; //Cnt
    vi_chn_attr.enWorkMode = VI_WORK_MODE_NORMAL; //Mode
    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;
    //******     VENC Attr Set   ************************//
    venc_chn_attr.stVencAttr.enType = RK_CODEC_TYPE_H264;
    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 = 66;
    venc_chn_attr.stVencAttr.imageType = IMAGE_TYPE_NV12;
    venc_chn_attr.stVencAttr.enRotation = VENC_ROTATION_0;

    //********* VENC RCMODE Set  *******************//
    venc_chn_attr.stRcAttr.enRcMode = VENC_RC_MODE_H264CBR;
    venc_chn_attr.stRcAttr.stH264Cbr.u32Gop = 25;
    //25/1 NUM/DEN == FrameRate
    venc_chn_attr.stRcAttr.stH264Cbr.u32SrcFrameRateDen = 1; //
    venc_chn_attr.stRcAttr.stH264Cbr.u32SrcFrameRateNum = 25;
    venc_chn_attr.stRcAttr.stH264Cbr.fr32DstFrameRateDen = 1;
    venc_chn_attr.stRcAttr.stH264Cbr.fr32DstFrameRateNum = 25;
    venc_chn_attr.stRcAttr.stH264Cbr.u32BitRate = 8388608; //1M
    ret = RK_MPI_VENC_CreateChn(VENC_CHN, &venc_chn_attr);
    if(ret)
    {
        printf("Create  Venc Failed .....\n");
        return 0;
    }
    else
    {
        printf("Create  Venc Success .....\n");
    }

    MPP_CHN_S vi_chn_s;
    vi_chn_s.enModId = RK_ID_VI;
    vi_chn_s.s32ChnId = CAMERA_CHN;

    MPP_CHN_S venc_chn_s;
    venc_chn_s.enModId = RK_ID_VENC;
    venc_chn_s.s32ChnId = VENC_CHN;
    ret = RK_MPI_SYS_Bind(&vi_chn_s, &venc_chn_s);
    if(ret)
    {
        printf("RK_MPI_SYS_Bind  Failed .....\n");
        return 0;
    }
    else
    {
        printf("RK_MPI_SYS_Bind  Success .....\n");
    }

    pthread_t pid;
    pthread_create(&pid, NULL, get_h264_venc_thread, NULL);

    while (1)
    {
        sleep(1);
    }

    RK_MPI_VI_DisableChn(CAMERA_ID, CAMERA_CHN);
    RK_MPI_VENC_DestroyChn(VENC_CHN);
    RK_MPI_SYS_UnBind(&vi_chn_s, &venc_chn_s);

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值