博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
音视频开发---v4l2---采集视频数据并编码为H264项目整理
阅读量:3920 次
发布时间:2019-05-23

本文共 6269 字,大约阅读时间需要 20 分钟。

实例:ffmpeg读取摄像头,仅仅调用v4l2(不涉及相关结构流程)

/*=============================================================================#     FileName: read_device.c#         Desc: use ffmpeg read a frame data from v4l2 #       Author: licaibiao#   LastChange: 2017-03-15 =============================================================================*/#include 
#include
#include
#include
#include "libavformat/avformat.h"#include "libavcodec/avcodec.h"#include "libavdevice/avdevice.h" char* input_name= "video4linux2";char* file_name = "/dev/video0";char* out_file = "test.jpeg"; void captureOneFrame(void){
AVFormatContext *fmtCtx = NULL; AVPacket *packet; AVInputFormat *inputFmt; FILE *fp; int ret;printf("1\n"); inputFmt = av_find_input_format (input_name); if (inputFmt == NULL) {
printf("can not find_input_format\n"); return; } printf("2\n"); if (avformat_open_input ( &fmtCtx, file_name, inputFmt, NULL) < 0){
printf("can not open_input_file\n"); return; }printf("3\n"); /* print device information*/ av_dump_format(fmtCtx, 0, file_name, 0);printf("4\n"); packet = (AVPacket *)av_malloc(sizeof(AVPacket)); av_read_frame(fmtCtx, packet); printf("data length = %d\n",packet->size); fp = fopen(out_file, "wb"); if (fp < 0) {
printf("open frame data file failed\n"); return ; } fwrite(packet->data, 1, packet->size, fp); fclose(fp); av_free_packet(packet); avformat_close_input(&fmtCtx); } int main(void){
avcodec_register_all(); avdevice_register_all(); captureOneFrame(); return 0;}

vfl2编码学习:

三种视频采集方式的选择,推荐的顺序是 userptr(使用程序内存) 、 mmap(使用内核内存) 、 read-write(慢)其中userptr 、 mmap 使用环形缓冲队列(使得效率高于read-write)

V4L2编程-常用的结构体(见/usr/include/linux/videodev2.h)

//h264的重要结构体都在x264.h中

Video for Linux Two header file(参见/usr/include/linux/videodev2.h): struct v4l2_requestbuffers reqbufs;        //向驱动申请帧缓冲的请求,里面包含申请的个数 struct v4l2_capability cap;                      //这个设备的功能,比如是否是视频输入设备 struct v4l2_input input;                           //视频输入 struct v4l2_standard std;                        //视频的制式,比如PAL,NTSC struct v4l2_format fmt;                            //帧的格式,比如宽度,高度等 struct v4l2_buffer buf;                            //代表驱动中的一帧 v4l2_std_id stdid;                                   //视频制式,例如:V4L2_STD_PAL_B struct v4l2_queryctrl query;                   //查询的控制 struct v4l2_control control;                    //具体控制的值

LINUX下采集视频数据并编码为H264项目,通过测试,编码后的视频清晰流畅,编码后的.264文件可以通过VCL播放器播放,摄像头可以使用符合UVC规范的的USB摄像头来做测试,本人使用多线程,在环形缓冲队列,确保采集的数据不会丢失,处理及时,才能保证编码后的图像流畅

1.若编码处理速度>生成原始数据 则:原始数据获取线程👉👉条件变量👉👉通知编码线程

1.获取并保存至队列2.从队列中取出并编码至输出文件//这里是获取部分 用条件变量进行等待	pthread_mutex_lock(&ptmp->lock);	if(ptmp->state==FRAME_INVALID)		//ptmp->state==FRAME_INVALID表示不满足线程编码执行条件   会用pthread_cond_wait将自己阻塞		{
pthread_cond_wait(&ptmp->cond,&ptmp->lock); //阻塞当前线程,等待别的线程使用pthread_cond_signal()或pthread_cond_broadcast来唤醒 //pthread_cond_wait()函数一进入wait状态就会自动release mutex。 //当其他线程通过pthread_cond_signal()或pthread_cond_broadcast,把该线程唤醒,使pthread_cond_wait()通过(返回)时,该线程又自动获得该mutex。 } memcpy(buf,ptmp->buf,FRAME_SIZE); ptmp->state=FRAME_INVALID; raw_frame_read_head=raw_frame_read_head->next; pthread_mutex_unlock(&ptmp->lock);

2.如果生成原始数据>编码处理速度

打法应该是覆盖前面的frame 但是实际上没有出现这种情况

最蠢的是:笔记本自带摄像头可用,而买的usb摄像头就永远select超时,明明参数全部一样,只有名字不一样

v4l2对应用程序抽象了操作音频视频设备的细节。应用程序只需要调用v4l2接口函数就可以操作设备,无须关心是什么样的设备,比如在应用程序层面上,USB摄像头与其他类型的摄像头没有分别。

查看摄像头信息v4l2-ctl -d  /dev/video* --all//需要安装v4l2-ctl

遇到的问题

设置像素YUV422   但是baseline不支持422应该设置:en->param->i_csp=X264_CSP_I422;	// /* 编码比特流的CSP,仅支持i420,色彩空间设置 *///x264.h中声明:static const char * const x264_profile_names[] = { "baseline", "main", "high", "high10", "high422", "high444", 0 };原本为:x264_param_apply_profile(en->param, x264_profile_names[0]); //使用baseline   设置profile故修改为👇x264_param_apply_profile(en->param, x264_profile_names[4]); //使用baseline   设置profile
x264 [info]: using cpu capabilities: none!没有安装NASM并编译x264的汇编部分代码ASM parts      //make sure "--no-asm" isn't used.//解释:http://forum.doom9.org/showthread.php?t=135590而重新编译x264版本(包括编译asm汇编部分) 配置时报错:Found no assemblerMinimum version is nasm-2.13故而通过apt-get install nasm安装//root@ubuntu:/home/sxm-download/x264-master# nasm -version//NASM version 2.11.08版本还是太低,那就去官网下载//在网站下载2.13这个版本   解压安装

下面是的测试结果:

[root@redhat test]# lsh264encoder.c  include  lib  main.c  Makefile  out[root@redhat test]# makegcc -g    -c -o main.o main.cgcc -g    -c -o h264encoder.o h264encoder.cgcc -g -o x264_test main.o  h264encoder.o -lpthread -lx264 -lm[root@redhat test]# lsh264encoder.c  h264encoder.o  include  lib  main.c  main.o  Makefile  out  x264_test[root@redhat test]# ./x264_test  camera driver name is : uvcvideocamera device name is : UVC Camera (046d:0825)camera bus information: usb-0000:00:1a.0-1.1n_buffer = 4x264 [warning]: lookaheadless mb-tree requires intra refresh or infinite keyintx264 [info]: using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVXx264 [info]: profile High 4:2:2, level 3.0, 4:2:2 8-bitspend time 85.082031 sx264 [info]: frame I:8     Avg QP:20.27  size: 21592x264 [info]: frame P:503   Avg QP:21.18  size:  3119x264 [info]: frame B:1485  Avg QP:22.03  size:   952x264 [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]#

转载地址:http://hfhrn.baihongyu.com/

你可能感兴趣的文章
Xamarin使XRPC实现接口/委托远程调用
查看>>
如何成功搞垮一个团队?
查看>>
.NET开源5年了,这些宝藏你还没get?
查看>>
【日常排雷】 .Net core 生产环境appsetting读取失败
查看>>
从内存中释放Selenium chromedriver.exe
查看>>
如何在 C# 中使用 MSMQ
查看>>
小试elsa
查看>>
巧用 Lazy 解决.NET Core中的循环依赖关系
查看>>
微前端架构在容器平台的应用
查看>>
C# 中的 null 包容运算符 “!” —— 概念、由来、用法和注意事项
查看>>
仓储模式到底是不是反模式?
查看>>
ABP vNext分布式事件总线RabbitMQ注意事项
查看>>
【One by One系列】IdentityServer4(一)OAuth2.0与OpenID Connect 1.0
查看>>
为什么人和人的差距这么大?
查看>>
ML.NET 推荐引擎中一类矩阵因子分解的缺陷
查看>>
微软2020开源回顾:止不住的挨骂,停不下的贡献
查看>>
说说 RabbiMQ 的应答模式
查看>>
OpenTelemetry - 云原生下可观测性的新标准
查看>>
使用 ML.NET 实现峰值检测来排查异常
查看>>
通过 .NET NativeAOT 实现用户体验升级
查看>>