OpenCV摄像头视频数据采集与RTSP和RTMP直播 (转)

最近比较闲,因此研究了一下通过OpenCV采集摄像头数据,并同时将视频流数据推送到RTSP和RTMP。

RTSP服务采用的事开源的LIVE555(需要自己修改和实现部分代码)。

RTMP服务采用的是开源的CRtmpServer。


具体的实现细节我就不说了,大概的步骤如下:

1. OpenCV采集摄像头的一帧数据(cvQueryFrame函数)

2. FFmpeg编码该帧为H264和FLV流数据

3. 推送H264到LIVE555(自己实现),同时通过推送FLV流到CRtmpServer(通过FFmpeg)


因为CRtmpServer和LIVE555都是开源的,网上有很多资料;并且FFmpeg的H264和FLV编码、H264和FLV流推送这两个功能之前已经在其他项目总已经实现过,而且OpenCV在网上也有很多关于摄像头数据采集的资料,因此实现过程并不复杂。


但是在接收RTSP和RTMP流,并播放时总感觉比较卡,特别是RTMP感觉非常明显。视频老是在缓冲。

最后发现是OpenCV的cvQueryFrame非常耗时间:

  1. while (pEncoder->m_bRunFlag)  
  2.         {  
  3.             LARGE_INTEGER freq;  
  4.             LARGE_INTEGER start;  
  5.             LARGE_INTEGER end;  
  6.   
  7.             QueryPerformanceFrequency(&freq);  
  8.             QueryPerformanceCounter(&start);  
  9.   
  10.             //获取一帧数据  
  11.             pFrame = cvQueryFrame(pCapture);  
  12.   
  13.             QueryPerformanceCounter(&end);  
  14.   
  15.             //发送数据给H264编码器  
  16.             if (pFrame)  
  17.             {  
  18.                 frame.nFrameHeight = pFrame->height;  
  19.                 frame.nFrameWidth = pFrame->width;  
  20.                 frame.nFrameSize = pFrame->imageSize;  
  21.                 frame.nFrameType = AEC_VIDEO_DATA_RGB24;  
  22.                 frame.pszFrameData = pFrame->imageData;  
  23.                 g_pH264SendFrame(frame);  
  24.             }  
  25.   
  26.             double fElapsedTime = double(end.QuadPart - start.QuadPart) / double(freq.QuadPart);  
  27.             TRACE("Elapsed time = %f ms\n", fElapsedTime * 1000);  
  28.         }  



也就是说fps平均12左右,RTSP还比较流畅,但是RTMP播放一秒后就又开始缓冲。将H264和FLV编码器的帧率从25降低到8,效果也一样。

看来后续需要研究其他摄像头视频数据采集方案,特此笔记。


后记:

经过查找资料发现,OpenCV底层采用的是微软的VFW(Video for Window)。VFW(Video for Windows)是Microsoft推出的关于数字视频的一个软件开发包,VFW的核心是AVI文件标准。AVI(Audio Video Interleave)文件中的音、视频数据帧交错存放。

VFW的主要函数如下:

(1)capCreateCaptureWindow()::创建视频窗体
(2)capDriverConnect(): 连接驱动
(3)capGetStatus():获得视频状态
(4)capPreviewRate():设置预览速率
(5)capFileSaveAs():将视频转换成AVI文件
(6)capFileSaveDIB():将视频转换成BMP文件
(7)capGetUserData():获取用户定义的数据
(8)capGetVideoFormat(): 获取视频格式
(9)capGrabFrame():获取当前帧
(10)capDlgVideoDisplay():设置显示的对话框
(11)capCaptureSetSetup():设置视频捕获
(12)capSetCallbackOnFrame():设置每帧的回调函数
(13)capSetCallbackOnVideoStream():设置视频流的回调函数
(14)capSetCallbackOnWaveStream():设置声音流的回调函数


后续将尝试DirectShow方式驱动摄像头,实现RTSP和RTMP直播。

posted @ 2014-10-20 17:22  视界君  阅读(3570)  评论(0)    收藏  举报