From 8d396ebedaa9ed6d9152fb8a4f90a3ea347fdec0 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Thu, 31 Oct 2013 15:06:30 +0100 Subject: [PATCH 1/2] Initial porting effort to GStreamer 1.0. Imported from git@github.com:jhodapp/qtmultimedia.git Contributions from: Ilya Smelykh Jim Hodapp Sergio Schvezov Change-Id: I10fa5e5078efa4564ce833befd417008e26a90a9 Reviewed-by: Yoann Lopes (cherry picked from commit d91dac090d92fdbc3a3425e8d969c62e5c79eff9) Conflicts: src/gsttools/qgstreamervideorenderer.cpp src/gsttools/qgstreamervideowidget.cpp src/gsttools/qgstreamervideowindow.cpp src/plugins/gstreamer/camerabin/camerabinsession.cpp src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp --- config.tests/gstreamer/gstreamer.pro | 11 +- config.tests/gstreamer_appsrc/gstreamer_appsrc.pro | 13 +- .../gstreamer_encodingprofiles.pro | 13 +- .../gstreamer_photography.pro | 15 +- qtmultimedia.pro | 22 ++- src/gsttools/gsttools.pro | 22 +-- src/gsttools/gstvideoconnector.c | 199 +++++++++++++++++++-- src/gsttools/qgstappsrc.cpp | 29 ++- src/gsttools/qgstreameraudioprobecontrol.cpp | 19 +- src/gsttools/qgstreamerbushelper.cpp | 8 + src/gsttools/qgstreamervideoprobecontrol.cpp | 9 + src/gsttools/qgstreamervideorenderer.cpp | 3 +- src/gsttools/qgstreamervideowidget.cpp | 29 ++- src/gsttools/qgstreamervideowindow.cpp | 79 +++++++- src/gsttools/qgstutils.cpp | 27 ++- src/gsttools/qgstvideobuffer.cpp | 18 +- src/gsttools/qvideosurfacegstsink.cpp | 143 +++++++++++++-- src/multimedia/gsttools_headers/qgstappsrc_p.h | 3 + .../qgstreameraudioprobecontrol_p.h | 5 +- .../qgstreamervideoprobecontrol_p.h | 4 + .../gsttools_headers/qgstreamervideowindow_p.h | 4 + src/multimedia/gsttools_headers/qgstutils_p.h | 4 + .../gsttools_headers/qgstvideobuffer_p.h | 3 + .../gsttools_headers/qvideosurfacegstsink_p.h | 6 +- .../qgstreameraudiodecoderserviceplugin.cpp | 27 ++- .../audiodecoder/qgstreameraudiodecodersession.cpp | 33 +++- .../gstreamer/camerabin/camerabinsession.cpp | 25 +++ src/plugins/gstreamer/common.pri | 21 ++- src/plugins/gstreamer/gstreamer.pro | 3 +- .../mediacapture/qgstreamercapturesession.cpp | 5 + src/plugins/gstreamer/mediaplayer/mediaplayer.pro | 1 - .../mediaplayer/qgstreamerplayercontrol.cpp | 2 + .../mediaplayer/qgstreamerplayerservice.cpp | 9 +- .../mediaplayer/qgstreamerplayerserviceplugin.cpp | 27 ++- .../mediaplayer/qgstreamerplayersession.cpp | 154 ++++++++++++++-- .../mediaplayer/qgstreamerplayersession.h | 9 + 36 files changed, 873 insertions(+), 131 deletions(-) diff --git a/config.tests/gstreamer/gstreamer.pro b/config.tests/gstreamer/gstreamer.pro index 02a7e34..6b9843a 100644 --- a/config.tests/gstreamer/gstreamer.pro +++ b/config.tests/gstreamer/gstreamer.pro @@ -3,11 +3,10 @@ SOURCES += main.cpp CONFIG += link_pkgconfig PKGCONFIG += \ - gstreamer-0.10 \ - gstreamer-base-0.10 \ - gstreamer-interfaces-0.10 \ - gstreamer-audio-0.10 \ - gstreamer-video-0.10 \ - gstreamer-pbutils-0.10 + gstreamer-$$GST_VERSION \ + gstreamer-base-$$GST_VERSION \ + gstreamer-audio-$$GST_VERSION \ + gstreamer-video-$$GST_VERSION \ + gstreamer-pbutils-$$GST_VERSION diff --git a/config.tests/gstreamer_appsrc/gstreamer_appsrc.pro b/config.tests/gstreamer_appsrc/gstreamer_appsrc.pro index 9f61703..0f3ca2b 100644 --- a/config.tests/gstreamer_appsrc/gstreamer_appsrc.pro +++ b/config.tests/gstreamer_appsrc/gstreamer_appsrc.pro @@ -3,11 +3,8 @@ SOURCES += main.cpp CONFIG += link_pkgconfig PKGCONFIG += \ - gstreamer-0.10 \ - gstreamer-base-0.10 \ - gstreamer-interfaces-0.10 \ - gstreamer-audio-0.10 \ - gstreamer-video-0.10 \ - gstreamer-app-0.10 - - + gstreamer-$$GST_VERSION \ + gstreamer-base-$$GST_VERSION \ + gstreamer-audio-$$GST_VERSION \ + gstreamer-video-$$GST_VERSION \ + gstreamer-pbutils-$$GST_VERSION diff --git a/config.tests/gstreamer_encodingprofiles/gstreamer_encodingprofiles.pro b/config.tests/gstreamer_encodingprofiles/gstreamer_encodingprofiles.pro index 7e8a9e7..fad40b0 100644 --- a/config.tests/gstreamer_encodingprofiles/gstreamer_encodingprofiles.pro +++ b/config.tests/gstreamer_encodingprofiles/gstreamer_encodingprofiles.pro @@ -2,11 +2,10 @@ SOURCES += main.cpp CONFIG += link_pkgconfig -PKGCONFIG += \ - gstreamer-0.10 \ - gstreamer-base-0.10 \ - gstreamer-interfaces-0.10 \ - gstreamer-audio-0.10 \ - gstreamer-video-0.10 \ - gstreamer-pbutils-0.10 +PKGCONFIG += \ + gstreamer-$$GST_VERSION \ + gstreamer-base-$$GST_VERSION \ + gstreamer-audio-$$GST_VERSION \ + gstreamer-video-$$GST_VERSION \ + gstreamer-pbutils-$$GST_VERSION diff --git a/config.tests/gstreamer_photography/gstreamer_photography.pro b/config.tests/gstreamer_photography/gstreamer_photography.pro index 6b530cb..975991f 100644 --- a/config.tests/gstreamer_photography/gstreamer_photography.pro +++ b/config.tests/gstreamer_photography/gstreamer_photography.pro @@ -3,12 +3,11 @@ SOURCES += main.cpp CONFIG += link_pkgconfig PKGCONFIG += \ - gstreamer-0.10 \ - gstreamer-base-0.10 \ - gstreamer-interfaces-0.10 \ - gstreamer-audio-0.10 \ - gstreamer-video-0.10 \ - gstreamer-pbutils-0.10 - -LIBS += -lgstphotography-0.10 + gstreamer-$$GST_VERSION \ + gstreamer-base-$$GST_VERSION \ + gstreamer-audio-$$GST_VERSION \ + gstreamer-video-$$GST_VERSION \ + gstreamer-pbutils-$$GST_VERSION + +LIBS += -lgstphotography-$$GST_VERSION diff --git a/qtmultimedia.pro b/qtmultimedia.pro index c7f093c..37f42a0 100644 --- a/qtmultimedia.pro +++ b/qtmultimedia.pro @@ -21,10 +21,24 @@ win32 { } else { qtCompileTest(alsa) qtCompileTest(pulseaudio) - qtCompileTest(gstreamer) { - qtCompileTest(gstreamer_photography) - qtCompileTest(gstreamer_encodingprofiles) - qtCompileTest(gstreamer_appsrc) + !done_config_gstreamer { + gstver=1.0 + cache(GST_VERSION, set, gstver); + qtCompileTest(gstreamer) { + qtCompileTest(gstreamer_photography) + qtCompileTest(gstreamer_encodingprofiles) + qtCompileTest(gstreamer_appsrc) + } else { + gstver=0.10 + cache(GST_VERSION, set, gstver); + # Force a re-run of the test + CONFIG -= done_config_gstreamer + qtCompileTest(gstreamer) { + qtCompileTest(gstreamer_photography) + qtCompileTest(gstreamer_encodingprofiles) + qtCompileTest(gstreamer_appsrc) + } + } } qtCompileTest(resourcepolicy) qtCompileTest(gpu_vivante) diff --git a/src/gsttools/gsttools.pro b/src/gsttools/gsttools.pro index 15edd04..d252344 100644 --- a/src/gsttools/gsttools.pro +++ b/src/gsttools/gsttools.pro @@ -2,7 +2,7 @@ TEMPLATE = lib TARGET = qgsttools_p QPRO_PWD = $$PWD -QT = core-private multimedia-private gui-private +QT = core-private multimedia-private gui-private opengl !static:DEFINES += QT_MAKEDLL DEFINES += GLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_26 @@ -15,13 +15,14 @@ LIBS_PRIVATE += \ CONFIG += link_pkgconfig -PKGCONFIG_PRIVATE += \ - gstreamer-0.10 \ - gstreamer-base-0.10 \ - gstreamer-interfaces-0.10 \ - gstreamer-audio-0.10 \ - gstreamer-video-0.10 \ - gstreamer-pbutils-0.10 +PKGCONFIG += \ + gstreamer-$$GST_VERSION \ + gstreamer-base-$$GST_VERSION \ + gstreamer-audio-$$GST_VERSION \ + gstreamer-video-$$GST_VERSION \ + gstreamer-pbutils-$$GST_VERSION + +equals(GST_VERSION,"0.10"): PKGCONFIG_PRIVATE += gstreamer-interfaces-$$GST_VERSION maemo*: PKGCONFIG_PRIVATE +=gstreamer-plugins-bad-0.10 @@ -33,6 +34,7 @@ config_resourcepolicy { # Header files must go inside source directory of a module # to be installed by syncqt. INCLUDEPATH += ../multimedia/gsttools_headers/ +INCLUDEPATH += ../plugins/gstreamer/mediaplayer/ VPATH += ../multimedia/gsttools_headers/ PRIVATE_HEADERS += \ @@ -91,13 +93,13 @@ maemo6 { } config_gstreamer_appsrc { - PKGCONFIG_PRIVATE += gstreamer-app-0.10 + PKGCONFIG_PRIVATE += gstreamer-app-$$GST_VERSION PRIVATE_HEADERS += qgstappsrc_p.h SOURCES += qgstappsrc.cpp DEFINES += HAVE_GST_APPSRC - LIBS_PRIVATE += -lgstapp-0.10 + LIBS_PRIVATE += -lgstapp-$$GST_VERSION } HEADERS += $$PRIVATE_HEADERS diff --git a/src/gsttools/gstvideoconnector.c b/src/gsttools/gstvideoconnector.c index 3e08fe5..ff3f9a3 100644 --- a/src/gsttools/gstvideoconnector.c +++ b/src/gsttools/gstvideoconnector.c @@ -67,26 +67,93 @@ GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_ALWAYS, GST_STATIC_CAPS_ANY); + +#if GST_CHECK_VERSION(1,0,0) + +G_DEFINE_TYPE(GstVideoConnector, gst_video_connector, GST_TYPE_ELEMENT); +#else #define _do_init(bla) \ GST_DEBUG_CATEGORY_INIT (video_connector_debug, \ "video-connector", 0, "An identity like element for reconnecting video stream"); GST_BOILERPLATE_FULL (GstVideoConnector, gst_video_connector, GstElement, GST_TYPE_ELEMENT, _do_init); +#endif static void gst_video_connector_dispose (GObject * object); + +#if GST_CHECK_VERSION(1,0,0) +static GstFlowReturn gst_video_connector_chain (GstPad * pad, GstObject* parent, GstBuffer * buf); +#else static GstFlowReturn gst_video_connector_chain (GstPad * pad, GstBuffer * buf); static GstFlowReturn gst_video_connector_buffer_alloc (GstPad * pad, guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf); +#endif + static GstStateChangeReturn gst_video_connector_change_state (GstElement * element, GstStateChange transition); + +#if GST_CHECK_VERSION(1,0,0) +static gboolean gst_video_connector_handle_sink_event (GstPad * pad, GstObject* parent, + GstEvent * event); +#else static gboolean gst_video_connector_handle_sink_event (GstPad * pad, GstEvent * event); +#endif + +#if GST_CHECK_VERSION(1,0,0) +static GstPadProbeReturn gst_video_connector_new_buffer_probe(GstPad *pad, GstPadProbeInfo *info, gpointer object); +static GstPadProbeReturn gst_video_connector_new_event_probe(GstPad *pad, GstPadProbeInfo *info, gpointer object); +static GstPadProbeReturn gst_video_connector_new_query_probe(GstPad *pad, GstPadProbeInfo *info, gpointer object); +#else static gboolean gst_video_connector_new_buffer_probe(GstObject *pad, GstBuffer *buffer, guint * object); -static void gst_video_connector_resend_new_segment(GstElement * element, gboolean emitFailedSignal); static gboolean gst_video_connector_setcaps (GstPad *pad, GstCaps *caps); static GstCaps *gst_video_connector_getcaps (GstPad * pad); static gboolean gst_video_connector_acceptcaps (GstPad * pad, GstCaps * caps); +#endif + +static void gst_video_connector_resend_new_segment(GstElement * element, gboolean emitFailedSignal); + +#if GST_CHECK_VERSION(1,0,0) +static void +gst_video_connector_class_init (GstVideoConnectorClass * klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass); + + gst_element_class_set_details_simple (gstelement_class, "Video Connector", + "Generic", + "An identity like element used for reconnecting video stream", + "Dmytro Poplavskiy "); + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&gst_video_connector_sink_factory)); + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&gst_video_connector_src_factory)); + + gst_video_connector_parent_class = g_type_class_peek_parent (klass); + + gobject_class->dispose = gst_video_connector_dispose; + gstelement_class->change_state = gst_video_connector_change_state; + klass->resend_new_segment = gst_video_connector_resend_new_segment; + + gst_video_connector_signals[SIGNAL_RESEND_NEW_SEGMENT] = + g_signal_new ("resend-new-segment", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (GstVideoConnectorClass, resend_new_segment), NULL, NULL, + g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN); + + gst_video_connector_signals[SIGNAL_CONNECTION_FAILED] = + g_signal_new ("connection-failed", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + + GST_DEBUG_CATEGORY_INIT(video_connector_debug, "video-connector", 0, + "An identity like element for reconnecting video stream"); + +} + +#else static void gst_video_connector_base_init (gpointer g_class) @@ -128,18 +195,33 @@ gst_video_connector_class_init (GstVideoConnectorClass * klass) g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); } +#endif + static void -gst_video_connector_init (GstVideoConnector *element, - GstVideoConnectorClass *g_class) +gst_video_connector_init (GstVideoConnector *element +#if GST_CHECK_VERSION(1,0,0) +#else + ,GstVideoConnectorClass *g_class +#endif + ) { +#if GST_CHECK_VERSION(1,0,0) +#else (void) g_class; +#endif element->sinkpad = gst_pad_new_from_static_template (&gst_video_connector_sink_factory, "sink"); gst_pad_set_chain_function(element->sinkpad, GST_DEBUG_FUNCPTR (gst_video_connector_chain)); +#if GST_CHECK_VERSION(1,0,0) + /* gstreamer 1.x uses QUERIES and EVENTS for allocation and caps handiling purposes */ + GST_OBJECT_FLAG_SET (element->sinkpad, GST_PAD_FLAG_PROXY_CAPS); + GST_OBJECT_FLAG_SET (element->sinkpad, GST_PAD_FLAG_PROXY_ALLOCATION); +#else gst_pad_set_event_function(element->sinkpad, GST_DEBUG_FUNCPTR (gst_video_connector_handle_sink_event)); + gst_pad_set_bufferalloc_function(element->sinkpad, GST_DEBUG_FUNCPTR (gst_video_connector_buffer_alloc)); gst_pad_set_setcaps_function(element->sinkpad, @@ -148,14 +230,23 @@ gst_video_connector_init (GstVideoConnector *element, GST_DEBUG_FUNCPTR(gst_video_connector_getcaps)); gst_pad_set_acceptcaps_function(element->sinkpad, GST_DEBUG_FUNCPTR(gst_video_connector_acceptcaps)); - +#endif gst_element_add_pad (GST_ELEMENT (element), element->sinkpad); element->srcpad = gst_pad_new_from_static_template (&gst_video_connector_src_factory, "src"); +#if GST_CHECK_VERSION(1,0,0) + gst_pad_add_probe(element->srcpad, GST_PAD_PROBE_TYPE_BUFFER, + gst_video_connector_new_buffer_probe, element, NULL); + gst_pad_add_probe(element->srcpad, GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM, + gst_video_connector_new_query_probe, element, NULL); + gst_pad_add_probe(element->sinkpad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, + gst_video_connector_new_event_probe, element, NULL); +#else gst_pad_add_buffer_probe(element->srcpad, G_CALLBACK(gst_video_connector_new_buffer_probe), element); +#endif gst_element_add_pad (GST_ELEMENT (element), element->srcpad); element->relinked = FALSE; @@ -183,9 +274,16 @@ gst_video_connector_dispose (GObject * object) gst_video_connector_reset (element); +#if GST_CHECK_VERSION(1,0,0) + G_OBJECT_CLASS (gst_video_connector_parent_class)->dispose (object); +#else G_OBJECT_CLASS (parent_class)->dispose (object); +#endif } +#if GST_CHECK_VERSION(1,0,0) +/* For gstreamer 1.x we handle it in ALLOCATION Query */ +#else // "When this function returns anything else than GST_FLOW_OK, // the buffer allocation failed and buf does not contain valid data." static GstFlowReturn @@ -229,6 +327,7 @@ gst_video_connector_buffer_alloc (GstPad * pad, guint64 offset, guint size, if (state == GST_STATE_NULL) { GST_DEBUG_OBJECT (element, "Downstream element is in NULL state"); // Downstream filter seems to be in the wrong state + return GST_FLOW_UNEXPECTED; } } @@ -301,6 +400,7 @@ static GstCaps *gst_video_connector_getcaps (GstPad * pad) return caps; } + static gboolean gst_video_connector_acceptcaps (GstPad * pad, GstCaps * caps) { GstVideoConnector *element; @@ -308,6 +408,7 @@ static gboolean gst_video_connector_acceptcaps (GstPad * pad, GstCaps * caps) return gst_pad_peer_accept_caps(element->srcpad, caps); } +#endif static void gst_video_connector_resend_new_segment(GstElement * element, gboolean emitFailedSignal) @@ -319,11 +420,39 @@ gst_video_connector_resend_new_segment(GstElement * element, gboolean emitFailed connector->failedSignalEmited = FALSE; } +#if GST_CHECK_VERSION(1,0,0) +static GstPadProbeReturn gst_video_connector_new_event_probe(GstPad *pad, GstPadProbeInfo *info, gpointer object) +{ + GstVideoConnector *connector = GST_VIDEO_CONNECTOR (object); + GstEvent *event = gst_pad_probe_info_get_event(info); + + GST_DEBUG_OBJECT(connector, "Event %"GST_PTR_FORMAT" received\n", event); + + return GST_PAD_PROBE_OK; +} + +static GstPadProbeReturn gst_video_connector_new_query_probe(GstPad *pad, GstPadProbeInfo *info, gpointer object) +{ + GstVideoConnector *connector = GST_VIDEO_CONNECTOR (object); + GstQuery *query = gst_pad_probe_info_get_query(info); + + GST_DEBUG_OBJECT(connector, "Query %"GST_PTR_FORMAT" received\n", query); + + return GST_PAD_PROBE_OK; +} +#endif +#if GST_CHECK_VERSION(1,0,0) +static GstPadProbeReturn gst_video_connector_new_buffer_probe(GstPad *pad, GstPadProbeInfo *info, gpointer object) +{ + (void) info; +#else static gboolean gst_video_connector_new_buffer_probe(GstObject *pad, GstBuffer *buffer, guint * object) { - (void) pad; (void) buffer; +#endif + (void) pad; + GstVideoConnector *element = GST_VIDEO_CONNECTOR (object); @@ -335,16 +464,23 @@ static gboolean gst_video_connector_new_buffer_probe(GstObject *pad, GstBuffer * if (element->relinked) GST_LOG_OBJECT(element, "rejected buffer because of new segment request"); - return !element->relinked; + return element->relinked ? GST_PAD_PROBE_DROP : GST_PAD_PROBE_OK; } - static GstFlowReturn +#if GST_CHECK_VERSION(1,0,0) +gst_video_connector_chain (GstPad * pad, GstObject* parent, GstBuffer * buf) +#else gst_video_connector_chain (GstPad * pad, GstBuffer * buf) +#endif { GstFlowReturn res; GstVideoConnector *element; +#if GST_CHECK_VERSION(1,0,0) + (void)parent; +#endif + element = GST_VIDEO_CONNECTOR (gst_pad_get_parent (pad)); do { @@ -356,20 +492,29 @@ gst_video_connector_chain (GstPad * pad, GstBuffer * buf) */ while (element->relinked) { element->relinked = FALSE; - +#if GST_CHECK_VERSION(1,0,0) + if (element->latest_buffer && GST_BUFFER_TIMESTAMP_IS_VALID(element->latest_buffer)) { + element->segment.position = GST_BUFFER_TIMESTAMP (element->latest_buffer); + } +#else gint64 pos = element->segment.last_stop; - if (element->latest_buffer && GST_BUFFER_TIMESTAMP_IS_VALID(element->latest_buffer)) { pos = GST_BUFFER_TIMESTAMP (element->latest_buffer); } +#endif //push a new segment and last buffer +#if GST_CHECK_VERSION(1,0,0) + GstEvent *ev = gst_event_new_segment (&element->segment); + +#else GstEvent *ev = gst_event_new_new_segment (TRUE, element->segment.rate, element->segment.format, pos, //start element->segment.stop, pos); +#endif GST_DEBUG_OBJECT (element, "Pushing new segment event"); if (!gst_pad_push_event (element->srcpad, ev)) { @@ -432,8 +577,11 @@ gst_video_connector_change_state (GstElement * element, GstStateChangeReturn result; connector = GST_VIDEO_CONNECTOR(element); +#if GST_CHECK_VERSION(1,0,0) + result = GST_ELEMENT_CLASS (gst_video_connector_parent_class)->change_state(element, transition); +#else result = GST_ELEMENT_CLASS (parent_class)->change_state(element, transition); - +#endif switch (transition) { case GST_STATE_CHANGE_PAUSED_TO_READY: gst_video_connector_reset (connector); @@ -448,9 +596,32 @@ gst_video_connector_change_state (GstElement * element, return result; } -static gboolean -gst_video_connector_handle_sink_event (GstPad * pad, GstEvent * event) +#if GST_CHECK_VERSION(1,0,0) +static gboolean gst_video_connector_handle_sink_event (GstPad * pad, GstObject* parent, + GstEvent * event) +{ + GstVideoConnector *element = GST_VIDEO_CONNECTOR (gst_pad_get_parent (pad)); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_SEGMENT: + break; + case GST_EVENT_CAPS: + break; + default: + break; + } + + gst_object_unref (element); + return gst_pad_event_default (pad, parent, event); +} + +#else + +static gboolean gst_video_connector_handle_sink_event (GstPad * pad, + GstEvent * event) { + (void)parent; + if (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT) { GstVideoConnector *element = GST_VIDEO_CONNECTOR (gst_pad_get_parent (pad)); @@ -461,7 +632,6 @@ gst_video_connector_handle_sink_event (GstPad * pad, GstEvent * event) gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format, &start, &stop, &time); - GST_LOG_OBJECT (element, "NEWSEGMENT update %d, rate %lf, applied rate %lf, " "format %d, " "%" G_GINT64_FORMAT " -- %" G_GINT64_FORMAT ", time %" @@ -469,9 +639,10 @@ gst_video_connector_handle_sink_event (GstPad * pad, GstEvent * event) gst_segment_set_newsegment_full (&element->segment, update, rate, arate, format, start, stop, time); - gst_object_unref (element); } return gst_pad_event_default (pad, event); } + +#endif diff --git a/src/gsttools/qgstappsrc.cpp b/src/gsttools/qgstappsrc.cpp index 2c9f64c..7916d89 100644 --- a/src/gsttools/qgstappsrc.cpp +++ b/src/gsttools/qgstappsrc.cpp @@ -155,23 +155,44 @@ void QGstAppSrc::pushDataToAppSrc() size = qMin(m_stream->bytesAvailable(), (qint64)m_dataRequestSize); if (size) { - void *data = g_malloc(size); - GstBuffer* buffer = gst_app_buffer_new(data, size, g_free, data); + GstBuffer* buffer = gst_buffer_new_and_alloc(size); + +#if GST_CHECK_VERSION(1,0,0) + GstMapInfo mapInfo; + gst_buffer_map(buffer, &mapInfo, GST_MAP_WRITE); + void* bufferData = mapInfo.data; +#else + void* bufferData = GST_BUFFER_DATA(buffer); +#endif + buffer->offset = m_stream->pos(); - qint64 bytesRead = m_stream->read((char*)GST_BUFFER_DATA(buffer), size); + qint64 bytesRead = m_stream->read((char*)bufferData, size); buffer->offset_end = buffer->offset + bytesRead - 1; +#if GST_CHECK_VERSION(1,0,0) + gst_buffer_unmap(buffer, &mapInfo); +#endif + if (bytesRead > 0) { m_dataRequested = false; m_enoughData = false; GstFlowReturn ret = gst_app_src_push_buffer (GST_APP_SRC (element()), buffer); if (ret == GST_FLOW_ERROR) { qWarning()<<"appsrc: push buffer error"; +#if GST_CHECK_VERSION(1,0,0) + } else if (ret == GST_FLOW_FLUSHING) { + qWarning()<<"appsrc: push buffer wrong state"; + } +#else } else if (ret == GST_FLOW_WRONG_STATE) { qWarning()<<"appsrc: push buffer wrong state"; - } else if (ret == GST_FLOW_RESEND) { + } +#endif +#if GST_VERSION_MAJOR < 1 + else if (ret == GST_FLOW_RESEND) { qWarning()<<"appsrc: push buffer resend"; } +#endif } } else { sendEOS(); diff --git a/src/gsttools/qgstreameraudioprobecontrol.cpp b/src/gsttools/qgstreameraudioprobecontrol.cpp index 94d07c9..8c85973 100644 --- a/src/gsttools/qgstreameraudioprobecontrol.cpp +++ b/src/gsttools/qgstreameraudioprobecontrol.cpp @@ -53,9 +53,14 @@ QGstreamerAudioProbeControl::~QGstreamerAudioProbeControl() } +#if GST_CHECK_VERSION(1,0,0) +void QGstreamerAudioProbeControl::bufferProbed(GstBuffer* buffer, GstCaps* caps) +{ +#else void QGstreamerAudioProbeControl::bufferProbed(GstBuffer* buffer) { - GstCaps* caps = gst_buffer_get_caps(buffer); + gst_buffer_get_caps(buffer); +#endif if (!caps) return; @@ -64,8 +69,20 @@ void QGstreamerAudioProbeControl::bufferProbed(GstBuffer* buffer) if (!format.isValid()) return; + #if GST_CHECK_VERSION(1,0,0) + + GstMapInfo info; + + gst_buffer_map (buffer, &info, GST_MAP_READ); + QAudioBuffer audioBuffer = QAudioBuffer(QByteArray((const char*)info.data, info.size), format); + gst_buffer_unmap(buffer, &info); + + #else + QAudioBuffer audioBuffer = QAudioBuffer(QByteArray((const char*)buffer->data, buffer->size), format); + #endif + { QMutexLocker locker(&m_bufferMutex); m_pendingBuffer = audioBuffer; diff --git a/src/gsttools/qgstreamerbushelper.cpp b/src/gsttools/qgstreamerbushelper.cpp index da7506e..6b4cdd2 100644 --- a/src/gsttools/qgstreamerbushelper.cpp +++ b/src/gsttools/qgstreamerbushelper.cpp @@ -162,13 +162,21 @@ QGstreamerBusHelper::QGstreamerBusHelper(GstBus* bus, QObject* parent): QObject(parent) { d = new QGstreamerBusHelperPrivate(this, bus); +#if GST_CHECK_VERSION(1,0,0) + gst_bus_set_sync_handler(bus, (GstBusSyncHandler)syncGstBusFilter, d, 0); +#else gst_bus_set_sync_handler(bus, (GstBusSyncHandler)syncGstBusFilter, d); +#endif gst_object_ref(GST_OBJECT(bus)); } QGstreamerBusHelper::~QGstreamerBusHelper() { +#if GST_CHECK_VERSION(1,0,0) + gst_bus_set_sync_handler(d->bus(), 0, 0, 0); +#else gst_bus_set_sync_handler(d->bus(),0,0); +#endif gst_object_unref(GST_OBJECT(d->bus())); } diff --git a/src/gsttools/qgstreamervideoprobecontrol.cpp b/src/gsttools/qgstreamervideoprobecontrol.cpp index f2e6c3f..55632ff 100644 --- a/src/gsttools/qgstreamervideoprobecontrol.cpp +++ b/src/gsttools/qgstreamervideoprobecontrol.cpp @@ -75,12 +75,21 @@ void QGstreamerVideoProbeControl::stopFlushing() m_flushing = false; } +#if GST_CHECK_VERSION(1,0,0) +void QGstreamerVideoProbeControl::bufferProbed(GstBuffer* buffer, GstCaps* caps) +#else void QGstreamerVideoProbeControl::bufferProbed(GstBuffer* buffer) +#endif { if (m_flushing) return; +#if GST_CHECK_VERSION(1,0,0) + // FIXME: + // GstCaps* caps = NULL;//gst_buffer_get_caps(buffer); +#else GstCaps* caps = gst_buffer_get_caps(buffer); +#endif if (!caps) return; diff --git a/src/gsttools/qgstreamervideorenderer.cpp b/src/gsttools/qgstreamervideorenderer.cpp index 36c9f78..da85dea 100644 --- a/src/gsttools/qgstreamervideorenderer.cpp +++ b/src/gsttools/qgstreamervideorenderer.cpp @@ -43,8 +43,7 @@ #include #include #include - -#include +#include #include diff --git a/src/gsttools/qgstreamervideowidget.cpp b/src/gsttools/qgstreamervideowidget.cpp index 7e11bfb..7848f2f 100644 --- a/src/gsttools/qgstreamervideowidget.cpp +++ b/src/gsttools/qgstreamervideowidget.cpp @@ -48,8 +48,13 @@ #include #include + +#if !GST_CHECK_VERSION(1,0,0) #include #include +#else +#include +#endif QT_BEGIN_NAMESPACE @@ -177,9 +182,13 @@ bool QGstreamerVideoWidgetControl::processSyncMessage(const QGstreamerMessage &m { GstMessage* gm = message.rawMessage(); +#if !GST_CHECK_VERSION(1,0,0) if (gm && (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT) && gst_structure_has_name(gm->structure, "prepare-xwindow-id")) { - +#else + if (gm && (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT) && + gst_structure_has_name(gst_message_get_structure(gm), "prepare-window-handle")) { +#endif setOverlay(); QMetaObject::invokeMethod(this, "updateNativeVideoSize", Qt::QueuedConnection); return true; @@ -207,18 +216,29 @@ bool QGstreamerVideoWidgetControl::processBusMessage(const QGstreamerMessage &me void QGstreamerVideoWidgetControl::setOverlay() { +#if !GST_CHECK_VERSION(1,0,0) if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) { gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(m_videoSink), m_windowId); } +#else + if (m_videoSink && GST_IS_VIDEO_OVERLAY(m_videoSink)) { + gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(m_videoSink), m_windowId); + } +#endif } void QGstreamerVideoWidgetControl::updateNativeVideoSize() { if (m_videoSink) { //find video native size to update video widget size hint - GstPad *pad = gst_element_get_static_pad(m_videoSink,"sink"); + GstPad *pad = gst_element_get_static_pad(m_videoSink, "sink"); +#if !GST_CHECK_VERSION(1,0,0) GstCaps *caps = gst_pad_get_negotiated_caps(pad); gst_object_unref(GST_OBJECT(pad)); +#else + GstCaps *caps = gst_pad_get_current_caps(pad); + gst_object_unref(GST_OBJECT(pad)); +#endif if (caps) { m_widget->setNativeSize(QGstUtils::capsCorrectedResolution(caps)); @@ -233,8 +253,13 @@ void QGstreamerVideoWidgetControl::updateNativeVideoSize() void QGstreamerVideoWidgetControl::windowExposed() { +#if !GST_CHECK_VERSION(1,0,0) if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) gst_x_overlay_expose(GST_X_OVERLAY(m_videoSink)); +#else + if (m_videoSink && GST_IS_VIDEO_OVERLAY(m_videoSink)) + gst_video_overlay_expose(GST_VIDEO_OVERLAY(m_videoSink)); +#endif } QWidget *QGstreamerVideoWidgetControl::videoWidget() diff --git a/src/gsttools/qgstreamervideowindow.cpp b/src/gsttools/qgstreamervideowindow.cpp index 2dc3510..45e9374 100644 --- a/src/gsttools/qgstreamervideowindow.cpp +++ b/src/gsttools/qgstreamervideowindow.cpp @@ -45,8 +45,12 @@ #include #include +#include + +#if !GST_CHECK_VERSION(1,0,0) #include #include +#endif QGstreamerVideoWindow::QGstreamerVideoWindow(QObject *parent, const char *elementName) @@ -57,18 +61,25 @@ QGstreamerVideoWindow::QGstreamerVideoWindow(QObject *parent, const char *elemen , m_fullScreen(false) , m_colorKey(QColor::Invalid) { - if (elementName) + if (elementName) { m_videoSink = gst_element_factory_make(elementName, NULL); - else + } else { m_videoSink = gst_element_factory_make("xvimagesink", NULL); + } if (m_videoSink) { qt_gst_object_ref_sink(GST_OBJECT(m_videoSink)); //Take ownership GstPad *pad = gst_element_get_static_pad(m_videoSink,"sink"); +#if GST_CHECK_VERSION(1,0,0) + m_bufferProbeId = gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_BUFFER, padBufferProbe, this, NULL); +#else m_bufferProbeId = gst_pad_add_buffer_probe(pad, G_CALLBACK(padBufferProbe), this); +#endif gst_object_unref(GST_OBJECT(pad)); } + else + qDebug() << "No m_videoSink available!"; } QGstreamerVideoWindow::~QGstreamerVideoWindow() @@ -90,11 +101,15 @@ void QGstreamerVideoWindow::setWinId(WId id) WId oldId = m_windowId; m_windowId = id; - +#if GST_CHECK_VERSION(1,0,0) + if (m_videoSink && GST_IS_VIDEO_OVERLAY(m_videoSink)) { + gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(m_videoSink), m_windowId); + } +#else if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) { gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(m_videoSink), m_windowId); } - +#endif if (!oldId) emit readyChanged(true); @@ -105,7 +120,20 @@ void QGstreamerVideoWindow::setWinId(WId id) bool QGstreamerVideoWindow::processSyncMessage(const QGstreamerMessage &message) { GstMessage* gm = message.rawMessage(); +#if GST_CHECK_VERSION(1,0,0) + const GstStructure *s = gst_message_get_structure(gm); + if ((GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT) && + gst_structure_has_name(s, "prepare-window-handle") && + m_videoSink && GST_IS_VIDEO_OVERLAY(m_videoSink)) { + + gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(m_videoSink), m_windowId); + GstPad *pad = gst_element_get_static_pad(m_videoSink,"sink"); + m_bufferProbeId = gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_BUFFER, padBufferProbe, this, NULL); + + return true; + } +#else if ((GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT) && gst_structure_has_name(gm->structure, "prepare-xwindow-id") && m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) { @@ -118,7 +146,7 @@ bool QGstreamerVideoWindow::processSyncMessage(const QGstreamerMessage &message) return true; } - +#endif return false; } @@ -130,7 +158,19 @@ QRect QGstreamerVideoWindow::displayRect() const void QGstreamerVideoWindow::setDisplayRect(const QRect &rect) { m_displayRect = rect; - +#if GST_CHECK_VERSION(1,0,0) + if (m_videoSink && GST_IS_VIDEO_OVERLAY(m_videoSink)) { + if (m_displayRect.isEmpty()) + gst_video_overlay_set_render_rectangle(GST_VIDEO_OVERLAY(m_videoSink), -1, -1, -1, -1); + else + gst_video_overlay_set_render_rectangle(GST_VIDEO_OVERLAY(m_videoSink), + m_displayRect.x(), + m_displayRect.y(), + m_displayRect.width(), + m_displayRect.height()); + repaint(); + } +#else if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) { #if GST_VERSION_MICRO >= 29 if (m_displayRect.isEmpty()) @@ -144,6 +184,7 @@ void QGstreamerVideoWindow::setDisplayRect(const QRect &rect) repaint(); #endif } +#endif } Qt::AspectRatioMode QGstreamerVideoWindow::aspectRatioMode() const @@ -165,6 +206,16 @@ void QGstreamerVideoWindow::setAspectRatioMode(Qt::AspectRatioMode mode) void QGstreamerVideoWindow::repaint() { +#if GST_CHECK_VERSION(1,0,0) + if (m_videoSink && GST_IS_VIDEO_OVERLAY(m_videoSink)) { + //don't call gst_x_overlay_expose if the sink is in null state + GstState state = GST_STATE_NULL; + GstStateChangeReturn res = gst_element_get_state(m_videoSink, &state, NULL, 1000000); + if (res != GST_STATE_CHANGE_FAILURE && state != GST_STATE_NULL) { + gst_video_overlay_expose(GST_VIDEO_OVERLAY(m_videoSink)); + } + } +#else if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) { //don't call gst_x_overlay_expose if the sink is in null state GstState state = GST_STATE_NULL; @@ -173,6 +224,7 @@ void QGstreamerVideoWindow::repaint() gst_x_overlay_expose(GST_X_OVERLAY(m_videoSink)); } } +#endif } QColor QGstreamerVideoWindow::colorKey() const @@ -304,11 +356,22 @@ QSize QGstreamerVideoWindow::nativeSize() const return m_nativeSize; } +#if GST_CHECK_VERSION(1,0,0) +GstPadProbeReturn QGstreamerVideoWindow::padBufferProbe(GstPad *pad, GstPadProbeInfo *info, gpointer user_data) +#else void QGstreamerVideoWindow::padBufferProbe(GstPad *pad, GstBuffer * /* buffer */, gpointer user_data) +#endif { QGstreamerVideoWindow *control = reinterpret_cast(user_data); QMetaObject::invokeMethod(control, "updateNativeVideoSize", Qt::QueuedConnection); + +#if GST_CHECK_VERSION(1,0,0) + Q_UNUSED(pad); + Q_UNUSED(info); + return GST_PAD_PROBE_REMOVE; +#else gst_pad_remove_buffer_probe(pad, control->m_bufferProbeId); +#endif } void QGstreamerVideoWindow::updateNativeVideoSize() @@ -319,7 +382,11 @@ void QGstreamerVideoWindow::updateNativeVideoSize() if (m_videoSink) { //find video native size to update video widget size hint GstPad *pad = gst_element_get_static_pad(m_videoSink,"sink"); +#if GST_CHECK_VERSION(1,0,0) + GstCaps *caps = gst_pad_get_current_caps(pad); +#else GstCaps *caps = gst_pad_get_negotiated_caps(pad); +#endif gst_object_unref(GST_OBJECT(pad)); if (caps) { diff --git a/src/gsttools/qgstutils.cpp b/src/gsttools/qgstutils.cpp index 41bd005..3ca1921 100644 --- a/src/gsttools/qgstutils.cpp +++ b/src/gsttools/qgstutils.cpp @@ -89,8 +89,13 @@ static void addTagToMap(const GstTagList *list, break; default: // GST_TYPE_DATE is a function, not a constant, so pull it out of the switch +#if GST_CHECK_VERSION(1,0,0) + if (G_VALUE_TYPE(&val) == G_TYPE_DATE) { + const GDate *date = (const GDate *)g_value_get_boxed(&val); +#else if (G_VALUE_TYPE(&val) == GST_TYPE_DATE) { const GDate *date = gst_value_get_date(&val); +#endif if (g_date_valid(date)) { int year = g_date_get_year(date); int month = g_date_get_month(date); @@ -254,6 +259,24 @@ QAudioFormat QGstUtils::audioFormatForCaps(const GstCaps *caps) } + +#if GST_CHECK_VERSION(1,0,0) +/*! + Returns audio format for a buffer. + If the buffer doesn't have a valid audio format, an empty QAudioFormat is returned. +*/ + +QAudioFormat QGstUtils::audioFormatForSample(GstSample *sample) +{ + GstCaps* caps = gst_sample_get_caps(sample); + if (!caps) + return QAudioFormat(); + + QAudioFormat format = QGstUtils::audioFormatForCaps(caps); + gst_caps_unref(caps); + return format; +} +#else /*! Returns audio format for a buffer. If the buffer doesn't have a valid audio format, an empty QAudioFormat is returned. @@ -269,7 +292,7 @@ QAudioFormat QGstUtils::audioFormatForBuffer(GstBuffer *buffer) gst_caps_unref(caps); return format; } - +#endif /*! Builds GstCaps for an audio format. @@ -403,7 +426,7 @@ QMultimedia::SupportEstimate QGstUtils::hasSupport(const QString &mimeType, void qt_gst_object_ref_sink(gpointer object) { -#if (GST_VERSION_MAJOR >= 0) && (GST_VERSION_MINOR >= 10) && (GST_VERSION_MICRO >= 24) +#if (GST_VERSION_MAJOR >= 0) && (GST_VERSION_MINOR >= 10) && (GST_VERSION_MICRO >= 24) || GST_CHECK_VERSION(1,0,0) gst_object_ref_sink(object); #else g_return_if_fail (GST_IS_OBJECT(object)); diff --git a/src/gsttools/qgstvideobuffer.cpp b/src/gsttools/qgstvideobuffer.cpp index 45556d1..750a07f 100644 --- a/src/gsttools/qgstvideobuffer.cpp +++ b/src/gsttools/qgstvideobuffer.cpp @@ -78,21 +78,33 @@ QAbstractVideoBuffer::MapMode QGstVideoBuffer::mapMode() const uchar *QGstVideoBuffer::map(MapMode mode, int *numBytes, int *bytesPerLine) { if (mode != NotMapped && m_mode == NotMapped) { - if (numBytes) - *numBytes = m_buffer->size; + m_mode = mode; if (bytesPerLine) *bytesPerLine = m_bytesPerLine; - m_mode = mode; +#if GST_CHECK_VERSION(1,0,0) + gst_buffer_map(m_buffer, &m_mapInfo, GST_MAP_READ); + if (numBytes) + *numBytes = m_mapInfo.size; + + return m_mapInfo.data; +#else + if (numBytes) + *numBytes = m_buffer->size; return m_buffer->data; +#endif } else { return 0; } } void QGstVideoBuffer::unmap() { +#if GST_CHECK_VERSION(1,0,0) + if (m_mode != NotMapped) + gst_buffer_unmap(m_buffer, &m_mapInfo); +#endif m_mode = NotMapped; } diff --git a/src/gsttools/qvideosurfacegstsink.cpp b/src/gsttools/qvideosurfacegstsink.cpp index 81d5f60..51c4107 100644 --- a/src/gsttools/qvideosurfacegstsink.cpp +++ b/src/gsttools/qvideosurfacegstsink.cpp @@ -51,7 +51,11 @@ #include "qvideosurfacegstsink_p.h" -//#define DEBUG_VIDEO_SURFACE_SINK +#if GST_VERSION_MAJOR >=1 +#include +#endif + +#define DEBUG_VIDEO_SURFACE_SINK QT_BEGIN_NAMESPACE @@ -71,10 +75,12 @@ QVideoSurfaceGstDelegate::QVideoSurfaceGstDelegate( if (m_surface) { foreach (QObject *instance, bufferPoolLoader()->instances(QGstBufferPoolPluginKey)) { QGstBufferPoolInterface* plugin = qobject_cast(instance); + if (plugin) { m_pools.append(plugin); } } + updateSupportedFormats(); connect(m_surface, SIGNAL(supportedFormatsChanged()), this, SLOT(updateSupportedFormats())); } @@ -208,6 +214,8 @@ GstFlowReturn QVideoSurfaceGstDelegate::render(GstBuffer *buffer) if (QThread::currentThread() == thread()) { if (!m_surface.isNull()) m_surface->present(m_frame); + else + qWarning() << "m_surface.isNull()."; } else { QMetaObject::invokeMethod(this, "queuedRender", Qt::QueuedConnection); m_renderCondition.wait(&m_mutex, 300); @@ -310,6 +318,27 @@ void QVideoSurfaceGstDelegate::updateSupportedFormats() } } +#if GST_CHECK_VERSION(1,0,0) +struct YuvFormat +{ + QVideoFrame::PixelFormat pixelFormat; + GstVideoFormat vfmt; + guint32 fourcc; + int bitsPerPixel; +}; + +static const YuvFormat qt_yuvColorLookup[] = +{ + { QVideoFrame::Format_YUV420P, GST_VIDEO_FORMAT_I420, GST_MAKE_FOURCC('I','4','2','0'), 8 }, + { QVideoFrame::Format_YV12, GST_VIDEO_FORMAT_YV12, GST_MAKE_FOURCC('Y','V','1','2'), 8 }, + { QVideoFrame::Format_UYVY, GST_VIDEO_FORMAT_UYVY, GST_MAKE_FOURCC('U','Y','V','Y'), 16 }, + { QVideoFrame::Format_YUYV, GST_VIDEO_FORMAT_YUY2, GST_MAKE_FOURCC('Y','U','Y','2'), 16 }, + { QVideoFrame::Format_NV12, GST_VIDEO_FORMAT_NV12, GST_MAKE_FOURCC('N','V','1','2'), 8 }, + { QVideoFrame::Format_NV21, GST_VIDEO_FORMAT_NV21, GST_MAKE_FOURCC('N','V','2','1'), 8 }, + { QVideoFrame::Format_AYUV444, GST_VIDEO_FORMAT_AYUV, GST_MAKE_FOURCC('A','Y','U','V'), 32 }, +}; + +#else struct YuvFormat { QVideoFrame::PixelFormat pixelFormat; @@ -327,6 +356,7 @@ static const YuvFormat qt_yuvColorLookup[] = { QVideoFrame::Format_NV21, GST_MAKE_FOURCC('N','V','2','1'), 8 }, { QVideoFrame::Format_AYUV444, GST_MAKE_FOURCC('A','Y','U','V'), 32 } }; +#endif static int indexOfYuvColor(QVideoFrame::PixelFormat format) { @@ -339,12 +369,20 @@ static int indexOfYuvColor(QVideoFrame::PixelFormat format) return -1; } +#if GST_VERSION_MAJOR >=1 +static int indexOfYuvColor(GstVideoFormat vfmt) +#else static int indexOfYuvColor(guint32 fourcc) +#endif { const int count = sizeof(qt_yuvColorLookup) / sizeof(YuvFormat); for (int i = 0; i < count; ++i) +#if GST_VERSION_MAJOR >=1 + if (qt_yuvColorLookup[i].vfmt == vfmt) +#else if (qt_yuvColorLookup[i].fourcc == fourcc) +#endif return i; return -1; @@ -417,13 +455,13 @@ GType QVideoSurfaceGstSink::get_type() if (type == 0) { static const GTypeInfo info = { - sizeof(QVideoSurfaceGstSinkClass), // class_size + sizeof(QVideoSurfaceGstSinkClass), // class_size base_init, // base_init NULL, // base_finalize class_init, // class_init NULL, // class_finalize NULL, // class_data - sizeof(QVideoSurfaceGstSink), // instance_size + sizeof(QVideoSurfaceGstSink), // instance_size 0, // n_preallocs instance_init, // instance_init 0 // value_table @@ -445,7 +483,11 @@ void QVideoSurfaceGstSink::class_init(gpointer g_class, gpointer class_data) GstBaseSinkClass *base_sink_class = reinterpret_cast(g_class); base_sink_class->get_caps = QVideoSurfaceGstSink::get_caps; base_sink_class->set_caps = QVideoSurfaceGstSink::set_caps; +// FIXME: +#if GST_CHECK_VERSION(1,0,0) +#else base_sink_class->buffer_alloc = QVideoSurfaceGstSink::buffer_alloc; +#endif base_sink_class->start = QVideoSurfaceGstSink::start; base_sink_class->stop = QVideoSurfaceGstSink::stop; // base_sink_class->unlock = QVideoSurfaceGstSink::unlock; // Not implemented. @@ -464,6 +506,18 @@ void QVideoSurfaceGstSink::base_init(gpointer g_class) { static GstStaticPadTemplate sink_pad_template = GST_STATIC_PAD_TEMPLATE( "sink", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS( +#if GST_CHECK_VERSION(1,0,0) + "video/x-raw, " + "format = (string) RGBA," + "framerate = (fraction) [ 0, MAX ], " + "width = (int) [ 1, MAX ], " + "height = (int) [ 1, MAX ]; " + "video/x-raw, " + "format = (string) I420," + "framerate = (fraction) [ 0, MAX ], " + "width = (int) [ 1, MAX ], " + "height = (int) [ 1, MAX ]")); +#else "video/x-raw-rgb, " "framerate = (fraction) [ 0, MAX ], " "width = (int) [ 1, MAX ], " @@ -472,6 +526,7 @@ void QVideoSurfaceGstSink::base_init(gpointer g_class) "framerate = (fraction) [ 0, MAX ], " "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")); +#endif gst_element_class_add_pad_template( GST_ELEMENT_CLASS(g_class), gst_static_pad_template_get(&sink_pad_template)); @@ -520,7 +575,11 @@ GstStateChangeReturn QVideoSurfaceGstSink::change_state( element, transition); } -GstCaps *QVideoSurfaceGstSink::get_caps(GstBaseSink *base) +GstCaps *QVideoSurfaceGstSink::get_caps(GstBaseSink *base +#if GST_CHECK_VERSION(1,0,0) + , GstCaps* /*filterCaps*/ +#endif +) { VO_SINK(base); @@ -533,6 +592,7 @@ GstCaps *QVideoSurfaceGstSink::get_caps(GstBaseSink *base) QList poolHandleFormats; sink->delegate->poolMutex()->lock(); QGstBufferPoolInterface *pool = sink->delegate->pool(); + if (pool) poolHandleFormats = sink->delegate->supportedPixelFormats(pool->handleType()); sink->delegate->poolMutex()->unlock(); @@ -548,11 +608,19 @@ GstCaps *QVideoSurfaceGstSink::get_caps(GstBaseSink *base) if (index != -1) { gst_caps_append_structure(caps, gst_structure_new( +#if GST_CHECK_VERSION(1,0,0) + "video/x-raw", +#else "video/x-raw-yuv", +#endif "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, INT_MAX, 1, "width" , GST_TYPE_INT_RANGE, 1, INT_MAX, "height" , GST_TYPE_INT_RANGE, 1, INT_MAX, - "format" , GST_TYPE_FOURCC, qt_yuvColorLookup[index].fourcc, +#if GST_CHECK_VERSION(1,0,0) + "format" , G_TYPE_STRING, gst_video_format_to_string(qt_yuvColorLookup[index].vfmt), +#else + "format" , G_TYPE_STRING, qt_yuvColorLookup[index].fourcc, +#endif NULL)); continue; } @@ -562,7 +630,18 @@ GstCaps *QVideoSurfaceGstSink::get_caps(GstBaseSink *base) for (int i = 0; i < count; ++i) { if (qt_rgbColorLookup[i].pixelFormat == format) { GstStructure *structure = gst_structure_new( +#if GST_CHECK_VERSION(1,0,0) + "video/x-raw", + "format" , G_TYPE_STRING, gst_video_format_to_string(gst_video_format_from_masks(qt_rgbColorLookup[i].depth, + qt_rgbColorLookup[i].bitsPerPixel, + qt_rgbColorLookup[i].endianness, + qt_rgbColorLookup[i].red, + qt_rgbColorLookup[i].green, + qt_rgbColorLookup[i].blue, + qt_rgbColorLookup[i].alpha)), +#else "video/x-raw-rgb", +#endif "framerate" , GST_TYPE_FRACTION_RANGE, 0, 1, INT_MAX, 1, "width" , GST_TYPE_INT_RANGE, 1, INT_MAX, "height" , GST_TYPE_INT_RANGE, 1, INT_MAX, @@ -583,6 +662,7 @@ GstCaps *QVideoSurfaceGstSink::get_caps(GstBaseSink *base) } } +// printf("get Caps %"GST_PTR_FORMAT"\n", caps); return caps; } @@ -622,7 +702,7 @@ gboolean QVideoSurfaceGstSink::set_caps(GstBaseSink *base, GstCaps *caps) sink->lastRequestedCaps = 0; #ifdef DEBUG_VIDEO_SURFACE_SINK - qDebug() << "Staring video surface, format:"; + qDebug() << "Starting video surface, format:"; qDebug() << format; qDebug() << "bytesPerLine:" << bytesPerLine; #endif @@ -647,11 +727,49 @@ QVideoSurfaceFormat QVideoSurfaceGstSink::formatForCaps(GstCaps *caps, int *byte gst_structure_get_int(structure, "width", &size.rwidth()); gst_structure_get_int(structure, "height", &size.rheight()); +#if GST_CHECK_VERSION(1, 0, 0) + GstVideoInfo info; + gst_video_info_from_caps(&info, caps); + + if (info.finfo->format == GST_VIDEO_FORMAT_I420) { + int index = indexOfYuvColor(GST_VIDEO_FORMAT_I420); + + if (index != -1) { + pixelFormat = qt_yuvColorLookup[index].pixelFormat; + bitsPerPixel = qt_yuvColorLookup[index].bitsPerPixel; + } + } else if (info.finfo->format == GST_VIDEO_FORMAT_RGBx) { + int depth = 0; + int endianness = 0; + int red = 0; + int green = 0; + int blue = 0; + int alpha = 0; + + gst_structure_get_int(structure, "bpp", &bitsPerPixel); + gst_structure_get_int(structure, "depth", &depth); + gst_structure_get_int(structure, "endianness", &endianness); + gst_structure_get_int(structure, "red_mask", &red); + gst_structure_get_int(structure, "green_mask", &green); + gst_structure_get_int(structure, "blue_mask", &blue); + gst_structure_get_int(structure, "alpha_mask", &alpha); + + int index = indexOfRgbColor(bitsPerPixel, depth, endianness, red, green, blue, alpha); + printf("INDEX %x\n", index); + if (index != -1) + pixelFormat = qt_rgbColorLookup[index].pixelFormat; + } +#else + if (qstrcmp(gst_structure_get_name(structure), "video/x-raw-yuv") == 0) { guint32 fourcc = 0; +#if GST_CHECK_VERSION(1, 0, 0) + int index = indexOfYuvColor(gst_video_format_from_string(gst_structure_get_string(structure, "format"))); +#else gst_structure_get_fourcc(structure, "format", &fourcc); int index = indexOfYuvColor(fourcc); +#endif if (index != -1) { pixelFormat = qt_yuvColorLookup[index].pixelFormat; bitsPerPixel = qt_yuvColorLookup[index].bitsPerPixel; @@ -677,6 +795,7 @@ QVideoSurfaceFormat QVideoSurfaceGstSink::formatForCaps(GstCaps *caps, int *byte if (index != -1) pixelFormat = qt_rgbColorLookup[index].pixelFormat; } +#endif if (pixelFormat != QVideoFrame::Format_Invalid) { QVideoSurfaceFormat format(size, pixelFormat, handleType); @@ -773,7 +892,11 @@ GstFlowReturn QVideoSurfaceGstSink::buffer_alloc( poolLock.unlock(); +#if GST_CHECK_VERSION(1,0,0) + GstCaps *intersection = gst_caps_intersect(get_caps(GST_BASE_SINK(sink), NULL), caps); +#else GstCaps *intersection = gst_caps_intersect(get_caps(GST_BASE_SINK(sink)), caps); +#endif if (gst_caps_is_empty (intersection)) { gst_caps_unref(intersection); @@ -814,7 +937,7 @@ GstFlowReturn QVideoSurfaceGstSink::buffer_alloc( QVideoSurfaceFormat surfaceFormat = sink->delegate->surfaceFormat(); if (!pool->isFormatSupported(surfaceFormat)) { - //qDebug() << "sink doesn't support native pool format, skip custom buffers allocation"; + qDebug() << "sink doesn't support native pool format, skip custom buffers allocation"; return GST_FLOW_OK; } @@ -838,7 +961,6 @@ GstFlowReturn QVideoSurfaceGstSink::buffer_alloc( gboolean QVideoSurfaceGstSink::start(GstBaseSink *base) { Q_UNUSED(base); - return TRUE; } @@ -864,8 +986,9 @@ gboolean QVideoSurfaceGstSink::event(GstBaseSink *base, GstEvent *event) VO_SINK(base); sink->delegate->setLastPrerolledBuffer(0); } - - return TRUE; +#if GST_CHECK_VERSION(1, 0, 0) + return GST_BASE_SINK_CLASS (sink_parent_class)->event (base, event); +#endif } GstFlowReturn QVideoSurfaceGstSink::preroll(GstBaseSink *base, GstBuffer *buffer) diff --git a/src/multimedia/gsttools_headers/qgstappsrc_p.h b/src/multimedia/gsttools_headers/qgstappsrc_p.h index bfb038e..a188e18 100644 --- a/src/multimedia/gsttools_headers/qgstappsrc_p.h +++ b/src/multimedia/gsttools_headers/qgstappsrc_p.h @@ -47,7 +47,10 @@ #include #include + +#if GST_VERSION_MAJOR < 1 #include +#endif QT_BEGIN_NAMESPACE diff --git a/src/multimedia/gsttools_headers/qgstreameraudioprobecontrol_p.h b/src/multimedia/gsttools_headers/qgstreameraudioprobecontrol_p.h index 71ea2ff..879f071 100644 --- a/src/multimedia/gsttools_headers/qgstreameraudioprobecontrol_p.h +++ b/src/multimedia/gsttools_headers/qgstreameraudioprobecontrol_p.h @@ -55,8 +55,11 @@ class QGstreamerAudioProbeControl : public QMediaAudioProbeControl public: explicit QGstreamerAudioProbeControl(QObject *parent); virtual ~QGstreamerAudioProbeControl(); - +#if GST_CHECK_VERSION(1,0,0) + void bufferProbed(GstBuffer* buffer, GstCaps* caps); +#else void bufferProbed(GstBuffer* buffer); +#endif private slots: void bufferProbed(); diff --git a/src/multimedia/gsttools_headers/qgstreamervideoprobecontrol_p.h b/src/multimedia/gsttools_headers/qgstreamervideoprobecontrol_p.h index c512b48..0a8a654 100644 --- a/src/multimedia/gsttools_headers/qgstreamervideoprobecontrol_p.h +++ b/src/multimedia/gsttools_headers/qgstreamervideoprobecontrol_p.h @@ -56,7 +56,11 @@ public: explicit QGstreamerVideoProbeControl(QObject *parent); virtual ~QGstreamerVideoProbeControl(); +#if GST_CHECK_VERSION(1,0,0) + void bufferProbed(GstBuffer* buffer, GstCaps*); +#else void bufferProbed(GstBuffer* buffer); +#endif void startFlushing(); void stopFlushing(); diff --git a/src/multimedia/gsttools_headers/qgstreamervideowindow_p.h b/src/multimedia/gsttools_headers/qgstreamervideowindow_p.h index 45582d6..4440337 100644 --- a/src/multimedia/gsttools_headers/qgstreamervideowindow_p.h +++ b/src/multimedia/gsttools_headers/qgstreamervideowindow_p.h @@ -112,7 +112,11 @@ private slots: void updateNativeVideoSize(); private: +#if GST_CHECK_VERSION(1,0,0) + static GstPadProbeReturn padBufferProbe(GstPad *pad, GstPadProbeInfo *info, gpointer user_data); +#else static void padBufferProbe(GstPad *pad, GstBuffer *buffer, gpointer user_data); +#endif GstElement *m_videoSink; WId m_windowId; diff --git a/src/multimedia/gsttools_headers/qgstutils_p.h b/src/multimedia/gsttools_headers/qgstutils_p.h index eea1e15..6369df7 100644 --- a/src/multimedia/gsttools_headers/qgstutils_p.h +++ b/src/multimedia/gsttools_headers/qgstutils_p.h @@ -70,7 +70,11 @@ namespace QGstUtils { QSize capsResolution(const GstCaps *caps); QSize capsCorrectedResolution(const GstCaps *caps); QAudioFormat audioFormatForCaps(const GstCaps *caps); +#if GST_CHECK_VERSION(1,0,0) + QAudioFormat audioFormatForSample(GstSample *sample); +#else QAudioFormat audioFormatForBuffer(GstBuffer *buffer); +#endif GstCaps *capsForAudioFormat(QAudioFormat format); void initializeGst(); QMultimedia::SupportEstimate hasSupport(const QString &mimeType, diff --git a/src/multimedia/gsttools_headers/qgstvideobuffer_p.h b/src/multimedia/gsttools_headers/qgstvideobuffer_p.h index 505a6c6..9bde1e0 100644 --- a/src/multimedia/gsttools_headers/qgstvideobuffer_p.h +++ b/src/multimedia/gsttools_headers/qgstvideobuffer_p.h @@ -79,6 +79,9 @@ private: int m_bytesPerLine; MapMode m_mode; QVariant m_handle; +#if GST_CHECK_VERSION(1,0,0) + GstMapInfo m_mapInfo; +#endif }; QT_END_NAMESPACE diff --git a/src/multimedia/gsttools_headers/qvideosurfacegstsink_p.h b/src/multimedia/gsttools_headers/qvideosurfacegstsink_p.h index 7563f06..505ff39 100644 --- a/src/multimedia/gsttools_headers/qvideosurfacegstsink_p.h +++ b/src/multimedia/gsttools_headers/qvideosurfacegstsink_p.h @@ -146,7 +146,11 @@ private: static GstStateChangeReturn change_state(GstElement *element, GstStateChange transition); - static GstCaps *get_caps(GstBaseSink *sink); + static GstCaps *get_caps(GstBaseSink *sink +#if GST_CHECK_VERSION(1,0,0) + , GstCaps* /*filterCaps*/ +#endif + ); static gboolean set_caps(GstBaseSink *sink, GstCaps *caps); static GstFlowReturn buffer_alloc( diff --git a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderserviceplugin.cpp b/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderserviceplugin.cpp index e6d2421..00291ab 100644 --- a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderserviceplugin.cpp +++ b/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderserviceplugin.cpp @@ -82,29 +82,42 @@ void QGstreamerAudioDecoderServicePlugin::updateSupportedMimeTypes() const gst_init(NULL, NULL); GList *plugins, *orig_plugins; +#if GST_CHECK_VERSION(1,0,0) + orig_plugins = plugins = gst_registry_get_plugin_list (gst_registry_get()); +#else orig_plugins = plugins = gst_default_registry_get_plugin_list (); - +#endif while (plugins) { GList *features, *orig_features; GstPlugin *plugin = (GstPlugin *) (plugins->data); plugins = g_list_next (plugins); +#if GST_CHECK_VERSION(1,0,0) + if (GST_OBJECT_FLAG_IS_SET(plugin, GST_PLUGIN_FLAG_BLACKLISTED)) + continue; +#else if (plugin->flags & (1<<1)) //GST_PLUGIN_FLAG_BLACKLISTED continue; - - orig_features = features = gst_registry_get_feature_list_by_plugin(gst_registry_get_default (), - plugin->desc.name); +#endif + orig_features = features = gst_registry_get_feature_list_by_plugin(gst_registry_get (), + gst_plugin_get_name(plugin)); while (features) { if (!G_UNLIKELY(features->data == NULL)) { GstPluginFeature *feature = GST_PLUGIN_FEATURE(features->data); if (GST_IS_ELEMENT_FACTORY (feature)) { GstElementFactory *factory = GST_ELEMENT_FACTORY(gst_plugin_feature_load(feature)); if (factory - && factory->numpadtemplates > 0 + && gst_element_factory_get_num_pad_templates(factory) > 0 +#if GST_CHECK_VERSION(1,0,0) + && (qstrcmp(gst_element_factory_get_metadata(factory, GST_ELEMENT_METADATA_KLASS), "Codec/Decoder/Audio") == 0 + || qstrcmp(gst_element_factory_get_metadata(factory, GST_ELEMENT_METADATA_KLASS), "Codec/Demux") == 0 ) +#else && (qstrcmp(factory->details.klass, "Codec/Decoder/Audio") == 0 - || qstrcmp(factory->details.klass, "Codec/Demux") == 0 )) { - const GList *pads = factory->staticpadtemplates; + || qstrcmp(factory->details.klass, "Codec/Demux") == 0 ) +#endif + ) { + const GList *pads = gst_element_factory_get_static_pad_templates(factory); while (pads) { GstStaticPadTemplate *padtemplate = (GstStaticPadTemplate*)(pads->data); pads = g_list_next (pads); diff --git a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodersession.cpp b/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodersession.cpp index 9f1a765..dd6bd02 100644 --- a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodersession.cpp +++ b/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodersession.cpp @@ -454,21 +454,40 @@ QAudioBuffer QGstreamerAudioDecoderSession::read() if (buffersAvailable == 1) emit bufferAvailableChanged(false); + const char* bufferData = 0; + int bufferSize = 0; + +#if GST_CHECK_VERSION(1,0,0) + GstSample *sample = gst_app_sink_pull_sample(m_appSink); + GstBuffer *buffer = gst_sample_get_buffer(sample); + GstMapInfo mapInfo; + gst_buffer_map(buffer, &mapInfo, GST_MAP_READ); + bufferData = (const char*)mapInfo.data; + bufferSize = mapInfo.size; + QAudioFormat format = QGstUtils::audioFormatForSample(sample); +#else GstBuffer *buffer = gst_app_sink_pull_buffer(m_appSink); - + bufferData = (const char*)buffer->data; + bufferSize = buffer->size; QAudioFormat format = QGstUtils::audioFormatForBuffer(buffer); +#endif + if (format.isValid()) { // XXX At the moment we have to copy data from GstBuffer into QAudioBuffer. // We could improve performance by implementing QAbstractAudioBuffer for GstBuffer. qint64 position = getPositionFromBuffer(buffer); - audioBuffer = QAudioBuffer(QByteArray((const char*)buffer->data, buffer->size), format, position); + audioBuffer = QAudioBuffer(QByteArray((const char*)bufferData, bufferSize), format, position); position /= 1000; // convert to milliseconds if (position != m_position) { m_position = position; emit positionChanged(m_position); } } +#if GST_CHECK_VERSION(1,0,0) + gst_sample_unref(sample); +#else gst_buffer_unref(buffer); +#endif } return audioBuffer; @@ -539,7 +558,12 @@ void QGstreamerAudioDecoderSession::addAppSink() GstAppSinkCallbacks callbacks; memset(&callbacks, 0, sizeof(callbacks)); +#if GST_CHECK_VERSION(1,0,0) + // ### Should perhaps also rename new_buffer to new_sample. + callbacks.new_sample = &new_buffer; +#else callbacks.new_buffer = &new_buffer; +#endif gst_app_sink_set_callbacks(m_appSink, &callbacks, this, NULL); gst_app_sink_set_max_buffers(m_appSink, MAX_BUFFERS_IN_QUEUE); gst_base_sink_set_sync(GST_BASE_SINK(m_appSink), FALSE); @@ -565,8 +589,13 @@ void QGstreamerAudioDecoderSession::updateDuration() gint64 gstDuration = 0; int duration = -1; +#if GST_CHECK_VERSION(1,0,0) + if (m_playbin && gst_element_query_duration(m_playbin, format, &gstDuration)) + duration = gstDuration / 1000000; +#else if (m_playbin && gst_element_query_duration(m_playbin, &format, &gstDuration)) duration = gstDuration / 1000000; +#endif if (m_duration != duration) { m_duration = duration; diff --git a/src/plugins/gstreamer/camerabin/camerabinsession.cpp b/src/plugins/gstreamer/camerabin/camerabinsession.cpp index 6e3448f..0dbf848 100644 --- a/src/plugins/gstreamer/camerabin/camerabinsession.cpp +++ b/src/plugins/gstreamer/camerabin/camerabinsession.cpp @@ -726,7 +726,11 @@ qint64 CameraBinSession::duration() const GstFormat format = GST_FORMAT_TIME; gint64 duration = 0; +#if GST_CHECK_VERSION(1,0,0) + if ( m_camerabin && gst_element_query_duration(m_camerabin, format, &duration)) +#else if ( m_camerabin && gst_element_query_position(m_camerabin, &format, &duration)) +#endif return duration / 1000000; else return 0; @@ -759,8 +763,13 @@ void CameraBinSession::setMetaData(const QMap &data) if (m_camerabin) { GstIterator *elements = gst_bin_iterate_all_by_interface(GST_BIN(m_camerabin), GST_TYPE_TAG_SETTER); +#if GST_CHECK_VERSION(1,0,0) + GValue *element = 0; + while (gst_iterator_next(elements, element) == GST_ITERATOR_OK) { +#else GstElement *element = 0; while (gst_iterator_next(elements, (void**)&element) == GST_ITERATOR_OK) { +#endif gst_tag_setter_reset_tags(GST_TAG_SETTER(element)); QMapIterator it(data); @@ -821,7 +830,11 @@ bool CameraBinSession::processSyncMessage(const QGstreamerMessage &message) if (gm && GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT) { if (m_captureMode == QCamera::CaptureStillImage && +#if GST_CHECK_VERSION(1,0,0) + gst_message_has_name (gm, "preview-image")) { +#else gst_structure_has_name(gm->structure, "preview-image")) { +#endif st = gst_message_get_structure(gm); if (gst_structure_has_field_typed(st, "buffer", GST_TYPE_BUFFER)) { @@ -831,7 +844,11 @@ bool CameraBinSession::processSyncMessage(const QGstreamerMessage &message) QImage img; +#if GST_CHECK_VERSION(1,0,0) GstCaps *caps = gst_buffer_get_caps(buffer); +#else + GstCaps *caps = gst_buffer_get_caps(buffer); +#endif if (caps) { GstStructure *structure = gst_caps_get_structure(caps, 0); gint width = 0; @@ -1103,7 +1120,11 @@ QList< QPair > CameraBinSession::supportedFrameRates(const QSize &frame gst_structure_remove_all_fields(structure); gst_structure_set_value(structure, "framerate", &rate); } +#if GST_CHECK_VERSION(1,0,0) + caps = gst_caps_simplify(caps); +#else gst_caps_do_simplify(caps); +#endif for (uint i=0; i CameraBinSession::supportedResolutions(QPair rate, gst_structure_set_value(structure, "width", &w); gst_structure_set_value(structure, "height", &h); } +#if GST_CHECK_VERSION(1,0,0) + caps = gst_caps_simplify(caps); +#else gst_caps_do_simplify(caps); +#endif for (uint i=0; ishowPrerollFrames(false); // stop showing prerolled frames in stop state } + qWarning() << "Processing EOS!"; + popAndNotifyState(); } diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayerservice.cpp b/src/plugins/gstreamer/mediaplayer/qgstreamerplayerservice.cpp index 854da46..2fd4345 100644 --- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayerservice.cpp +++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayerservice.cpp @@ -59,7 +59,11 @@ #include #if defined(Q_WS_MAEMO_6) && defined(__arm__) -#include "qgstreamergltexturerenderer.h" +#include "private/qgstreamergltexturerenderer.h" +#endif + +#if defined(HAVE_MIR) && defined (__arm__) +#include "private/qgstreamermirtexturerenderer_p.h" #endif #include "qgstreamerstreamscontrol.h" @@ -90,6 +94,9 @@ QGstreamerPlayerService::QGstreamerPlayerService(QObject *parent): #if defined(Q_WS_MAEMO_6) && defined(__arm__) m_videoRenderer = new QGstreamerGLTextureRenderer(this); +#elif defined(HAVE_MIR) && defined (__arm__) + //m_videoRenderer = new QGstreamerVideoRenderer(this); + m_videoRenderer = new QGstreamerMirTextureRenderer(this, m_session); #else m_videoRenderer = new QGstreamerVideoRenderer(this); #endif diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayerserviceplugin.cpp b/src/plugins/gstreamer/mediaplayer/qgstreamerplayerserviceplugin.cpp index a9052ca..7968799 100644 --- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayerserviceplugin.cpp +++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayerserviceplugin.cpp @@ -95,7 +95,11 @@ void QGstreamerPlayerServicePlugin::updateSupportedMimeTypes() const gst_init(NULL, NULL); GList *plugins, *orig_plugins; +#if GST_CHECK_VERSION(1,0,0) + orig_plugins = plugins = gst_registry_get_plugin_list (gst_registry_get()); +#else orig_plugins = plugins = gst_default_registry_get_plugin_list (); +#endif while (plugins) { GList *features, *orig_features; @@ -103,22 +107,33 @@ void QGstreamerPlayerServicePlugin::updateSupportedMimeTypes() const GstPlugin *plugin = (GstPlugin *) (plugins->data); plugins = g_list_next (plugins); +#if GST_CHECK_VERSION(1,0,0) + if (GST_OBJECT_FLAG_IS_SET(plugin, GST_PLUGIN_FLAG_BLACKLISTED)) + continue; +#else if (plugin->flags & (1<<1)) //GST_PLUGIN_FLAG_BLACKLISTED continue; +#endif - orig_features = features = gst_registry_get_feature_list_by_plugin(gst_registry_get_default (), - plugin->desc.name); + orig_features = features = gst_registry_get_feature_list_by_plugin(gst_registry_get(), + gst_plugin_get_name(plugin)); while (features) { if (!G_UNLIKELY(features->data == NULL)) { GstPluginFeature *feature = GST_PLUGIN_FEATURE(features->data); if (GST_IS_ELEMENT_FACTORY (feature)) { GstElementFactory *factory = GST_ELEMENT_FACTORY(gst_plugin_feature_load(feature)); if (factory - && factory->numpadtemplates > 0 - && (qstrcmp(factory->details.klass, "Codec/Decoder/Audio") == 0 +#if GST_CHECK_VERSION(1,0,0) + && (qstrcmp(gst_element_factory_get_metadata(factory, GST_ELEMENT_METADATA_KLASS), "Codec/Decoder/Audio") == 0 + || qstrcmp(gst_element_factory_get_metadata(factory, GST_ELEMENT_METADATA_KLASS),"Codec/Decoder/Video") == 0 + || qstrcmp(gst_element_factory_get_metadata(factory, GST_ELEMENT_METADATA_KLASS), "Codec/Demux") == 0 ) +#else + && (qstrcmp(factory->details.klass, "Codec/Decoder/Audio") == 0 || qstrcmp(factory->details.klass, "Codec/Decoder/Video") == 0 - || qstrcmp(factory->details.klass, "Codec/Demux") == 0 )) { - const GList *pads = factory->staticpadtemplates; + || qstrcmp(factory->details.klass, "Codec/Demux") == 0 ) +#endif + ) { + const GList *pads = gst_element_factory_get_static_pad_templates(factory); while (pads) { GstStaticPadTemplate *padtemplate = (GstStaticPadTemplate*)(pads->data); pads = g_list_next (pads); diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp index 87b71d7..03185a2 100644 --- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp +++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp @@ -93,6 +93,16 @@ typedef enum { GST_PLAY_FLAG_BUFFERING = 0x000000100 } GstPlayFlags; +#if GST_CHECK_VERSION(1,0,0) +#define DEFAULT_RAW_CAPS \ + "video/x-surface; " \ + "text/plain; " \ + "text/x-pango-markup; " \ + "video/x-dvd-subpicture; " \ + "subpicture/x-pgs" \ + "video/x-raw" \ + "audio/x-raw" +#else #define DEFAULT_RAW_CAPS \ "video/x-raw-yuv; " \ "video/x-raw-rgb; " \ @@ -105,6 +115,8 @@ typedef enum { "text/x-pango-markup; " \ "video/x-dvd-subpicture; " \ "subpicture/x-pgs" +#endif + static GstStaticCaps static_RawCaps = GST_STATIC_CAPS(DEFAULT_RAW_CAPS); QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent) @@ -145,8 +157,11 @@ QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent) gboolean result = gst_type_find_register(0, "playlist", GST_RANK_MARGINAL, playlistTypeFindFunction, 0, 0, this, 0); Q_ASSERT(result == TRUE); Q_UNUSED(result); - +#if GST_CHECK_VERSION(1,0,0) + m_playbin = gst_element_factory_make("playbin", NULL); +#else m_playbin = gst_element_factory_make("playbin2", NULL); +#endif if (m_playbin) { //GST_PLAY_FLAG_NATIVE_VIDEO omits configuration of ffmpegcolorspace and videoscale, @@ -196,7 +211,11 @@ QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent) m_videoIdentity = GST_ELEMENT(g_object_new(gst_video_connector_get_type(), 0)); // floating ref g_signal_connect(G_OBJECT(m_videoIdentity), "connection-failed", G_CALLBACK(insertColorSpaceElement), (gpointer)this); +#if GST_CHECK_VERSION(1,0,0) + m_colorSpace = gst_element_factory_make("videoconvert", "ffmpegcolorspace-vo"); +#else m_colorSpace = gst_element_factory_make("ffmpegcolorspace", "ffmpegcolorspace-vo"); +#endif // might not get a parent, take ownership to avoid leak qt_gst_object_ref_sink(GST_OBJECT(m_colorSpace)); @@ -214,7 +233,7 @@ QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent) // add ghostpads GstPad *pad = gst_element_get_static_pad(m_videoIdentity,"sink"); - gst_element_add_pad(GST_ELEMENT(m_videoOutputBin), gst_ghost_pad_new("videosink", pad)); + gst_element_add_pad(GST_ELEMENT(m_videoOutputBin), gst_ghost_pad_new("sink", pad)); gst_object_unref(GST_OBJECT(pad)); if (m_playbin != 0) { @@ -226,7 +245,7 @@ QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent) g_object_set(G_OBJECT(m_playbin), "video-sink", m_videoOutputBin, NULL); g_signal_connect(G_OBJECT(m_playbin), "notify::source", G_CALLBACK(playbinNotifySource), this); - g_signal_connect(G_OBJECT(m_playbin), "element-added", G_CALLBACK(handleElementAdded), this); + //g_signal_connect(G_OBJECT(m_playbin), "element-added", G_CALLBACK(handleElementAdded), this); if (usePlaybinVolume()) { updateVolume(); @@ -350,9 +369,13 @@ qint64 QGstreamerPlayerSession::position() const GstFormat format = GST_FORMAT_TIME; gint64 position = 0; +#if GST_CHECK_VERSION(1,0,0) + if ( m_playbin && gst_element_query_position(m_playbin, format, &position)) + m_lastPosition = position / 1000000; +#else if ( m_playbin && gst_element_query_position(m_playbin, &format, &position)) m_lastPosition = position / 1000000; - +#endif return m_lastPosition; } @@ -482,9 +505,18 @@ bool QGstreamerPlayerSession::isAudioAvailable() const return m_audioAvailable; } +#if GST_CHECK_VERSION(1,0,0) +static GstPadProbeReturn block_pad_cb(GstPad *pad, GstPadProbeInfo *info, gpointer user_data) +#else static void block_pad_cb(GstPad *pad, gboolean blocked, gpointer user_data) +#endif { Q_UNUSED(pad); +#if GST_CHECK_VERSION(1,0,0) + Q_UNUSED(info); + Q_UNUSED(user_data); + return GST_PAD_PROBE_OK; +#else #ifdef DEBUG_PLAYBIN qDebug() << "block_pad_cb, blocked:" << blocked; #endif @@ -493,6 +525,7 @@ static void block_pad_cb(GstPad *pad, gboolean blocked, gpointer user_data) QGstreamerPlayerSession *session = reinterpret_cast(user_data); QMetaObject::invokeMethod(session, "finishVideoOutputChange", Qt::QueuedConnection); } +#endif } void QGstreamerPlayerSession::updateVideoRenderer() @@ -537,7 +570,7 @@ void QGstreamerPlayerSession::setVideoRenderer(QObject *videoOutput) m_renderer = renderer; #ifdef DEBUG_VO_BIN_DUMP - _gst_debug_bin_to_dot_file_with_ts(GST_BIN(m_playbin), + gst_debug_bin_to_dot_file_with_ts(GST_BIN(m_playbin), GstDebugGraphDetails(GST_DEBUG_GRAPH_SHOW_ALL /* GST_DEBUG_GRAPH_SHOW_MEDIA_TYPE | GST_DEBUG_GRAPH_SHOW_NON_DEFAULT_PARAMS | GST_DEBUG_GRAPH_SHOW_STATES*/), "playbin_set"); #endif @@ -641,7 +674,11 @@ void QGstreamerPlayerSession::setVideoRenderer(QObject *videoOutput) //block pads, async to avoid locking in paused state GstPad *srcPad = gst_element_get_static_pad(m_videoIdentity, "src"); +#if GST_CHECK_VERSION(1,0,0) + this->pad_probe_id = gst_pad_add_probe(srcPad, (GstPadProbeType)(GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_BLOCK), block_pad_cb, this, NULL); +#else gst_pad_set_blocked_async(srcPad, true, &block_pad_cb, this); +#endif gst_object_unref(GST_OBJECT(srcPad)); //Unpause the sink to avoid waiting until the buffer is processed @@ -682,7 +719,11 @@ void QGstreamerPlayerSession::finishVideoOutputChange() //video output was change back to the current one, //no need to torment the pipeline, just unblock the pad if (gst_pad_is_blocked(srcPad)) +#if GST_CHECK_VERSION(1,0,0) + gst_pad_remove_probe(srcPad, this->pad_probe_id); +#else gst_pad_set_blocked_async(srcPad, false, &block_pad_cb, 0); +#endif m_pendingVideoSink = 0; gst_object_unref(GST_OBJECT(srcPad)); @@ -768,12 +809,17 @@ void QGstreamerPlayerSession::finishVideoOutputChange() //don't have to wait here, it will unblock eventually if (gst_pad_is_blocked(srcPad)) - gst_pad_set_blocked_async(srcPad, false, &block_pad_cb, 0); +#if GST_CHECK_VERSION(1,0,0) + gst_pad_remove_probe(srcPad, this->pad_probe_id); +#else + gst_pad_set_blocked_async(srcPad, false, &block_pad_cb, 0); +#endif + gst_object_unref(GST_OBJECT(srcPad)); #ifdef DEBUG_VO_BIN_DUMP - _gst_debug_bin_to_dot_file_with_ts(GST_BIN(m_playbin), - GstDebugGraphDetails(GST_DEBUG_GRAPH_SHOW_ALL /* GST_DEBUG_GRAPH_SHOW_MEDIA_TYPE | GST_DEBUG_GRAPH_SHOW_NON_DEFAULT_PARAMS | GST_DEBUG_GRAPH_SHOW_STATES*/), + gst_debug_bin_to_dot_file_with_ts(GST_BIN(m_playbin), + GstDebugGraphDetails(GST_DEBUG_GRAPH_SHOW_ALL /* | GST_DEBUG_GRAPH_SHOW_MEDIA_TYPE | GST_DEBUG_GRAPH_SHOW_NON_DEFAULT_PARAMS | GST_DEBUG_GRAPH_SHOW_STATES */), "playbin_finish"); #endif } @@ -838,6 +884,7 @@ bool QGstreamerPlayerSession::play() #ifdef DEBUG_PLAYBIN qDebug() << Q_FUNC_INFO; #endif + m_everPlayed = false; if (m_playbin) { m_pendingState = QMediaPlayer::PlayingState; @@ -1335,8 +1382,11 @@ void QGstreamerPlayerSession::getStreamsInfo() default: break; } - +#if GST_CHECK_VERSION(1,0,0) + if (tags && GST_IS_TAG_LIST(tags)) { +#else if (tags && gst_is_tag_list(tags)) { +#endif gchar *languageCode = 0; if (gst_tag_list_get_string(tags, GST_TAG_LANGUAGE_CODE, &languageCode)) streamProperties[QMediaMetaData::Language] = QString::fromUtf8(languageCode); @@ -1375,7 +1425,11 @@ void QGstreamerPlayerSession::updateVideoResolutionTag() QSize aspectRatio; GstPad *pad = gst_element_get_static_pad(m_videoIdentity, "src"); +#if GST_CHECK_VERSION(1,0,0) + GstCaps *caps = gst_pad_get_current_caps(pad); +#else GstCaps *caps = gst_pad_get_negotiated_caps(pad); +#endif if (caps) { const GstStructure *structure = gst_caps_get_structure(caps, 0); @@ -1419,7 +1473,11 @@ void QGstreamerPlayerSession::updateDuration() gint64 gstDuration = 0; int duration = -1; +#if GST_CHECK_VERSION(1,0,0) + if (m_playbin && gst_element_query_duration(m_playbin, format, &gstDuration)) +#else if (m_playbin && gst_element_query_duration(m_playbin, &format, &gstDuration)) +#endif duration = gstDuration / 1000000; if (m_duration != duration) { @@ -1475,7 +1533,11 @@ void QGstreamerPlayerSession::playbinNotifySource(GObject *o, GParamSpec *p, gpo // The rest if (g_object_class_find_property(G_OBJECT_GET_CLASS(source), "extra-headers") != 0) { +#if GST_CHECK_VERSION(1,0,0) + GstStructure *extras = gst_structure_new_empty("extras"); +#else GstStructure *extras = gst_structure_empty_new("extras"); +#endif foreach (const QByteArray &rawHeader, self->m_request.rawHeaderList()) { if (rawHeader == userAgentString) // Filter User-Agent @@ -1630,7 +1692,11 @@ GstAutoplugSelectResult QGstreamerPlayerSession::handleAutoplugSelect(GstBin *bi const gchar *factoryName = gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(factory)); if (g_str_has_prefix(factoryName, "vaapi")) { GstPad *sinkPad = gst_element_get_static_pad(session->m_videoSink, "sink"); +#if GST_CHECK_VERSION(1,0,0) + GstCaps *sinkCaps = gst_pad_query_caps(sinkPad, NULL); +#else GstCaps *sinkCaps = gst_pad_get_caps(sinkPad); +#endif #if (GST_VERSION_MAJOR == 0) && ((GST_VERSION_MINOR < 10) || (GST_VERSION_MICRO < 33)) if (!factory_can_src_any_caps(factory, sinkCaps)) @@ -1659,14 +1725,19 @@ void QGstreamerPlayerSession::handleElementAdded(GstBin *bin, GstElement *elemen // Disable on-disk buffering. g_object_set(G_OBJECT(element), "temp-template", NULL, NULL); } else if (g_str_has_prefix(elementName, "uridecodebin") || - g_str_has_prefix(elementName, "decodebin2")) { - +#if GST_CHECK_VERSION(1,0,0) + g_str_has_prefix(elementName, "decodebin")) { +#else + g_str_has_prefix(elementName, "decodebin2")) { +#endif if (g_str_has_prefix(elementName, "uridecodebin")) { // Add video/x-surface (VAAPI) to default raw formats g_object_set(G_OBJECT(element), "caps", gst_static_caps_get(&static_RawCaps), NULL); // listen for uridecodebin autoplug-select to skip VAAPI usage when the current // video sink doesn't support it +#if !(GST_CHECK_VERSION(1,0,0)) g_signal_connect(element, "autoplug-select", G_CALLBACK(handleAutoplugSelect), session); +#endif } //listen for queue2 element added to uridecodebin/decodebin2 as well. @@ -1734,7 +1805,27 @@ void QGstreamerPlayerSession::removeProbe(QGstreamerVideoProbeControl* probe) // Assume user releases any outstanding references to video frames. } -gboolean QGstreamerPlayerSession::padVideoBufferProbe(GstPad *pad, GstBuffer *buffer, gpointer user_data) +#if GST_CHECK_VERSION(1,0,0) +GstPadProbeReturn QGstreamerPlayerSession::padVideoBufferProbe(GstPad *pad, GstPadProbeInfo *info, gpointer user_data) +{ + Q_UNUSED(pad); + GstBuffer* buffer = GST_PAD_PROBE_INFO_BUFFER(info); + + QGstreamerPlayerSession *session = reinterpret_cast(user_data); + QMutexLocker locker(&session->m_videoProbeMutex); + + if (session->m_videoProbes.isEmpty()) + return GST_PAD_PROBE_OK; + + foreach (QGstreamerVideoProbeControl* probe, session->m_videoProbes) + probe->bufferProbed(buffer, gst_pad_get_current_caps(pad)); + + return GST_PAD_PROBE_OK; +} + +#else + +static gboolean QGstreamerPlayerSession::padVideoBufferProbe(GstPad *pad, GstBuffer *buffer, gpointer user_data) { Q_UNUSED(pad); @@ -1749,6 +1840,7 @@ gboolean QGstreamerPlayerSession::padVideoBufferProbe(GstPad *pad, GstBuffer *bu return TRUE; } +#endif void QGstreamerPlayerSession::addProbe(QGstreamerAudioProbeControl* probe) { @@ -1766,6 +1858,24 @@ void QGstreamerPlayerSession::removeProbe(QGstreamerAudioProbeControl* probe) m_audioProbes.removeOne(probe); } +#if GST_CHECK_VERSION(1,0,0) +GstPadProbeReturn QGstreamerPlayerSession::padAudioBufferProbe(GstPad *pad, GstPadProbeInfo* info, gpointer user_data) +{ + Q_UNUSED(pad); + GstBuffer* buffer = GST_PAD_PROBE_INFO_BUFFER(info); + + QGstreamerPlayerSession *session = reinterpret_cast(user_data); + QMutexLocker locker(&session->m_audioProbeMutex); + + if (session->m_audioProbes.isEmpty()) + return GST_PAD_PROBE_OK; + + foreach (QGstreamerAudioProbeControl* probe, session->m_audioProbes) + probe->bufferProbed(buffer, gst_pad_get_current_caps(pad)); + + return GST_PAD_PROBE_OK; +} +#else gboolean QGstreamerPlayerSession::padAudioBufferProbe(GstPad *pad, GstBuffer *buffer, gpointer user_data) { Q_UNUSED(pad); @@ -1781,7 +1891,7 @@ gboolean QGstreamerPlayerSession::padAudioBufferProbe(GstPad *pad, GstBuffer *bu return TRUE; } - +#endif // This function is similar to stop(), // but does not set m_everPlayed, m_lastPosition, // and setSeekable() values. @@ -1814,7 +1924,11 @@ void QGstreamerPlayerSession::removeVideoBufferProbe() GstPad *pad = gst_element_get_static_pad(m_videoSink, "sink"); if (pad) { +#if GST_CHECK_VERSION(1,0,0) + gst_pad_remove_probe(pad, m_videoBufferProbeId); +#else gst_pad_remove_buffer_probe(pad, m_videoBufferProbeId); +#endif gst_object_unref(GST_OBJECT(pad)); } @@ -1829,7 +1943,11 @@ void QGstreamerPlayerSession::addVideoBufferProbe() GstPad *pad = gst_element_get_static_pad(m_videoSink, "sink"); if (pad) { +#if GST_CHECK_VERSION(1,0,0) + m_videoBufferProbeId = gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_BUFFER, padVideoBufferProbe, this, NULL); +#else m_videoBufferProbeId = gst_pad_add_buffer_probe(pad, G_CALLBACK(padVideoBufferProbe), this); +#endif gst_object_unref(GST_OBJECT(pad)); } } @@ -1846,7 +1964,11 @@ void QGstreamerPlayerSession::removeAudioBufferProbe() GstPad *pad = gst_element_get_static_pad(m_audioSink, "sink"); if (pad) { +#if GST_CHECK_VERSION(1,0,0) + gst_pad_remove_probe(pad, m_audioBufferProbeId); +#else gst_pad_remove_buffer_probe(pad, m_audioBufferProbeId); +#endif gst_object_unref(GST_OBJECT(pad)); } @@ -1861,7 +1983,11 @@ void QGstreamerPlayerSession::addAudioBufferProbe() GstPad *pad = gst_element_get_static_pad(m_audioSink, "sink"); if (pad) { +#if GST_CHECK_VERSION(1,0,0) + m_audioBufferProbeId = gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_BUFFER, padAudioBufferProbe, this, NULL); +#else m_audioBufferProbeId = gst_pad_add_buffer_probe(pad, G_CALLBACK(padAudioBufferProbe), this); +#endif gst_object_unref(GST_OBJECT(pad)); } } @@ -1894,7 +2020,7 @@ void QGstreamerPlayerSession::playlistTypeFindFunction(GstTypeFind *find, gpoint length = qMin(length, guint64(1024)); while (length > 0) { - guint8 *data = gst_type_find_peek(find, 0, length); + const guint8 *data = gst_type_find_peek(find, 0, length); if (data) { session->m_isPlaylist = (QPlaylistFileParser::findPlaylistType(QString::fromUtf8(uri), 0, data, length) != QPlaylistFileParser::UNKNOWN); return; diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h index 23e7031..707779b 100644 --- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h +++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h @@ -127,11 +127,19 @@ public: void addProbe(QGstreamerVideoProbeControl* probe); void removeProbe(QGstreamerVideoProbeControl* probe); +#if GST_CHECK_VERSION(1,0,0) + static GstPadProbeReturn padVideoBufferProbe(GstPad *pad, GstPadProbeInfo *info, gpointer user_data); +#else static gboolean padVideoBufferProbe(GstPad *pad, GstBuffer *buffer, gpointer user_data); +#endif void addProbe(QGstreamerAudioProbeControl* probe); void removeProbe(QGstreamerAudioProbeControl* probe); +#if GST_CHECK_VERSION(1,0,0) + static GstPadProbeReturn padAudioBufferProbe(GstPad *pad, GstPadProbeInfo* info, gpointer user_data); +#else static gboolean padAudioBufferProbe(GstPad *pad, GstBuffer *buffer, gpointer user_data); +#endif void endOfMediaReset(); @@ -260,6 +268,7 @@ private: bool m_isLiveSource; bool m_isPlaylist; + gulong pad_probe_id; }; QT_END_NAMESPACE -- 2.0.0