Gstreamer with multithread app (Qt)
Matias Hernandez Arellano
msdark at archlinux.cl
Tue Apr 12 14:34:10 PDT 2011
(me again)...
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 ...
but.. yet.. i have a problem..
Here some snippets of code
main.cpp
int main(int argc, char *argv[]){
QCoreApplication a(argc, argv);
QGst::init(&argc,&argv);
FrameBuffer *buffer = new FrameBuffer(3);
FrameBuffer *buffer2 = new FrameBuffer(3);
CaptureThread *capture = new CaptureThread(buffer,0);
ProcessingThread *processing = new ProcessingThread(buffer,buffer2,capture->getSourceWidth(),capture->getSourceHeight());
StreamThread *stream = new StreamThread(buffer2);
QCoreApplication::connect(processing,SIGNAL(newframe()),stream,SLOT(update()),Qt::QueuedConnection);
capture->start();
processing->start();
stream->start();
return a.exec();;
}
buffer and buffer2 are Circular Buffers that hold cv::Mat (OpenCV Images).
buffer hold cv::Mat obtained with CaptureThread. ProcessingThread pull images from here.
ProcessingThread push images into buffer2 and StreamThread pull images from here.
The cycle works good...
now the StreamThread
StreamThread::StreamThread(FrameBuffer *b, QObject *parent): ImageBuffer(b),QThread(parent){
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 "
" ! videoscale ! video/x-raw-rgb,width=320,height=240 "
" ! queue ! ffmpegcolorspace ! jpegenc ! queue "
" ! tcpserversink port=5000 ").arg(WIDTH,HEIGHT);
this->pipeline = QGst::Parse::launch(pipe_str).dynamicCast<QGst::Pipeline>();
QGlib::connect(this->pipeline->bus(),"message",this,&StreamThread::onBusMessage);
this->pipeline->bus()->addSignalWatch();
this->pipeline->setState(QGst::StatePlaying);
this->m_src.setElement(this->pipeline->getElementByName("appsrc"));
}
void StreamThread::onBusMessage(const QGst::MessagePtr &message){
switch (message->type()) {
case QGst::MessageEos:
quit();
break;
case QGst::MessageError:
qCritical() << message.staticCast<QGst::ErrorMessage>()->error();
break;
default:
break;
}
}
void StreamThread::run(){
this->exec();
}
//This SLOT fires up when ProcessingThread calls the newImage() SIGNAL ..
// this signal ocurrs when a new processing image was push into the buffer
void StreamThread::update(){
if(!this->m_src.element().isNull()){
this->pipeline->setState(QGst::StatePlaying);
QGst::BufferPtr buffer = QGst::Buffer::create(WIDTH*HEIGHT*3*sizeof(quint8*));
quint8 *data = buffer->data();
Mat frame = this->ImageBuffer->getFrame();
data = (quint8*)frame.data;
QGst::FlowReturn ret = this->m_src.pushBuffer(buffer);
if(ret!=QGst::FlowOk){
qDebug()<<"Error pushing data";
}
}
}
StreamThread::~StreamThread(){
this->pipeline->setState(QGst::StateNull);
}
When i run this app i don't get errors, just this warning (this doesn't show if i don't execute StreamThread)
QObject::startTimer: QTimer can only be used with threads started with QThread
So i suppose that QGstreamer use QTimer in some hidden part.
And... if i try to see the stream using
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
I get:
Estableciendo el conducto a PAUSA ?
El conducto est? PREPAR?NDOSE ?
But the pipeline never goes to PLAYING and nothing happen (i can't see the result)...
Any idea??
Thanks in advance
El 08-04-2011, a las 4:34, Tim-Philipp Müller escribió:
> On Thu, 2011-04-07 at 18:20 -0400, Matias Hernandez Arellano wrote:
>
>> It's possible to use gstreamer in a multithread app?
>
> Yes.
>
>> I have an Producer/Consumer application where i have two groups 1 with
>> 1 Producer and 1 Cosumer (Capture Video with Opencv/Process Image) and
>> other group equal ... Take de Process Frame / Stream the frames...
>
> Have you considered writing a simple source element that captures and
> processes the frame directly in a GStreamer pipeline?
>
>> The communication between threads works good, but know i need to add
>> the stream part .. I have another app where i test the functionality of
>> AppSrc and works!!! .. So i need to add this (Read from the Buffer
>> where i have images, push into AppSrc and Stream over network) in a
>> thread.
>>
>> is this possible??
>
> Why would this not be possible? Have you tried it and run into problems?
>
> GStreamer does (almost) all of its processing in dedicated threads of
> its own ("streaming threads"). You should be able to push buffers into
> appsrc from any application thread (they will get queued internally in
> appsrc and then processed in the GStreamer streaming thread).
>
> Cheers
> -Tim
>
>
> _______________________________________________
> gstreamer-devel mailing list
> gstreamer-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Matías Hernandez Arellano
Ingeniero de Software/Proyectos en VisionLabs S.A
CDA Archlinux-CL
www.msdark.archlinux.cl
More information about the gstreamer-devel
mailing list