以前在公司作的一个小项目,功能很简单,就是在Ubuntu下采集 指定采集卡(模转数)的电视画面,以及音频输入信号,完成后再在本机进行视频的全屏播放,以及音频的本地播放(麦克风>>扬声器)。git
中间视频画面通过了图像格式的转换,最终由SDL进行渲染播放。服务器
同时附加简单的冗余功能,有两台设备同事运行,之间互有心跳,一台设备挂机后,另外一台设备自动开始工做。并发
程序使用QT/C/C++进行开发,使用V4L2,FFMPEG,SDL进行开发。app
入口:ide
#include <QtGui/QApplication> #include "widget.h" #include <QSharedMemory> int main(int argc, char *argv[]) { QApplication a(argc, argv); //共享内存保证单实例运行 QSharedMemory *shareMem = new QSharedMemory(QString("SingleInstanceIdentify")); /* if the sharedmemory has not been created, it returns false, otherwise true. * But if the application exit unexpectedly, the sharedmemory will not detach. * So, we try twice. */ volatile short i = 2; while (i--) { if (shareMem->attach(QSharedMemory::ReadOnly)) /* no need to lock, bcs it's read only */ { shareMem->detach(); } } if (shareMem->create(1)) { //采集并播放类开始运行,所有放到UI类中进行 MainWindow w; w.setWindowTitle("LCD Player"); // w.show(); w.showFullScreen(); a.exec(); } }
主要的设备管理、逻辑管理类接口:ui
class CDeviceCtrl : public QObject { Q_OBJECT public: explicit CDeviceCtrl(QObject *parent = 0); ~CDeviceCtrl(); int OpenDevice(); int ReadAndDisplay(); int CloseDevice(); int GetDeviceHandle() {return fd;} PSDLMODULE GetSdlModule(){return pSdlModule;} PTAVSDLYUVSURFACE GetSurface(){return pSurface;} struct VideoBuffer *GetVideoBuffer(){return video_buffers;} bool GetCapFlag() {return devam;} CDebugLog* GetDebugLog(){ return pLog;} protected: int ReadConfigure(const char *filename); private: QObject* parent; CDebugLog* pLog; pthread_t hThreadDisplayHandle; //渲染线程句柄 pthread_t hThreadRecordHandle; //录制线程句柄 bool devam; int fd; unsigned int buffer_count; char out_name[256]; PSDLMODULE pSdlModule; //SDL资源 PTAVSDLYUVSURFACE pSurface; //SDL资源 struct VideoBuffer* video_buffers; }
完整代码,请前往个人码云平台下载,地址是:https://git.oschina.net/icedbeer/LinuxMediaCapture编码
这是QT工程,请使用QtCreator打开工程文件.pro。.net
上面的这个工程这是简单的把画面进行本地显示,若是须要进行编码并传输的话,请参考另外一个工程(QT+Linux),源码下载地址是:https://git.oschina.net/icedbeer/LinuxMediaCaptureRtsp线程
此工程主要功能是:code
Linux下视频采集并编码H.264格式,同时封装为TS流;
开启RTST流服务器监控,接受客户端链接请求,并建立一个新的线程将TS流数据发送给Client。
此代码只是实验性的代码,每一个Client都会开启一个线程,因此若是须要大并发运行的话,请勿效仿。