DSP

基于USB摄像头视频数据采集和利用FFMPEG库函数进行视频数据压缩

2019-07-13 15:51发布

  1. 从一篇博客中看到的代码,觉得很有用,暂时没时间研究就先转载保存先。参考http://blog.csdn.net/yakimin/article/details/19284467
  2. 后面可以通过tcp传输等,在pc上或者开发板上把yuv视频解码,然后再把yuv转RGB播放出来。同时之前找了个解码的播放器有源码,可以结合两者实现此功能。链接:

  3. #include   
  4. #include   
  5. #include   
  6. #include   
  7. #include   
  8. #include   
  9. #include   
  10. #include   
  11. #include   
  12. #include   
  13. #include   
  14. #include   
  15. #include   
  16. #include   
  17. #include   
  18. #include   
  19. #include   
  20.   
  21. #define VIDEO_WIDTH 640  
  22. #define VIDEO_HEIGHT 480  
  23. #define VIDEO_FORMAT V4L2_PIX_FMT_YUYV  
  24. #define BUFFER_COUNT 4  
  25. #define URL_WRONLY 1  
  26.   
  27. struct fimc_buffer {  
  28.     int length;  
  29.     void *start;  
  30. } framebuf[BUFFER_COUNT];  
  31.   
  32. int fd;  
  33. unsigned char yuv4200[1000000] = { 0 };  
  34. unsigned char yuv4220[1000000] = { 0 };  
  35.   
  36. AVFormatContext* pFormatCtxEnc;  
  37. AVCodecContext* pCodecCtxEnc;  
  38. AVFrame* pFrameEnc;  
  39.   
  40. void register_init();  
  41. int open_device();  
  42. int capability();  
  43. int set_v4l2_format();  
  44. int request_buffers();  
  45. int get_camera_data();  
  46. void unregister_all();  
  47. void video_encode_init();  
  48.   
  49. int yuv422_2_yuv420(unsigned char* yuv420, unsigned char* yuv422, int width,  
  50.         int height);  
  51.   
  52. void register_init() {  
  53.     avcodec_register_all();  
  54.     av_register_all();  
  55.   
  56. }  
  57.   
  58. int open_device() {  
  59.     char camera_device[20];  
  60.     struct stat buf;  
  61.     int i;  
  62.     for (i = 0; i < 10; i++) {  
  63.         sprintf(camera_device, "/dev/video%i", i);  
  64.         if (stat(camera_device, &buf) == 0) {  
  65.             break;  
  66.         }  
  67.   
  68.     }  
  69.     fd = open(camera_device, O_RDWR, 0); //设备以非阻塞方式打开  
  70.     if (fd < 0) {  
  71.         printf("Cannot open camera_device ");  
  72.         return -1;  
  73.     }  
  74.   
  75. }  
  76.   
  77. int set_v4l2_format() {  
  78.     int ret;  
  79.     struct v4l2_format fmt; //设置视频制式和帧格式  
  80.     memset(&fmt, 0, sizeof(fmt));  
  81.     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;  
  82.     fmt.fmt.pix.width = VIDEO_WIDTH;  
  83.     fmt.fmt.pix.height = VIDEO_HEIGHT;  
  84.     fmt.fmt.pix.pixelformat = VIDEO_FORMAT;  
  85.     fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;  
  86.     ret = ioctl(fd, VIDIOC_S_FMT, &fmt);  
  87.     if (ret < 0) {  
  88.         printf("VIDIOC_S_FMT failed ");  
  89.         return ret;  
  90.     }  
  91.   
  92.     ret = ioctl(fd, VIDIOC_G_FMT, &fmt); //获取视频制式和帧格式的实际值,看是否设置正确  
  93.     if (ret < 0) {  
  94.         printf("VIDIOC_G_FMT failed (%d)/n", ret);  
  95.         return ret;  
  96.     }  
  97.   
  98. }  
  99.   
  100. int request_buffers() {  
  101.     int ret;  
  102.     int i;  
  103.     struct v4l2_requestbuffers reqbuf; //向驱动申请帧缓冲  
  104.     reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;  
  105.     reqbuf.memory = V4L2_MEMORY_MMAP;  
  106.     reqbuf.count = BUFFER_COUNT;  
  107.     ret = ioctl(fd, VIDIOC_REQBUFS, &reqbuf);  
  108.     if (ret < 0) {  
  109.         printf("VIDIOC_REQBUFS failed  ");  
  110.         return