题目:视频流在Windows系统上的实时捕捉与传输
参考资料:以下资料都是我从网上找到并积累的,感觉都还可以,有参考价值。
有点兴奋,一周的成果,不容易呀,真心的。
从一个对视频这块一无所知的码农,到现在稍稍入门的码农。没有什么大的变化,不过还是了解到行行都比较难搞。
言归正传:开始讲讲 我的大致思路:如下图所示。
其实,之前想过多种方案。
方案一:
比较靠谱点的是在linux下,用fifo传输数据,一边采集并转化为h264,linux自己可以转,这个比windows简单多了。
然后,live555这一端,用fifo(其实是管道)来搞,这样的好处在于 保证两个进程间通信。而且比较实时。
当然,在windows下,也可以通过进程间通信的方式来实现 有很多方式,这里面不多做介绍。
但是,还有更简单的方式,我们完全可以用多线程来实现,在另一个线程中,我们利用循环数组的方式实现,这样的话,可以保证实时性。
方案二:
用opencv采集数据,并可以对数据进行图像处理,然后,我们可以用libx264库对视频进行编码成h264格式,然后进行推送至rtsp服务器。
不过,这里的一个难点就是 libx264使用不太熟悉,导致后来我放弃了这种方案。
后来,看到雷神写的一篇文章,终于让我下定决心,用ffmpeg+live555来搞。
如何实现:
关键点分析:
程序由三个线程组成: 一个采集并编码线程;一个将编码后的数据推送至rtsp264线程;一个主线程。线程之间传递数据利用循环数组实现。
整体结构如下:
下面一个个分析下实现思路:
- 采集并编码线程:
参考雷神的两篇日志
http://blog.csdn.net/leixiaohua1020/article/details/39759623 最简单的基于FFmpeg的内存读写的例子:内存转码器
http://blog.csdn.net/leixiaohua1020/article/details/39759163 最简单的基于FFmpeg的内存读写的例子:内存播放器
- 将编码后的数据推送至rtsp264线程
参考网上两个哥们的日志
http://bubuko.com/infodetail-272265.html
Windows下利用live555实现H264实时流RTSP发送
http://blog.csdn.net/xiejiashu/article/details/8269873 用live555做本地视频采集转发,附源码
主要是重写getnextframe 代码
整个代码如下:
-
#include "global.h"
-
#include "FFmpegReadCamera.h"
-
#include "H264LiveVideoServerMediaSubssion.hh"
-
#include "H264FramedLiveSource.hh"
-
#include "liveMedia.hh"
-
#include "BasicUsageEnvironment.hh"
-
-
#define BUFSIZE 10000
-
-
DWORD WINAPI ChildFunc1(LPVOID);
-
DWORD WINAPI ChildFunc2(LPVOID);
-
-
-
static void announceStream(RTSPServer* rtspServer, ServerMediaSession* sms,char const* streamName)//显示RTSP连接信息
-
{
-
char* url = rtspServer->rtspURL(sms);
-
UsageEnvironment& env = rtspServer->envir();
-
env <<streamName<< "\n";
-
env << "Play this stream using the URL \"" << url << "\"\n";
-
delete[] url;
-
}
-
-
int main(int argc, char** argv)
-
{
-
for (int i = 0; i < ARRAYLENGTH; ++i)
-
{
-
memset(&szbuffer[i],0,sizeof(StreamData));
-
}
-
-
CreateThread(NULL,0,ChildFunc1,0,0,NULL);
-
Sleep(3000);
-
CreateThread(NULL,0,ChildFunc2,0,0,NULL);
-
while(1)
-
{
-
Sleep(1);
-
}
-
return 0;
-
-
}
-
-
DWORD WINAPI ChildFunc1(LPVOID p)
-
{
-
int ret;
-
AVFormatContext *ofmt_ctx = NULL;
-
AVStream *out_stream;
-
AVStream *in_stream;
-
AVCodecContext *enc_ctx;
-
AVCodecContext *dec_ctx;
-
AVCodec* encoder;
-
enum AVMediaType type;
-
fp_write = fopen("test.h264","wb+");
-
unsigned int stream_index;
-
AVPacket enc_pkt;
-
int enc_got_frame;
-
-
AVFormatContext *pFormatCtx;
-
int i, videoindex;
-
AVCodecContext *pCodecCtx;
-
AVCodec *pCodec;
-
-
av_register_all();
-
-
avformat_network_init();
-
pFormatCtx = avformat_alloc_context();
-
-
avformat_alloc_output_context2(&ofmt_ctx,NULL,"h264",NULL);
-
-
//Register Device 注册所有硬件
-
avdevice_register_all();
-
//Show Dshow Device 显示所有可用的硬件
-
show_dshow_device();
-
//Show Device Options 显示某一个硬件的所有参数(摄像头参数)
-
show_dshow_device_option();
-
//Show VFW Options
-
show_vfw_device();
-
//Windows
-
#ifdef _WIN32
-
#if USE_DSHOW
-
AVInputFormat *ifmt=av_find_input_format("dshow");
-
//Set own video device's name
-
if(avformat_open_input(&pFormatCtx,"video=Integrated Webcam",ifmt,NULL)!=0){