zoukankan      html  css  js  c++  java
  • 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 ");          
    31.         return;      
    32.     }      
    33.   
    34.     if (avformat_open_input ( &fmtCtx, file_name, inputFmt, NULL) < 0){  
    35.         printf("can not open_input_file ");         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 ",packet->size);     
    43.   
    44.     fp = fopen(out_file, "wb");      
    45.     if (fp < 0)    {          
    46.         printf("open frame data file failed ");          
    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 文件。打开如下:

  • 相关阅读:
    CLR Via
    HTML&XML
    SNS研究
    DotNet&C#
    电子商务
    WCF学习
    SQL
    构架设计
    JS&Ajax
    NHibernate之旅系列文章导航
  • 原文地址:https://www.cnblogs.com/lidabo/p/7345860.html
Copyright © 2011-2022 走看看