LibVLC —— Qt下OpenGL播放rtsp/rtmp流,每帧图像基于OpenCv处理

本文

     本文介绍并附源码。介绍使用LibVLC读取网络媒体的rtmp流(CCTV6、湖南卫视),可切换rtmp流进行换台播放,同时将视频的每帧图像使用OpenCv进行色度简单处理,且将处理前后的图像分别使用Label、OpenGL显示。

视频地址

rtmp视频若卡顿则说明该服务网络较差,请稍等片刻。


简说

     RTMP是Real Time Messaging Protocol(实时消息传输协议)的首字母缩写。该协议基于TCP,是一个协议族,包括RTMP基本协议及RTMPT/RTMPS/RTMPE等多种变种。RTMP是一种设计用来进行实时数据通信的网络协议,主要用来在Flash/AIR平台和支持RTMP协议的流媒体/交互服务器之间进行音视频和数据通信。支持该协议的软件包括Adobe Media Server/Ultrant Media Server/red5等。RTMP与HTTP一样,都属于TCP/IP四层模型的应用层。

     RTSP是基于文本的协议,采用ISO10646字符集,使用UTF-8编码方案。行以CRLF中断,包括消息类型、消息头、消息体和消息长。但接收者本身可将CR和LF解释成行终止符。基于文本的协议使其以自描述方式增加可选参数更容易,接口中采用SDP作为描述语言。

     OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉和机器学习软件库,可以运行在Linux、Windows、Android和Mac OS操作系统上。 [1] 它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。

     Qt是一个1991年由Qt Company开发的跨平台C++图形用户界面应用程序开发框架。它既可以开发GUI程序,也可用于开发非GUI程序,比如控制台工具和服务器。Qt是面向对象的框架,使用特殊的代码生成扩展(称为元对象编译器(Meta Object Compiler, moc))以及一些宏,Qt很容易扩展,并且允许真正地组件编程。

关键代码
// 视频帧回调 - 生成Mat,传递到后续处理。
void LibVLC::libvlc_video_display_cb(void *opaque, void *)
{
	if (opaque)
	{
		LibVLC *libVlc = static_cast<LibVLC*>(opaque);
		if (libVlc)
		{
            Mutex.lock();
            cv::Mat Mat(static_cast<int>(libVlc->height),static_cast<int>(libVlc->width),CV_8UC4,libVlc->ImageBuf);
            Mutex.unlock();

            if(!Mat.empty())
            {
                libVlc->Image(Mat);
            }
		}
		libVlc = nullptr;
	}
	opaque = nullptr;
}


// 组成Mat的容器,在另外的线程处理并解析渲染
void MatList::Push(cv::Mat mat)
{
    if(!mat.empty())
    {
        Mutex.lock();
        matList.push_back(mat);
        Mutex.unlock();
    }
}
void MatList::run()
{
    ThreadFlag = true;
    while(ThreadFlag)
    {
        if(!matList.isEmpty())
        {
            Mutex.lock();
            cv::Mat Mat = matList.front();
            matList.pop_front();
            Mutex.unlock();
            
            if(!Mat.empty())
            {
                QImage Image = MatToQImage(Mat);
                if(!Image.isNull())
                {
                    ImageFrame(Image);
                }
                cv::Mat garyImage,dstImage;
                cv::cvtColor(Mat, garyImage, CV_BGR2GRAY);
                cv::applyColorMap(garyImage, dstImage, userColor);
                QImage ImageCV = MatToQImage(dstImage);
                if(!ImageCV.isNull())
                {
                    ImageFrameCV(ImageCV);
                }
            }
        }
    }
    ThreadFlag = false;
}

// qt的opengl主要是渲染
void OpenGLWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    QMatrix4x4 matrix;
    matrix.translate(0.0, 0.0, -5.0);
    program.enableAttributeArray(0);
    program.enableAttributeArray(1);
    program.setAttributeArray(0, vertices.constData());
    program.setAttributeArray(1, texCoords.constData());
    program.setUniformValue("texture", 0);
    texture->bind();
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    texture->release();
    texture->destroy();
    texture->create();
}
void OpenGLWidget::initializeGL()
{
    initializeOpenGLFunctions();
    glClearColor(0, 0, 0, 0);
    glEnable(GL_TEXTURE_2D);
    initTextures();
    initShaders();
}
void OpenGLWidget::resizeGL(int w, int h)
{
    qreal aspect = qreal(w) / qreal(h ? h : 1);
    const qreal zNear = 3.0, zFar = 7.0, fov = 45.0;
    projection.setToIdentity();
    projection.perspective(fov, static_cast<float>(aspect), zNear, zFar);
}


推荐LibVLC课程

     51cto - 基于Qt的LibVLC专业开发技术

     csdn学院 - 基于Qt的LibVLC专业开发技术

关注

笔者 - jxd

微信公众号搜索 “码农总动员” 或 微信扫描下方二维码,了解更多你不知道的XX,O(∩_∩)O

在这里插入图片描述

你可能感兴趣的:(LibVLC,opencv,libvlc)