最近在研究FFmpeg,比較驚訝的是網上一大堆資料都是在說如何從已有的視頻中截取一幀圖像,卻很少說到如何直接從攝像頭中捕獲一幀圖像,其實我一直有個疑問,就是在Linux下,大家是用什么庫來采集攝像頭的(opencv?)?還是自己寫v4l2的代碼來實現?我之前一直都是用v4l2來采集攝像頭的。經過一些時間的研究,最后成功地用FFmpeg實現了從攝像頭采集一幀圖像,實現代碼也非常簡單。不多說,上代碼。
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <fcntl.h>
5 #include <unistd.h>
6
7 #include <libavformat/avformat.h>
8 #include <libavcodec/avcodec.h>
9 #include <libavdevice/avdevice.h>
10
11
12 void captureOneFrame()
13 {
14 AVFormatContext *fmtCtx = NULL;
15 AVFormatParameters inputFmtParameter;
16 AVPacket *pcaket;
17
18 //輸入格式(V4L2)
19 AVInputFormat *inputFmt = av_find_input_format ("video4linux2");
20 if (inputFmt == NULL)
21 {
22 printf("can not find_input_format\n");
23 return;
24 }
25
26 memset (&inputFmtParameter, 0, sizeof(inputFmtParameter));
27 //采集圖像的高度
28 inputFmtParameter.height = 240;
29 //采集圖像的寬度
30 inputFmtParameter.width = 320;
31
32 //打開攝像頭設備
33 if (av_open_input_file ( &fmtCtx, "/dev/video0", inputFmt,
34 sizeof(inputFmtParameter),&inputFmtParameter) < 0)
35 {
36 printf("can not open_input_file\n");
37 return;
38 }
39 //從攝像頭獲取一幀圖像
40 av_read_frame(fmtCtx, pcaket);
41 //輸出圖像的大小
42 printf("data length = %d\n",pcaket->size);
43
44 FILE *fp;
45 //打開(新建)文件
46 fp = fopen("out.yuv", "wb");
47 if (fp < 0)
48 {
49 printf("open frame data file failed\n");
50 return ;
51 }
52 //將數據寫入文件
53 fwrite(pcaket->data, 1, pcaket->size, fp);
54 //關閉文件
55 fclose(fp);
56
57 //關閉設備文件
58 av_close_input_file(fmtCtx);
59 }
60
61
62 int main()
63 {
64 avcodec_init();
65 avcodec_register_all();
66 avdevice_register_all();
67
68 captureOneFrame();
69
70 return 0;
71 }
注意:采集出來的圖像的是YV12格式的。用YUV格式查看軟件看下效果:

