简介:将摄像头采集的视频以H264编码存储在本地文件test_out.h264里,并以ffmpeg播放
**1.**流程图
2.源代码
bananapeelx_h264.h
#ifndef BANANAPEELX_H264_H
#define BANANAPEELX_H264_H
#include <assert.h>
#include <fcntl.h>
#include <getopt.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#include "sample_common.h"
#include "im2d.h"
#include "rga.h"
#include "rockx.h"
#include "rkmedia_api.h"
// #include "rk_aiq_common.h"
void *collect_thread(void *arg);
#endif // !BANANAPEELX_H264_H
bananapeelx_h264.cpp
#include "bananapeelx_h264.h"
int main(int argc, char *argv[])
{
int disp_width=1056,disp_height = 1920;
RK_U32 video_width = 1056, video_height = 1920;
RK_U32 u32BufCnt = 3;
RK_S32 s32CamId = 0;
RK_BOOL bMultictx = RK_FALSE;
char *iq_file_dir = "/etc/iqfiles";
RK_CHAR *pDeviceName = "rkispp_scale0";
pthread_t collect_tidp;
rk_aiq_working_mode_t hdr_mode = RK_AIQ_WORKING_MODE_NORMAL;
/*系统初始化*/
SAMPLE_COMM_ISP_Init(s32CamId, hdr_mode, bMultictx, iq_file_dir);
SAMPLE_COMM_ISP_Run(s32CamId);
SAMPLE_COMM_ISP_SetFrameRate(s32CamId, 30);
/*摄像头vi设置*/
RK_MPI_SYS_Init();//初始化系统。
VI_CHN_ATTR_S vi_chn_attr;
vi_chn_attr.pcVideoNode = pDeviceName;
vi_chn_attr.u32BufCnt = u32BufCnt;
vi_chn_attr.u32Width = video_width;
vi_chn_attr.u32Height = video_height;
vi_chn_attr.enPixFmt = IMAGE_TYPE_NV12;
vi_chn_attr.enBufType = VI_CHN_BUF_TYPE_MMAP;
vi_chn_attr.enWorkMode = VI_WORK_MODE_NORMAL;
int ret = RK_MPI_VI_SetChnAttr(s32CamId, 1, &vi_chn_attr);//设置VI通道属性。
ret |= RK_MPI_VI_EnableChn(s32CamId, 1);
if (ret)
{
printf("ERROR: create VI[0:1] error! ret=%d\n", ret);
return -1;
}
/*摄像头VENC设置*/
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 = video_width * video_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 = video_width;
venc_chn_attr.stVencAttr.u32PicHeight = video_height;
venc_chn_attr.stVencAttr.u32VirWidth = video_width;
venc_chn_attr.stVencAttr.u32VirHeight = video_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;
}
/*VI,VENC绑定*/
MPP_CHN_S stSrcChn,stDestChn;
printf("Bind VI[] to VENC[]....\n");
stSrcChn.enModId = RK_ID_VI;
stSrcChn.s32DevId = s32CamId;
stSrcChn.s32ChnId = 1;
stDestChn.enModId = RK_ID_VENC;
stDestChn.s32DevId = s32CamId;
stDestChn.s32ChnId = 0;
ret = RK_MPI_SYS_Bind(&stSrcChn, &stDestChn);
if (ret)
{
printf("ERROR: Bind VI[0:1] to RGA[0:1] failed! ret=%d\n", ret);
return -1;
}
/*创建采集线程*/
pthread_create(&collect_tidp, NULL, collect_thread, NULL);
while(1)
{
sleep(20);
}
return 0;
}
void *collect_thread(void *arg)
{
pthread_detach(pthread_self());//将线程状态改为unjoinable状态,确保资源的释放
MEDIA_BUFFER mb;
FILE *h264_file = fopen("./test_out.h264","w+");
while(1)
{
mb = RK_MPI_SYS_GetMediaBuffer(RK_ID_VENC, 0 , -1); //从指定通道中获取数据。
if(!mb)
{
printf("Get Venc Buffer Break....\n");
break;
}
printf("mmmmmm\n");
fwrite(RK_MPI_MB_GetPtr(mb), RK_MPI_MB_GetSize(mb), 1, h264_file);
}
return NULL;
}
CMakeLists.txt
${TOOLCHAIN_DIR}/usr/bin/arm-linux-gnueabihf-g++)
set(CMAKE_C_COMPILER ${TOOLCHAIN_DIR}/usr/bin/arm-linux-gnueabihf-gcc)
set(SYSROOT ${TOOLCHAIN_DIR}/arm-buildroot-linux-gnueabihf/sysroot/usr/include)
set(CMAKE_SYSROOT ${TOOLCHAIN_DIR}/arm-buildroot-linux-gnueabihf/sysroot)
add_definitions(-g -O0 -ggdb -gdwarf -funwind-tables -rdynamic -fpermissive)
add_definitions(-Wno-write-strings -Wno-return-type)
include_directories(${SYSROOT})
include_directories(${SYSROOT}/rga)
include_directories(${SYSROOT}/easymedia)
include_directories(${SYSROOT}/rkaiq/uAPI)
include_directories(${SYSROOT}/rkaiq/xcore)
include_directories(${SYSROOT}/rkaiq/algos)
include_directories(${SYSROOT}/rkaiq/common)
include_directories(${SYSROOT}/rkaiq/iq_parser)
include_directories(${SYSROOT}/rockx)
include_directories(.)
set(RKMEDIA_LIBS easymedia rga rkaiq rockx sample_common_isp)
#命令用于在源文件的编译中添加-D定义标志
add_definitions(-DRKAIQ)
project(bananapeelx)
add_executable(bananapeelx_h264 bananapeelx_h264.cpp)
target_link_libraries(bananapeelx_h264 ${RKMEDIA_LIBS} pthread )
3.编译及测试
ubuntu端
mkdir build
cd build
cmake ../
make
scp bananapeelx_h264 root@192.168.10.50:/mytest
板端
cd mytest
./bananapeelx_h264
ubuntu
scp root@192.168.10.50:/mytest/test_out.h264 .
在windows上使用Notepad查看
在windows上使用ffmpeg播放:
ffplay -i test_out.h264