前几天在网上买个罗技的C270摄像头,它支持YUYV(YUV422)和JPEG数据输出。它规格书上写的是支持HD720P(1280*720像素),在实际的调试过程中,我使用该分辨率会导致数据采集过慢。这里需要注意一下,罗技的摄像头C270在有些虚拟机上使用是有异常的,有些是不能映射到虚拟机上,有些是映射过去操作非常缓慢。因为之前在自己的开发板上调试过YUV420的摄像头,在此基础上改为YUYV数据格式,调试的时候还是遇到不少的问题。

x264库的编译可以见之前博客:http://blog.csdn.net/li_wen01/article/details/53571929

在PC上编译X264,可以直接执行下面三条命令:

./configure --enable-shared
make
make install

下面贴出x264部分的代码:

/*=============================================================================
#     FileName: h264encoder.c
#         Desc: this program aim to get image from USB camera,
#               used the V4L2 interface.
#       Author: licaibiao
#      Version:
#   LastChange: 2017-02-21
=============================================================================*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "./include/h264encoder.h"int WIDTH = 640;
int HEIGHT = 480;void compress_begin(Encoder *en, int width, int height) {en->param = (x264_param_t *) malloc(sizeof(x264_param_t));en->picture = (x264_picture_t *) malloc(sizeof(x264_picture_t));x264_param_default(en->param); //set default param//en->param->rc.i_rc_method = X264_RC_CQP;// en->param->i_log_level = X264_LOG_NONE;en->param->i_threads  = X264_SYNC_LOOKAHEAD_AUTO;en->param->i_width = width; //set frame widthen->param->i_height = height; //set frame heightWIDTH = width;HEIGHT = height;//en->param->i_frame_total = 0;//en->param->i_keyint_max = 10;en->param->rc.i_lookahead = 0; //en->param->i_bframe = 5; //en->param->b_open_gop = 0;//en->param->i_bframe_pyramid = 0;//en->param->i_bframe_adaptive = X264_B_ADAPT_TRELLIS;//en->param->rc.i_bitrate = 1024 * 10;//rate 10 kbpsen->param->i_fps_num = 30; en->param->i_fps_den = 1;en->param->i_csp = X264_CSP_I422;x264_param_apply_profile(en->param, x264_profile_names[4]); if ((en->handle = x264_encoder_open(en->param)) == 0) {return;}/* Create a new pic */x264_picture_alloc(en->picture, X264_CSP_I422, en->param->i_width,en->param->i_height);
}int compress_frame(Encoder *en, int type, uint8_t *in, uint8_t *out) {x264_picture_t pic_out;int index_y, index_u, index_v;int num;int nNal = -1;int result = 0;int i = 0;static long int pts = 0;uint8_t *p_out = out;char *y = en->picture->img.plane[0];   char *u = en->picture->img.plane[1];   char *v = en->picture->img.plane[2];   char * ptr;index_y = 0;index_u = 0;index_v = 0;num = WIDTH * HEIGHT * 2 - 4  ;for(i=0; i<num; i=i+4){*(y + (index_y++)) = *(in + i);*(u + (index_u++)) = *(in + i + 1);*(y + (index_y++)) = *(in + i + 2);*(v + (index_v++)) = *(in + i + 3);}switch (type) {case 0:en->picture->i_type = X264_TYPE_P;break;case 1:en->picture->i_type = X264_TYPE_IDR;break;case 2:en->picture->i_type = X264_TYPE_I;break;default:en->picture->i_type = X264_TYPE_AUTO;break;}en->picture->i_pts = pts++;if (x264_encoder_encode(en->handle, &(en->nal), &nNal, en->picture,&pic_out) < 0) {return -1;}for (i = 0; i < nNal; i++) {memcpy(p_out, en->nal[i].p_payload, en->nal[i].i_payload);   p_out += en->nal[i].i_payload;                               result += en->nal[i].i_payload;}return result;
}void compress_end(Encoder *en) {if (en->handle) {x264_encoder_close(en->handle);}if (en->picture) {x264_picture_clean(en->picture);free(en->picture);en->picture = 0;}if (en->param) {free(en->param);en->param = 0;}
}

上面的代码是配置x264编码器的,有下面几个地方需要特别注意:

(1)CSP参数的配置

en->param->i_csp = X264_CSP_I422;

在X264中默认的i_csp值是3,也就是X264_CSP_NV12 的值,如果采用YUYV(422)输入格式,这个值一定需要重新设置,不然会出现错误提示:x264 [error]: Invalid input colorspace 。这是因为在x264内核中他会把输入格式装换为下面三种中的一种:X264_CSP_NV12,X264_CSP_NV16,X264_CSP_I444.转换如下:

static int x264_frame_internal_csp( int external_csp )
{switch( external_csp & X264_CSP_MASK ){case X264_CSP_NV12:case X264_CSP_NV21:case X264_CSP_I420:case X264_CSP_YV12:return X264_CSP_NV12;case X264_CSP_NV16:case X264_CSP_I422:case X264_CSP_YV16:case X264_CSP_V210:return X264_CSP_NV16;case X264_CSP_I444:case X264_CSP_YV24:case X264_CSP_BGR:case X264_CSP_BGRA:case X264_CSP_RGB:return X264_CSP_I444;default:return X264_CSP_NONE;}
}

(2)profile类型设置

x264_param_apply_profile(en->param, x264_profile_names[4]); 

在YUV422中,它不支持baseline,默认设置会提示:x264 [error]: baseline profile doesn't support 4:2:2 可以设置下面的其他参数:

x264_profile_names[] = { "baseline", "main", "high", "high10", "high422", "high444", 0 };

(3)图片内存分配

x264_picture_alloc(en->picture, X264_CSP_I422, en->param->i_width,en->param->i_height);

这里的第二个参数一定要与你的输入格式先对应,不然的话会出现内存溢出的错误。因为默认的分配图片内存大小是YUV420的。以640*480 分辨率来举例,YUV420 分配一帧图像的内存是450K,而我们YUV422的数据量是600K。

(4)Y,U,V 数据需要分离

for(i=0; i<num; i=i+4){*(y + (index_y++)) = *(in + i);*(u + (index_u++)) = *(in + i + 1);*(y + (index_y++)) = *(in + i + 2);*(v + (index_v++)) = *(in + i + 3);}

YUYV的数据是交错存储的,因此需要把他们分离出来单独存储,如果这里不做处理,图像就会出现异常。

(5)i_pts 参数需要递增

en->picture->i_pts = pts++;

i_pts = pts的参数是需要递增的,不让回出现警告:x264 [warning]: non-strictly-monotonic PTS

完整的编译运行结果如下:

[root@redhat test]# ls
h264encoder.c  include  lib  main.c  Makefile  out
[root@redhat test]# make
gcc -g    -c -o main.o main.c
gcc -g    -c -o h264encoder.o h264encoder.c
gcc -g -o x264_test main.o  h264encoder.o -lpthread -lx264 -lm
[root@redhat test]# ls
h264encoder.c  h264encoder.o  include  lib  main.c  main.o  Makefile  out  x264_test
[root@redhat test]# ./x264_test camera driver name is : uvcvideo
camera device name is : UVC Camera (046d:0825)
camera bus information: usb-0000:00:1a.0-1.1
n_buffer = 4
x264 [warning]: lookaheadless mb-tree requires intra refresh or infinite keyint
x264 [info]: using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX
x264 [info]: profile High 4:2:2, level 3.0, 4:2:2 8-bit
spend time 85.082031 s
x264 [info]: frame I:8     Avg QP:20.27  size: 21592
x264 [info]: frame P:503   Avg QP:21.18  size:  3119
x264 [info]: frame B:1485  Avg QP:22.03  size:   952
x264 [info]: consecutive B-frames:  0.8%  0.0%  0.0% 99.2%
x264 [info]: mb I  I16..4: 11.9% 55.2% 32.9%
x264 [info]: mb P  I16..4:  0.4%  0.2%  0.1%  P16..4: 44.8%  7.9%  8.5%  0.0%  0.0%    skip:38.2%
x264 [info]: mb B  I16..4:  0.0%  0.0%  0.0%  B16..8: 25.9%  0.6%  0.1%  direct: 1.7%  skip:71.7%  L0:51.6% L1:47.0% BI: 1.4%
x264 [info]: 8x8 transform intra:46.7% inter:95.7%
x264 [info]: coded y,uvDC,uvAC intra: 60.5% 87.6% 59.7% inter: 5.7% 23.2% 0.9%
x264 [info]: i16 v,h,dc,p:  4%  8%  1% 87%
x264 [info]: i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 16% 39% 12%  3%  5%  4% 10%  4%  7%
x264 [info]: i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 24% 41%  8%  3%  4%  3%  8%  3%  4%
x264 [info]: i8c dc,h,v,p: 50% 22% 21%  6%
x264 [info]: Weighted P-Frames: Y:0.2% UV:0.0%
x264 [info]: ref P L0: 40.2%  4.8% 39.3% 15.7%
x264 [info]: ref B L0: 65.6% 20.4% 14.0%
x264 [info]: ref B L1: 91.2%  8.8%
x264 [info]: kb/s:379.47[root@redhat test]# 

这里设置的分辨率是640*480 ,这样采集数据比较快。我编码2000帧数据需要的是大约85s,帧率大约在23fps 。也不知道具体是什么原因导致耗时这么长时间。

视频运行如下:

完整的工程下载路径:V4L2采集YUYV数据x264编码成H264视频

V4L2采集YUYV数据—X264编码H264视频实例相关推荐

  1. V4L2视频采集与H264编码1—V4L2采集JPEG数据

    最近在做视频编码,经过一段时间的折腾,终于可以把V4L2采集到的图片数据编码成H264视频,并且成功将工程移植到了ARM开发板上.无奈开发板性能太低,每秒钟只能编码一帧数据,查看CPU已经跑到100% ...

  2. linux下使用ffmpeg采集摄像头数据并编码成h264文件

    本文讲述如何在linux下,使用ffmpeg采集视频数据,并编码成h264文件. 打算分成3部分讲解: 需要具备的软硬件环境 ffmpeg命令采集摄像头数据并编码成h264文件 ffmpeg代码采集摄 ...

  3. V4L2视频采集与H264编码2—v4l2采集YUV数据

    在上一篇中因为是在PC机上使用的USB摄像头只能支持GPEG image格式,但是H264编码需要使用YUV数据,所以我找了个ARM开发板来做测试.本以为代码从PC机移植到开发板是很简单的一个事,谁知 ...

  4. ffmpeg + x264 编码H264(x86+arm)

    一.x86-linux 1.  编译x264 我用的是目前最新版:x264-snapshot-20101130-2245.tar.bz2 ./configure --disable-asm mak ...

  5. php html转成数组,PHP_php将HTML表格每行每列转为数组实现采集表格数据的方法,本文实例讲述了php将HTML表格每 - phpStudy...

    php将HTML表格每行每列转为数组实现采集表格数据的方法 本文实例讲述了php将HTML表格每行每列转为数组实现采集表格数据的方法.分享给大家供大家参考.具体如下: 下面的php代码可以将HTML表 ...

  6. 用FFmpeg编码h264视频介绍

    尚在整理中... x264 – Rate Control Choices Firstly, you need to decide on a rate control method. This cont ...

  7. 嵌入式监控【v4l2采集->vpu编码->live555推流】

    嵌入式监控[v4l2采集->vpu编码->live555推流] 文章目录 嵌入式监控[v4l2采集->vpu编码->live555推流] 介绍 数据流图 一.v4l2 1.1 ...

  8. 嵌入式监控【v4l2采集-vpu编码-live555推流】

    嵌入式监控[v4l2采集->vpu编码->live555推流] 文章目录 嵌入式监控[v4l2采集->vpu编码->live555推流] 介绍 数据流图 一.v4l2 1.1 ...

  9. 使用live555 直播来自v4l2的摄像头数据

    使用live555 直播来自v4l2的摄像头数据,在我的这个工程中,基本思路是:使用V4L2采集摄像头数据,然后使用x264库对摄像头数据进行编码,编成H264数据格式,然后把数据写入到命名管道中.最 ...

最新文章

  1. python replace函数用法_Python实现的从右到左字符串替换方法示例
  2. 现在的年轻人。。。到处都是套路。。。
  3. 地图瓦片相关学习总结
  4. AndroidStudio中安装GsonFormat插件并根据json文件生成JavaBean
  5. CrystalDiskInfo的下载使用
  6. Vue + Spring Boot 项目实战(六):使用 Element 辅助前端开发
  7. datagridview 手动添加的行如何进行重载_【厚积薄发】如何规划UI图标图集
  8. 工作流中ServiceTask的各种方法
  9. [推荐算法]基于用户的协同过滤算法
  10. 服务器如果选用CPU
  11. 图像检索基于BOF(Bag-Of-Features Models)
  12. 最新官方新浪短网址API接口分享-附代码调用演示
  13. 随机误差与Allan方差的理解
  14. Docker安装Tomcat镜像并部署web项目简述
  15. 【Vscode】解决报错 An SSH installation couldn‘t be found
  16. 消除计算机上的静电有哪些方法,电脑有静电怎么消除
  17. 中国灾害预警爬取解析
  18. php behaviors,在PHP的Yii框架中使用行为Behaviors的方法
  19. PhoneGap简介
  20. 因果系列文章(4)——拨开混杂的迷雾

热门文章

  1. esper java_Esper教程 —— Esper 进程模型是什么(3)
  2. 怎么防有人使用Windows启动盘偷走你的文件
  3. [Overleaf] LaTeX中的斜体、加粗、下划线和简单指令
  4. Ubuntu 16.04 安装cuda9.0 cudnn7.0 之妙法:NVIDIA 驱动-cuda-cudnn-安装tensorflow-gpu(windows 也可参考),试一下?
  5. HTTPS那些事(一)HTTPS原理
  6. opencv——opencv配置选项详解
  7. pthread_create回调函数返回值
  8. WPF TabControl Styles
  9. 数据仓库(4)基于维度建模的数仓KimBall架构
  10. python执行pyc文件_Python 编译:code对象 与 pyc文件