FFMPEG(一) 从V4L2捕获摄像头数据

系列相关博文:

 

            FFMPEG(一) 从V4L2捕获摄像头数据

            FFMPEG(二) v4l2 数据格式装换

            FFMPEG(三) v4l2 数据编码H264

 

    最近在学习FFMPEG,发现网上的很多例子都是基于读文件的。直接从摄像头中读取数据的却很少。之前写过通过v4l2采集摄像头数据然后调用x264编码成视频文件的例子。在FFMPEG中,它将很多的V4L2操作函数已经封装好,这里提供一个最简的例程。需要注意的是,我采用的FFMPEG的版本是最新的ffmpeg-3.2.4 版本,不同版本的库,接口函数有有些不一样。

 

[objc] view plain copy
 
 print?
  1. /*============================================================================= 
  2. #     FileName: read_device.c 
  3. #         Desc: use ffmpeg read a frame data from v4l2  
  4. #       Author: licaibiao 
  5. #   LastChange: 2017-03-15  
  6. =============================================================================*/  
  7. #include <stdio.h>  
  8. #include <string.h>  
  9. #include <stdlib.h>  
  10. #include <unistd.h>  
  11. #include "avformat.h"  
  12. #include "avcodec.h"  
  13. #include "avdevice.h"  
  14.   
  15. char* input_name= "video4linux2";  
  16. char* file_name = "/dev/video0";  
  17. char* out_file  = "test.jpeg";  
  18.   
  19. void captureOneFrame(void){  
  20.     AVFormatContext *fmtCtx = NULL;      
  21.     AVPacket *packet;   
  22.     AVInputFormat *inputFmt;  
  23.     FILEFILE *fp;   
  24.     int ret;  
  25.   
  26.   
  27.     inputFmt = av_find_input_format (input_name);      
  28.      
  29.     if (inputFmt == NULL)    {          
  30.         printf("can not find_input_format\n");          
  31.         return;      
  32.     }      
  33.   
  34.     if (avformat_open_input ( &fmtCtx, file_name, inputFmt, NULL) < 0){  
  35.         printf("can not open_input_file\n");         return;      
  36.     }  
  37.     /* print device information*/  
  38.     av_dump_format(fmtCtx, 0, file_name, 0);  
  39.   
  40.     packet = (AVPacket *)av_malloc(sizeof(AVPacket));      
  41.     av_read_frame(fmtCtx, packet);   
  42.     printf("data length = %d\n",packet->size);     
  43.   
  44.     fp = fopen(out_file, "wb");      
  45.     if (fp < 0)    {          
  46.         printf("open frame data file failed\n");          
  47.         return ;      
  48.     }      
  49.       
  50.     fwrite(packet->data, 1, packet->size, fp);      
  51.   
  52.     fclose(fp);      
  53.     av_free_packet(packet);      
  54.     avformat_close_input(&fmtCtx);  
  55.  }   
  56.   
  57. int main(void){      
  58.     avcodec_register_all();      
  59.     avdevice_register_all();      
  60.     captureOneFrame();      
  61.     return 0;  
  62. }  

    Makefile文件如下:

 

 

[objc] view plain copy
 
 print?
  1. OUT_APP      = test  
  2. INCLUDE_PATH = /usr/local/include/  
  3. INCLUDE = -I$(INCLUDE_PATH)libavutil/ -I$(INCLUDE_PATH)libavdevice/ \  
  4.             -I$(INCLUDE_PATH)libavcodec/ -I$(INCLUDE_PATH)libswresample \  
  5.             -I$(INCLUDE_PATH)libavfilter/ -I$(INCLUDE_PATH)libavformat \  
  6.             -I$(INCLUDE_PATH)libswscale/  
  7.   
  8. FFMPEG_LIBS = -lavformat -lavutil -lavdevice -lavcodec -lswresample -lavfilter -lswscale  
  9. SDL_LIBS    =   
  10. LIBS        = $(FFMPEG_LIBS)$(SDL_LIBS)  
  11.   
  12. COMPILE_OPTS = $(INCLUDE)  
  13. C            = c  
  14. OBJ          = o  
  15. C_COMPILER   = cc  
  16. C_FLAGS      = $(COMPILE_OPTS) $(CPPFLAGS) $(CFLAGS)  
  17.   
  18. LINK         = cc -o   
  19. LINK_OPTS    = -lz -lm  -lpthread  
  20. LINK_OBJ     = read_device.o   
  21.   
  22. .$(C).$(OBJ):  
  23.     $(C_COMPILER) -c -g $(C_FLAGS) $<  
  24.   
  25.   
  26. $(OUT_APP): $(LINK_OBJ)  
  27.     $(LINK)$@  $(LINK_OBJ)  $(LIBS) $(LINK_OPTS)  
  28.   
  29. clean:  
  30.         -rm -rf *.$(OBJ) $(OUT_APP) core *.core *~  *.jpeg  

 

    编译运行结果如下:

 

[objc] view plain copy
 
 print?
  1. licaibiao@ubuntu:~/test/FFMPEG/device$ ./test   
  2. [video4linux2,v4l2 @ 0x1d18040] Time per frame unknown  
  3. Input #0, video4linux2,v4l2, from '/dev/video0':  
  4.   Duration: N/A, bitrate: N/A  
  5.     Stream #0:0: Video: mjpeg, none, 640x480, 1000k tbn  
  6. data length = 27697  
  7. licaibiao@ubuntu:~/test/FFMPEG/device$ ls  
  8. Makefile  read_device.c  read_device.o  test  test.jpeg  webcm.c  
  9. licaibiao@ubuntu:~/test/FFMPEG/device$   

    我使用的摄像头输出的是mjpeg格式数据,将它保存到test.jpeg 文件。打开如下:

 

 

FFMPEG(一) 从V4L2捕获摄像头数据

 

上一篇:sql 2005 分页存储过程


下一篇:【数据蒋堂】第1期:多维分析的后台性能优化手段