Chinaunix首页 | 论坛 | 博客
  • 博客访问: 9146951
  • 博文数量: 1726
  • 博客积分: 12961
  • 博客等级: 上将
  • 技术积分: 19850
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-09 11:25
个人简介

偷得浮生半桶水(半日闲), 好记性不如抄下来(烂笔头). 信息爆炸的时代, 学习是一项持续的工作.

文章分类

全部博文(1726)

文章存档

2024年(2)

2023年(26)

2022年(112)

2021年(217)

2020年(157)

2019年(192)

2018年(81)

2017年(78)

2016年(70)

2015年(52)

2014年(40)

2013年(51)

2012年(85)

2011年(45)

2010年(231)

2009年(287)

分类: 其他平台

2018-04-18 19:43:00

使用管道为ffmpeg输入视频内容.

首先 建立管道 FIFO. 把 JPG 内容不断的送往 FIFO中.
然后 命令行 ffmpeg  -f bmp_pipe -i t.v -r 1 -y a.flv  即可产生视频流


点击(此处)折叠或打开

  1. #include <unistd.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <stdio.h>
  5. #include <sys/types.h>
  6. #include <sys/stat.h>
  7. #include <fcntl.h>


  8. //摄像头通用接口
  9. #include <opencv2/opencv.hpp>
  10. #include <opencv2/highgui/highgui.hpp>
  11. #include <opencv2/imgproc/imgproc.hpp>
  12. #include <opencv2/core/core.hpp>
  13. #include <opencv2/objdetect/objdetect.hpp>
  14. #include <signal.h>
  15. #include <sys/socket.h>
  16. #include <arpa/inet.h>
  17. #include <netinet/in.h>
  18. using namespace cv;
  19. /* Video 通用接口 */
  20. typedef struct {
  21.     int             idx;
  22.     VideoCapture     *stream;
  23.     Mat                frame;
  24. }WebcamContext;
  25. static WebcamContext gCtx[3] = {0}; //目前最大支持 3 个摄像头.

  26. //打开摄像头
  27. static int InitCameraViaID(int idx, int camera_idx, int w, int h)
  28. {
  29.     //参数检查
  30.     gCtx[idx].stream = new VideoCapture(camera_idx);
  31.     if (!gCtx[idx].stream) {
  32.         printf("Cannot open Camera %d\n", camera_idx);
  33.         exit(-1);
  34.         return -1;
  35.     }
  36.     gCtx[idx].stream->set(CV_CAP_PROP_FRAME_WIDTH, w);
  37.     gCtx[idx].stream->set(CV_CAP_PROP_FRAME_HEIGHT, h);
  38.     return 0;
  39. }

  40. static void FinalCamera(void)
  41. {
  42.     for (int i=0; i<sizeof(gCtx)/sizeof(gCtx[0]); i++) {
  43.         if (gCtx[i].stream) {
  44.             gCtx[i].stream->release();
  45.             gCtx[i].stream = NULL;
  46.             if (!gCtx[i].frame.empty())
  47.                 gCtx[i].frame.release();
  48.         }
  49.     }
  50. }

  51. //获取摄像头的数据
  52. static Mat Get_Picture(int idx)
  53. {
  54.     gCtx[idx].stream->read(gCtx[idx].frame);
  55.     return gCtx[idx].frame;
  56. }

  57. static int fd_fifo = -1;

  58. static void save_bmp_to_file(int idx, uint8_t* bmp, int bmp_size)
  59. {    
  60.     if (fd_fifo = -1) {
  61.         char filename[128];
  62.         //sprintf(filename, "/tmp/jpg/%d.bmp", idx);
  63.         sprintf(filename, "/tmp/jpg/t.v");
  64.         int fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0666);
  65.         if (fd > 0) {
  66.             fd_fifo = fd;
  67.         }    
  68.     }
  69.     
  70.     if (fd_fifo > 0) {
  71.         write(fd_fifo, bmp, bmp_size);
  72.     }
  73.     
  74.     if ((fd_fifo > 0) && ((bmp_size==0) || (bmp == NULL))) {
  75.         close(fd_fifo);
  76.     }    
  77. }

  78. #define dbg()        printf("%d.\n", __LINE__)
  79. static uint8_t* convert_Mat_to_BMP(Mat *img, int *bmp_size);

  80. int main(int argc, char **argv)
  81. {
  82.     int idx = 0;
  83.     
  84.     InitCameraViaID(0, 1, 800, 600);
  85.     
  86.     int bmp_size, fd;
  87.     uint8_t* bmp = NULL;
  88.     
  89.     //while (idx++ < 100) 
  90.     while (1)
  91.     {
  92.         Mat frame = Get_Picture(0);                
  93.         bmp = convert_Mat_to_BMP(&frame, &bmp_size);
  94.         save_bmp_to_file(idx, bmp, bmp_size);
  95.         
  96.         usleep(100000);    
  97.     }
  98.     save_bmp_to_file(0, NULL, 0);
  99.     
  100.     FinalCamera();
  101.     return 0;
  102. }

  103. //convert Mat-object to bmp-struct.

  104. //https://www.cnblogs.com/lzlsky/archive/2012/08/16/2641698.html
  105. typedef uint32_t            DWORD;
  106. typedef uint16_t            WORD;
  107. typedef int32_t                LONG;
  108. typedef uint8_t                BYTE;

  109. typedef struct tagBITMAPFILEHEADER {
  110.     WORD    bfType;                 //2
  111.     DWORD    bfSize;                 //6
  112.     WORD    bfReserved1;             //8
  113.     WORD    bfReserved2;             //10
  114.     DWORD    bfOffBits;                 //14
  115. } __attribute__((packed)) BITMAPFILEHEADER;

  116. typedef struct tagBITMAPINFOHEADER{
  117.     DWORD        biSize;             //4
  118.     LONG        biWidth;             //8
  119.     LONG        biHeight;             //12
  120.     WORD        biPlanes;             //14
  121.     WORD        biBitCount;         //16
  122.     DWORD        biCompression;         //20
  123.     DWORD        biSizeImage;         //24
  124.     LONG        biXPelsPerMeter;     //28
  125.     LONG        biYPelsPerMeter;     //32
  126.     DWORD        biClrUsed;             //36
  127.     DWORD        biClrImportant;     //40
  128. } __attribute__((packed)) BITMAPINFOHEADER;


  129. typedef struct tagRGBQUAD {
  130.     BYTE rgbBlue;
  131.     BYTE rgbGreen;
  132.     BYTE rgbRed;
  133.     BYTE rgbReserved;
  134. } __attribute__((packed)) RGBQUAD;

  135. //return the pointer of BMP-in-memeory.
  136. /*
  137. input: Mat -> img
  138. output: bmp_size
  139. return: bmp_buffer pointer. (need to free by USER)
  140. */
  141. static uint8_t *convert_Mat_to_BMP(Mat *img, int *bmp_size)
  142. {
  143.     uint8_t *pBmpArray = NULL;
  144.     //======建立位图信息 ===========
  145.     int width, height, depth, channel;
  146.     width = img->cols;
  147.     height = img->rows;
  148.     depth = img->depth();
  149.     channel = img->channels();
  150.     
  151.     printf("w=%d h=%d d=%d c=%d\n", width, height, depth, channel);
  152.     
  153.     int bits, colors;
  154.     uint8_t idx;
  155.     bits = (8 << (depth/2)) * channel;
  156.     
  157. #if 0    
  158.     if (bits > 8)
  159.         colors = 0;
  160.     else
  161.         colors = 1<<bits; //now, bits must be 8; so color = 256
  162. #endif
  163.         
  164.     if (bits == 24)
  165.         bits = 32;
  166.         
  167.     //待存储图像数据每行字节数为4的倍数
  168.     int lineByte=(width * bits/8+3)/4*4;
  169.     
  170.     int colorTablesize = 0;
  171.     if (bits == 8) { // 256 色位图, // 设置灰阶调色板
  172.         colorTablesize = 256 * sizeof(RGBQUAD);
  173.     }    
  174. ///////////////////////////////////////////////////////////////////////////////////////////////////////////    
  175.     DWORD    bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + colorTablesize + lineByte*height;
  176.     //bitmap 文件 buffer
  177.     pBmpArray = (uint8_t *)malloc(bfSize);
  178.     memset(pBmpArray, 0, bfSize);
  179.     *bmp_size = bfSize;
  180. ///////////////////////////////////////////////////////////////////////////////////////////////////////////    
  181.     BITMAPFILEHEADER *fileHead = (BITMAPFILEHEADER *)pBmpArray; // sizeof(BITMAPFILEHEADER) = 14;
  182.     fileHead->bfType = 0x4D42;    //bmp类型
  183.     //bfSize是图像文件4个组成部分之和
  184.     fileHead->bfSize = bfSize;
  185.     //bfOffBits是图像文件前3个部分所需空间之和
  186.     fileHead->bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + colorTablesize;
  187. ///////////////////////////////////////////////////////////////////////////////////////////////////////////    
  188.     //位图的头
  189.     BITMAPINFOHEADER *head = (BITMAPINFOHEADER *)(&pBmpArray[sizeof(BITMAPFILEHEADER)]); // sizeof(BITMAPINFOHEADER) = 40;
  190.     head->biSize            = 40;
  191.     head->biWidth            = width;
  192.     head->biHeight            = height;
  193.     head->biPlanes            = 1;
  194.     head->biBitCount        = bits; //表示颜色用到的位数
  195.     head->biCompression        = 0; //0:不压缩(用BI_RGB表示)
  196.     head->biSizeImage        = lineByte*height; //图像数据站的字节数
  197.     head->biXPelsPerMeter    = 0;
  198.     head->biYPelsPerMeter    = 0;
  199.     head->biClrUsed            = 0;
  200.     head->biClrImportant    = 0;
  201. ///////////////////////////////////////////////////////////////////////////////////////////////////////////    
  202.     RGBQUAD *VgaColorTab = (RGBQUAD *)(&pBmpArray[sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)]);
  203.     if (bits == 8) { // 256 色位图, // 设置灰阶调色板
  204.         for (idx=0;idx<256;idx++) {
  205.             VgaColorTab[idx].rgbRed=VgaColorTab[idx].rgbGreen=VgaColorTab[idx].rgbBlue= idx;
  206.         }
  207.     }
  208. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  209.     //======颠倒数据
  210.     //======Mat 中从上往下存,而 bitmap 中从下往上存。 都是从左往右,并 且 bitmap 每一个点多占一个保留字节,默认 255
  211.     unsigned char *m_pDibBits = pBmpArray + fileHead->bfOffBits ;//存储图像中的数据,从下向上,从左向右 //x行 * Y列
  212.     int x, y;
  213.     unsigned char * bmpdata;
  214.     unsigned char * imgData = img->data;
  215.     
  216.     if (bits == 8)
  217.     {
  218.         //把 imgData 中的第一行复制到 m_pDibBits 的最后一行 , 依次颠倒
  219.         for (x=0; x<height; x++ )
  220.         {
  221.             bmpdata = m_pDibBits + (height-1-x)*width;
  222.             memcpy(bmpdata,imgData,width);
  223.             imgData = imgData + width;
  224.         }
  225.     }
  226.     else if (bits == 32)
  227.     {
  228.         //把 imgData 中的第一行复制到 m_pDibBits 的最后一行 , 依次颠倒
  229.         for (x=0; x<height; x++ )
  230.         {
  231.             bmpdata = m_pDibBits + (height-1-x)*width*4;
  232.             for (y = 0; y<width; y++)
  233.             {
  234.                 memcpy(bmpdata,imgData,3);
  235.                 bmpdata[3] = 255;
  236.                 bmpdata = bmpdata+4;
  237.                 imgData = imgData+3;
  238.             }
  239.         }
  240.     }
  241.     
  242. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  243.     return pBmpArray;
  244. }

衍生一下, 使用opencv 处理图像, 图像通过FIFO给 ffmpeg用,即可.
阅读(8795) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~