Zeta--S3 Linux抓取一帧YUV图像后使用硬件编码器编码成H.264
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <malloc.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <asm/types.h>
#include <linux/videodev2.h>
#include <pthread.h>
#include <memoryAdapter.h>
#include <vencoder.h> static VideoEncoder *gVideoEnc;
static VencBaseConfig baseConfig;
static int gWidth = ;
static int gHeight = ; #define ALIGN_4K(x) (((x) + (4095)) & ~(4095))
#define ALIGN_1K(x) (((x) + (1023)) & ~(1023))
#define ALIGN_32B(x) (((x) + (31)) & ~(31))
#define ALIGN_16B(x) (((x) + (15)) & ~(15))
#define ALIGN_8B(x) (((x) + (7)) & ~(7)) #define REQ_COUNT 10 struct buffer
{
void *start;
size_t length;
char *addrVirY;
char *addrVirC;
}; static int fd = -;
struct buffer *buffers = NULL; struct v4l2_capability cap;
struct v4l2_format fmt;
struct v4l2_buffer buf[REQ_COUNT];
struct v4l2_requestbuffers req;
struct v4l2_buffer tmp_buf;
enum v4l2_buf_type type; int H264EncodeOneFrame(unsigned char *AddrVirY, unsigned char *AddrVirC, FILE *fpH264)
{
int result = ;
VencInputBuffer inputBuffer;
VencOutputBuffer outputBuffer;
int value;
unsigned int head_num = ;
VencHeaderData sps_pps_data; VencH264Param h264Param;
//* h264 param
h264Param.bEntropyCodingCABAC = ;
h264Param.nBitrate = * * ;
h264Param.nFramerate = ;
h264Param.nCodingMode = VENC_FRAME_CODING;
//h264Param.nCodingMode = VENC_FIELD_CODING;
h264Param.nMaxKeyInterval = ;
h264Param.sProfileLevel.nProfile = VENC_H264ProfileMain;
h264Param.sProfileLevel.nLevel = VENC_H264Level31;
h264Param.sQPRange.nMinqp = ;
h264Param.sQPRange.nMaxqp = ;
memset(&baseConfig, , sizeof(VencBaseConfig)); if (baseConfig.memops == NULL)
{
baseConfig.memops = MemAdapterGetOpsS();
if (baseConfig.memops == NULL)
{
printf("MemAdapterGetOpsS failed\n"); return -;
}
CdcMemOpen(baseConfig.memops);
} baseConfig.nInputWidth = gWidth;
baseConfig.nInputHeight = gHeight;
baseConfig.nStride = gWidth;
baseConfig.nDstWidth = gWidth;
baseConfig.nDstHeight = gHeight;
baseConfig.eInputFormat = VENC_PIXEL_YVU420SP; if (gVideoEnc == NULL)
{
printf("get SPS PPS\n");
gVideoEnc = VideoEncCreate((VENC_CODEC_TYPE)VENC_CODEC_H264);
VideoEncSetParameter(gVideoEnc, VENC_IndexParamH264Param, &h264Param);
value = ;
VideoEncSetParameter(gVideoEnc, VENC_IndexParamIfilter, &value);
value = ; //degree
VideoEncSetParameter(gVideoEnc, VENC_IndexParamRotation, &value);
value = ;
VideoEncSetParameter(gVideoEnc, VENC_IndexParamSetPSkip, &value);
VideoEncInit(gVideoEnc, &baseConfig);
}
VideoEncGetParameter(gVideoEnc, VENC_IndexParamH264SPSPPS, &sps_pps_data); fwrite(sps_pps_data.pBuffer, , sps_pps_data.nLength, fpH264); VencAllocateBufferParam bufferParam;
memset(&bufferParam, , sizeof(VencAllocateBufferParam));
memset(&inputBuffer, , sizeof(VencInputBuffer)); bufferParam.nSizeY = baseConfig.nInputWidth * baseConfig.nInputHeight;
bufferParam.nSizeC = baseConfig.nInputWidth * baseConfig.nInputHeight / ;
bufferParam.nBufferNum = ;
AllocInputBuffer(gVideoEnc, &bufferParam); GetOneAllocInputBuffer(gVideoEnc, &inputBuffer); memcpy(inputBuffer.pAddrVirY, AddrVirY, baseConfig.nInputWidth * baseConfig.nInputHeight);
memcpy(inputBuffer.pAddrVirC, AddrVirC, baseConfig.nInputWidth * baseConfig.nInputHeight / );
inputBuffer.bEnableCorp = ;
inputBuffer.sCropInfo.nLeft = ;
inputBuffer.sCropInfo.nTop = ;
inputBuffer.sCropInfo.nWidth = ;
inputBuffer.sCropInfo.nHeight = ;
FlushCacheAllocInputBuffer(gVideoEnc, &inputBuffer);
AddOneInputBuffer(gVideoEnc, &inputBuffer);
if (VENC_RESULT_OK != VideoEncodeOneFrame(gVideoEnc))
{
printf("VideoEncodeOneFrame failed.\n");
return -;
}
AlreadyUsedInputBuffer(gVideoEnc, &inputBuffer);
ReturnOneAllocInputBuffer(gVideoEnc, &inputBuffer); GetOneBitstreamFrame(gVideoEnc, &outputBuffer);
if (outputBuffer.nSize0 > )
{
printf("write pData0\n");
fwrite(outputBuffer.pData0, , outputBuffer.nSize0, fpH264);
}
if (outputBuffer.nSize1 > )
{
printf("write pData1\n");
fwrite(outputBuffer.pData1, , outputBuffer.nSize1, fpH264);
}
// outputBuffer.pData0;
// outputBuffer.nSize0;
// outputBuffer.pData1;
// outputBuffer.nSize1; FreeOneBitStreamFrame(gVideoEnc, &outputBuffer); if (baseConfig.memops != NULL)
{
CdcMemClose(baseConfig.memops);
baseConfig.memops = NULL;
}
VideoEncDestroy(gVideoEnc);
gVideoEnc = NULL; return ;
} int main(int argc, char **argv)
{
int iCounterCamera = ;
int iCounter100frame = ;
struct v4l2_fmtdesc fmtd;
int ret = ;
int index = ;
struct v4l2_format fmt2; if ((fd = open("/dev/video0", O_RDWR | O_NONBLOCK, )) < )
{
printf("open video0 failed.\n");
return -;
} memset(&fmtd, , sizeof(fmtd));
fmtd.index = ;
fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; while ((ret = ioctl(fd, VIDIOC_ENUM_FMT, &fmtd)) == )
{
fmtd.index++;
}
if (ioctl(fd, VIDIOC_QUERYCAP, &cap) < )
{
printf("Error:VIDIOC_QUERYCAP\n");
return -;
} if (ioctl(fd, VIDIOC_S_INPUT, &index) < )
{
printf("Error:VIDIOC_S_INPUT\n");
return -;
} fmt2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
ret = ioctl(fd, VIDIOC_G_FMT, &fmt2);
printf("VIDIOC_G_FMT ret=%d \n", ret); fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = gWidth;
fmt.fmt.pix.height = gHeight; fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_NV21;
if (ioctl(fd, VIDIOC_S_FMT, &fmt) < )
{
printf("Error:VIDIOC_S_FMT\n");
return -;
} req.count = REQ_COUNT;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;
if (ioctl(fd, VIDIOC_REQBUFS, &req) < )
{
printf("Error:VIDIOC_REQBUFS\n");
return -;
} buffers = calloc(req.count, sizeof(*buffers)); for (int i = ; i < req.count; i++)
{
buf[i].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf[i].memory = V4L2_MEMORY_MMAP;
buf[i].index = i;
if (ioctl(fd, VIDIOC_QUERYBUF, buf + i) < )
{
printf("Error:VIDIOC_QUERYBUF\n");
return -;
} buffers[i].length = buf[i].length;
buffers[i].start = mmap(NULL, buf[i].length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf[i].m.offset); buf[i].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf[i].memory = V4L2_MEMORY_MMAP;
buf[i].index = i; if (ioctl(fd, VIDIOC_QBUF, buf + i) < )
{
printf("Error: VIDIOC_QBUF\n");
return -;
} buffers[i].addrVirY = buffers[i].start;
buffers[i].addrVirC = buffers[i].addrVirY + ALIGN_16B(gWidth) * ALIGN_16B(gHeight);
} type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (ioctl(fd, VIDIOC_STREAMON, &type) < )
{
printf("Error: VIDIOC_STREAMON\n");
return -;
} FILE *fpYUV = NULL;
FILE *fpH264 = NULL;
char yuv_path[];
char h264_path[];
for (int i = ; i < req.count; i++)
{
struct v4l2_buffer buf; /*帧出列*/
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = i;
ioctl(fd, VIDIOC_DQBUF, &buf); memset(yuv_path, , );
memset(h264_path, , );
sprintf(yuv_path, "/mnt/extsd/src%04d.yuv", buf.index);
sprintf(h264_path, "/mnt/extsd/dst%04d.h264", buf.index);
fpYUV = fopen(yuv_path, "w");
fwrite(buffers[buf.index].addrVirY, , gWidth * gHeight, fpYUV);
fwrite(buffers[buf.index].addrVirC, , gWidth * gHeight / , fpYUV);
fpH264 = fopen(h264_path, "w");
H264EncodeOneFrame(buffers[buf.index].addrVirY, buffers[buf.index].addrVirC, fpH264);
fclose(fpYUV);
fpYUV = NULL;
fclose(fpH264);
fpH264 = NULL; /*buf入列*/
ioctl(fd, VIDIOC_QBUF, &buf);
} if (ioctl(fd, VIDIOC_STREAMOFF, &type) < )
{
printf("Error:VIDIOC_STREAMOFF\n"); // return 0;
return;
} for (int i = ; i < req.count; i++)
{
munmap(buffers[i].start, buf[i].length);
} close(fd); return ;
}
Zeta--S3 Linux抓取一帧YUV图像后使用硬件编码器编码成H.264的更多相关文章
- linux抓取top命令中数据的方法
top在linux中是一个非常直观的命令,可以清晰地看到各进程对资源的使用情况. 但是如果你想从top命令展示中提取某些数据出来,如果想当然地使用这句命令: top|grep xxx 就会被卡住, ...
- 使用JavaCV/OpenCV抓取并存储摄像头图像
http://blog.csdn.net/ljsspace/article/details/6702178 分类: 图形图像(3) 版权声明:本文为博主原创文章,未经博主允许不得转载. 本程序通过 ...
- 【Azure 环境】在Windows环境中抓取网络包(netsh trace)后,如何转换为Wireshark格式以便进行分析
问题描述 如何在Windows环境中,不安装第三方软件的情况下(使用Windows内置指令),如何抓取网络包呢?并且如何转换为Wireshark 格式呢? 操作步骤 1) 以管理员模式打开CMD,使用 ...
- linux 抓取访问量排行
需求: 分析图片服务日志,把日志(每个图片访问次数*图片大小的总和)排行,取top10,也就是计算每个url的总访问大小 语句: awk '{a[$1]+=$10;}END{for(i in a){p ...
- Linux 抓取网站命令
wget -m -e robots=off -U "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.1.6) Gecko/200 ...
- linux抓取usb包设置usbmon
- 用libvlc 抓取解码后的帧数据
vlc是一套优秀的开源媒体库,其特点是提供了完整的流媒体框架, 用它可以非常方便的实现抓取解码帧的功能. 与此功能有关的关键API为 libvlc_video_set_callbacks /*设置回调 ...
- linux抓包工具tcpdump基本使用
tcpdump 是一款灵活.功能强大的抓包工具,能有效地帮助排查网络故障问题. tcpdump 是一个命令行实用工具,允许你抓取和分析经过系统的流量数据包.它通常被用作于网络故障分析工具以及安全工具. ...
- Linux抓包工具:tcpdump
tcpdump 是一个命令行实用工具,允许你抓取和分析经过系统的流量数据包.它通常被用作于网络故障分析工具以及安全工具. tcpdump 是一款强大的工具,支持多种选项和过滤规则,适用场景十分广泛.由 ...
随机推荐
- JDBC连接数据库反射实现O/R映射
测试preparedStatement public void testPreparedStatement(){ Connection connection=null; PreparedStateme ...
- 计算Pan手势到指定点的角度
计算Pan手势到指定点的角度 效果图: 源码: // // RootViewController.m // Circle // // Copyright (c) 2014年 Y.X. All righ ...
- 克隆对象__clone()方法
有的时候我们需要在一个项目里面,使用两个或多个一样的对象,如果你使用“new”关键字重新创建对象的话,再赋值上相同的属性,这样做比较烦琐而且也容易出错,所以要根据一个对象完全克隆出一个一模一样的对象, ...
- Monster: half man, half beast and very scary.
Monster: half man, half beast and very scary. 怪物,半人半兽很吓人.
- Linux命令--用户管理
useradd命令 Linux useradd命令用于建立用户帐号. useradd可用来建立用户帐号.帐号建好之后,再用passwd设定帐号的密码.而可用userdel删除帐号.使用useradd指 ...
- H3C笔试题目
最近这段时间正在找工作,去H3C做了下笔试题,题目出的还不错,比一般公司水平高上一点点,偷偷弄了点回来,分享一下,我把答案和解析全部整理了出来,有需要的可以看看. 1.以下描述正确的有(AD) A.1 ...
- Running Protractor Tests on Docker
配置这个Protractor环境真是折磨死人了,webdriver-manage update怎么都不成功,即使自己下载好chromederiver放到相应文件夹下,也不能使用.费时三四天终于按照ht ...
- 协议森林03 IP接力赛 (IP, ARP, RIP和BGP协议)
网络层(network layer)是实现互联网的最重要的一层.正是在网络层面上,各个局域网根据IP协议相互连接,最终构成覆盖全球的Internet.更高层的协议,无论是TCP还是UDP,必须通过网络 ...
- vue2.* 双向数据绑定 Vue事件介绍 以及Vue中的ref获取dom节点 04
<template> <div id="app"> <!-- 双向数据绑定(必须在表单里面使用) m:model v:view mvvm:model改 ...
- 6、Spring Cloud -熔断器Hystrix
6.1.什么是Hystrix 在分布式系统中.服务与服务之间的依赖错综复杂,一种不可避免的情况就是某些服务 出现故障,导致依赖于它们的其他服务出现远程调度的线程阻塞. Hystrix是Netfli ...