<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><blockquote type="cite">Why on earth are you using so many threads here. Each queue starts a<br>new thread; additionally, appsrc starts a new thread too and maintains<br>an internal queue (making the second queue right after it completely<br>useless).</blockquote><div><br></div>The true.. i find/read some example and this work.... but i ever think about this, but "if work don't touch it" ... xD<div><blockquote type="cite"><blockquote type="cite"><br>&nbsp;&nbsp; this-&gt;pipeline = QGst::Parse::launch(pipe_str).dynamicCast&lt;QGst::Pipeline&gt;();<br></blockquote><blockquote type="cite">&nbsp;&nbsp; QGlib::connect(this-&gt;pipeline-&gt;bus(),"message",this,&amp;StreamThread::onBusMessage);<br></blockquote><blockquote type="cite">&nbsp;&nbsp; this-&gt;pipeline-&gt;bus()-&gt;addSignalWatch();</blockquote></blockquote></div><div><blockquote type="cite">This is where the QTimer starts, inside the signal watch. You can see<br>the code here [1] if you want. This timer expires every once in a<br>while and polls the GstBus for new messages. It's purpose is to<br>deliver messages to the main thread. I'm not sure why it shows that<br>error message though on the output... I'll check it, it doesn't seem<br>normal.</blockquote><div><br></div></div><div>So if i remove this (the connect and addSignalWatch) i don't use QTimer, but i can't get errors messages from the pipeline.</div><div><br></div><div><blockquote type="cite"><blockquote type="cite">void StreamThread::run(){<br></blockquote><blockquote type="cite">&nbsp;&nbsp; this-&gt;exec();<br></blockquote><blockquote type="cite">}</blockquote></blockquote><br></div><div>I modify this to run a infinite &nbsp;loop where i push data into appsrc.</div><div><br></div><div><blockquote type="cite">Why are you setting the pipeline *again* to playing state?</blockquote><br></div><div>A mistake ... this was for testing purpose ...</div><div><br></div><div><blockquote type="cite"><blockquote type="cite">&nbsp;&nbsp; &nbsp; &nbsp; Mat frame = this-&gt;ImageBuffer-&gt;getFrame();<br></blockquote><blockquote type="cite">&nbsp;&nbsp; &nbsp; &nbsp; data &nbsp; &nbsp; &nbsp;= (quint8*)frame.data;<br></blockquote><br>I hope you realize that this statement is void, it copies no actual<br>data. You need to copy the data with memcpy() instead.<br><br><blockquote type="cite">&nbsp;&nbsp; &nbsp; &nbsp; QGst::FlowReturn ret = this-&gt;m_src.pushBuffer(buffer);<br></blockquote></blockquote><br></div><div><br></div><div>I do this cause i asking in other thread about the use of QGst::Buffer and i get this:</div><div><br></div><div><font class="Apple-style-span" face="Helvetica-LightOblique">The QGst::Buffer class has a data() method which gives you a pointer<br>to the allocated buffer. You can use this pointer to write on the<br>buffer.<br><br>Btw, the above line of code looks terribly wrong to me... Here is how<br>you should use it:<br><br>QGst::BufferPtr b = QGst::Buffer::create(size);<br>quint8 *data = b-&gt;data();<br>//use the data pointer to write.</font></div><div><font class="Apple-style-span" face="Helvetica-LightOblique"><br></font></div><div>But i don't know if this is right.. so i try with memcpy. When i testing with C interface of Gstreamer i do this:</div><div><div>memcpy(GST_BUFFER_DATA(buffer),img_data,data_size);</div></div><div><br></div><div>even i use this GST_BUFFER_DATA(buffer) = img_data; GST_BUFFER_SIZE(buffer) = 640*480*3*sizeof(uchar*);</div><div><br></div><div>but now i don't know how copy the data into QGst::Buffer... this don't work ...</div><div>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><!--StartFragment--><span style=" color:#008000;">memcpy(data,frame.data,640*480*3*sizeof(uchar*))</span><!--EndFragment--></pre><div><br></div></div><div>Sorry if my questions are too silly but i'm a newbie with this..</div><div><br></div><div>Thanks a lot!!</div><div><br></div><div>&nbsp;</div><div><div><div>El 12-04-2011, a las 17:26, George Kiagiadakis escribió:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div>Hello,<br><br>On Wed, Apr 13, 2011 at 12:34 AM, Matias Hernandez Arellano<br>&lt;<a href="mailto:msdark@archlinux.cl">msdark@archlinux.cl</a>&gt; wrote:<br><blockquote type="cite">(me again)...<br></blockquote><blockquote type="cite">Well i try it a lot of things and finally i get a proof of concept of the final application semi functional using Qt+OpenCV+QGstreamer ...<br></blockquote><blockquote type="cite">but.. yet.. i have a problem..<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Here some snippets of code<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">main.cpp<br></blockquote><blockquote type="cite">&nbsp;int main(int argc, char *argv[]){<br></blockquote><blockquote type="cite">&nbsp; &nbsp;QCoreApplication a(argc, argv);<br></blockquote><blockquote type="cite">&nbsp; &nbsp;QGst::init(&amp;argc,&amp;argv);<br></blockquote><blockquote type="cite">&nbsp; &nbsp;FrameBuffer *buffer = new FrameBuffer(3);<br></blockquote><blockquote type="cite">&nbsp; &nbsp;FrameBuffer *buffer2 = new FrameBuffer(3);<br></blockquote><blockquote type="cite">&nbsp; &nbsp;CaptureThread *capture = new CaptureThread(buffer,0);<br></blockquote><blockquote type="cite">&nbsp; &nbsp;ProcessingThread *processing = new ProcessingThread(buffer,buffer2,capture-&gt;getSourceWidth(),capture-&gt;getSourceHeight());<br></blockquote><blockquote type="cite">&nbsp; &nbsp;StreamThread &nbsp; &nbsp; *stream &nbsp; &nbsp; = new StreamThread(buffer2);<br></blockquote><blockquote type="cite">&nbsp; &nbsp;QCoreApplication::connect(processing,SIGNAL(newframe()),stream,SLOT(update()),Qt::QueuedConnection);<br></blockquote><blockquote type="cite">&nbsp; &nbsp;capture-&gt;start();<br></blockquote><blockquote type="cite">&nbsp; &nbsp;processing-&gt;start();<br></blockquote><blockquote type="cite">&nbsp; &nbsp;stream-&gt;start();<br></blockquote><blockquote type="cite">&nbsp; &nbsp;return a.exec();;<br></blockquote><blockquote type="cite">}<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">buffer and buffer2 are Circular Buffers that hold cv::Mat (OpenCV Images).<br></blockquote><blockquote type="cite">buffer hold cv::Mat obtained with CaptureThread. ProcessingThread pull images from here.<br></blockquote><blockquote type="cite">ProcessingThread push images into buffer2 and StreamThread pull images from here.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">The cycle works good...<br></blockquote><blockquote type="cite">now the StreamThread<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">&nbsp;StreamThread::StreamThread(FrameBuffer *b, QObject *parent): ImageBuffer(b),QThread(parent){<br></blockquote><blockquote type="cite">&nbsp; &nbsp;QString pipe_str = QString("appsrc name=\"appsrc\" caps=\"video/x-raw-rgb,width=320,height=240\" ! queue ! videoparse format=14 width=%1 height=%1 ! videorate "<br></blockquote><blockquote type="cite">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; " ! videoscale ! video/x-raw-rgb,width=320,height=240 "<br></blockquote><blockquote type="cite">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; " ! queue ! ffmpegcolorspace ! jpegenc &nbsp;! queue &nbsp;"<br></blockquote><blockquote type="cite">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; " ! tcpserversink port=5000 &nbsp;").arg(WIDTH,HEIGHT);<br></blockquote><br>Why on earth are you using so many threads here. Each queue starts a<br>new thread; additionally, appsrc starts a new thread too and maintains<br>an internal queue (making the second queue right after it completely<br>useless).<br><br><blockquote type="cite">&nbsp; &nbsp;this-&gt;pipeline = QGst::Parse::launch(pipe_str).dynamicCast&lt;QGst::Pipeline&gt;();<br></blockquote><blockquote type="cite">&nbsp; &nbsp;QGlib::connect(this-&gt;pipeline-&gt;bus(),"message",this,&amp;StreamThread::onBusMessage);<br></blockquote><blockquote type="cite">&nbsp; &nbsp;this-&gt;pipeline-&gt;bus()-&gt;addSignalWatch();<br></blockquote><br>This is where the QTimer starts, inside the signal watch. You can see<br>the code here [1] if you want. This timer expires every once in a<br>while and polls the GstBus for new messages. It's purpose is to<br>deliver messages to the main thread. I'm not sure why it shows that<br>error message though on the output... I'll check it, it doesn't seem<br>normal.<br><br><blockquote type="cite">&nbsp; &nbsp;this-&gt;pipeline-&gt;setState(QGst::StatePlaying);<br></blockquote><blockquote type="cite">&nbsp; &nbsp;this-&gt;m_src.setElement(this-&gt;pipeline-&gt;getElementByName("appsrc"));<br></blockquote><blockquote type="cite">}<br></blockquote><blockquote type="cite">void StreamThread::onBusMessage(const QGst::MessagePtr &amp;message){<br></blockquote><blockquote type="cite">&nbsp; &nbsp;switch (message-&gt;type()) {<br></blockquote><blockquote type="cite">&nbsp; &nbsp;case QGst::MessageEos:<br></blockquote><blockquote type="cite">&nbsp; &nbsp; &nbsp; &nbsp;quit();<br></blockquote><blockquote type="cite">&nbsp; &nbsp; &nbsp; &nbsp;break;<br></blockquote><blockquote type="cite">&nbsp; &nbsp;case QGst::MessageError:<br></blockquote><blockquote type="cite">&nbsp; &nbsp; &nbsp; &nbsp;qCritical() &lt;&lt; message.staticCast&lt;QGst::ErrorMessage&gt;()-&gt;error();<br></blockquote><blockquote type="cite">&nbsp; &nbsp; &nbsp; &nbsp;break;<br></blockquote><blockquote type="cite">&nbsp; &nbsp;default:<br></blockquote><blockquote type="cite">&nbsp; &nbsp; &nbsp; &nbsp;break;<br></blockquote><blockquote type="cite">&nbsp; &nbsp;}<br></blockquote><blockquote type="cite">}<br></blockquote><blockquote type="cite">void StreamThread::run(){<br></blockquote><blockquote type="cite">&nbsp; &nbsp;this-&gt;exec();<br></blockquote><blockquote type="cite">}<br></blockquote><br>I wonder if you understand that this event loop here is completely<br>useless. The update() slot will NEVER be called in this thread,<br>because this QThread object, being a QObject itself, lives in the main<br>thread and all of its slots are called in the context of the main<br>thread. So, the whole "StreamThread" could actually be a QObject<br>instead of a QThread and still do the same job. Let me add that since<br>appsrc itself handles queuing, you don't really need this extra thread<br>here.<br><br><blockquote type="cite">//This SLOT fires up when ProcessingThread calls the newImage() SIGNAL ..<br></blockquote><blockquote type="cite">// this signal ocurrs when a new processing image was push into the buffer<br></blockquote><blockquote type="cite">void StreamThread::update(){<br></blockquote><blockquote type="cite">&nbsp; &nbsp;if(!this-&gt;m_src.element().isNull()){<br></blockquote><blockquote type="cite">&nbsp; &nbsp; &nbsp; &nbsp;this-&gt;pipeline-&gt;setState(QGst::StatePlaying);<br></blockquote><br>Why are you setting the pipeline *again* to playing state?<br><br><blockquote type="cite">&nbsp; &nbsp; &nbsp; &nbsp;QGst::BufferPtr buffer = QGst::Buffer::create(WIDTH*HEIGHT*3*sizeof(quint8*));<br></blockquote><blockquote type="cite">&nbsp; &nbsp; &nbsp; &nbsp;quint8 *data = buffer-&gt;data();<br></blockquote><blockquote type="cite">&nbsp; &nbsp; &nbsp; &nbsp;Mat frame = this-&gt;ImageBuffer-&gt;getFrame();<br></blockquote><blockquote type="cite">&nbsp; &nbsp; &nbsp; &nbsp;data &nbsp; &nbsp; &nbsp;= (quint8*)frame.data;<br></blockquote><br>I hope you realize that this statement is void, it copies no actual<br>data. You need to copy the data with memcpy() instead.<br><br><blockquote type="cite">&nbsp; &nbsp; &nbsp; &nbsp;QGst::FlowReturn ret = this-&gt;m_src.pushBuffer(buffer);<br></blockquote><br>...and effectively here you are pushing an empty buffer. No wonder why<br>the other end doesn't receive anything.<br><br><blockquote type="cite">&nbsp; &nbsp; &nbsp; &nbsp;if(ret!=QGst::FlowOk){<br></blockquote><blockquote type="cite">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;qDebug()&lt;&lt;"Error pushing data";<br></blockquote><blockquote type="cite">&nbsp; &nbsp; &nbsp; &nbsp;}<br></blockquote><blockquote type="cite">&nbsp; &nbsp;}<br></blockquote><blockquote type="cite">}<br></blockquote><blockquote type="cite">StreamThread::~StreamThread(){<br></blockquote><blockquote type="cite">&nbsp; &nbsp;this-&gt;pipeline-&gt;setState(QGst::StateNull);<br></blockquote><blockquote type="cite">}<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">When i run this app i don't get errors, just this warning (this doesn't show if i don't execute StreamThread)<br></blockquote><blockquote type="cite">QObject::startTimer: QTimer can only be used with threads started with QThread<br></blockquote><blockquote type="cite">So i suppose that QGstreamer use QTimer in some hidden part.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">And... if i try to see the stream using<br></blockquote><blockquote type="cite">gst-launch tcpclientsrc host=127.0.0.1 port=5000 ! &nbsp;jpegdec ! queue ! video/x-raw-rgb,width=320,height=240 ! ffmpegcolorspace ! queue ! glimagesink sync=false<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">I get:<br></blockquote><blockquote type="cite">Estableciendo el conducto a PAUSA ?<br></blockquote><blockquote type="cite">El conducto est? PREPAR?NDOSE ?<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">But the pipeline never goes to PLAYING and nothing happen (i can't see the result)...<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Any idea??<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Thanks in advance<br></blockquote><br>Regards,<br>George<br><br>[1]. <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/qt-gstreamer/html/bus_8cpp_source.html">http://gstreamer.freedesktop.org/data/doc/gstreamer/head/qt-gstreamer/html/bus_8cpp_source.html</a><br>_______________________________________________<br>gstreamer-devel mailing list<br><a href="mailto:gstreamer-devel@lists.freedesktop.org">gstreamer-devel@lists.freedesktop.org</a><br>http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel<br></div></blockquote></div><br><div apple-content-edited="true">Matías Hernandez Arellano<br>Ingeniero de Software/Proyectos en VisionLabs S.A<br>CDA Archlinux-CL<br><a href="http://www.msdark.archlinux.cl">www.msdark.archlinux.cl</a><br><br><br><br></div><br></div></body></html>