本文共 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)
//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.获取并保存至队列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);
打法应该是覆盖前面的frame 但是实际上没有出现这种情况
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/