<div dir="ltr"><div><div><div><div>Hey guys,<br><br></div>I am just starting to use QGst with Qt and C++ on Linux.<br><br></div>I started off of the recorder.cpp example and tried to show a video from RTSP into a frame of that is embedded into groupbox on the dialog.<br>
<br></div>However the frame turns black after onRtpBinPadAdded is called and stays black forever. But I can see there is a lot of network traffic going on but the video is just black.<br><br><br></div><div>If someone can help, heres the code:<br>
</div><br><br><br>#include "recorder.h"<br><br><br>#include <QtCore/QDir><br>#include <QtGui/QApplication><br>#include <QtGui/QDialog><br>#include <QtGui/QMessageBox><br>#include <QtGui/QVBoxLayout><br>
<br><br>#include <QGlib/Error><br>#include <QGlib/Connect><br>#include <QGst/Init><br>#include <QGst/ElementFactory><br>#include <QGst/ChildProxy><br>#include <QGst/PropertyProbe><br>#include <QGst/Pipeline><br>
#include <QGst/Pad><br>#include <QGst/Event><br>#include <QGst/Message><br>#include <QGst/Bus><br><br>Recorder::Recorder(QWidget *parent)<br>    : QDialog(parent)<br>{<br>    m_ui.setupUi(this);<br>
}<br><br>void Recorder::start()<br>{<br>    m_pipeline = QGst::Pipeline::create( "Video Player");<br><br>    QGst::ElementPtr src    = QGst::ElementFactory::make("rtspsrc", "src");<br>    QGst::ElementPtr demux  = QGst::ElementFactory::make("rtpmp4vdepay", "depay");<br>
    QGst::ElementPtr decode = QGst::ElementFactory::make("ffdec_mpeg4", "decode");<br>    QGst::ElementPtr colour = QGst::ElementFactory::make("ffmpegcolorspace",  "colour");<br>    QGst::ElementPtr sink   = QGst::ElementFactory::make("autovideosink", "sink"); //qwidgetvideosink<br>
<br>    if ( !src || !decode || !src || !demux || !sink || !colour) {<br>        QMessageBox::critical(this, tr("Error"), tr("One or more elements could not be created. "<br>                              "Verify that you have all the necessary element plugins installed."));<br>
        return;<br>    }<br><br>    src->setProperty( "location", "rtsp://<a href="http://192.168.1.11:8554/2.sdp">192.168.1.11:8554/2.sdp</a>");<br>    src->setProperty( "latency", 0);<br>
<br>    sink->setProperty( "window-height", 200);<br>    sink->setProperty( "window-width", 200);<br><br>    m_pipeline->add( src, demux, decode, colour, sink);<br>    src->linkMany(demux, decode, colour, sink);<br>
<br>    m_pVideoWidget = new QGst::Ui::VideoWidget( m_ui.frame);<br>    m_pVideoWidget->adjustSize();<br>    sink->unparent();<br>    m_pVideoWidget->setVideoSink( sink);<br>    m_pVideoWidget->show();<br><br>
<br>    //watch for the receiving side src pads<br>    QGlib::connect(src, "pad-added", this, &Recorder::onRtpBinPadAdded);<br><br>    //connect the bus<br>    m_pipeline->bus()->addSignalWatch();<br>    QGlib::connect(m_pipeline->bus(), "message", this, &Recorder::onBusMessage);<br>
<br>    QVBoxLayout* layout = new QVBoxLayout;<br><br>    layout->addWidget( m_pVideoWidget);<br><br>    m_ui.frame->setLayout( layout);<br><br>    //go!<br>    m_pipeline->setState(QGst::StatePlaying);<br>    m_ui.startStopButton->setText(tr("Stop recording"));<br>
}<br><br>void Recorder::onRtpBinPadAdded(const QGst::PadPtr & pad)<br>{<br>    QGst::ElementPtr bin;<br>    QString str;<br><br>    str = pad->caps()->internalStructure(0)->value("media").toString();<br>
<br><br>    try {<br>        if (pad->caps()->internalStructure(0)->value("media").toString() == QLatin1String("audio"))<br>        {<br>            bin = QGst::Bin::fromDescription(<br>                "rtpspeexdepay ! speexdec ! audioconvert ! autoaudiosink"<br>
            );<br>        }<br>        else<br>        {<br>            bin = QGst::Bin::fromDescription(<br>                "rtph264depay ! ffdec_h264 ! ffmpegcolorspace ! autovideosink"<br>            );<br>        }<br>
    } catch (const QGlib::Error & error) {<br>        qCritical() << error;<br>        qFatal("One ore more required elements are missing. Aborting...");<br>    }<br><br>    bool r = bin.isNull();<br><br>
    m_pipeline->add(bin);<br>    bin->syncStateWithParent();<br>    pad->link(bin->getStaticPad("sink"));<br>}<br><br><br><br>void Recorder::stop()<br>{<br>    //stop recording<br>    m_pipeline->setState(QGst::StateNull);<br>
<br>    //clear the pointer, destroying the pipeline as its reference count drops to zero.<br>    m_pipeline.clear();<br><br>    //restore the button's text<br>    m_ui.startStopButton->setText(tr("Start recording"));<br>
}<br><br>void Recorder::onBusMessage(const QGst::MessagePtr & message)<br>{<br>    switch (message->type())<br>    {<br>    case QGst::MessageEos:<br>        //got end-of-stream - stop the pipeline<br>        stop();<br>
        break;<br>    case QGst::MessageError:<br>        //check if the pipeline exists before destroying it,<br>        //as we might get multiple error messages<br>        if (m_pipeline)<br>        {<br>            stop();<br>
        }<br>        QMessageBox::critical(this, tr("Pipeline Error"),<br>                              message.staticCast<QGst::ErrorMessage>()->error().message());<br>        break;<br>    default:<br>
        break;<br>    }<br>}<br><br>void Recorder::on_startStopButton_clicked()<br>{<br>    if (m_pipeline)<br>    { //pipeline exists - destroy it<br>        //send an end-of-stream event to flush metadata and cause an EosMessage to be delivered<br>
        m_pipeline->sendEvent(QGst::EosEvent::create());<br>    }<br>    else<br>    { //pipeline doesn't exist - start a new one<br>        start();<br>    }<br>}<br><br></div>