Does your StreamThread inherits from QThread? If not you have the answer.<br><br>I think generally you have a problem here because you are using singal/slot mechanism which was designed for GUI not for normal (fast) operation. I could not find it in the documentation (somebody please correct me if wrong) but my guess is that signal/slot mechanism is using qtimer.<br>
Excerpt from the documentation: "In general, emitting a signal that is connected to some slots, is
approximately ten times slower than calling the receivers directly, with
non-virtual function calls." From here <a href="http://doc.qt.nokia.com/latest/signalsandslots.html">http://doc.qt.nokia.com/latest/signalsandslots.html</a>.<br><br>So if you want some real-time processing to happen and you have a producer-consumer scenario I would suggest to use semaphores (QSemaphore ) for that.<br>
<br>Otherways (if qtimer is involved in multithreading) you will get performance issues sooner or later. <br>Checked on my own skin.<br><br><br><br>If not I guess it should <br><br><div class="gmail_quote">2011/4/13 Matias Hernandez Arellano <span dir="ltr"><<a href="mailto:msdark@archlinux.cl">msdark@archlinux.cl</a>></span><br>
<blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">(me again)...<br>
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>
but.. yet.. i have a problem..<br>
<br>
Here some snippets of code<br>
<br>
main.cpp<br>
int main(int argc, char *argv[]){<br>
QCoreApplication a(argc, argv);<br>
QGst::init(&argc,&argv);<br>
FrameBuffer *buffer = new FrameBuffer(3);<br>
FrameBuffer *buffer2 = new FrameBuffer(3);<br>
CaptureThread *capture = new CaptureThread(buffer,0);<br>
ProcessingThread *processing = new ProcessingThread(buffer,buffer2,capture->getSourceWidth(),capture->getSourceHeight());<br>
StreamThread *stream = new StreamThread(buffer2);<br>
QCoreApplication::connect(processing,SIGNAL(newframe()),stream,SLOT(update()),Qt::QueuedConnection);<br>
capture->start();<br>
processing->start();<br>
stream->start();<br>
return a.exec();;<br>
}<br>
<br>
buffer and buffer2 are Circular Buffers that hold cv::Mat (OpenCV Images).<br>
buffer hold cv::Mat obtained with CaptureThread. ProcessingThread pull images from here.<br>
ProcessingThread push images into buffer2 and StreamThread pull images from here.<br>
<br>
The cycle works good...<br>
now the StreamThread<br>
<br>
StreamThread::StreamThread(FrameBuffer *b, QObject *parent): ImageBuffer(b),QThread(parent){<br>
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>
" ! videoscale ! video/x-raw-rgb,width=320,height=240 "<br>
" ! queue ! ffmpegcolorspace ! jpegenc ! queue "<br>
" ! tcpserversink port=5000 ").arg(WIDTH,HEIGHT);<br>
this->pipeline = QGst::Parse::launch(pipe_str).dynamicCast<QGst::Pipeline>();<br>
QGlib::connect(this->pipeline->bus(),"message",this,&StreamThread::onBusMessage);<br>
this->pipeline->bus()->addSignalWatch();<br>
this->pipeline->setState(QGst::StatePlaying);<br>
this->m_src.setElement(this->pipeline->getElementByName("appsrc"));<br>
}<br>
void StreamThread::onBusMessage(const QGst::MessagePtr &message){<br>
switch (message->type()) {<br>
case QGst::MessageEos:<br>
quit();<br>
break;<br>
case QGst::MessageError:<br>
qCritical() << message.staticCast<QGst::ErrorMessage>()->error();<br>
break;<br>
default:<br>
break;<br>
}<br>
}<br>
void StreamThread::run(){<br>
this->exec();<br>
}<br>
<br>
//This SLOT fires up when ProcessingThread calls the newImage() SIGNAL ..<br>
// this signal ocurrs when a new processing image was push into the buffer<br>
void StreamThread::update(){<br>
if(!this->m_src.element().isNull()){<br>
this->pipeline->setState(QGst::StatePlaying);<br>
QGst::BufferPtr buffer = QGst::Buffer::create(WIDTH*HEIGHT*3*sizeof(quint8*));<br>
quint8 *data = buffer->data();<br>
Mat frame = this->ImageBuffer->getFrame();<br>
data = (quint8*)frame.data;<br>
QGst::FlowReturn ret = this->m_src.pushBuffer(buffer);<br>
if(ret!=QGst::FlowOk){<br>
qDebug()<<"Error pushing data";<br>
}<br>
}<br>
}<br>
StreamThread::~StreamThread(){<br>
this->pipeline->setState(QGst::StateNull);<br>
}<br>
<br>
When i run this app i don't get errors, just this warning (this doesn't show if i don't execute StreamThread)<br>
<div class="im">QObject::startTimer: QTimer can only be used with threads started with QThread<br>
</div>So i suppose that QGstreamer use QTimer in some hidden part.<br>
<br>
And... if i try to see the stream using<br>
gst-launch tcpclientsrc host=127.0.0.1 port=5000 ! jpegdec ! queue ! video/x-raw-rgb,width=320,height=240 ! ffmpegcolorspace ! queue ! glimagesink sync=false<br>
<br>
I get:<br>
Estableciendo el conducto a PAUSA ?<br>
El conducto est? PREPAR?NDOSE ?<br>
<br>
But the pipeline never goes to PLAYING and nothing happen (i can't see the result)...<br>
<br>
Any idea??<br>
<br>
Thanks in advance<br>
<div class="im"><br>
<br>
El 08-04-2011, a las 4:34, Tim-Philipp Müller escribió:<br>
<br>
</div><div><div></div><div class="h5">> On Thu, 2011-04-07 at 18:20 -0400, Matias Hernandez Arellano wrote:<br>
><br>
>> It's possible to use gstreamer in a multithread app?<br>
><br>
> Yes.<br>
><br>
>> I have an Producer/Consumer application where i have two groups 1 with<br>
>> 1 Producer and 1 Cosumer (Capture Video with Opencv/Process Image) and<br>
>> other group equal ... Take de Process Frame / Stream the frames...<br>
><br>
> Have you considered writing a simple source element that captures and<br>
> processes the frame directly in a GStreamer pipeline?<br>
><br>
>> The communication between threads works good, but know i need to add<br>
>> the stream part .. I have another app where i test the functionality of<br>
>> AppSrc and works!!! .. So i need to add this (Read from the Buffer<br>
>> where i have images, push into AppSrc and Stream over network) in a<br>
>> thread.<br>
>><br>
>> is this possible??<br>
><br>
> Why would this not be possible? Have you tried it and run into problems?<br>
><br>
> GStreamer does (almost) all of its processing in dedicated threads of<br>
> its own ("streaming threads"). You should be able to push buffers into<br>
> appsrc from any application thread (they will get queued internally in<br>
> appsrc and then processed in the GStreamer streaming thread).<br>
><br>
> Cheers<br>
> -Tim<br>
><br>
><br>
> _______________________________________________<br>
> gstreamer-devel mailing list<br>
> <a href="mailto:gstreamer-devel@lists.freedesktop.org">gstreamer-devel@lists.freedesktop.org</a><br>
> <a href="http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel" target="_blank">http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel</a><br>
<br>
</div></div><div class="im">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" target="_blank">www.msdark.archlinux.cl</a><br>
<br>
<br>
<br>
<br>
_______________________________________________<br>
</div><div><div></div><div class="h5">gstreamer-devel mailing list<br>
<a href="mailto:gstreamer-devel@lists.freedesktop.org">gstreamer-devel@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel" target="_blank">http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel</a><br>
</div></div></blockquote></div><br><br clear="all"><br>-- <br>Your Sincerely<br>Michal Joachimiak<br>