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 是一款强大的工具,支持多种选项和过滤规则,适用场景十分广泛.由 ...
随机推荐
- Azure 经典模式中虚拟机证书指纹的生成和作用
用户在使用经典虚拟机时,经常会有如下疑问:门户主板页面中的 SSH/RDP 证书指纹这项信息是怎么来的?用途是什么?为什么有的时候为空?有没有对虚拟机使用有什么影响?以下我们进行一些基本的介绍: 证书 ...
- SQL Server Mobile/Compact Edition 简单介绍
除了SQL Server Express,SQL Server还有个更轻量级的版本:SQL Server Compact Edition,容易让人想起Windows Compact Edition ( ...
- [翻译] HSDatePickerViewController
HSDatePickerViewController HSDatePickerViewController is an iOS ViewController for date and time pic ...
- 随手记C#资料
1.where T: new()where后的称为泛型约束,这里约束泛型参数T必须具有无参的构造函数 2.判断路径是本地路径还是网址 private static bool IsLocalPath(s ...
- SQL查询含有%号的字段
select * from EMS_ANNOUNCEMENT where 1=1 and title like '%\%%' escape '\'
- 新增检查sql脚本是否符合ANSI编码格式
'******************************************************************* '作用:transfer转换文件编码格式 '参数含义:inco ...
- [DP]硬币问题
今天再写一下硬币问题 为什么是再呢 这是个很羞耻的话题 昨天写了一遍硬币 在某谷上跑 没错 挂掉了 TLE MD_SB ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ...
- kali_metasploit问题
出现类似提示: Failed to connect to the database: could not connect to server: Connection refused Is the ...
- Redux 源码解读 —— 从源码开始学 Redux
已经快一年没有碰过 React 全家桶了,最近换了个项目组要用到 React 技术栈,所以最近又复习了一下:捡起旧知识的同时又有了一些新的收获,在这里作文以记之. 在阅读文章之前,最好已经知道如何使用 ...
- 在Django中使用Q()对象
转载于: http://www.smallerpig.com/1000.html 问题 一般我们在Django程序中查询数据库操作都是在QuerySet里进行进行,例如下面代码: >>& ...