1. 程式人生 > >使用ffmpeg獲取一幀攝像頭資料

使用ffmpeg獲取一幀攝像頭資料

近在研究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格式檢視軟體看下效果: