Gstreamer playbin integration in QT application

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Gstreamer playbin integration in QT application

arnaud tonda
Hi everybody,

I don't know if it's the right place but i try.

after writing a C standalone code using playbin2 gstreamer elements, i started integration on a QT c++ source Application.

i have a lot of windows and one is dedicated to video rendering.
I want to use gstxoverlay.

firstly i tried to use the gstreamer sample code shown on gstxoverlay Api.

with videotestsrc and xvimagesrc :

######################################
  GstElement *pipeline = gst_pipeline_new ("xvoverlay");

GstElement *src = gst_element_factory_make ("videotestsrc", NULL);

GstElement *sink = gst_element_factory_make ("xvimagesink", NULL);

gst_bin_add_many (GST_BIN (pipeline), src, sink, NULL);

gst_element_link (src, sink);

        gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(sink), windowId );

bus = gst_pipeline_get_bus (GST_PIPELINE(pipeline));

gst_bus_add_watch(bus, (GstBusFunc)bus_callback, NULL);

gst_object_unref(bus);

gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_PLAYING);
######################################

here i have what i expected, videotest is displayed on the right window without problem.

secondly i tried to use playbin2 and the problem is there.

i get the video-sink element of playbin2 but before pipeline is playing video-sink is null.
if i overload video-sink with a xvimagesink element video-sink is not null, and i can use gst_x_overlay_set_xwindow_id on this.
but it result on a fullscreen video.... i think something is wrong but i don't understand what....

######################################

playbin = gst_element_factory_make("playbin2","playbin");

GstElement *videosink = gst_element_factory_make("xvimagesink", "videosink");

g_object_set(G_OBJECT(playbin), "video-sink", videosink, NULL);

g_object_set(G_OBJECT(playbin),"uri","file:///root/test.mkv",NULL);
g_object_set(G_OBJECT(playbin),"flags",0x00000013,NULL);

//2 - We add a message Handler
bus = gst_pipeline_get_bus (GST_PIPELINE(playbin));
gst_bus_add_watch(bus, (GstBusFunc)bus_callback, NULL);
gst_object_unref(bus);

g_signal_connect(G_OBJECT(playbin),"video-changed",G_CALLBACK(on_video_changed),this);
g_signal_connect(G_OBJECT(playbin),"pad-added",G_CALLBACK(on_pad_added),this);
g_signal_connect(G_OBJECT(playbin),"deep-notify::source",(GCallback)on_video_sink_notify,this);

        GstElement *videosink2 = 0;
        g_object_get(playbin, "video-sink", &videosink2, NULL);
    
    if (videosink2 && GST_IS_X_OVERLAY(videosink2) )
    {
     cout << "videosink and overlay are OK" << endl;
        gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(videosink), windowId );
    }
    else
    {
     if(!videosink)
     cout << "videosink is NULL" << endl;
     else
     cout << "overlay is NULL" << endl;
    }

gst_element_set_state(GST_ELEMENT(playbin), GST_STATE_PLAYING);

######################################

any idea? what is wrong?

One other thing :

the gst_bus_add_watch did not work. the attached callback is never called.
Has it work on the standalone C source code i think it is due to the QT event loop but i can't confirm.
am i right?

Best regards

--
Arnaud Tonda


_______________________________________________
gstreamer-devel mailing list
[hidden email]
http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Gstreamer playbin integration in QT application

arnaud tonda
Some news on the subject.

i have made some investigation and tested to create my own pipeline without playbin2.

the pipeline looks like this :

filesrc ==> matroskademux ==> fluvadec ==> fluvasink

and the code is below :

############################################
GstElement *pipeline = gst_pipeline_new("pipeline");
GstElement *videoSrc = gst_element_factory_make("filesrc","filesrc");
GstElement *demux = gst_element_factory_make("matroskademux","demux");
GstElement *dec = gst_element_factory_make("fluvadec","dec");
GstElement *sink = gst_element_factory_make("fluvasink","sink");

g_object_set(G_OBJECT(videoSrc),"location","/root/test.mkv",NULL);

gst_bin_add_many(GST_BIN (pipeline), videoSrc, demux,dec,sink, NULL);

gst_element_link(videoSrc,demux);
gst_element_link(dec,sink);

g_signal_connect(G_OBJECT(demux),"pad-added",G_CALLBACK(on_pad_added),dec);

        gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(sink), windowIdStatic );

        gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_PLAYING);
############################################

in precision, i link demux and dec on a on_pad_add callback.

with this code there no problem and the result is has expected, the video is playing on the dedicated window.

it seems that my problem is with the playbin2 element.

any idea?

2011/7/22 arnaud tonda <[hidden email]>
Hi everybody,

I don't know if it's the right place but i try.

after writing a C standalone code using playbin2 gstreamer elements, i started integration on a QT c++ source Application.

i have a lot of windows and one is dedicated to video rendering.
I want to use gstxoverlay.

firstly i tried to use the gstreamer sample code shown on gstxoverlay Api.

with videotestsrc and xvimagesrc :

######################################
  GstElement *pipeline = gst_pipeline_new ("xvoverlay");

GstElement *src = gst_element_factory_make ("videotestsrc", NULL);

GstElement *sink = gst_element_factory_make ("xvimagesink", NULL);

gst_bin_add_many (GST_BIN (pipeline), src, sink, NULL);

gst_element_link (src, sink);

        gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(sink), windowId );

bus = gst_pipeline_get_bus (GST_PIPELINE(pipeline));

gst_bus_add_watch(bus, (GstBusFunc)bus_callback, NULL);

gst_object_unref(bus);

gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_PLAYING);
######################################

here i have what i expected, videotest is displayed on the right window without problem.

secondly i tried to use playbin2 and the problem is there.

i get the video-sink element of playbin2 but before pipeline is playing video-sink is null.
if i overload video-sink with a xvimagesink element video-sink is not null, and i can use gst_x_overlay_set_xwindow_id on this.
but it result on a fullscreen video.... i think something is wrong but i don't understand what....

######################################

playbin = gst_element_factory_make("playbin2","playbin");

GstElement *videosink = gst_element_factory_make("xvimagesink", "videosink");

g_object_set(G_OBJECT(playbin), "video-sink", videosink, NULL);

g_object_set(G_OBJECT(playbin),"uri","file:///root/test.mkv",NULL);
g_object_set(G_OBJECT(playbin),"flags",0x00000013,NULL);

//2 - We add a message Handler
bus = gst_pipeline_get_bus (GST_PIPELINE(playbin));
gst_bus_add_watch(bus, (GstBusFunc)bus_callback, NULL);
gst_object_unref(bus);

g_signal_connect(G_OBJECT(playbin),"video-changed",G_CALLBACK(on_video_changed),this);
g_signal_connect(G_OBJECT(playbin),"pad-added",G_CALLBACK(on_pad_added),this);
g_signal_connect(G_OBJECT(playbin),"deep-notify::source",(GCallback)on_video_sink_notify,this);

        GstElement *videosink2 = 0;
        g_object_get(playbin, "video-sink", &videosink2, NULL);
    
    if (videosink2 && GST_IS_X_OVERLAY(videosink2) )
    {
     cout << "videosink and overlay are OK" << endl;
        gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(videosink), windowId );
    }
    else
    {
     if(!videosink)
     cout << "videosink is NULL" << endl;
     else
     cout << "overlay is NULL" << endl;
    }

gst_element_set_state(GST_ELEMENT(playbin), GST_STATE_PLAYING);

######################################

any idea? what is wrong?

One other thing :

the gst_bus_add_watch did not work. the attached callback is never called.
Has it work on the standalone C source code i think it is due to the QT event loop but i can't confirm.
am i right?

Best regards

--
Arnaud Tonda



_______________________________________________
gstreamer-devel mailing list
[hidden email]
http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Gstreamer playbin integration in QT application

George Kiagiadakis
In reply to this post by arnaud tonda
On Fri, Jul 22, 2011 at 3:49 PM, arnaud tonda <[hidden email]> wrote:
> secondly i tried to use playbin2 and the problem is there.
> i get the video-sink element of playbin2 but before pipeline is playing
> video-sink is null.

This is correct, because the video sink is created when the playbin
switches to the PAUSED state, and it is created in another thread.
To make this work, you need to connect to the bus sync-message signal,
wait for the "prepare-xwindow-id" message and set the window ID from
there. Of course you need to save the window id earlier because you
can't call QWidget::winId() from another thread.

See http://cgit.freedesktop.org/gstreamer/qt-gstreamer/tree/src/QGst/Ui/videowidget.cpp#n139
for an example.

> if i overload video-sink with a xvimagesink element video-sink is not null,
> and i can use gst_x_overlay_set_xwindow_id on this.
> but it result on a fullscreen video.... i think something is wrong but i
> don't understand what....

Maybe something is not correctly in sync. Try calling
QApplication::syncX() before setting the window id.

> the gst_bus_add_watch did not work. the attached callback is never called.
> Has it work on the standalone C source code i think it is due to the QT
> event loop but i can't confirm.
> am i right?

It depends. On Unix/X11, Qt can optionally use the Glib event loop,
which achieves proper integration with the bus watch. Most
distributions compile Qt with Glib support, so it should work.
However, if you have compiled Qt yourself, you may have omited Glib
support... But to make sure it works in either case, you need to write
some dispatcher that will poll the bus for new messages from the Qt
main loop.

See http://cgit.freedesktop.org/gstreamer/qt-gstreamer/tree/src/QGst/bus.cpp#n29
for an example.

PS: You can also just use QtGStreamer... ;)

Regards,
George
_______________________________________________
gstreamer-devel mailing list
[hidden email]
http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Gstreamer playbin integration in QT application

arnaud tonda
2011/7/23 George Kiagiadakis <[hidden email]>

>
> On Fri, Jul 22, 2011 at 3:49 PM, arnaud tonda <[hidden email]> wrote:
> > secondly i tried to use playbin2 and the problem is there.
> > i get the video-sink element of playbin2 but before pipeline is playing
> > video-sink is null.
>
> This is correct, because the video sink is created when the playbin
> switches to the PAUSED state, and it is created in another thread.
> To make this work, you need to connect to the bus sync-message signal,
> wait for the "prepare-xwindow-id" message and set the window ID from
> there. Of course you need to save the window id earlier because you
> can't call QWidget::winId() from another thread.
>
> See http://cgit.freedesktop.org/gstreamer/qt-gstreamer/tree/src/QGst/Ui/videowidget.cpp#n139
> for an example.
>
Thanks for the reply, i will try this.

> > if i overload video-sink with a xvimagesink element video-sink is not null,
> > and i can use gst_x_overlay_set_xwindow_id on this.
> > but it result on a fullscreen video.... i think something is wrong but i
> > don't understand what....
>
> Maybe something is not correctly in sync. Try calling
> QApplication::syncX() before setting the window id.
>
> > the gst_bus_add_watch did not work. the attached callback is never called.
> > Has it work on the standalone C source code i think it is due to the QT
> > event loop but i can't confirm.
> > am i right?
>
> It depends. On Unix/X11, Qt can optionally use the Glib event loop,
> which achieves proper integration with the bus watch. Most
> distributions compile Qt with Glib support, so it should work.
> However, if you have compiled Qt yourself, you may have omited Glib
> support... But to make sure it works in either case, you need to write
> some dispatcher that will poll the bus for new messages from the Qt
> main loop.
>
> See http://cgit.freedesktop.org/gstreamer/qt-gstreamer/tree/src/QGst/bus.cpp#n29
> for an example.
>
> PS: You can also just use QtGStreamer... ;)
>
Yes, i know about QTGstreamer but the problem is that i must (for the
moment) use QT3.3. so i cant use this and cant compile my own
QTGstreamer. it's boring it would be a real time saver.....
thanks.
> Regards,
> George
> _______________________________________________
> gstreamer-devel mailing list
> [hidden email]
> http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel



--
Arnaud Tonda

téléphone : 06 34 23 57 78
_______________________________________________
gstreamer-devel mailing list
[hidden email]
http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Gstreamer playbin integration in QT application

arnaud tonda
Hi,

I answer to myself...

George was right.

the problem was that i did set the windowId on the video-sink too early.
in fact in my code i used the gst_bus_add_watch() that don't work in
my configuration.
i must use gst_bus_set_sync_handler() instead.

with this i can receive all messages transiting into the Bus and
waiting a GST_MESSAGE_ELEMENT that contains a structure named
"prepare-xwindow-id". if a get the GstElement emitting this message
and apply the WindowId on it, all is fine.

here is a part of my switch on bus_message_callback :

                case GST_MESSAGE_ELEMENT:
                         if (gst_structure_has_name (msg->structure, "prepare-xwindow-id"))
                             gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(GST_MESSAGE_SRC
(msg)), windowId);
                        break;

Thanks all and Best regards

Arnaud


2011/7/25 arnaud tonda <[hidden email]>:

> 2011/7/23 George Kiagiadakis <[hidden email]>
>>
>> On Fri, Jul 22, 2011 at 3:49 PM, arnaud tonda <[hidden email]> wrote:
>> > secondly i tried to use playbin2 and the problem is there.
>> > i get the video-sink element of playbin2 but before pipeline is playing
>> > video-sink is null.
>>
>> This is correct, because the video sink is created when the playbin
>> switches to the PAUSED state, and it is created in another thread.
>> To make this work, you need to connect to the bus sync-message signal,
>> wait for the "prepare-xwindow-id" message and set the window ID from
>> there. Of course you need to save the window id earlier because you
>> can't call QWidget::winId() from another thread.
>>
>> See http://cgit.freedesktop.org/gstreamer/qt-gstreamer/tree/src/QGst/Ui/videowidget.cpp#n139
>> for an example.
>>
> Thanks for the reply, i will try this.
>
>> > if i overload video-sink with a xvimagesink element video-sink is not null,
>> > and i can use gst_x_overlay_set_xwindow_id on this.
>> > but it result on a fullscreen video.... i think something is wrong but i
>> > don't understand what....
>>
>> Maybe something is not correctly in sync. Try calling
>> QApplication::syncX() before setting the window id.
>>
>> > the gst_bus_add_watch did not work. the attached callback is never called.
>> > Has it work on the standalone C source code i think it is due to the QT
>> > event loop but i can't confirm.
>> > am i right?
>>
>> It depends. On Unix/X11, Qt can optionally use the Glib event loop,
>> which achieves proper integration with the bus watch. Most
>> distributions compile Qt with Glib support, so it should work.
>> However, if you have compiled Qt yourself, you may have omited Glib
>> support... But to make sure it works in either case, you need to write
>> some dispatcher that will poll the bus for new messages from the Qt
>> main loop.
>>
>> See http://cgit.freedesktop.org/gstreamer/qt-gstreamer/tree/src/QGst/bus.cpp#n29
>> for an example.
>>
>> PS: You can also just use QtGStreamer... ;)
>>
> Yes, i know about QTGstreamer but the problem is that i must (for the
> moment) use QT3.3. so i cant use this and cant compile my own
> QTGstreamer. it's boring it would be a real time saver.....
> thanks.
>> Regards,
>> George
>> _______________________________________________
>> gstreamer-devel mailing list
>> [hidden email]
>> http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
>
>
>
> --
> Arnaud Tonda
>
> téléphone : 06 34 23 57 78
>



--
Arnaud Tonda
_______________________________________________
gstreamer-devel mailing list
[hidden email]
http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel