FFmpeg decoding RTSP/TCP Video stream H.264 (QT interface Display video screen)

Source: Internet
Author: User
Tags mutex

SOURCE Download Address: http://download.csdn.net/detail/liukang325/9489952

the ffmpeg version I used is ffmpeg-2.1.8.tar.bz2.
The version is low I'm afraid some headers and APIs are not found.
After the Linux decompression after the compilation, Linux under the compiler is very simple, I generated the dynamic library here:
./configure–enable-shared
Make
You can find each of the so dynamic library files.
After moving the position, remember to manually link:

Ln-s libavcodec.so.55 libavcodec.so
ln-s libavdevice.so.55 libavdevice.so ln-s libavfilter.so.3
libavfilter.so
ln-s libavformat.so.55 libavformat.so
ln-s libavutil.so.52 libavutil.so
ln-s Libswscale.so.2 libswscale.so

QT Pro File Remember to add:
Includepath + + Ffmpeg/include
Windows use these several
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 with these few
LIBS + +-lavcodec-lavdevice-lavfilter-lavformat-lavutil-lswscale-l./ffmpeg/so

I am here to provide three external interfaces:

void Videostream::seturl (QString url)
{
    m_str_url = URL;
}

void Videostream::startstream ()
{
    videostreamindex=-1;
    Av_register_all ()///register all available file formats and decoders
    avformat_network_init ();//Initialize network streaming format, use RTSP network stream must first execute
    Pavformatcontext = Avformat_alloc_context ()//Request a AVFORMATCONTEXT structure of memory, and a simple initialization of
    pavframe=av_frame_alloc ();
    if (This->init ())
    {
        m_timerplay->start ();
    }
}
void Videostream::stopstream ()
{
    m_timerplay->stop ();

    Avformat_free_context (pavformatcontext);
    Av_frame_free (&pavframe);
    Sws_freecontext (Pswscontext);
}

inside the private variable associated with the FFmpeg decoding:

    Qmutex Mutex;
    Avpicture  pavpicture;
    Avformatcontext *pavformatcontext;
    Avcodeccontext *pavcodeccontext;
    Avframe *pavframe;
    Swscontext * PSWSCONTEXT;
    Avpacket Pavpacket;

in Qt, a Qlabel object is used to display the decoded video image:

Connect (this,signal (GetImage (QImage)), This,slot (Setimageslots (QImage));

...
void Videostream::setimageslots (const QImage &image)
{
    if (image.height () >0) {
        Qpixmap pix = Qpixmap::fromimage (image.scaled (M_i_w,m_i_h));
        M_label->setpixmap (PIX);
    }

here the Qtimer is used to decode a frame of data, or it can be decoded using a thread such as Qthread:

    M_timerplay = new Qtimer;
    M_timerplay->setinterval (10);

    Connect (m_timerplay,signal (timeout ()), This,slot (Playslots ()));

m_i_framefinished = 0;
    ... bool Videostream::init () {if (M_str_url.isempty ()) return false;
    Open the video stream int result=avformat_open_input (&pavformatcontext, M_str_url.tostdstring (). C_STR (), null,null);
        if (result<0) {qdebug () << "open video stream failed";
    return false;
    ///Get Video stream Information Result=avformat_find_stream_info (pavformatcontext,null);
        if (result<0) {qdebug () << "Get video stream information failed";
    return false;
    //Get the video stream index Videostreamindex =-1; for (UINT i = 0; i < pavformatcontext->nb_streams; i++) {if (pavformatcontext->streams[i]->codec->
            Codec_type = = Avmedia_type_video) {videostreamindex = i;
        Break
        } if (Videostreamindex==-1) {qdebug () << "Get video stream index failed";
    return false;
    //Get the resolution size of the video streamPavcodeccontext = pavformatcontext->streams[videostreamindex]->codec;
    videowidth=pavcodeccontext->width;

    videoheight=pavcodeccontext->height;

    Avpicture_alloc (&pavpicture,pix_fmt_rgb24,videowidth,videoheight);

    Avcodec *pavcodec;
    Gets the video stream decoder Pavcodec = Avcodec_find_decoder (pavcodeccontext->codec_id); Pswscontext = Sws_getcontext (videowidth,videoheight,pix_fmt_yuv420p,videowidth,videoheight,pix_fmt_rgb24,sws_

    bicubic,0,0,0);
    Open the corresponding decoder result=avcodec_open2 (pavcodeccontext,pavcodec,null);
        if (result<0) {qdebug () << "open decoder failed";
    return false;
    Qdebug () << "initialization of video stream success";
return true;
        } void Videostream::p layslots () {//frame-by-frame read video if (Av_read_frame (Pavformatcontext, &pavpacket) >= 0) { if (pavpacket.stream_index==videostreamindex) {qdebug () << "Start decoding" <<qdatetime::currentdatetime (). ToS
            Tring ("Yyyy-mm-dd HH:mm:ss"); Avcodec_decode_video2 (PavcodecconText, Pavframe, &m_i_framefinished, &pavpacket);
                if (m_i_framefinished) {mutex.lock (); Sws_scale (Pswscontext, (const uint8_t* const *) Pavframe->data,pavframe->linesize,0,videoheight,
                Pavpicture.data,pavpicture.linesize);
                Send to get a frame image signal QImage images (pavpicture.data[0],videowidth,videoheight,qimage::format_rgb888);
                Emit GetImage (image);
            Mutex.unlock (); }} av_free_packet (&pavpacket);/free resources, otherwise memory will keep rising}

Note:
header file inclusion and precautions

Must be under the content, otherwise the compilation cannot pass, in order to be compatible with the C and C99 standard

#ifndef int64_c
#define Int64_c
#define Uint64_c
#endif

// Introduce ffmpeg header file
extern "C"
{
#include <libavcodec/avcodec.h>
#include <libavformat/ avformat.h>
#include <libavfilter/avfilter.h>
#include <libswscale/swscale.h>
# Include <libavutil/frame.h>
}

inspiration:
SetUrl (QString URL);
Here the URL is generally a RTSP stream of the playback address, such as rtsp://192.168.1.123:554/stream1
But it can also be a TCP stream.
My test here is a local socket stream, set URL address for http://127.0.0.1:5858
Can be directly decoded playback.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.