ffmpeg解码RTSP/TCP视频流H.264(QT界面显示视频画面)

源码下载地址:  http://download.csdn.net/detail/liukang325/9489952

我用的ffmpeg版本为 ffmpeg-2.1.8.tar.bz2 
版本低了恐怕有些头文件和API找不到。 
Linux下解压后编译,Linux下编译很简单,我这里生成的动态库: 
./configure –enable-shared 
make 
就能找到各个so动态库文件。 
移动位置后,记得手动链接 一下:

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">ln -s libavcodec<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.so</span><span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">.55</span> libavcodec<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.so</span>
ln -s libavdevice<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.so</span><span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">.55</span> libavdevice<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.so</span>
ln -s libavfilter<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.so</span><span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">.3</span> libavfilter<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.so</span>
ln -s libavformat<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.so</span><span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">.55</span> libavformat<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.so</span>
ln -s libavutil<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.so</span><span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">.52</span> libavutil<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.so</span>
ln -s libswscale<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.so</span><span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">.2</span> libswscale<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.so</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>

QT pro文件中记得加入: 
INCLUDEPATH += ffmpeg/include 
// windows下用这几个 
win32: LIBS += ffmpeg/lib/libavcodec.dll.a ffmpeg/lib/libavfilter.dll.a ffmpeg/lib/libavformat.dll.a ffmpeg/lib/libswscale.dll.a ffmpeg/lib/libavutil.dll.a 
// Linux下用这几个 
LIBS += -lavcodec -lavdevice -lavfilter -lavformat -lavutil -lswscale -L./ffmpeg/so

我这里对外提供三个接口:

<code class="language-C++ hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">void</span> VideoStream<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;">::setUrl</span>(QString url)
{
    m_str_url <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> url;
}

<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">void</span> VideoStream<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;">::startStream</span>()
{
    videoStreamIndex<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=-</span><span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
    av_register_all();<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//注册库中所有可用的文件格式和解码器</span>
    avformat_network_init();<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//初始化网络流格式,使用RTSP网络流时必须先执行</span>
    pAVFormatContext <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> avformat_alloc_context();<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//申请一个AVFormatContext结构的内存,并进行简单初始化</span>
    pAVFrame<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span>av_frame_alloc();
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (this<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>Init())
    {
        m_timerPlay<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>start();
    }
}
<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">void</span> VideoStream<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;">::stopStream</span>()
{
    m_timerPlay<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>stop();

    avformat_free_context(pAVFormatContext);
    av_frame_free(<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">&</span>pAVFrame);
    sws_freeContext(pSwsContext);
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li></ul>

里面与ffmpeg解码相关的私有变量:

<code class="language-C++ hljs perl has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    QMutex mutex;
    AVPicture  pAVPicture;
    AVFormatContext <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">*pAVFormatContext</span>;
    AVCodecContext <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">*pAVCodecContext</span>;
    AVFrame <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">*pAVFrame</span>;
    SwsContext * pSwsContext;
    AVPacket pAVPacket;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

在QT里,用一个QLabel的对象来显示解码后的视频画面:

<code class="language-C++ hljs r has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">connect(this,SIGNAL(GetImage(QImage)),this,SLOT(SetImageSlots(QImage)));

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>
void VideoStream::SetImageSlots(const QImage &image)
{
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (image.height()><span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>){
        QPixmap pix = QPixmap::fromImage(image.scaled(m_i_w,m_i_h));
        m_label->setPixmap(pix);
    }
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul>

这里用的QTimer来进行一帧帧数据的解码,也可以用一个线程比如QThread来进行解码:

<code class="language-C++ hljs objectivec has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    m_timerPlay = new QTimer;
    m_timerPlay->setInterval(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>);
    connect(m_timerPlay,SIGNAL(timeout()),<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>,SLOT(playSlots()));

    m_i_frameFinished = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;

... 
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">bool</span> VideoStream::Init()
{
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(m_str_url<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.isEmpty</span>())
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">false</span>;
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//打开视频流</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> result=avformat_open_input(&pAVFormatContext, m_str_url<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.toStdString</span>()<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.c_str</span>(),<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">NULL</span>,<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">NULL</span>);
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (result<<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>){
        qDebug()<<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"打开视频流失败"</span>;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">false</span>;
    }

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//获取视频流信息</span>
    result=avformat_find_stream_info(pAVFormatContext,<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">NULL</span>);
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (result<<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>){
        qDebug()<<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"获取视频流信息失败"</span>;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">false</span>;
    }

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//获取视频流索引</span>
    videoStreamIndex = -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (uint i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; i < pAVFormatContext->nb_streams; i++) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (pAVFormatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
            videoStreamIndex = i;
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>;
        }
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (videoStreamIndex==-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>){
        qDebug()<<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"获取视频流索引失败"</span>;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">false</span>;
    }

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//获取视频流的分辨率大小</span>
    pAVCodecContext = pAVFormatContext->streams[videoStreamIndex]->codec;
    videoWidth=pAVCodecContext->width;
    videoHeight=pAVCodecContext->height;

    avpicture_alloc(&pAVPicture,PIX_FMT_RGB24,videoWidth,videoHeight);

    AVCodec *pAVCodec;

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//获取视频流解码器</span>
    pAVCodec = avcodec_find_decoder(pAVCodecContext->codec_id);
    pSwsContext = sws_getContext(videoWidth,videoHeight,PIX_FMT_YUV420P,videoWidth,videoHeight,PIX_FMT_RGB24,SWS_BICUBIC,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>);

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//打开对应解码器</span>
    result=avcodec_open2(pAVCodecContext,pAVCodec,<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">NULL</span>);
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (result<<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>){
        qDebug()<<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"打开解码器失败"</span>;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">false</span>;
    }

    qDebug()<<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"初始化视频流成功"</span>;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">true</span>;
}

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> VideoStream::playSlots()
{
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//一帧一帧读取视频</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (av_read_frame(pAVFormatContext, &pAVPacket) >= <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>){
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(pAVPacket<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.stream_index</span>==videoStreamIndex){
            qDebug()<<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"开始解码"</span><<QDateTime::currentDateTime()<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.toString</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"yyyy-MM-dd HH:mm:ss"</span>);
            avcodec_decode_video2(pAVCodecContext, pAVFrame, &m_i_frameFinished, &pAVPacket);
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (m_i_frameFinished){
                mutex<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.lock</span>();
                sws_scale(pSwsContext,(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> uint8_t* <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> *)pAVFrame->data,pAVFrame->linesize,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,videoHeight,pAVPicture<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.data</span>,pAVPicture<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.linesize</span>);
                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//发送获取一帧图像信号</span>
                QImage image(pAVPicture<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.data</span>[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>],videoWidth,videoHeight,QImage::Format_RGB888);
                emit GetImage(image);
                mutex<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.unlock</span>();
            }
        }
    }
    av_free_packet(&pAVPacket);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//释放资源,否则内存会一直上升</span>
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li><li style="box-sizing: border-box; padding: 0px 5px;">80</li><li style="box-sizing: border-box; padding: 0px 5px;">81</li><li style="box-sizing: border-box; padding: 0px 5px;">82</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li><li style="box-sizing: border-box; padding: 0px 5px;">80</li><li style="box-sizing: border-box; padding: 0px 5px;">81</li><li style="box-sizing: border-box; padding: 0px 5px;">82</li></ul>

备注: 
头文件包含及注意事项

<code class="hljs vala has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//必须加以下内容,否则编译不能通过,为了兼容C和C99标准</span>

<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#ifndef INT64_C</span>
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#define INT64_C</span>
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#define UINT64_C</span>
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#endif</span>

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//引入ffmpeg头文件</span>
extern <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"C"</span>
{
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <libavcodec/avcodec.h></span>
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <libavformat/avformat.h></span>
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <libavfilter/avfilter.h></span>
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <libswscale/swscale.h></span>
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <libavutil/frame.h></span>
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li></ul>

启发: 
setUrl(QString url); 
这里的url 一般情况下是一个RTSP流的播放地址,如rtsp://192.168.1.123:554/stream1 
但也可以是一个TCP流。 
我这边测试的是一个本地的socket流,设url地址为 http://127.0.0.1:5858 
可直接解码播放。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值