<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>