From f2f655c9cf4a55171f2ac19d0ca7e0b4afbd8175 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Sat, 21 Feb 2009 18:42:46 +0000 Subject: [PATCH 01/52] Back to development -> 0.10.14.1 --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 43c12c5028..4179daa9a3 100644 --- a/configure.ac +++ b/configure.ac @@ -5,7 +5,7 @@ dnl please read gstreamer/docs/random/autotools before changing this file dnl initialize autoconf dnl releases only do -Wall, cvs and prerelease does -Werror too dnl use a three digit version number for releases, and four for cvs/pre -AC_INIT(GStreamer Good Plug-ins, 0.10.14, +AC_INIT(GStreamer Good Plug-ins, 0.10.14.1, http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer, gst-plugins-good) From 2f203be331107efeaffed3e4e03a704c4c8a85ac Mon Sep 17 00:00:00 2001 From: David Schleef Date: Sat, 21 Feb 2009 11:13:43 -0800 Subject: [PATCH 02/52] Automatic update of common submodule From 80c627d to 5d7c9cc --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common b/common index 80c627dfab..5d7c9cc163 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 80c627dfabb45c3f40727dce755c81bed1e38e3d +Subproject commit 5d7c9cc163b211f5f3a9b8663e055c03bdacb343 From b6e745d2d3690883b1d9c0e9e5f31d38a4fd967a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Sun, 22 Feb 2009 12:41:53 +0100 Subject: [PATCH 03/52] hdv1394src: Don't use void * pointer arithmetic --- ext/raw1394/gsthdv1394src.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/raw1394/gsthdv1394src.c b/ext/raw1394/gsthdv1394src.c index cbb02136f1..30f59d5909 100644 --- a/ext/raw1394/gsthdv1394src.c +++ b/ext/raw1394/gsthdv1394src.c @@ -317,7 +317,7 @@ gst_hdv1394src_iec61883_receive (unsigned char *data, int len, return -1; if (len == IEC61883_MPEG2_TSP_SIZE) { - memcpy (dv1394src->outdata + dv1394src->outoffset, data, len); + memcpy ((guint8 *) dv1394src->outdata + dv1394src->outoffset, data, len); dv1394src->outoffset += len; } dv1394src->frame_sequence++; From 64a91fcf8a40e660a75ee1e427cb23d6a2febdd8 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Sun, 22 Feb 2009 15:52:06 +0000 Subject: [PATCH 04/52] Automatic update of common submodule From 5d7c9cc to 9cf8c9b --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common b/common index 5d7c9cc163..9cf8c9b62f 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 5d7c9cc163b211f5f3a9b8663e055c03bdacb343 +Subproject commit 9cf8c9b62f6b2d9e43b7fb0cb9dcfb86b8ceba01 From dfa627da30dd44e170f3249ff3bdda333ea1edf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Sun, 22 Feb 2009 18:08:59 +0100 Subject: [PATCH 05/52] pulsemixer: Don't use g_atomic_int_(get|set) for accessing the mixer track flags g_atomic_int_(get|set) only work on ints and the flags are an enum (which on most architectures is stored as an int). Also the way the flags were accessed atomically would still leave a possible race condition and we don't do it in any other mixer track implementation, let alone at any other place where an integer could be changed from different threads. Removing the g_atomic_int_(get|set) will only introduce a new race condition on architectures where integers could be half-written while reading them which shouldn't be the case for any modern architecture and if we really care about this we need to use g_atomic_int_(get|set) at many other places too. Apart from that g_atomic_int_(set|get) will result in aliasing warnings if their argument is explicitely casted to an int *. Fixes bug #571153. --- ext/pulse/pulsemixerctrl.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/ext/pulse/pulsemixerctrl.c b/ext/pulse/pulsemixerctrl.c index 41b68cfcd2..ae807c6609 100644 --- a/ext/pulse/pulsemixerctrl.c +++ b/ext/pulse/pulsemixerctrl.c @@ -93,10 +93,11 @@ gst_pulsemixer_ctrl_sink_info_cb (pa_context * context, const pa_sink_info * i, c->type = GST_PULSEMIXER_SINK; if (c->track) { - int i = g_atomic_int_get ((gint *) & c->track->flags); + GstMixerTrackFlags flags = c->track->flags; - i = (i & ~GST_MIXER_TRACK_MUTE) | (c->muted ? GST_MIXER_TRACK_MUTE : 0); - g_atomic_int_set ((gint *) & c->track->flags, i); + flags = + (flags & ~GST_MIXER_TRACK_MUTE) | (c->muted ? GST_MIXER_TRACK_MUTE : 0); + c->track->flags = flags; } c->operation_success = 1; @@ -142,10 +143,11 @@ gst_pulsemixer_ctrl_source_info_cb (pa_context * context, c->type = GST_PULSEMIXER_SOURCE; if (c->track) { - int i = g_atomic_int_get ((gint *) & c->track->flags); + GstMixerTrackFlags flags = c->track->flags; - i = (i & ~GST_MIXER_TRACK_MUTE) | (c->muted ? GST_MIXER_TRACK_MUTE : 0); - g_atomic_int_set ((gint *) & c->track->flags, i); + flags = + (flags & ~GST_MIXER_TRACK_MUTE) | (c->muted ? GST_MIXER_TRACK_MUTE : 0); + c->track->flags = flags; } c->operation_success = 1; @@ -572,10 +574,11 @@ gst_pulsemixer_ctrl_set_mute (GstPulseMixerCtrl * c, GstMixerTrack * track, c->update_mute = TRUE; if (c->track) { - int i = g_atomic_int_get ((gint *) & c->track->flags); + GstMixerTrackFlags flags = c->track->flags; - i = (i & ~GST_MIXER_TRACK_MUTE) | (c->muted ? GST_MIXER_TRACK_MUTE : 0); - g_atomic_int_set ((gint *) & c->track->flags, i); + flags = + (flags & ~GST_MIXER_TRACK_MUTE) | (c->muted ? GST_MIXER_TRACK_MUTE : 0); + c->track->flags = flags; } restart_time_event (c); From 6756475fd3af29844a77bcb08d9943070daf6f9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Sun, 22 Feb 2009 18:32:02 +0100 Subject: [PATCH 06/52] avidemux: Fix alignment issues by using GST_READ_* Reading integers from random memory addresses will result in SIGBUS on some architectures if the memory address is not correctly aligned. This can happen at two places in avidemux so we should use GST_READ_UINT32_LE and friends here. Fixes bug #572256. --- gst/avi/gstavidemux.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gst/avi/gstavidemux.c b/gst/avi/gstavidemux.c index 7a3166cfd7..2473b922ce 100644 --- a/gst/avi/gstavidemux.c +++ b/gst/avi/gstavidemux.c @@ -1707,7 +1707,7 @@ gst_avi_demux_parse_odml (GstAviDemux * avi, GstBuffer * buf) goto next; } _dmlh = (gst_riff_dmlh *) GST_BUFFER_DATA (sub); - dmlh.totalframes = GUINT32_FROM_LE (_dmlh->totalframes); + dmlh.totalframes = GST_READ_UINT32_LE (&_dmlh->totalframes); GST_INFO_OBJECT (avi, "dmlh tag found:"); GST_INFO_OBJECT (avi, " totalframes: %u", dmlh.totalframes); @@ -1799,10 +1799,10 @@ gst_avi_demux_parse_index (GstAviDemux * avi, GstFormat format; _entry = &((gst_riff_index_entry *) data)[i]; - entry.id = GUINT32_FROM_LE (_entry->id); - entry.offset = GUINT32_FROM_LE (_entry->offset); - entry.flags = GUINT32_FROM_LE (_entry->flags); - entry.size = GUINT32_FROM_LE (_entry->size); + entry.id = GST_READ_UINT32_LE (&_entry->id); + entry.offset = GST_READ_UINT32_LE (&_entry->offset); + entry.flags = GST_READ_UINT32_LE (&_entry->flags); + entry.size = GST_READ_UINT32_LE (&_entry->size); target = &entries[n]; if (entry.id == GST_RIFF_rec || entry.id == 0 || From b3a90202c12619bb32712a5d185d48b6286911e6 Mon Sep 17 00:00:00 2001 From: Olivier Crete Date: Sun, 22 Feb 2009 18:46:03 +0100 Subject: [PATCH 07/52] alaw/mulaw: Don't require both, rate and channel, to be set in _getcaps Fixes bug #572358. --- gst/law/alaw-encode.c | 22 ++++++++++------------ gst/law/mulaw-encode.c | 22 ++++++++++------------ 2 files changed, 20 insertions(+), 24 deletions(-) diff --git a/gst/law/alaw-encode.c b/gst/law/alaw-encode.c index ba8587a2d4..b98d8e2e6f 100644 --- a/gst/law/alaw-encode.c +++ b/gst/law/alaw-encode.c @@ -318,8 +318,8 @@ gst_alaw_enc_getcaps (GstPad * pad) GstStructure *structure; const GValue *orate, *ochans; const GValue *rate, *chans; - GValue irate = { 0 }, ichans = { - 0}; + GValue irate = { 0 }; + GValue ichans = { 0 }; if (gst_caps_is_empty (othercaps) || gst_caps_is_any (othercaps)) goto done; @@ -327,22 +327,20 @@ gst_alaw_enc_getcaps (GstPad * pad) structure = gst_caps_get_structure (othercaps, 0); orate = gst_structure_get_value (structure, "rate"); ochans = gst_structure_get_value (structure, "channels"); - if (!orate || !ochans) - goto done; structure = gst_caps_get_structure (base_caps, 0); rate = gst_structure_get_value (structure, "rate"); chans = gst_structure_get_value (structure, "channels"); - if (!rate || !chans) - goto done; - gst_value_intersect (&irate, orate, rate); - gst_value_intersect (&ichans, ochans, chans); + if (orate) { + gst_value_intersect (&irate, orate, rate); + gst_structure_set_value (structure, "rate", &irate); + } - /* Set the samplerate/channels on the to-be-returned caps */ - structure = gst_caps_get_structure (base_caps, 0); - gst_structure_set_value (structure, "rate", &irate); - gst_structure_set_value (structure, "channels", &ichans); + if (ochans) { + gst_value_intersect (&ichans, ochans, chans); + gst_structure_set_value (structure, "channels", &ichans); + } done: gst_caps_unref (othercaps); diff --git a/gst/law/mulaw-encode.c b/gst/law/mulaw-encode.c index f60e0b2e09..022e96f179 100644 --- a/gst/law/mulaw-encode.c +++ b/gst/law/mulaw-encode.c @@ -75,8 +75,8 @@ mulawenc_getcaps (GstPad * pad) GstStructure *structure; const GValue *orate, *ochans; const GValue *rate, *chans; - GValue irate = { 0 }, ichans = { - 0}; + GValue irate = { 0 }; + GValue ichans = { 0 }; if (gst_caps_is_empty (othercaps) || gst_caps_is_any (othercaps)) goto done; @@ -84,22 +84,20 @@ mulawenc_getcaps (GstPad * pad) structure = gst_caps_get_structure (othercaps, 0); orate = gst_structure_get_value (structure, "rate"); ochans = gst_structure_get_value (structure, "channels"); - if (!orate || !ochans) - goto done; structure = gst_caps_get_structure (base_caps, 0); rate = gst_structure_get_value (structure, "rate"); chans = gst_structure_get_value (structure, "channels"); - if (!rate || !chans) - goto done; - gst_value_intersect (&irate, orate, rate); - gst_value_intersect (&ichans, ochans, chans); + if (orate) { + gst_value_intersect (&irate, orate, rate); + gst_structure_set_value (structure, "rate", &irate); + } - /* Set the samplerate/channels on the to-be-returned caps */ - structure = gst_caps_get_structure (base_caps, 0); - gst_structure_set_value (structure, "rate", &irate); - gst_structure_set_value (structure, "channels", &ichans); + if (ochans) { + gst_value_intersect (&ichans, ochans, chans); + gst_structure_set_value (structure, "channels", &ichans); + } done: gst_caps_unref (othercaps); From bfcf84a3eb766f2da0cf1cfdecdd9dcdf847f75f Mon Sep 17 00:00:00 2001 From: Olivier Crete Date: Sun, 22 Feb 2009 18:47:35 +0100 Subject: [PATCH 08/52] alaw/mulaw: Implement _getcaps function for alaw/mulaw decoders Fixes bug #572358. --- gst/law/alaw-decode.c | 55 ++++++++++++++++++++++++++++++++++++++++++ gst/law/mulaw-decode.c | 53 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) diff --git a/gst/law/alaw-decode.c b/gst/law/alaw-decode.c index 9b990f7e1c..cead144401 100644 --- a/gst/law/alaw-decode.c +++ b/gst/law/alaw-decode.c @@ -145,6 +145,57 @@ gst_alaw_dec_sink_setcaps (GstPad * pad, GstCaps * caps) return ret; } +static GstCaps * +gst_alaw_dec_getcaps (GstPad * pad) +{ + GstALawDec *alawdec; + GstPad *otherpad; + GstCaps *base_caps, *othercaps; + + alawdec = GST_ALAW_DEC (GST_PAD_PARENT (pad)); + + base_caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad)); + + if (pad == alawdec->srcpad) { + otherpad = alawdec->sinkpad; + } else { + otherpad = alawdec->srcpad; + } + othercaps = gst_pad_peer_get_caps (otherpad); + if (othercaps) { + GstStructure *structure; + const GValue *orate, *ochans; + const GValue *rate, *chans; + GValue irate = { 0 }; + GValue ichans = { 0 }; + + if (gst_caps_is_empty (othercaps) || gst_caps_is_any (othercaps)) + goto done; + + structure = gst_caps_get_structure (othercaps, 0); + orate = gst_structure_get_value (structure, "rate"); + ochans = gst_structure_get_value (structure, "channels"); + + structure = gst_caps_get_structure (base_caps, 0); + rate = gst_structure_get_value (structure, "rate"); + chans = gst_structure_get_value (structure, "channels"); + + if (orate) { + gst_value_intersect (&irate, orate, rate); + gst_structure_set_value (structure, "rate", &irate); + } + + if (ochans) { + gst_value_intersect (&ichans, ochans, chans); + gst_structure_set_value (structure, "channels", &ichans); + } + + done: + gst_caps_unref (othercaps); + } + return base_caps; +} + static void gst_alaw_dec_base_init (gpointer klass) { @@ -177,6 +228,8 @@ gst_alaw_dec_init (GstALawDec * alawdec, GstALawDecClass * klass) gst_pad_new_from_static_template (&alaw_dec_sink_factory, "sink"); gst_pad_set_setcaps_function (alawdec->sinkpad, GST_DEBUG_FUNCPTR (gst_alaw_dec_sink_setcaps)); + gst_pad_set_getcaps_function (alawdec->sinkpad, + GST_DEBUG_FUNCPTR (gst_alaw_dec_getcaps)); gst_pad_set_chain_function (alawdec->sinkpad, GST_DEBUG_FUNCPTR (gst_alaw_dec_chain)); gst_element_add_pad (GST_ELEMENT (alawdec), alawdec->sinkpad); @@ -184,6 +237,8 @@ gst_alaw_dec_init (GstALawDec * alawdec, GstALawDecClass * klass) alawdec->srcpad = gst_pad_new_from_static_template (&alaw_dec_src_factory, "src"); gst_pad_use_fixed_caps (alawdec->srcpad); + gst_pad_set_getcaps_function (alawdec->srcpad, + GST_DEBUG_FUNCPTR (gst_alaw_dec_getcaps)); gst_element_add_pad (GST_ELEMENT (alawdec), alawdec->srcpad); } diff --git a/gst/law/mulaw-decode.c b/gst/law/mulaw-decode.c index 42b208f613..a1727d9c9d 100644 --- a/gst/law/mulaw-decode.c +++ b/gst/law/mulaw-decode.c @@ -88,6 +88,57 @@ mulawdec_sink_setcaps (GstPad * pad, GstCaps * caps) return ret; } +static GstCaps * +mulawdec_getcaps (GstPad * pad) +{ + GstMuLawDec *mulawdec; + GstPad *otherpad; + GstCaps *base_caps, *othercaps; + + mulawdec = GST_MULAWDEC (GST_PAD_PARENT (pad)); + + base_caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad)); + + if (pad == mulawdec->srcpad) { + otherpad = mulawdec->sinkpad; + } else { + otherpad = mulawdec->srcpad; + } + othercaps = gst_pad_peer_get_caps (otherpad); + if (othercaps) { + GstStructure *structure; + const GValue *orate, *ochans; + const GValue *rate, *chans; + GValue irate = { 0 }; + GValue ichans = { 0 }; + + if (gst_caps_is_empty (othercaps) || gst_caps_is_any (othercaps)) + goto done; + + structure = gst_caps_get_structure (othercaps, 0); + orate = gst_structure_get_value (structure, "rate"); + ochans = gst_structure_get_value (structure, "channels"); + + structure = gst_caps_get_structure (base_caps, 0); + rate = gst_structure_get_value (structure, "rate"); + chans = gst_structure_get_value (structure, "channels"); + + if (orate) { + gst_value_intersect (&irate, orate, rate); + gst_structure_set_value (structure, "rate", &irate); + } + + if (ochans) { + gst_value_intersect (&ichans, ochans, chans); + gst_structure_set_value (structure, "channels", &ichans); + } + + done: + gst_caps_unref (othercaps); + } + return base_caps; +} + GType gst_mulawdec_get_type (void) { @@ -146,12 +197,14 @@ gst_mulawdec_init (GstMuLawDec * mulawdec) mulawdec->sinkpad = gst_pad_new_from_static_template (&mulaw_dec_sink_factory, "sink"); gst_pad_set_setcaps_function (mulawdec->sinkpad, mulawdec_sink_setcaps); + gst_pad_set_getcaps_function (mulawdec->sinkpad, mulawdec_getcaps); gst_pad_set_chain_function (mulawdec->sinkpad, gst_mulawdec_chain); gst_element_add_pad (GST_ELEMENT (mulawdec), mulawdec->sinkpad); mulawdec->srcpad = gst_pad_new_from_static_template (&mulaw_dec_src_factory, "src"); gst_pad_use_fixed_caps (mulawdec->srcpad); + gst_pad_set_getcaps_function (mulawdec->srcpad, mulawdec_getcaps); gst_element_add_pad (GST_ELEMENT (mulawdec), mulawdec->srcpad); } From a7c2b1354310b3c0fa81dc1d164fffca9c573c67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Sun, 22 Feb 2009 19:25:39 +0100 Subject: [PATCH 09/52] matroskademux: Unref the buffer and not the memory address of the buffer --- gst/matroska/matroska-demux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c index 3c656c2cdc..118886fc75 100644 --- a/gst/matroska/matroska-demux.c +++ b/gst/matroska/matroska-demux.c @@ -3864,7 +3864,7 @@ gst_matroska_demux_check_subtitle_buffer (GstElement * element, GST_BUFFER_SIZE (newbuf) = strlen (utf8); gst_buffer_copy_metadata (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS); - gst_buffer_unref (buf); + gst_buffer_unref (*buf); *buf = newbuf; return GST_FLOW_OK; From ef33cf891f7a9f97f178169adb87aa3695bf9b2b Mon Sep 17 00:00:00 2001 From: Sjoerd Simons Date: Sun, 22 Feb 2009 19:30:32 +0100 Subject: [PATCH 10/52] gconfvideo(src|sink): Disconnect GConf notifications Fixes bug #571321. --- ext/gconf/gstgconfvideosink.c | 5 ++++- ext/gconf/gstgconfvideosink.h | 3 +++ ext/gconf/gstgconfvideosrc.c | 5 ++++- ext/gconf/gstgconfvideosrc.h | 3 +++ 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/ext/gconf/gstgconfvideosink.c b/ext/gconf/gstgconfvideosink.c index 4090cc9114..1b05fd3717 100644 --- a/ext/gconf/gstgconfvideosink.c +++ b/ext/gconf/gstgconfvideosink.c @@ -122,7 +122,7 @@ gst_gconf_video_sink_init (GstGConfVideoSink * sink, sink->client = gconf_client_get_default (); gconf_client_add_dir (sink->client, GST_GCONF_DIR, GCONF_CLIENT_PRELOAD_RECURSIVE, NULL); - gconf_client_notify_add (sink->client, + sink->notify_id = gconf_client_notify_add (sink->client, GST_GCONF_DIR "/" GST_GCONF_VIDEOSINK_KEY, cb_toggle_element, sink, NULL, NULL); } @@ -133,6 +133,9 @@ gst_gconf_video_sink_dispose (GObject * object) GstGConfVideoSink *sink = GST_GCONF_VIDEO_SINK (object); if (sink->client) { + if (sink->notify_id != 0) + gconf_client_notify_remove (sink->client, sink->notify_id); + g_object_unref (G_OBJECT (sink->client)); sink->client = NULL; } diff --git a/ext/gconf/gstgconfvideosink.h b/ext/gconf/gstgconfvideosink.h index 8f69c81a15..2461e6526b 100644 --- a/ext/gconf/gstgconfvideosink.h +++ b/ext/gconf/gstgconfvideosink.h @@ -46,6 +46,9 @@ typedef struct _GstGConfVideoSink { GstElement *kid; GstPad *pad; + /* gconf notify id */ + guint notify_id; + /* Current gconf string */ gchar *gconf_str; } GstGConfVideoSink; diff --git a/ext/gconf/gstgconfvideosrc.c b/ext/gconf/gstgconfvideosrc.c index fe177d8639..6192d73d1d 100644 --- a/ext/gconf/gstgconfvideosrc.c +++ b/ext/gconf/gstgconfvideosrc.c @@ -124,7 +124,7 @@ gst_gconf_video_src_init (GstGConfVideoSrc * src, src->client = gconf_client_get_default (); gconf_client_add_dir (src->client, GST_GCONF_DIR, GCONF_CLIENT_PRELOAD_RECURSIVE, NULL); - gconf_client_notify_add (src->client, + src->notify_id = gconf_client_notify_add (src->client, GST_GCONF_DIR "/" GST_GCONF_VIDEOSRC_KEY, cb_toggle_element, src, NULL, NULL); } @@ -135,6 +135,9 @@ gst_gconf_video_src_dispose (GObject * object) GstGConfVideoSrc *src = GST_GCONF_VIDEO_SRC (object); if (src->client) { + if (src->notify_id != 0) + gconf_client_notify_remove (src->client, src->notify_id); + g_object_unref (G_OBJECT (src->client)); src->client = NULL; } diff --git a/ext/gconf/gstgconfvideosrc.h b/ext/gconf/gstgconfvideosrc.h index 6f64e6d109..4a2c8cddf1 100644 --- a/ext/gconf/gstgconfvideosrc.h +++ b/ext/gconf/gstgconfvideosrc.h @@ -40,6 +40,9 @@ typedef struct _GstGConfVideoSrc { GstElement *kid; GstPad *pad; + /* gconf key notification id */ + guint notify_id; + /* Current gconf string */ gchar *gconf_str; } GstGConfVideoSrc; From 8c9931e13ef5b7dbe2179d245ae65999cad7f035 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 13 Feb 2009 14:39:29 +0100 Subject: [PATCH 11/52] Don't use GST_ERROR for non-error cases. Turn a GST_ERROR line into a GST_DEBUG line so that we don't spam the log with errors. Fixes #570781. --- gst/law/alaw-decode.c | 3 ++- gst/law/mulaw-decode.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/gst/law/alaw-decode.c b/gst/law/alaw-decode.c index cead144401..f308cf70f9 100644 --- a/gst/law/alaw-decode.c +++ b/gst/law/alaw-decode.c @@ -300,7 +300,8 @@ not_negotiated: alloc_failed: { gst_buffer_unref (buffer); - GST_ERROR_OBJECT (alawdec, "pad alloc failed"); + GST_DEBUG_OBJECT (alawdec, "pad alloc failed %d (%s)", ret, + gst_flow_get_name (ret)); return ret; } } diff --git a/gst/law/mulaw-decode.c b/gst/law/mulaw-decode.c index a1727d9c9d..83b383979e 100644 --- a/gst/law/mulaw-decode.c +++ b/gst/law/mulaw-decode.c @@ -264,7 +264,8 @@ not_negotiated: } alloc_failed: { - GST_ERROR_OBJECT (mulawdec, "pad alloc failed"); + GST_DEBUG_OBJECT (mulawdec, "pad alloc failed %d (%s)", ret, + gst_flow_get_name (ret)); gst_buffer_unref (buffer); return ret; } From c4d53e9cc213098710bf28096ec0faed9be58bf2 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 23 Feb 2009 11:13:30 +0100 Subject: [PATCH 12/52] Add method for hadling server requests Add method to handle server requests on the list of RTSP extensions. --- gst/rtsp/gstrtspext.c | 17 +++++++++++++++++ gst/rtsp/gstrtspext.h | 1 + 2 files changed, 18 insertions(+) diff --git a/gst/rtsp/gstrtspext.c b/gst/rtsp/gstrtspext.c index 0ad81b5618..a321679459 100644 --- a/gst/rtsp/gstrtspext.c +++ b/gst/rtsp/gstrtspext.c @@ -247,3 +247,20 @@ gst_rtsp_ext_list_connect (GstRTSPExtensionList * ext, g_signal_connect (elem, detailed_signal, c_handler, data); } } + +GstRTSPResult +gst_rtsp_ext_list_receive_request (GstRTSPExtensionList * ext, + GstRTSPMessage * req) +{ + GList *walk; + GstRTSPResult res = GST_RTSP_ENOTIMPL; + + for (walk = ext->extensions; walk; walk = g_list_next (walk)) { + GstRTSPExtension *elem = (GstRTSPExtension *) walk->data; + + res = gst_rtsp_extension_receive_request (elem, req); + if (res != GST_RTSP_ENOTIMPL) + break; + } + return res; +} diff --git a/gst/rtsp/gstrtspext.h b/gst/rtsp/gstrtspext.h index fa7f6892a1..f30b302ff4 100644 --- a/gst/rtsp/gstrtspext.h +++ b/gst/rtsp/gstrtspext.h @@ -76,6 +76,7 @@ GstRTSPResult gst_rtsp_ext_list_stream_select (GstRTSPExtensionList *ext, Gs void gst_rtsp_ext_list_connect (GstRTSPExtensionList *ext, const gchar *detailed_signal, GCallback c_handler, gpointer data); +GstRTSPResult gst_rtsp_ext_list_receive_request (GstRTSPExtensionList *ext, GstRTSPMessage *req); G_END_DECLS From a08d75b8926685928bf1c4b40b448fe7320ec0d5 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 23 Feb 2009 11:42:53 +0100 Subject: [PATCH 13/52] Call new receive_request method Call the receive_request extension methods so that extensions can handle the server request if they want. --- gst/rtsp/gstrtspsrc.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/gst/rtsp/gstrtspsrc.c b/gst/rtsp/gstrtspsrc.c index 02970c425c..6dc09cc51b 100644 --- a/gst/rtsp/gstrtspsrc.c +++ b/gst/rtsp/gstrtspsrc.c @@ -2536,20 +2536,25 @@ gst_rtspsrc_handle_request (GstRTSPSrc * src, GstRTSPMessage * request) if (src->debug) gst_rtsp_message_dump (request); - res = - gst_rtsp_message_init_response (&response, GST_RTSP_STS_OK, "OK", - request); - if (res < 0) - goto send_error; + res = gst_rtsp_ext_list_receive_request (src->extensions, request); - GST_DEBUG_OBJECT (src, "replying with OK"); + if (res == GST_RTSP_ENOTIMPL) { + /* default implementation, send OK */ + res = + gst_rtsp_message_init_response (&response, GST_RTSP_STS_OK, "OK", + request); + if (res < 0) + goto send_error; - if (src->debug) - gst_rtsp_message_dump (&response); + GST_DEBUG_OBJECT (src, "replying with OK"); - res = gst_rtspsrc_connection_send (src, &response, NULL); - if (res < 0) - goto send_error; + if (src->debug) + gst_rtsp_message_dump (&response); + + res = gst_rtspsrc_connection_send (src, &response, NULL); + if (res < 0) + goto send_error; + } return GST_RTSP_OK; From bde39c955f00cff971633f7c4f8243c3553cfe7d Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 23 Feb 2009 11:45:50 +0100 Subject: [PATCH 14/52] Require newer gst-p-b for the RTSP extensions. -- --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 4179daa9a3..59a1221ca0 100644 --- a/configure.ac +++ b/configure.ac @@ -48,7 +48,7 @@ AM_PROG_LIBTOOL dnl *** required versions of GStreamer stuff *** GST_REQ=0.10.22 -GSTPB_REQ=0.10.22 +GSTPB_REQ=0.10.22.1 dnl *** autotools stuff **** From b9adb5846bb4d663928e441cf90e1efb75f36630 Mon Sep 17 00:00:00 2001 From: Arnout Vandecappelle Date: Mon, 23 Feb 2009 12:14:23 +0100 Subject: [PATCH 15/52] Don't do crazy things with 0/1 framerates We use 0/1 framerates to mark variable framerates and matroskamux should not try to calculate a frame duration for it. Fixes #571294. --- gst/matroska/matroska-mux.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst/matroska/matroska-mux.c b/gst/matroska/matroska-mux.c index 746e3d1947..1b958d69ec 100644 --- a/gst/matroska/matroska-mux.c +++ b/gst/matroska/matroska-mux.c @@ -650,7 +650,8 @@ gst_matroska_mux_video_pad_setcaps (GstPad * pad, GstCaps * caps) gst_structure_get_int (structure, "height", &height); videocontext->pixel_width = width; videocontext->pixel_height = height; - if (gst_structure_get_fraction (structure, "framerate", &fps_n, &fps_d)) { + if (gst_structure_get_fraction (structure, "framerate", &fps_n, &fps_d) + && fps_n > 0) { context->default_duration = gst_util_uint64_scale_int (GST_SECOND, fps_d, fps_n); GST_LOG_OBJECT (pad, "default duration = %" GST_TIME_FORMAT, From aeee52be051d7d73cd565e7eaf9b49b84a00c8a2 Mon Sep 17 00:00:00 2001 From: Wai-Ming Ho Date: Mon, 23 Feb 2009 15:43:51 +0100 Subject: [PATCH 16/52] Always add PPS to the sprop-parameters-set Rework the parsing code that under certain circumstances dropped the PPS from the sprop-parameters-set. Fixes #572854. --- gst/rtp/gstrtph264pay.c | 122 +++++++++++++++++----------------------- 1 file changed, 52 insertions(+), 70 deletions(-) diff --git a/gst/rtp/gstrtph264pay.c b/gst/rtp/gstrtph264pay.c index f0cd9ee840..8fdd895a75 100644 --- a/gst/rtp/gstrtph264pay.c +++ b/gst/rtp/gstrtph264pay.c @@ -467,89 +467,71 @@ gst_rtp_h264_pay_decode_nal (GstRtpH264Pay * payloader, { guint8 *sps = NULL, *pps = NULL; guint sps_len = 0, pps_len = 0; + guint8 header, type; + guint len; /* default is no update */ *updated = FALSE; - if (size <= 3) { - GST_WARNING ("Encoded buffer len %u <= 3", size); + GST_DEBUG ("NAL payload len=%u", size); + + len = size; + header = data[0]; + type = header & 0x1f; + + /* keep sps & pps separately so that we can update either one + * independently */ + if (SPS_TYPE_ID == type) { + /* encode the entire SPS NAL in base64 */ + GST_DEBUG ("Found SPS %x %x %x Len=%u", (header >> 7), + (header >> 5) & 3, type, len); + + sps = data; + sps_len = len; + } else if (PPS_TYPE_ID == type) { + /* encoder the entire PPS NAL in base64 */ + GST_DEBUG ("Found PPS %x %x %x Len = %u", + (header >> 7), (header >> 5) & 3, type, len); + + pps = data; + pps_len = len; } else { - GST_DEBUG ("NAL payload len=%u", size); + GST_DEBUG ("NAL: %x %x %x Len = %u", (header >> 7), + (header >> 5) & 3, type, len); + } - /* loop through all NAL units and save the locations of any - * SPS / PPS for later processing. Only the last seen SPS - * or PPS will be considered */ - while (size > 5) { - guint8 header, type; - guint len; - len = next_start_code (data, size); - header = data[0]; - type = header & 0x1f; + /* If we encountered an SPS and/or a PPS, check if it's the + * same as the one we have. If not, update our version and + * set *updated to TRUE + */ + if (sps_len > 0) { + if ((payloader->sps_len != sps_len) + || !is_nal_equal (payloader->sps, sps, sps_len)) { + payloader->profile = (sps[1] << 16) + (sps[2] << 8) + sps[3]; - /* keep sps & pps separately so that we can update either one - * independently */ - if (SPS_TYPE_ID == type) { - /* encode the entire SPS NAL in base64 */ - GST_DEBUG ("Found SPS %x %x %x Len=%u", (header >> 7), - (header >> 5) & 3, type, len); + GST_DEBUG ("Profile level IDC = %06x", payloader->profile); - sps = data; - sps_len = len; - } else if (PPS_TYPE_ID == type) { - /* encoder the entire PPS NAL in base64 */ - GST_DEBUG ("Found PPS %x %x %x Len = %u", - (header >> 7), (header >> 5) & 3, type, len); + if (payloader->sps_len) + g_free (payloader->sps); - pps = data; - pps_len = len; - } else { - GST_DEBUG ("NAL: %x %x %x Len = %u", (header >> 7), - (header >> 5) & 3, type, len); - } - - /* end of loop */ - if (len >= size - 4) { - break; - } - - /* next NAL start */ - data += len + 4; - size -= len + 4; + payloader->sps = sps_len ? g_new (guint8, sps_len) : NULL; + memcpy (payloader->sps, sps, sps_len); + payloader->sps_len = sps_len; + *updated = TRUE; } + } - /* If we encountered an SPS and/or a PPS, check if it's the - * same as the one we have. If not, update our version and - * set *updated to TRUE - */ - if (sps_len > 0) { - if ((payloader->sps_len != sps_len) - || !is_nal_equal (payloader->sps, sps, sps_len)) { - payloader->profile = (sps[1] << 16) + (sps[2] << 8) + sps[3]; + if (pps_len > 0) { + if ((payloader->pps_len != pps_len) + || !is_nal_equal (payloader->pps, pps, pps_len)) { + if (payloader->pps_len) + g_free (payloader->pps); - GST_DEBUG ("Profile level IDC = %06x", payloader->profile); - - if (payloader->sps_len) - g_free (payloader->sps); - - payloader->sps = sps_len ? g_new (guint8, sps_len) : NULL; - memcpy (payloader->sps, sps, sps_len); - payloader->sps_len = sps_len; - *updated = TRUE; - } - } - - if (pps_len > 0) { - if ((payloader->pps_len != pps_len) - || !is_nal_equal (payloader->pps, pps, pps_len)) { - if (payloader->pps_len) - g_free (payloader->pps); - - payloader->pps = pps_len ? g_new (guint8, pps_len) : NULL; - memcpy (payloader->pps, pps, pps_len); - payloader->pps_len = pps_len; - *updated = TRUE; - } + payloader->pps = pps_len ? g_new (guint8, pps_len) : NULL; + memcpy (payloader->pps, pps, pps_len); + payloader->pps_len = pps_len; + *updated = TRUE; } } } From 7e64f1d1069179f5b5f067595ed27cf9c1d8f6ab Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 23 Feb 2009 15:48:41 +0100 Subject: [PATCH 17/52] Some cleanups Remove some unused variables. Avoid a useless _resync call. Correctly use a gboolean. --- ext/jpeg/gstjpegenc.c | 5 +---- ext/jpeg/gstjpegenc.h | 1 - 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/ext/jpeg/gstjpegenc.c b/ext/jpeg/gstjpegenc.c index 908c7e00b2..df4b416f59 100644 --- a/ext/jpeg/gstjpegenc.c +++ b/ext/jpeg/gstjpegenc.c @@ -339,9 +339,8 @@ gst_jpegenc_setcaps (GstPad * pad, GstCaps * caps) ret = gst_pad_set_caps (jpegenc->srcpad, othercaps); gst_caps_unref (othercaps); - if (GST_PAD_LINK_SUCCESSFUL (ret)) { + if (ret) gst_jpegenc_resync (jpegenc); - } gst_object_unref (jpegenc); @@ -411,7 +410,6 @@ gst_jpegenc_resync (GstJpegEnc * jpegenc) jpeg_suppress_tables (&jpegenc->cinfo, TRUE); //jpeg_suppress_tables(&jpegenc->cinfo, FALSE); - jpegenc->buffer = NULL; GST_DEBUG_OBJECT (jpegenc, "resync done"); } @@ -557,7 +555,6 @@ gst_jpegenc_change_state (GstElement * element, GstStateChange transition) filter->line[0] = NULL; filter->line[1] = NULL; filter->line[2] = NULL; - gst_jpegenc_resync (filter); break; default: break; diff --git a/ext/jpeg/gstjpegenc.h b/ext/jpeg/gstjpegenc.h index 719b88b02d..993415698f 100644 --- a/ext/jpeg/gstjpegenc.h +++ b/ext/jpeg/gstjpegenc.h @@ -57,7 +57,6 @@ struct _GstJpegEnc { gint height; /* the video buffer */ gint bufsize; - GstBuffer *buffer; guint row_stride; /* the jpeg line buffer */ guchar **line[3]; From 42c8aa7abc14a67e1241d90ad0e6b0a6e8af08c0 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 23 Feb 2009 17:05:43 +0100 Subject: [PATCH 18/52] Add YVYU format to caps Add YVYU format to the caps. We don't have anything to handle these caps yet, though. --- sys/v4l2/gstv4l2src.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/sys/v4l2/gstv4l2src.c b/sys/v4l2/gstv4l2src.c index a90ddf8130..8eb3e661ff 100644 --- a/sys/v4l2/gstv4l2src.c +++ b/sys/v4l2/gstv4l2src.c @@ -129,6 +129,9 @@ static const guint32 gst_v4l2_formats[] = { #ifdef V4L2_PIX_FMT_PWC2 V4L2_PIX_FMT_PWC2, #endif +#ifdef V4L2_PIX_FMT_YVYU + V4L2_PIX_FMT_YVYU, +#endif }; #define GST_V4L2_FORMAT_COUNT (G_N_ELEMENTS (gst_v4l2_formats)) @@ -688,6 +691,9 @@ gst_v4l2src_v4l2fourcc_to_structure (guint32 fourcc) case V4L2_PIX_FMT_UYVY: case V4L2_PIX_FMT_Y41P: case V4L2_PIX_FMT_YUV422P: +#ifdef V4L2_PIX_FMT_YVYU + case V4L2_PIX_FMT_YVYU: +#endif case V4L2_PIX_FMT_YUV411P:{ guint32 fcc = 0; @@ -725,6 +731,11 @@ gst_v4l2src_v4l2fourcc_to_structure (guint32 fourcc) case V4L2_PIX_FMT_YUV422P: fcc = GST_MAKE_FOURCC ('Y', '4', '2', 'B'); break; +#ifdef V4L2_PIX_FMT_YVYU + case V4L2_PIX_FMT_YVYU: + fcc = GST_MAKE_FOURCC ('Y', 'V', 'Y', 'U'); + break; +#endif default: g_assert_not_reached (); break; @@ -969,6 +980,10 @@ gst_v4l2_get_caps_info (GstV4l2Src * v4l2src, GstCaps * caps, outsize = GST_ROUND_UP_4 (*w) * GST_ROUND_UP_2 (*h); outsize += (GST_ROUND_UP_4 (*w) * *h) / 2; break; + case GST_MAKE_FOURCC ('Y', 'V', 'Y', 'U'): + fourcc = V4L2_PIX_FMT_YVYU; + outsize = (GST_ROUND_UP_2 (*w) * 2) * *h; + break; } } else if (!strcmp (mimetype, "video/x-raw-rgb")) { gint depth, endianness, r_mask; From d2fc4cb3ba7711170d5f4d1a9f080496b3268b87 Mon Sep 17 00:00:00 2001 From: Levente Farkas Date: Tue, 17 Feb 2009 11:01:47 -0800 Subject: [PATCH 19/52] v4l2src: Make sort_by_frame_size conditionally compiled sort_by_frame_size is declared static and only used inside an ifdef, so use the same ifdef to define the function. Fixes #572185 Signed-off-by: David Schleef --- sys/v4l2/v4l2src_calls.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/v4l2/v4l2src_calls.c b/sys/v4l2/v4l2src_calls.c index c247c49766..971868bf02 100644 --- a/sys/v4l2/v4l2src_calls.c +++ b/sys/v4l2/v4l2src_calls.c @@ -771,6 +771,7 @@ unknown_type: } #endif /* defined VIDIOC_ENUM_FRAMEINTERVALS */ +#ifdef VIDIOC_ENUM_FRAMESIZES static gint sort_by_frame_size (GstStructure * s1, GstStructure * s2) { @@ -784,6 +785,7 @@ sort_by_frame_size (GstStructure * s1, GstStructure * s2) /* I think it's safe to assume that this won't overflow for a while */ return ((w2 * h2) - (w1 * h1)); } +#endif GstCaps * gst_v4l2src_probe_caps_for_format (GstV4l2Src * v4l2src, guint32 pixelformat, From 04359c838254f38e999f22684a7ed7146670506e Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 23 Feb 2009 19:53:58 +0100 Subject: [PATCH 20/52] Conditionally compile code for YVYU Only compile the code for the YVYU format when the format is actually defined. Spotted by tmatth on IRC. --- sys/v4l2/gstv4l2src.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/v4l2/gstv4l2src.c b/sys/v4l2/gstv4l2src.c index 8eb3e661ff..9f96a211d6 100644 --- a/sys/v4l2/gstv4l2src.c +++ b/sys/v4l2/gstv4l2src.c @@ -980,10 +980,12 @@ gst_v4l2_get_caps_info (GstV4l2Src * v4l2src, GstCaps * caps, outsize = GST_ROUND_UP_4 (*w) * GST_ROUND_UP_2 (*h); outsize += (GST_ROUND_UP_4 (*w) * *h) / 2; break; +#ifdef V4L2_PIX_FMT_YVYU case GST_MAKE_FOURCC ('Y', 'V', 'Y', 'U'): fourcc = V4L2_PIX_FMT_YVYU; outsize = (GST_ROUND_UP_2 (*w) * 2) * *h; break; +#endif } } else if (!strcmp (mimetype, "video/x-raw-rgb")) { gint depth, endianness, r_mask; From 969622b439cc7232e8889cd5c7a5579cba6b665f Mon Sep 17 00:00:00 2001 From: Aurelien Grimaud Date: Mon, 23 Feb 2009 20:49:37 +0100 Subject: [PATCH 21/52] Read ICMP error messages instead of looping When we are dealing with connected sockets shared between a udpsrc and a udpsink we might receive ICMP connection refused error messages in udpsrc that will cause it to go into a bursty loop because the poll returns right away without a message to read. Instead of looping, read the error message from the error queue in udpsrc. Fixes #567857. --- gst/udp/gstudpsrc.c | 46 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/gst/udp/gstudpsrc.c b/gst/udp/gstudpsrc.c index bcdbc35961..58980b9e4b 100644 --- a/gst/udp/gstudpsrc.c +++ b/gst/udp/gstudpsrc.c @@ -357,6 +357,35 @@ gst_udpsrc_getcaps (GstBaseSrc * src) return gst_caps_new_any (); } +/* read a message from the error queue */ +static void +clear_error (GstUDPSrc * udpsrc) +{ + struct msghdr cmsg; + char cbuf[128]; + char msgbuf[CMSG_SPACE (128)]; + struct iovec iov; + + /* Flush ERRORS from fd so next poll will not return at once */ + /* No need for address : We look for local error */ + cmsg.msg_name = NULL; + cmsg.msg_namelen = 0; + + /* IOV */ + memset (&cbuf, 0, sizeof (cbuf)); + iov.iov_base = cbuf; + iov.iov_len = sizeof (cbuf); + cmsg.msg_iov = &iov; + cmsg.msg_iovlen = 1; + + /* msg_control */ + memset (&msgbuf, 0, sizeof (msgbuf)); + cmsg.msg_control = &msgbuf; + cmsg.msg_controllen = sizeof (msgbuf); + + recvmsg (udpsrc->sock.fd, &cmsg, MSG_ERRQUEUE); +} + static GstFlowReturn gst_udpsrc_create (GstPushSrc * psrc, GstBuffer ** buf) { @@ -434,8 +463,10 @@ retry: * woken up by activity on the socket but it was not a read. We know someone * will also do something with the socket so that we don't go into an infinite * loop in the select(). */ - if (G_UNLIKELY (!readsize)) + if (G_UNLIKELY (!readsize)) { + clear_error (udpsrc); goto retry; + } no_select: GST_LOG_OBJECT (udpsrc, "ioctl says %d bytes available", (int) readsize); @@ -447,10 +478,11 @@ no_select: len = sizeof (struct sockaddr); #ifdef G_OS_WIN32 ret = recvfrom (udpsrc->sock.fd, (char *) pktdata, pktsize, + 0, (struct sockaddr *) &tmpaddr, &len); #else ret = recvfrom (udpsrc->sock.fd, pktdata, pktsize, -#endif 0, (struct sockaddr *) &tmpaddr, &len); +#endif if (G_UNLIKELY (ret < 0)) { #ifdef G_OS_WIN32 /* WSAECONNRESET for a UDP socket means that a packet sent with udpsink @@ -730,6 +762,7 @@ static gboolean gst_udpsrc_start (GstBaseSrc * bsrc) { guint bc_val; + guint err_val; gint reuse; int port; GstUDPSrc *src; @@ -821,6 +854,15 @@ gst_udpsrc_start (GstBaseSrc * bsrc) g_strerror (errno), errno)); } + /* Accept ERRQUEUE to get and flush icmp errors */ + err_val = 1; + if ((ret = setsockopt (src->sock.fd, IPPROTO_IP, IP_RECVERR, &err_val, + sizeof (err_val))) < 0) { + GST_ELEMENT_WARNING (src, RESOURCE, SETTINGS, (NULL), + ("could not configure socket for IP_RECVERR %d: %s (%d)", ret, + g_strerror (errno), errno)); + } + if (src->auto_multicast && gst_udp_is_multicast (&src->myaddr)) { GST_DEBUG_OBJECT (src, "joining multicast group %s", src->multi_group); ret = gst_udp_join_group (src->sock.fd, &src->myaddr); From 21cb00aa9c290010c7da7afc04388348914e7c07 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Mon, 26 Jan 2009 11:06:13 +0100 Subject: [PATCH 22/52] rtspsrc: perform UDP SETUP according to MS RTSP spec MS RTSP spec states that the UDP port pair used in subsequent SETUP requests for various streams must be identical (since there will actually be only 1 stream of muxed asf packets). Following traditional specs and using different port pairs in the SETUPs for separate streams will result in all but the first one failing and only one stream being streamed. So, in appropriate circumstances, retry UDP SETUP using previously used port pair. Fixes #552650. --- gst/rtsp/gstrtspsrc.c | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/gst/rtsp/gstrtspsrc.c b/gst/rtsp/gstrtspsrc.c index 6dc09cc51b..b3e1df47b0 100644 --- a/gst/rtsp/gstrtspsrc.c +++ b/gst/rtsp/gstrtspsrc.c @@ -3790,7 +3790,8 @@ failed: } static GstRTSPResult -gst_rtspsrc_prepare_transports (GstRTSPStream * stream, gchar ** transports) +gst_rtspsrc_prepare_transports (GstRTSPStream * stream, gchar ** transports, + gint orig_rtpport, gint orig_rtcpport) { GstRTSPSrc *src; gint nr_udp, nr_int; @@ -3819,8 +3820,13 @@ gst_rtspsrc_prepare_transports (GstRTSPStream * stream, gchar ** transports) goto done; if (nr_udp > 0) { - if (!gst_rtspsrc_alloc_udp_ports (stream, &rtpport, &rtcpport)) - goto failed; + if (!orig_rtpport || !orig_rtcpport) { + if (!gst_rtspsrc_alloc_udp_ports (stream, &rtpport, &rtcpport)) + goto failed; + } else { + rtpport = orig_rtpport; + rtcpport = orig_rtcpport; + } } str = g_string_new (""); @@ -3880,6 +3886,7 @@ gst_rtspsrc_setup_streams (GstRTSPSrc * src) GstRTSPStream *stream = NULL; GstRTSPLowerTrans protocols; GstRTSPStatusCode code; + gint rtpport, rtcpport; /* we initially allow all configured lower transports. based on the URL * transports and the replies from the server we narrow them down. */ @@ -3892,9 +3899,11 @@ gst_rtspsrc_setup_streams (GstRTSPSrc * src) src->free_channel = 0; src->interleaved = FALSE; src->need_activate = FALSE; + rtpport = rtcpport = 0; for (walk = src->streams; walk; walk = g_list_next (walk)) { gchar *transports; + gint retry = 0; stream = (GstRTSPStream *) walk->data; @@ -3935,6 +3944,7 @@ gst_rtspsrc_setup_streams (GstRTSPSrc * src) GST_DEBUG_OBJECT (src, "doing setup of stream %p with %s", stream, stream->setup_url); +retry: /* create a string with all the transports */ res = gst_rtspsrc_create_transports_string (src, protocols, &transports); if (res < 0) @@ -3944,7 +3954,8 @@ gst_rtspsrc_setup_streams (GstRTSPSrc * src) /* replace placeholders with real values, this function will optionally * allocate UDP ports and other info needed to execute the setup request */ - res = gst_rtspsrc_prepare_transports (stream, &transports); + res = gst_rtspsrc_prepare_transports (stream, &transports, + retry > 0 ? rtpport : 0, retry > 0 ? rtcpport : 0); if (res < 0) goto setup_transport_failed; @@ -3971,8 +3982,17 @@ gst_rtspsrc_setup_streams (GstRTSPSrc * src) case GST_RTSP_STS_UNSUPPORTED_TRANSPORT: gst_rtsp_message_unset (&request); gst_rtsp_message_unset (&response); - /* cleanup of leftover transport and move to the next stream */ + /* cleanup of leftover transport */ gst_rtspsrc_stream_free_udp (stream); + /* MS WMServer RTSP MUST use same UDP pair in all SETUP requests; + * we might be in this case */ + if (stream->container && rtpport && rtcpport && !retry) { + GST_DEBUG_OBJECT (src, "retrying with original port pair %u-%u", + rtpport, rtcpport); + retry++; + goto retry; + } + /* give up on this stream and move to the next stream */ continue; default: /* cleanup of leftover transport and move to the next stream */ @@ -4029,13 +4049,17 @@ gst_rtspsrc_setup_streams (GstRTSPSrc * src) break; } - if (!stream->container || !src->interleaved) { + if (!stream->container || (!src->interleaved && !retry)) { /* now configure the stream with the selected transport */ if (!gst_rtspsrc_stream_configure_transport (stream, &transport)) { GST_DEBUG_OBJECT (src, "could not configure stream %p transport, skipping stream", stream); goto next; + } else if (stream->udpsrc[0] && stream->udpsrc[1]) { + /* retain the first allocated UDP port pair */ + g_object_get (G_OBJECT (stream->udpsrc[0]), "port", &rtpport, NULL); + g_object_get (G_OBJECT (stream->udpsrc[1]), "port", &rtcpport, NULL); } } /* we need to activate at least one streams when we detect activity */ From 6512b3eb81b8e98b9bde3e231d0a528e094ea5d6 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Tue, 24 Feb 2009 14:41:26 +0100 Subject: [PATCH 23/52] qtdemux: Also use "(c)inf" to fill the comment tag --- gst/qtdemux/qtdemux.c | 5 +++-- gst/qtdemux/qtdemux_fourcc.h | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/gst/qtdemux/qtdemux.c b/gst/qtdemux/qtdemux.c index fe555a198b..1cff41484f 100644 --- a/gst/qtdemux/qtdemux.c +++ b/gst/qtdemux/qtdemux.c @@ -3109,11 +3109,11 @@ qtdemux_parse_samples (GstQTDemux * qtdemux, QtDemuxStream * stream, index = QT_UINT32 ((guint8 *) stps->data + offset); if (index > 0 && index <= stream->n_samples) { samples[index - 1].keyframe = TRUE; - offset += 4; + offset += 4; + } } } } - } } else { /* no stss, all samples are keyframes */ stream->all_keyframe = TRUE; @@ -4184,6 +4184,7 @@ static const struct FOURCC__des, GST_TAG_DESCRIPTION, NULL, qtdemux_tag_add_str}, { FOURCC__day, GST_TAG_DATE, NULL, qtdemux_tag_add_date}, { FOURCC__too, GST_TAG_COMMENT, NULL, qtdemux_tag_add_str}, { + FOURCC__inf, GST_TAG_COMMENT, NULL, qtdemux_tag_add_str}, { FOURCC_trkn, GST_TAG_TRACK_NUMBER, GST_TAG_TRACK_COUNT, qtdemux_tag_add_num}, { FOURCC_disk, GST_TAG_ALBUM_VOLUME_NUMBER, GST_TAG_ALBUM_VOLUME_COUNT, qtdemux_tag_add_num}, { diff --git a/gst/qtdemux/qtdemux_fourcc.h b/gst/qtdemux/qtdemux_fourcc.h index b4dabd7322..cbf5b15f2d 100644 --- a/gst/qtdemux/qtdemux_fourcc.h +++ b/gst/qtdemux/qtdemux_fourcc.h @@ -90,6 +90,7 @@ G_BEGIN_DECLS #define FOURCC__day GST_MAKE_FOURCC(0xa9,'d','a','y') #define FOURCC__req GST_MAKE_FOURCC(0xa9,'r','e','q') #define FOURCC__enc GST_MAKE_FOURCC(0xa9,'e','n','c') +#define FOURCC__inf GST_MAKE_FOURCC(0xa9,'i','n','f') #define FOURCC_cprt GST_MAKE_FOURCC('c','p','r','t') #define FOURCC_gnre GST_MAKE_FOURCC('g','n','r','e') #define FOURCC_disc GST_MAKE_FOURCC('d','i','s','c') From 5da35b1ee243f25c17dc9a5350ce6b56ed174031 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 24 Feb 2009 14:55:28 +0100 Subject: [PATCH 24/52] gconf: Rename gconf.[ch] to gstgconf.[ch] to prevent name conflicts --- ext/gconf/Makefile.am | 4 ++-- ext/gconf/{gconf.c => gstgconf.c} | 2 +- ext/gconf/{gconf.h => gstgconf.h} | 0 ext/gconf/gstgconfelements.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename ext/gconf/{gconf.c => gstgconf.c} (99%) rename ext/gconf/{gconf.h => gstgconf.h} (100%) diff --git a/ext/gconf/Makefile.am b/ext/gconf/Makefile.am index 4f6f63ad0c..330cf29fc0 100644 --- a/ext/gconf/Makefile.am +++ b/ext/gconf/Makefile.am @@ -7,7 +7,7 @@ libgstgconfelements_la_SOURCES = \ gstgconfvideosink.c \ gstgconfvideosrc.c \ gstswitchsink.c \ - gconf.c + gstgconf.c DIR_CFLAGS = -DGST_GCONF_DIR=\"/system/gstreamer/@GST_MAJORMINOR@\" libgstgconfelements_la_CFLAGS = $(GST_CFLAGS) $(GCONF_CFLAGS) $(DIR_CFLAGS) @@ -22,4 +22,4 @@ noinst_HEADERS = \ gstgconfvideosink.h \ gstgconfvideosrc.h \ gstswitchsink.h \ - gconf.h + gstgconf.h diff --git a/ext/gconf/gconf.c b/ext/gconf/gstgconf.c similarity index 99% rename from ext/gconf/gconf.c rename to ext/gconf/gstgconf.c index e7214e2db9..eee80c9d97 100644 --- a/ext/gconf/gconf.c +++ b/ext/gconf/gstgconf.c @@ -29,7 +29,7 @@ #include -#include "gconf.h" +#include "gstgconf.h" #include "gstgconfelements.h" /* for debug category */ #ifndef GST_GCONF_DIR diff --git a/ext/gconf/gconf.h b/ext/gconf/gstgconf.h similarity index 100% rename from ext/gconf/gconf.h rename to ext/gconf/gstgconf.h diff --git a/ext/gconf/gstgconfelements.h b/ext/gconf/gstgconfelements.h index 1b3efe3cbc..872b2f2d90 100644 --- a/ext/gconf/gstgconfelements.h +++ b/ext/gconf/gstgconfelements.h @@ -20,7 +20,7 @@ #ifndef __GST_GCONF_ELEMENTS_H__ #define __GST_GCONF_ELEMENTS_H__ -#include +#include "gstgconf.h" GST_DEBUG_CATEGORY_EXTERN (gconf_debug); #define GST_CAT_DEFAULT gconf_debug From 929beb1ae0b6a6dcaff6b0c7c523f2d318e3416d Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Sun, 22 Feb 2009 17:23:09 +0000 Subject: [PATCH 25/52] Use shave for the build output --- configure.ac | 3 +++ docs/plugins/Makefile.am | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 59a1221ca0..26a058abeb 100644 --- a/configure.ac +++ b/configure.ac @@ -1049,11 +1049,14 @@ dnl whatevertarget_LIBS and -L flags here affect the rest of the linking GST_PLUGIN_LDFLAGS="-module -avoid-version -export-symbols-regex '^[_]*gst_plugin_desc\$\$' $GST_ALL_LDFLAGS" AC_SUBST(GST_PLUGIN_LDFLAGS) +SHAVE_INIT([common]) dnl *** output files *** dnl keep this alphabetic per directory, please AC_CONFIG_FILES( Makefile +common/shave +common/shave-libtool gst/Makefile gst/alpha/Makefile gst/apetag/Makefile diff --git a/docs/plugins/Makefile.am b/docs/plugins/Makefile.am index 82d27d9e7d..753fd1b770 100644 --- a/docs/plugins/Makefile.am +++ b/docs/plugins/Makefile.am @@ -216,8 +216,8 @@ extra_files = GTKDOC_CFLAGS = $(GST_BASE_CFLAGS) -I$(top_builddir) GTKDOC_LIBS = $(SCANOBJ_DEPS) $(GST_BASE_LIBS) -GTKDOC_CC=$(LIBTOOL) --mode=compile $(CC) -GTKDOC_LD=$(LIBTOOL) --mode=link $(CC) +GTKDOC_CC=$(LIBTOOL) --tag=CC --mode=compile $(CC) +GTKDOC_LD=$(LIBTOOL) --tag=CC --mode=link $(CC) # If you need to override some of the declarations, place them in this file # and uncomment this line. From b4115aa83e0804b0e315a4ecf9ca037c00c26a48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 24 Feb 2009 17:35:46 +0000 Subject: [PATCH 26/52] rtp: Fix compiler warning in h264 payloader MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix an undefined behaviour warning from gcc 4.4.0 Patch By: Tim-Philipp Müller Fixes: #570995 Signed-Off-By: Jan Schmidt --- gst/rtp/gstrtph264pay.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/gst/rtp/gstrtph264pay.c b/gst/rtp/gstrtph264pay.c index 8fdd895a75..a788316bfd 100644 --- a/gst/rtp/gstrtph264pay.c +++ b/gst/rtp/gstrtph264pay.c @@ -449,15 +449,17 @@ is_nal_equal (const guint8 * nal1, const guint8 * nal2, guint len) if (!remainder) { return TRUE; } else if (1 == remainder) { - return (nal1[--len] == nal2[len]); + --len; + return (nal1[len] == nal2[len]); } else { /* 2 or 3 */ if (remainder & 1) { /* -1 if 3 bytes left */ - if (nal1[--len] != nal2[len]) + --len; + if (nal1[len] != nal2[len]) return FALSE; } /* last 2 bytes */ - return ((nal1[--len] == nal2[len]) /* -1 */ - &&(nal1[--len] == nal2[len])); /* -2 */ + return ((nal1[len - 1] == nal2[len - 1]) /* -1 */ + &&(nal1[len - 2] == nal2[len - 2])); /* -2 */ } } From 8588ebd22a07c5f994b3410db6e73676b38550fd Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Tue, 24 Feb 2009 17:58:32 +0000 Subject: [PATCH 27/52] udp: Fix strict-aliasing warnings from gcc 4.4.0 Fix strict aliasing warnings by defining a union on the different sockaddr structs that we need. --- gst/udp/gstudpsrc.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/gst/udp/gstudpsrc.c b/gst/udp/gstudpsrc.c index 58980b9e4b..690bc06863 100644 --- a/gst/udp/gstudpsrc.c +++ b/gst/udp/gstudpsrc.c @@ -391,7 +391,13 @@ gst_udpsrc_create (GstPushSrc * psrc, GstBuffer ** buf) { GstUDPSrc *udpsrc; GstNetBuffer *outbuf; - struct sockaddr_storage tmpaddr; + union gst_sockaddr + { + struct sockaddr_storage sa_stor; + struct sockaddr sa; + struct sockaddr_in sa_in; + struct sockaddr_in6 sa_in6; + } sa; socklen_t len; guint8 *pktdata; gint pktsize; @@ -478,10 +484,10 @@ no_select: len = sizeof (struct sockaddr); #ifdef G_OS_WIN32 ret = recvfrom (udpsrc->sock.fd, (char *) pktdata, pktsize, - 0, (struct sockaddr *) &tmpaddr, &len); + 0, &sa.sa, &len); #else ret = recvfrom (udpsrc->sock.fd, pktdata, pktsize, - 0, (struct sockaddr *) &tmpaddr, &len); + 0, &sa.sa, &len); #endif if (G_UNLIKELY (ret < 0)) { #ifdef G_OS_WIN32 @@ -518,22 +524,19 @@ no_select: GST_BUFFER_DATA (outbuf) = pktdata; GST_BUFFER_SIZE (outbuf) = ret; - switch (tmpaddr.ss_family) { + switch (sa.sa_stor.ss_family) { case AF_INET: { - gst_netaddress_set_ip4_address (&outbuf->from, - ((struct sockaddr_in *) &tmpaddr)->sin_addr.s_addr, - ((struct sockaddr_in *) &tmpaddr)->sin_port); + gst_netaddress_set_ip4_address (&outbuf->from, sa.sa_in.sin_addr.s_addr, + sa.sa_in.sin_port); } break; case AF_INET6: { guint8 ip6[16]; - memcpy (ip6, &((struct sockaddr_in6 *) &tmpaddr)->sin6_addr, - sizeof (ip6)); - gst_netaddress_set_ip6_address (&outbuf->from, ip6, - ((struct sockaddr_in *) &tmpaddr)->sin_port); + memcpy (ip6, &sa.sa_in6.sin6_addr, sizeof (ip6)); + gst_netaddress_set_ip6_address (&outbuf->from, ip6, sa.sa_in6.sin6_port); } break; default: From 1fec7097926395c0a49f1e714b086129edc8ab09 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 25 Feb 2009 12:05:22 +0100 Subject: [PATCH 28/52] avidemux: avoid crashing on subtitles Avoid a crash in avi with subtitles by only dereferencing the video description when we actually are dealing with video in the _invert function. --- gst/avi/gstavidemux.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/gst/avi/gstavidemux.c b/gst/avi/gstavidemux.c index 2473b922ce..017a7f5806 100644 --- a/gst/avi/gstavidemux.c +++ b/gst/avi/gstavidemux.c @@ -3599,7 +3599,7 @@ static GstBuffer * gst_avi_demux_invert (avi_stream_context * stream, GstBuffer * buf) { GstStructure *s; - gint y, h = stream->strf.vids->height; + gint y, w, h; gint bpp, stride; guint8 *tmp = NULL; @@ -3616,7 +3616,14 @@ gst_avi_demux_invert (avi_stream_context * stream, GstBuffer * buf) return buf; } - stride = stream->strf.vids->width * (bpp / 8); + if (stream->strf.vids == NULL) { + GST_WARNING ("Failed to retrieve vids for stream"); + return buf; + } + + h = stream->strf.vids->height; + w = stream->strf.vids->width; + stride = w * (bpp / 8); buf = gst_buffer_make_writable (buf); if (GST_BUFFER_SIZE (buf) < (stride * h)) { From ba052466d86c71a7a54055fa4989fe6c09bbe6a6 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Wed, 25 Feb 2009 11:32:07 +0000 Subject: [PATCH 29/52] Automatic update of common submodule From 9cf8c9b to a6ce5c6 --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common b/common index 9cf8c9b62f..a6ce5c6139 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 9cf8c9b62f6b2d9e43b7fb0cb9dcfb86b8ceba01 +Subproject commit a6ce5c6139d128d95cfa6acfbcdb9e6ca7a5ffe2 From 6e5e9edabfc34f0486f7befcae9d5860fe76427b Mon Sep 17 00:00:00 2001 From: Peter Kjellerstedt Date: Wed, 25 Feb 2009 11:32:28 +0100 Subject: [PATCH 30/52] udpsrc: Unify the use of union gst_sockaddr. --- gst/udp/gstudpsrc.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/gst/udp/gstudpsrc.c b/gst/udp/gstudpsrc.c index 690bc06863..586f7c5706 100644 --- a/gst/udp/gstudpsrc.c +++ b/gst/udp/gstudpsrc.c @@ -393,12 +393,12 @@ gst_udpsrc_create (GstPushSrc * psrc, GstBuffer ** buf) GstNetBuffer *outbuf; union gst_sockaddr { - struct sockaddr_storage sa_stor; struct sockaddr sa; struct sockaddr_in sa_in; struct sockaddr_in6 sa_in6; + struct sockaddr_storage sa_stor; } sa; - socklen_t len; + socklen_t slen; guint8 *pktdata; gint pktsize; #ifdef G_OS_UNIX @@ -481,13 +481,12 @@ no_select: pktsize = readsize; while (TRUE) { - len = sizeof (struct sockaddr); + slen = sizeof (struct sockaddr); #ifdef G_OS_WIN32 - ret = recvfrom (udpsrc->sock.fd, (char *) pktdata, pktsize, - 0, &sa.sa, &len); + ret = recvfrom (udpsrc->sock.fd, (char *) pktdata, pktsize, 0, &sa.sa, + &slen); #else - ret = recvfrom (udpsrc->sock.fd, pktdata, pktsize, - 0, &sa.sa, &len); + ret = recvfrom (udpsrc->sock.fd, pktdata, pktsize, 0, &sa.sa, &slen); #endif if (G_UNLIKELY (ret < 0)) { #ifdef G_OS_WIN32 @@ -524,7 +523,7 @@ no_select: GST_BUFFER_DATA (outbuf) = pktdata; GST_BUFFER_SIZE (outbuf) = ret; - switch (sa.sa_stor.ss_family) { + switch (sa.sa.sa_family) { case AF_INET: { gst_netaddress_set_ip4_address (&outbuf->from, sa.sa_in.sin_addr.s_addr, From 7c56695160cd522f3998812dc796f3af34cb3465 Mon Sep 17 00:00:00 2001 From: Peter Kjellerstedt Date: Wed, 25 Feb 2009 11:35:31 +0100 Subject: [PATCH 31/52] udpsrc: Make sure the sockaddr length used for recvfrom() is big enough. Previously the sockaddr length used for recvfrom() was calculated as sizeof (struct sockaddr). However, this is too little to hold an IPv6 address, so the full size of the gst_sockaddr union should be used instead. --- gst/udp/gstudpsrc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/udp/gstudpsrc.c b/gst/udp/gstudpsrc.c index 586f7c5706..5b4f6a3e37 100644 --- a/gst/udp/gstudpsrc.c +++ b/gst/udp/gstudpsrc.c @@ -481,7 +481,7 @@ no_select: pktsize = readsize; while (TRUE) { - slen = sizeof (struct sockaddr); + slen = sizeof (sa); #ifdef G_OS_WIN32 ret = recvfrom (udpsrc->sock.fd, (char *) pktdata, pktsize, 0, &sa.sa, &slen); From 1a2bd6c617dff728a93801d98aeb81d1c8bd5c07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Thu, 19 Feb 2009 20:14:10 +0000 Subject: [PATCH 32/52] jpegenc: error out instead of crashing if no caps have been set Don't crash if we receive a buffer without caps. Fixes #572413. --- ext/jpeg/gstjpegenc.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/ext/jpeg/gstjpegenc.c b/ext/jpeg/gstjpegenc.c index df4b416f59..5edb11f1a9 100644 --- a/ext/jpeg/gstjpegenc.c +++ b/ext/jpeg/gstjpegenc.c @@ -427,6 +427,9 @@ gst_jpegenc_chain (GstPad * pad, GstBuffer * buf) jpegenc = GST_JPEGENC (GST_OBJECT_PARENT (pad)); + if (G_UNLIKELY (jpegenc->width <= 0 || jpegenc->height <= 0)) + goto not_negotiated; + data = GST_BUFFER_DATA (buf); size = GST_BUFFER_SIZE (buf); @@ -495,6 +498,14 @@ done: gst_buffer_unref (buf); return ret; + +/* ERRORS */ +not_negotiated: + { + GST_WARNING_OBJECT (jpegenc, "no input format set (no caps on buffer)"); + ret = GST_FLOW_NOT_NEGOTIATED; + goto done; + } } static void @@ -572,6 +583,8 @@ gst_jpegenc_change_state (GstElement * element, GstStateChange transition) filter->line[0] = NULL; filter->line[1] = NULL; filter->line[2] = NULL; + filter->width = -1; + filter->height = -1; break; default: break; From 40bc0400640d356aa008e2dd1821eb885e41adc3 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 25 Feb 2009 14:01:26 +0100 Subject: [PATCH 33/52] udpsrc: fix compilation Fix compilation on systems MSG_ERRQUEUE and IP_RECVERR. --- gst/udp/gstudpsrc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gst/udp/gstudpsrc.c b/gst/udp/gstudpsrc.c index 5b4f6a3e37..8d92241e79 100644 --- a/gst/udp/gstudpsrc.c +++ b/gst/udp/gstudpsrc.c @@ -361,6 +361,7 @@ gst_udpsrc_getcaps (GstBaseSrc * src) static void clear_error (GstUDPSrc * udpsrc) { +#if defined (MSG_ERRQUEUE) struct msghdr cmsg; char cbuf[128]; char msgbuf[CMSG_SPACE (128)]; @@ -384,6 +385,7 @@ clear_error (GstUDPSrc * udpsrc) cmsg.msg_controllen = sizeof (msgbuf); recvmsg (udpsrc->sock.fd, &cmsg, MSG_ERRQUEUE); +#endif } static GstFlowReturn @@ -858,12 +860,14 @@ gst_udpsrc_start (GstBaseSrc * bsrc) /* Accept ERRQUEUE to get and flush icmp errors */ err_val = 1; +#if defined (IP_RECVERR) if ((ret = setsockopt (src->sock.fd, IPPROTO_IP, IP_RECVERR, &err_val, sizeof (err_val))) < 0) { GST_ELEMENT_WARNING (src, RESOURCE, SETTINGS, (NULL), ("could not configure socket for IP_RECVERR %d: %s (%d)", ret, g_strerror (errno), errno)); } +#endif if (src->auto_multicast && gst_udp_is_multicast (&src->myaddr)) { GST_DEBUG_OBJECT (src, "joining multicast group %s", src->multi_group); From ed49e6688cd4f5dae19c10a7b85f3bdabd3c6fd4 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Wed, 25 Feb 2009 14:57:33 +0000 Subject: [PATCH 34/52] build: Update shave init statement for changes in common. Bump common. --- common | 2 +- configure.ac | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/common b/common index a6ce5c6139..57c83f2ced 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit a6ce5c6139d128d95cfa6acfbcdb9e6ca7a5ffe2 +Subproject commit 57c83f2ced9890f1f8c4c64cd6c0b70f952e6a59 diff --git a/configure.ac b/configure.ac index 26a058abeb..abc518792d 100644 --- a/configure.ac +++ b/configure.ac @@ -1049,7 +1049,7 @@ dnl whatevertarget_LIBS and -L flags here affect the rest of the linking GST_PLUGIN_LDFLAGS="-module -avoid-version -export-symbols-regex '^[_]*gst_plugin_desc\$\$' $GST_ALL_LDFLAGS" AC_SUBST(GST_PLUGIN_LDFLAGS) -SHAVE_INIT([common]) +SHAVE_INIT([common],[enable]) dnl *** output files *** dnl keep this alphabetic per directory, please From b264c990747bbe837caf89bad1b6c4924750e9fd Mon Sep 17 00:00:00 2001 From: David Schleef Date: Wed, 25 Feb 2009 19:58:29 -0800 Subject: [PATCH 35/52] dvdec: Add interlacing info to caps and buffers --- ext/dv/gstdvdec.c | 10 +++++++++- ext/dv/gstdvdec.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ext/dv/gstdvdec.c b/ext/dv/gstdvdec.c index ade979665f..fad43be279 100644 --- a/ext/dv/gstdvdec.c +++ b/ext/dv/gstdvdec.c @@ -43,6 +43,7 @@ #endif #include #include +#include #include "gstdvdec.h" @@ -328,7 +329,7 @@ gst_dvdec_src_negotiate (GstDVDec * dvdec) "framerate", GST_TYPE_FRACTION, dvdec->framerate_numerator, dvdec->framerate_denominator, "pixel-aspect-ratio", GST_TYPE_FRACTION, dvdec->par_x, - dvdec->par_y, NULL); + dvdec->par_y, "interlaced", G_TYPE_BOOLEAN, dvdec->interlaced, NULL); gst_pad_set_caps (dvdec->srcpad, othercaps); gst_caps_unref (othercaps); @@ -434,6 +435,7 @@ gst_dvdec_chain (GstPad * pad, GstBuffer * buf) dvdec->height = (dvdec->PAL ? PAL_HEIGHT : NTSC_HEIGHT); + dvdec->interlaced = !dv_is_progressive (dvdec->decoder); /* negotiate if not done yet */ if (!dvdec->src_negotiated) { @@ -466,6 +468,12 @@ gst_dvdec_chain (GstPad * pad, GstBuffer * buf) dv_decode_full_frame (dvdec->decoder, inframe, e_dv_color_yuv, outframe_ptrs, outframe_pitches); + if (dvdec->PAL) { + GST_BUFFER_FLAG_UNSET (outbuf, GST_VIDEO_BUFFER_TFF); + } else { + GST_BUFFER_FLAG_SET (outbuf, GST_VIDEO_BUFFER_TFF); + } + GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET (buf); GST_BUFFER_OFFSET_END (outbuf) = GST_BUFFER_OFFSET_END (buf); GST_BUFFER_TIMESTAMP (outbuf) = cstart; diff --git a/ext/dv/gstdvdec.h b/ext/dv/gstdvdec.h index 5f166a141f..de8481d910 100644 --- a/ext/dv/gstdvdec.h +++ b/ext/dv/gstdvdec.h @@ -57,6 +57,7 @@ struct _GstDVDec { gint quality; gboolean PAL; + gboolean interlaced; gboolean wide; gint frame_len; From 80510aeee70ca73d3102559ce9a919134ce9629e Mon Sep 17 00:00:00 2001 From: David Schleef Date: Wed, 25 Feb 2009 20:47:15 -0800 Subject: [PATCH 36/52] Change how win32/common/config.h is updated Generate win32/common/config.h-new directly from config.h.in, using shell variables in configure and some hard-coded information. Change top-level makefile so that 'make win32-update' copies the generated file to win32/common/config.h, which we keep in source control. It's kept in source control so that the git tree is buildable from VS. This change is similar to the one recently applied to GStreamer and gst-plugins-good. The previous config.h file in -good was in pretty bad shape, so unlike core and base, I didn't attempt to leave it strictly the same, but fixed it as necessary. Needs testing I cannot do myself. --- Makefile.am | 4 + configure.ac | 43 +++++- win32/common/config.h.in | 281 --------------------------------------- 3 files changed, 46 insertions(+), 282 deletions(-) delete mode 100644 win32/common/config.h.in diff --git a/Makefile.am b/Makefile.am index 46c6f5bbd6..4247a97150 100644 --- a/Makefile.am +++ b/Makefile.am @@ -55,5 +55,9 @@ check-torture: true endif +win32-update: + cp $(top_builddir)/win32/common/config.h-new \ + $(top_srcdir)/win32/common/config.h + include $(top_srcdir)/common/coverage/lcov.mak diff --git a/configure.ac b/configure.ac index abc518792d..5412d79695 100644 --- a/configure.ac +++ b/configure.ac @@ -1143,11 +1143,52 @@ m4/Makefile docs/Makefile docs/plugins/Makefile docs/version.entities -win32/common/config.h pkgconfig/Makefile pkgconfig/gstreamer-plugins-good-uninstalled.pc gst-plugins-good.spec ) + +dnl Create the config.h file for Visual Studio builds +dnl Beware of spaces and /'s in some of the shell variable contents. +sed \ + -e 's/.*config.h.in.*autoheader.*/\/* Autogenerated config.h created for win32 Visual Studio builds *\/\n\n\/* PREFIX -- specifically added for Windows for easier moving *\/\n#define PREFIX "C:\\\\gstreamer"\n\n#define GST_INSTALL_PLUGINS_HELPER PREFIX "\\\\libexec\\\\gst-install-plugins-helper.exe"/' \ + -e 's/.* GETTEXT_PACKAGE$/#define GETTEXT_PACKAGE "'$GETTEXT_PACKAGE'"/' \ + -e 's/.* GST_DATADIR$/#define GST_DATADIR PREFIX "\\\\share"/' \ + -e 's/.* GST_LEVEL_DEFAULT$/#define GST_LEVEL_DEFAULT GST_LEVEL_ERROR/' \ + -e 's/.* GST_LICENSE$/#define GST_LICENSE "'$GST_LICENSE'"/' \ + -e 's/.* GST_MAJORMINOR$/#define GST_MAJORMINOR "'$GST_MAJORMINOR'"/' \ + -e "s,.* GST_PACKAGE_NAME$,#define GST_PACKAGE_NAME \"${GST_PACKAGE_NAME}\"," \ + -e 's/.* GST_PACKAGE_ORIGIN$/#define GST_PACKAGE_ORIGIN "Unknown package origin"/' \ + -e 's/.* HAVE_CPU_I386$/#define HAVE_CPU_I386 1/' \ + -e 's/.* HAVE_FGETPOS$/#define HAVE_FGETPOS 1/' \ + -e 's/.* HAVE_FSETPOS$/#define HAVE_FSETPOS 1/' \ + -e 's/.* HAVE_LIBXML2$/#define HAVE_LIBXML2 1/' \ + -e 's/.* HAVE_PROCESS_H$/#define HAVE_PROCESS_H 1/' \ + -e 's/.* HAVE_STDLIB_H$/#define HAVE_STDLIB_H 1/' \ + -e 's/.* HAVE_STRING_H$/#define HAVE_STRING_H 1/' \ + -e 's/.* HAVE_SYS_STAT_H$/#define HAVE_SYS_STAT_H 1/' \ + -e 's/.* HAVE_SYS_TYPES_H$/#define HAVE_SYS_TYPES_H 1/' \ + -e 's/.* HAVE_WIN32$/#define HAVE_WIN32 1/' \ + -e 's/.* HAVE_WINSOCK2_H$/#define HAVE_WINSOCK2_H 1/' \ + -e 's/.* HOST_CPU$/#define HOST_CPU "i686"/' \ + -e 's/.* LIBDIR$/#ifdef _DEBUG\n# define LIBDIR PREFIX "\\\\debug\\\\lib"\n#else\n# define LIBDIR PREFIX "\\\\lib"\n#endif/' \ + -e 's/.* LOCALEDIR$/#define LOCALEDIR PREFIX "\\\\share\\\\locale"/' \ + -e "s/.* PACKAGE$/#define PACKAGE \"$PACKAGE\"/" \ + -e 's/.* PACKAGE_BUGREPORT$/#define PACKAGE_BUGREPORT "http:\/\/bugzilla.gnome.org\/enter_bug.cgi?product=GStreamer"/' \ + -e "s/.* PACKAGE_NAME$/#define PACKAGE_NAME \"$PACKAGE_NAME\"/" \ + -e "s/.* PACKAGE_STRING$/#define PACKAGE_STRING \"$PACKAGE_STRING\"/" \ + -e 's/.* PACKAGE_TARNAME$/#define PACKAGE_TARNAME "'$PACKAGE_TARNAME'"/' \ + -e 's/.* PACKAGE_VERSION$/#define PACKAGE_VERSION "'$PACKAGE_VERSION'"/' \ + -e 's/.* PLUGINDIR$/#ifdef _DEBUG\n# define PLUGINDIR PREFIX "\\\\debug\\\\lib\\\\gstreamer-0.10"\n#else\n# define PLUGINDIR PREFIX "\\\\lib\\\\gstreamer-0.10"\n#endif/' \ + -e 's/.* USE_BINARY_REGISTRY$/#define USE_BINARY_REGISTRY/' \ + -e 's/.* VERSION$/#define VERSION "'$VERSION'"/' \ + -e "s/.* DEFAULT_AUDIOSINK$/#define DEFAULT_AUDIOSINK \"directaudiosink\"/" \ + -e "s/.* DEFAULT_VIDEOSINK$/#define DEFAULT_VIDEOSINK \"directdrawsink\"/" \ + -e "s/.* DEFAULT_AUDIOSRC$/#define DEFAULT_AUDIOSRC \"audiotestsrc\"/" \ + -e "s/.* DEFAULT_VIDEOSRC$/#define DEFAULT_VIDEOSRC \"videotestsrc\"/" \ + -e "s/.* DEFAULT_VISUALIZER$/#define DEFAULT_VISUALIZER \"goom\"/" \ + config.h.in >win32/common/config.h-new + AC_OUTPUT AG_GST_OUTPUT_PLUGINS diff --git a/win32/common/config.h.in b/win32/common/config.h.in deleted file mode 100644 index 21b60390eb..0000000000 --- a/win32/common/config.h.in +++ /dev/null @@ -1,281 +0,0 @@ -/* config.h. Generated by configure. */ -/* config.h.in. Generated from configure.ac by autoheader. */ - -/* Default audio sink */ -#define DEFAULT_AUDIOSINK "autoaudiosink" - -/* Default audio source */ -#define DEFAULT_AUDIOSRC "alsasrc" - -/* Default video sink */ -#define DEFAULT_VIDEOSINK "autovideosink" - -/* Default video source */ -#define DEFAULT_VIDEOSRC "v4lsrc" - -/* Default visualizer */ -#define DEFAULT_VISUALIZER "goom" - -/* Define to 1 if translation of program messages to the user's native - language is requested. */ -#undef ENABLE_NLS - -/* gettext package name */ -#define GETTEXT_PACKAGE "@GETTEXT_PACKAGE@" - -/* PREFIX - specifically added for Windows for easier moving */ -#define PREFIX "C:\\gstreamer" - -/* Defined if gcov is enabled to force a rebuild due to config.h changing */ -/* #undef GST_GCOV_ENABLED */ - -/* Default errorlevel to use */ -#define GST_LEVEL_DEFAULT GST_LEVEL_ERROR - -/* GStreamer license */ -#define GST_LICENSE "@GST_LICENSE@" - -/* package name in plugins */ -#define GST_PACKAGE_NAME "@GST_PACKAGE_NAME@" - -/* package origin */ -#define GST_PACKAGE_ORIGIN "@GST_PACKAGE_ORIGIN@" - -/* support for features: aasink */ -#define HAVE_AALIB - -/* support for features: skeldec cmmlenc cmmldec */ -#define HAVE_ANNODEX - -/* support for features: cairo */ -#define HAVE_CAIRO - -/* support for features: cdio */ -#define HAVE_CDIO - -/* Define if the host CPU is an Alpha */ -/* #undef HAVE_CPU_ALPHA */ - -/* Define if the host CPU is an ARM */ -/* #undef HAVE_CPU_ARM */ - -/* Define if the host CPU is a HPPA */ -/* #undef HAVE_CPU_HPPA */ - -/* Define if the host CPU is an x86 */ -#define HAVE_CPU_I386 1 - -/* Define if the host CPU is a IA64 */ -/* #undef HAVE_CPU_IA64 */ - -/* Define if the host CPU is a M68K */ -/* #undef HAVE_CPU_M68K */ - -/* Define if the host CPU is a MIPS */ -/* #undef HAVE_CPU_MIPS */ - -/* Define if the host CPU is a PowerPC */ -/* #undef HAVE_CPU_PPC */ - -/* Define if the host CPU is a S390 */ -/* #undef HAVE_CPU_S390 */ - -/* Define if the host CPU is a SPARC */ -/* #undef HAVE_CPU_SPARC */ - -/* Define if the host CPU is a x86_64 */ -/* #undef HAVE_CPU_X86_64 */ - -/* Define if the GNU dcgettext() function is already present or preinstalled. - */ -#undef HAVE_DCGETTEXT - -/* Define to 1 if you have the header file. */ -#undef HAVE_DLFCN_H - -/* support for features: dv1394src */ -#define HAVE_DV1394 - -/* support for features: esdsink */ -#define HAVE_ESD - -/* support for features: */ -#define HAVE_EXTERNAL - -/* FIONREAD ioctl found in sys/filio.h */ -/* #undef HAVE_FIONREAD_IN_SYS_FILIO */ - -/* FIONREAD ioctl found in sys/ioclt.h */ -#define HAVE_FIONREAD_IN_SYS_IOCTL 1 - -/* support for features: flacenc flacdec */ -#define HAVE_FLAC - -/* support for features: */ -#define HAVE_GCONF - -/* support for features: */ -#define HAVE_GCONFTOOL - -/* support for features: gdkpixbufsrc */ -#define HAVE_GDK_PIXBUF - -/* Define to 1 if you have the `getpagesize' function. */ -#undef HAVE_GETPAGESIZE - -/* Define if the GNU gettext() function is already present or preinstalled. */ -#undef HAVE_GETTEXT - -/* support for features: */ -#define HAVE_HAL - -/* Define if you have the iconv() function. */ -/* #undef HAVE_ICONV */ - -/* Define to 1 if you have the header file. */ -#undef HAVE_INTTYPES_H - -/* support for features: jpegenc jpegdec */ -#define HAVE_JPEG - -/* support for features: ladspa */ -#define HAVE_LADSPA - -/* support for features: libcaca */ -#define HAVE_LIBCACA - -/* support for features: dvdec */ -#define HAVE_LIBDV - -/* support for features: pngenc */ -#define HAVE_LIBPNG - -/* Define if you have C99's lrint function. */ -#define HAVE_LRINT 1 - -/* Define if you have C99's lrintf function. */ -#define HAVE_LRINTF 1 - -/* Define to 1 if you have the header file. */ -#undef HAVE_MEMORY_H - -/* Define to 1 if you have a working `mmap' system call. */ -#undef HAVE_MMAP - -/* Define to 1 if you have the header file. */ -#undef HAVE_NETINET_IN_H - -/* support for features: osssrc osssink */ -#define HAVE_OSS - -/* Define if OSS includes are in /machine/ */ -/* #undef HAVE_OSS_INCLUDE_IN_MACHINE */ - -/* Define if OSS includes are in / */ -/* #undef HAVE_OSS_INCLUDE_IN_ROOT */ - -/* Define if OSS includes are in /sys/ */ -#define HAVE_OSS_INCLUDE_IN_SYS - -/* Define if RDTSC is available */ -#undef HAVE_RDTSC - -/* support for features: shout2send */ -#define HAVE_SHOUT2 - -/* support for features: speex */ -#define HAVE_SPEEX - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDINT_H - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRINGS_H - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 - -/* support for features: sunaudiosink */ -/* #undef HAVE_SUNAUDIO */ - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_SOCKET_H - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* support for features: taglib */ -#define HAVE_TAGLIB - -/* Define to 1 if you have the header file. */ -#undef HAVE_UNISTD_H - -/* Define if valgrind should be used */ -#undef HAVE_VALGRIND - -/* Define to 1 if you have the header file. */ -#define HAVE_WINSOCK2_H 1 - -/* support for features: ximagesrc */ -#define HAVE_X - -/* support for features: */ -#define HAVE_XSHM - -/* support for features: */ -#define HAVE_ZLIB - -/* gettext locale dir */ -#define LOCALEDIR PREFIX "\\share\\locale" - -/* Name of package */ -#define PACKAGE "@PACKAGE@" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "@PACKAGE_NAME@" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "@PACKAGE_STRING@" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "@PACKAGE_TARNAME@" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "@PACKAGE_VERSION@" - -/* Define the plugin directory */ -#ifdef _DEBUG -# define PLUGINDIR PREFIX "\\debug\\lib\\gstreamer-0.10" -#else -# define PLUGINDIR PREFIX "\\lib\\gstreamer-0.10" -#endif - -/* defined if speex 1.0.x API detected */ -#define SPEEX_1_0 1 - -/* Define to 1 if you have the ANSI C header files. */ -#undef STDC_HEADERS - -/* Version number of package */ -#define VERSION "@VERSION@" - -/* Define to 1 if your processor stores words with the most significant byte - first (like Motorola and SPARC, unlike Intel and VAX). */ -/* #undef WORDS_BIGENDIAN */ - -/* Define to 1 if the X Window System is missing or not being used. */ -/* #undef X_DISPLAY_MISSING */ - -/* Define socklen_t as it seems to be not defined in default VS setup */ -#ifndef socklen_t -typedef int socklen_t; -#endif \ No newline at end of file From 62d5787bcda78bba5384732f9d25042d33af7923 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 26 Feb 2009 13:00:58 +0100 Subject: [PATCH 37/52] rtpvrawpay: fail on interlaced video Detect and fail when trying to payload interlaced video. --- gst/rtp/gstrtpvrawpay.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/gst/rtp/gstrtpvrawpay.c b/gst/rtp/gstrtpvrawpay.c index 19c14c2bc9..0f0ef7e826 100644 --- a/gst/rtp/gstrtpvrawpay.c +++ b/gst/rtp/gstrtpvrawpay.c @@ -211,6 +211,7 @@ gst_rtp_vraw_pay_setcaps (GstBaseRTPPayload * payload, GstCaps * caps) GstVideoFormat sampling; const gchar *depthstr, *samplingstr, *colorimetrystr; gchar *wstr, *hstr; + gboolean interlaced; rtpvrawpay = GST_RTP_VRAW_PAY (payload); @@ -229,6 +230,13 @@ gst_rtp_vraw_pay_setcaps (GstBaseRTPPayload * payload, GstCaps * caps) if (!res) goto missing_dimension; + /* fail on interlaced video for now */ + if (!gst_structure_get_boolean (s, "interlaced", &interlaced)) + interlaced = FALSE; + + if (interlaced) + goto interlaced; + yp = up = vp = 0; xinc = yinc = 1; @@ -358,6 +366,11 @@ unknown_fourcc: GST_ERROR_OBJECT (payload, "invalid or missing fourcc"); return FALSE; } +interlaced: + { + GST_ERROR_OBJECT (payload, "interlaced video not supported yet"); + return FALSE; + } missing_dimension: { GST_ERROR_OBJECT (payload, "missing width or height property"); @@ -409,7 +422,7 @@ gst_rtp_vraw_pay_handle_buffer (GstBaseRTPPayload * payload, GstBuffer * buffer) GstBuffer *out; guint8 *outdata, *headers; gboolean next_line; - guint length, cont, pixels; + guint length, cont, pixels, fieldid; /* get the max allowed payload length size, we try to fill the complete MTU */ left = gst_rtp_buffer_calc_payload_len (mtu, 0, 0); @@ -422,6 +435,24 @@ gst_rtp_vraw_pay_handle_buffer (GstBaseRTPPayload * payload, GstBuffer * buffer) GST_LOG_OBJECT (rtpvrawpay, "created buffer of size %u for MTU %u", left, mtu); + /* + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Extended Sequence Number | Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |F| Line No |C| Offset | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Length |F| Line No | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |C| Offset | . + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ . + * . . + * . Two (partial) lines of video data . + * . . + * +---------------------------------------------------------------+ + */ + /* need 2 bytes for the extended sequence number */ *outdata++ = 0; *outdata++ = 0; @@ -456,8 +487,12 @@ gst_rtp_vraw_pay_handle_buffer (GstBaseRTPPayload * payload, GstBuffer * buffer) /* write length */ *outdata++ = (length >> 8) & 0xff; *outdata++ = length & 0xff; + + /* always 0 for now */ + fieldid = 0x00; + /* write line no */ - *outdata++ = (line >> 8) & 0x7f; + *outdata++ = ((line >> 8) & 0x7f) | fieldid; *outdata++ = line & 0xff; if (next_line) { From af2e8f847017263d2f103f522187e4e6d76a6395 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 26 Feb 2009 13:06:17 +0100 Subject: [PATCH 38/52] rtpvrawdepay: fail on interlaced video Fail on interlaced video until we support it. --- gst/rtp/gstrtpvrawdepay.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/gst/rtp/gstrtpvrawdepay.c b/gst/rtp/gstrtpvrawdepay.c index 35e68a3e4a..3f599f5dbc 100644 --- a/gst/rtp/gstrtpvrawdepay.c +++ b/gst/rtp/gstrtpvrawdepay.c @@ -139,6 +139,11 @@ gst_rtp_vraw_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps) goto no_height; height = atoi (str); + /* optional interlace value but we don't handle interlaced + * formats yet */ + if ((str = gst_structure_get_string (structure, "interlace"))) + goto interlaced; + if (!(str = gst_structure_get_string (structure, "sampling"))) goto no_sampling; @@ -248,6 +253,11 @@ no_height: GST_ERROR_OBJECT (depayload, "no height specified"); return FALSE; } +interlaced: + { + GST_ERROR_OBJECT (depayload, "interlaced formats not supported yet"); + return FALSE; + } no_sampling: { GST_ERROR_OBJECT (depayload, "no sampling specified"); From 474d9d7a9b9b32bfd66a558be468e7a5b588f992 Mon Sep 17 00:00:00 2001 From: Jan Smout Date: Thu, 26 Feb 2009 13:19:31 +0100 Subject: [PATCH 39/52] udp: fix gst_udp_set_loop_ttl() again Fix the gst_udp_set_loop_ttl() function that was commented out in a previous commit. See #573115. --- gst/udp/gstudpnetutils.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/gst/udp/gstudpnetutils.c b/gst/udp/gstudpnetutils.c index a1588caa6a..b1f864e394 100644 --- a/gst/udp/gstudpnetutils.c +++ b/gst/udp/gstudpnetutils.c @@ -115,12 +115,17 @@ beach: int gst_udp_set_loop_ttl (int sockfd, gboolean loop, int ttl) { + socklen_t socklen; + struct sockaddr_storage addr; int ret = -1; - -#if 0 int l = (loop == FALSE) ? 0 : 1; - switch (addr->ss_family) { + socklen = sizeof (addr); + if ((ret = getsockname (sockfd, (struct sockaddr *) &addr, &socklen)) < 0) { + return ret; + } + + switch (addr.ss_family) { case AF_INET: { if ((ret = @@ -151,7 +156,6 @@ gst_udp_set_loop_ttl (int sockfd, gboolean loop, int ttl) default: errno = EAFNOSUPPORT; } -#endif return ret; } From c7dd6a49026ca8818b80c138cdd511bd0266a416 Mon Sep 17 00:00:00 2001 From: Patrick Radizi Date: Thu, 26 Feb 2009 19:03:52 +0100 Subject: [PATCH 40/52] rtspsrc: add property to disable RTCP Some old servers don't like us doing RTCP and thus we need a property to disable it. See #573173. --- gst/rtsp/gstrtspsrc.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/gst/rtsp/gstrtspsrc.c b/gst/rtsp/gstrtspsrc.c index b3e1df47b0..7c5ef8a6b5 100644 --- a/gst/rtsp/gstrtspsrc.c +++ b/gst/rtsp/gstrtspsrc.c @@ -146,6 +146,7 @@ enum #define DEFAULT_LATENCY_MS 3000 #define DEFAULT_CONNECTION_SPEED 0 #define DEFAULT_NAT_METHOD GST_RTSP_NAT_DUMMY +#define DEFAULT_DO_RTCP TRUE enum { @@ -159,6 +160,7 @@ enum PROP_LATENCY, PROP_CONNECTION_SPEED, PROP_NAT_METHOD, + PROP_DO_RTCP, PROP_LAST }; @@ -335,6 +337,19 @@ gst_rtspsrc_class_init (GstRTSPSrcClass * klass) GST_TYPE_RTSP_NAT_METHOD, DEFAULT_NAT_METHOD, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + /** + * GstRTSPSrc::do-rtcp + * + * Enable RTCP support. Some old server don't like RTCP and then this property + * needs to be set to FALSE. + * + * Since: 0.10.15 + */ + g_object_class_install_property (gobject_class, PROP_DO_RTCP, + g_param_spec_boolean ("do-rtcp", "Do RTCP", + "Don't send RTCP packets", + DEFAULT_DO_RTCP, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + gstelement_class->change_state = gst_rtspsrc_change_state; gstbin_class->handle_message = gst_rtspsrc_handle_message; @@ -454,6 +469,9 @@ gst_rtspsrc_set_property (GObject * object, guint prop_id, const GValue * value, case PROP_NAT_METHOD: rtspsrc->nat_method = g_value_get_enum (value); break; + case PROP_DO_RTCP: + rtspsrc->do_rtcp = g_value_get_boolean (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -502,6 +520,9 @@ gst_rtspsrc_get_property (GObject * object, guint prop_id, GValue * value, case PROP_NAT_METHOD: g_value_set_enum (value, rtspsrc->nat_method); break; + case PROP_DO_RTCP: + g_value_set_boolean (value, rtspsrc->do_rtcp); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1942,8 +1963,8 @@ gst_rtspsrc_stream_configure_tcp (GstRTSPSrc * src, GstRTSPStream * stream, } gst_object_unref (template); } - /* setup RTCP transport back to the server */ - if (src->session) { + /* setup RTCP transport back to the server if we have to. */ + if (src->session && src->do_rtcp) { GstPad *pad; template = gst_static_pad_template_get (&anysinktemplate); @@ -2162,7 +2183,7 @@ gst_rtspsrc_stream_configure_udp_sinks (GstRTSPSrc * src, } /* it's possible that the server does not want us to send RTCP in which case * the port is -1 */ - if (rtcp_port != -1 && src->session != NULL) { + if (rtcp_port != -1 && src->session != NULL && src->do_rtcp) { GST_DEBUG_OBJECT (src, "configure RTCP UDP sink for %s:%d", destination, rtcp_port); @@ -3944,7 +3965,7 @@ gst_rtspsrc_setup_streams (GstRTSPSrc * src) GST_DEBUG_OBJECT (src, "doing setup of stream %p with %s", stream, stream->setup_url); -retry: + retry: /* create a string with all the transports */ res = gst_rtspsrc_create_transports_string (src, protocols, &transports); if (res < 0) From 51200cad4108eb60ebd5f5a319ada463d40b455b Mon Sep 17 00:00:00 2001 From: Patrick Radizi Date: Thu, 26 Feb 2009 19:05:06 +0100 Subject: [PATCH 41/52] rtspsrc: add the .h file change too Add the .h file change for the new property. --- gst/rtsp/gstrtspsrc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/gst/rtsp/gstrtspsrc.h b/gst/rtsp/gstrtspsrc.h index 95dd986913..40a368c6d7 100644 --- a/gst/rtsp/gstrtspsrc.h +++ b/gst/rtsp/gstrtspsrc.h @@ -186,6 +186,7 @@ struct _GstRTSPSrc { guint latency; guint connection_speed; GstRTSPNatMethod nat_method; + gboolean do_rtcp; /* state */ GstRTSPState state; From ec5229d75f51308abf4858769026d7c3970eaf73 Mon Sep 17 00:00:00 2001 From: Julien Moutte Date: Thu, 26 Feb 2009 19:07:35 +0100 Subject: [PATCH 42/52] avidemux: fix SEEK event handling in push mode When in push mode we should not try to handle the SEEK event as there's no code to handle it properly. Propagate upstream. --- gst/avi/gstavidemux.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/gst/avi/gstavidemux.c b/gst/avi/gstavidemux.c index 017a7f5806..adea05fdba 100644 --- a/gst/avi/gstavidemux.c +++ b/gst/avi/gstavidemux.c @@ -619,9 +619,13 @@ gst_avi_demux_handle_src_event (GstPad * pad, GstEvent * event) switch (GST_EVENT_TYPE (event)) { case GST_EVENT_SEEK: - /* handle seeking */ - res = gst_avi_demux_handle_seek (avi, pad, event); - gst_event_unref (event); + /* handle seeking only in pull mode */ + if (!avi->streaming) { + res = gst_avi_demux_handle_seek (avi, pad, event); + gst_event_unref (event); + } else { + res = gst_pad_event_default (pad, event); + } break; case GST_EVENT_QOS: case GST_EVENT_NAVIGATION: @@ -4246,6 +4250,7 @@ gst_avi_demux_sink_activate_pull (GstPad * sinkpad, gboolean active) if (active) { avi->segment_running = TRUE; + avi->streaming = FALSE; return gst_pad_start_task (sinkpad, (GstTaskFunction) gst_avi_demux_loop, sinkpad); } else { @@ -4257,9 +4262,11 @@ gst_avi_demux_sink_activate_pull (GstPad * sinkpad, gboolean active) static gboolean gst_avi_demux_activate_push (GstPad * pad, gboolean active) { + GstAviDemux *avi = GST_AVI_DEMUX (GST_OBJECT_PARENT (pad)); if (active) { GST_DEBUG ("avi: activating push/chain function"); + avi->streaming = TRUE; } else { GST_DEBUG ("avi: deactivating push/chain function"); } From 1846e0af0f55eb6931009242f23cfe0aaeb475f7 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Fri, 27 Feb 2009 11:04:08 +0100 Subject: [PATCH 43/52] matroskademux: Remove gst_util_dump_mem() calls. --- gst/matroska/matroska-demux.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c index 118886fc75..50011cffd1 100644 --- a/gst/matroska/matroska-demux.c +++ b/gst/matroska/matroska-demux.c @@ -5135,9 +5135,6 @@ gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext * guint rformat; guint subformat; - gst_util_dump_mem (data, size); - gst_util_dump_mem (data + 0x1a, size - 0x1a); - subformat = GST_READ_UINT32_BE (data + 0x1a); rformat = GST_READ_UINT32_BE (data + 0x1e); @@ -5503,7 +5500,6 @@ gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext * guint extra_data_size; GST_ERROR ("real audio raversion:%d", raversion); - gst_util_dump_mem (data, size); if (raversion == 8) { /* COOK */ flavor = GST_READ_UINT16_BE (data + 22); From 3310a540e3ad69d6ed87ddbafd9df22a5a7a7d89 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Fri, 27 Feb 2009 13:29:41 +0100 Subject: [PATCH 44/52] wavparse: Fix SEEK event handling in push mode, and SEEKABLY query handling Standard pull mode loop based SEEK handling fails in push mode, so convert the SEEK event appropriately and dispatch to upstream. Also cater for NEWSEGMENT event handling, and properly inform downstream and application of SEEKABLE capabilities, depending on scheduling mode and upstream. --- gst/wavparse/gstwavparse.c | 290 +++++++++++++++++++++++++++++++++---- 1 file changed, 260 insertions(+), 30 deletions(-) diff --git a/gst/wavparse/gstwavparse.c b/gst/wavparse/gstwavparse.c index 266c430fac..c8e7c756ef 100644 --- a/gst/wavparse/gstwavparse.c +++ b/gst/wavparse/gstwavparse.c @@ -77,6 +77,7 @@ static gboolean gst_wavparse_pad_convert (GstPad * pad, gint64 src_value, GstFormat * dest_format, gint64 * dest_value); static GstFlowReturn gst_wavparse_chain (GstPad * pad, GstBuffer * buf); +static gboolean gst_wavparse_sink_event (GstPad * pad, GstEvent * event); static void gst_wavparse_loop (GstPad * pad); static gboolean gst_wavparse_srcpad_event (GstPad * pad, GstEvent * event); @@ -193,6 +194,8 @@ gst_wavparse_init (GstWavParse * wavparse, GstWavParseClass * g_class) GST_DEBUG_FUNCPTR (gst_wavparse_sink_activate_pull)); gst_pad_set_chain_function (wavparse->sinkpad, GST_DEBUG_FUNCPTR (gst_wavparse_chain)); + gst_pad_set_event_function (wavparse->sinkpad, + GST_DEBUG_FUNCPTR (gst_wavparse_sink_event)); gst_element_add_pad (GST_ELEMENT_CAST (wavparse), wavparse->sinkpad); /* src, will be created later */ @@ -725,8 +728,35 @@ gst_wavparse_stream_init (GstWavParse * wav) return GST_FLOW_OK; } -/* This function is used to perform seeks on the element in - * pull mode. +static gboolean +gst_wavparse_time_to_bytepos (GstWavParse * wav, gint64 ts, gint64 * bytepos) +{ + /* -1 always maps to -1 */ + if (ts == -1) { + *bytepos = -1; + return TRUE; + } + + /* 0 always maps to 0 */ + if (ts == 0) { + *bytepos = 0; + return TRUE; + } + + if (wav->bps > 0) { + *bytepos = uint64_ceiling_scale (ts, (guint64) wav->bps, GST_SECOND); + return TRUE; + } else if (wav->fact) { + guint64 bps = + gst_util_uint64_scale_int (wav->datasize, wav->rate, wav->fact); + *bytepos = uint64_ceiling_scale (ts, bps, GST_SECOND); + return TRUE; + } + + return FALSE; +} + +/* This function is used to perform seeks on the element. * * It also works when event is NULL, in which case it will just * start from the last configured segment. This technique is @@ -783,6 +813,48 @@ gst_wavparse_perform_seek (GstWavParse * wav, GstEvent * event) stop_type = GST_SEEK_TYPE_SET; } + /* in push mode, we must delegate to upstream */ + if (wav->streaming) { + gboolean res = FALSE; + + /* if streaming not yet started; only prepare initial newsegment */ + if (!event || wav->state != GST_WAVPARSE_DATA) { + if (wav->start_segment) + gst_event_unref (wav->start_segment); + wav->start_segment = + gst_event_new_new_segment (FALSE, wav->segment.rate, + wav->segment.format, wav->segment.last_stop, wav->segment.duration, + wav->segment.last_stop); + res = TRUE; + } else { + /* convert seek positions to byte positions in data sections */ + if (format == GST_FORMAT_TIME) { + /* should not fail */ + if (!gst_wavparse_time_to_bytepos (wav, cur, &cur)) + goto no_position; + if (!gst_wavparse_time_to_bytepos (wav, stop, &stop)) + goto no_position; + } + /* mind sample boundary and header */ + if (cur >= 0) { + cur -= (cur % wav->bytes_per_sample); + cur += wav->datastart; + } + if (stop >= 0) { + stop -= (stop % wav->bytes_per_sample); + stop += wav->datastart; + } + GST_DEBUG_OBJECT (wav, "Pushing BYTE seek rate %g, " + "start %" G_GINT64_FORMAT ", stop %" G_GINT64_FORMAT, rate, cur, + stop); + /* BYTE seek event */ + event = gst_event_new_seek (rate, GST_FORMAT_BYTES, flags, cur_type, cur, + stop_type, stop); + res = gst_pad_push_event (wav->sinkpad, event); + } + return res; + } + /* get flush flag */ flush = flags & GST_SEEK_FLAG_FLUSH; @@ -832,16 +904,8 @@ gst_wavparse_perform_seek (GstWavParse * wav, GstEvent * event) /* bring offset to bytes, if the bps is 0, we have the segment in BYTES and * we can just copy the last_stop. If not, we use the bps to convert TIME to * bytes. */ - if (wav->bps > 0) - wav->offset = - uint64_ceiling_scale (seeksegment.last_stop, (guint64) wav->bps, - GST_SECOND); - else if (wav->fact) { - guint64 bps = - gst_util_uint64_scale_int (wav->datasize, wav->rate, wav->fact); - wav->offset = - uint64_ceiling_scale (seeksegment.last_stop, bps, GST_SECOND); - } else + if (!gst_wavparse_time_to_bytepos (wav, seeksegment.last_stop, + (gint64 *) & wav->offset)) wav->offset = seeksegment.last_stop; GST_LOG_OBJECT (wav, "offset=%" G_GUINT64_FORMAT, wav->offset); wav->offset -= (wav->offset % wav->bytes_per_sample); @@ -854,14 +918,7 @@ gst_wavparse_perform_seek (GstWavParse * wav, GstEvent * event) } if (stop_type != GST_SEEK_TYPE_NONE) { - if (wav->bps > 0) - wav->end_offset = - uint64_ceiling_scale (stop, (guint64) wav->bps, GST_SECOND); - else if (wav->fact) { - guint64 bps = - gst_util_uint64_scale_int (wav->datasize, wav->rate, wav->fact); - wav->end_offset = uint64_ceiling_scale (stop, bps, GST_SECOND); - } else + if (!gst_wavparse_time_to_bytepos (wav, stop, (gint64 *) & wav->end_offset)) wav->end_offset = stop; GST_LOG_OBJECT (wav, "end_offset=%" G_GUINT64_FORMAT, wav->end_offset); wav->end_offset -= (wav->end_offset % wav->bytes_per_sample); @@ -962,6 +1019,12 @@ no_format: GST_DEBUG_OBJECT (wav, "unsupported format given, seek aborted."); return FALSE; } +no_position: + { + GST_DEBUG_OBJECT (wav, + "Could not determine byte position for desired time"); + return FALSE; + } } /* @@ -1678,6 +1741,32 @@ iterate_adapter: if (wav->streaming) { guint avail = gst_adapter_available (wav->adapter); + guint extra; + + /* flush some bytes if evil upstream sends segment that starts + * before data or does is not send sample aligned segment */ + if (G_LIKELY (wav->offset >= wav->datastart)) { + extra = (wav->offset - wav->datastart) % wav->bytes_per_sample; + } else { + extra = wav->datastart - wav->offset; + } + + if (G_UNLIKELY (extra)) { + extra = wav->bytes_per_sample - extra; + if (extra <= avail) { + GST_DEBUG_OBJECT (wav, "flushing %d bytes to sample boundary", extra); + gst_adapter_flush (wav->adapter, extra); + wav->offset += extra; + wav->dataleft -= extra; + goto iterate_adapter; + } else { + GST_DEBUG_OBJECT (wav, "flushing %d bytes", avail); + gst_adapter_clear (wav->adapter); + wav->offset += avail; + wav->dataleft -= avail; + return GST_FLOW_OK; + } + } if (avail < desired) { GST_LOG_OBJECT (wav, "Got only %d bytes of data from the sinkpad", avail); @@ -1927,6 +2016,8 @@ gst_wavparse_chain (GstPad * pad, GstBuffer * buf) /* fall-through */ case GST_WAVPARSE_DATA: + if (buf && GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT)) + wav->discont = TRUE; if ((ret = gst_wavparse_stream_data (wav)) != GST_FLOW_OK) goto done; break; @@ -1937,6 +2028,132 @@ done: return ret; } +static GstFlowReturn +gst_wavparse_flush_data (GstWavParse * wav) +{ + GstFlowReturn ret = GST_FLOW_OK; + guint av; + + if ((av = gst_adapter_available (wav->adapter)) > 0) { + wav->dataleft = av; + wav->end_offset = wav->offset + av; + ret = gst_wavparse_stream_data (wav); + } + + return ret; +} + +static gboolean +gst_wavparse_sink_event (GstPad * pad, GstEvent * event) +{ + GstWavParse *wav = GST_WAVPARSE (GST_PAD_PARENT (pad)); + gboolean ret = TRUE; + + GST_LOG_OBJECT (wav, "handling %s event", GST_EVENT_TYPE_NAME (event)); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_NEWSEGMENT: + { + GstFormat format; + gdouble rate, arate; + gint64 start, stop, time, offset = 0, end_offset = -1; + gboolean update; + GstSegment segment; + + /* some debug output */ + gst_segment_init (&segment, GST_FORMAT_UNDEFINED); + gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format, + &start, &stop, &time); + gst_segment_set_newsegment_full (&segment, update, rate, arate, format, + start, stop, time); + GST_DEBUG_OBJECT (wav, + "received format %d newsegment %" GST_SEGMENT_FORMAT, format, + &segment); + + if (wav->state != GST_WAVPARSE_DATA) { + GST_DEBUG_OBJECT (wav, "still starting, eating event"); + goto exit; + } + + /* now we are either committed to TIME or BYTE format, + * and we only expect a BYTE segment, e.g. following a seek */ + if (format == GST_FORMAT_BYTES) { + if (start > 0) { + offset = start; + start -= wav->datastart; + start = MAX (start, 0); + } + if (stop > 0) { + end_offset = stop; + stop -= wav->datastart; + stop = MAX (stop, 0); + } + if (wav->segment.format == GST_FORMAT_TIME) { + guint64 bps = wav->bps; + + /* operating in format TIME, so we can convert */ + if (!bps && wav->fact) + bps = + gst_util_uint64_scale_int (wav->datasize, wav->rate, wav->fact); + if (bps) { + if (start >= 0) + start = + uint64_ceiling_scale (start, GST_SECOND, (guint64) wav->bps); + if (stop >= 0) + stop = + uint64_ceiling_scale (stop, GST_SECOND, (guint64) wav->bps); + } + } + } else { + GST_DEBUG_OBJECT (wav, "unsupported segment format, ignoring"); + goto exit; + } + + /* accept upstream's notion of segment and distribute along */ + gst_segment_set_newsegment_full (&wav->segment, update, rate, arate, + wav->segment.format, start, stop, start); + /* also store the newsegment event for the streaming thread */ + if (wav->start_segment) + gst_event_unref (wav->start_segment); + wav->start_segment = + gst_event_new_new_segment_full (update, rate, arate, + wav->segment.format, start, stop, start); + GST_DEBUG_OBJECT (wav, "Pushing newseg update %d, rate %g, " + "applied rate %g, format %d, start %" G_GINT64_FORMAT ", " + "stop %" G_GINT64_FORMAT, update, rate, arate, wav->segment.format, + start, stop); + + /* stream leftover data in current segment */ + gst_wavparse_flush_data (wav); + /* and set up streaming thread for next one */ + wav->offset = offset; + wav->end_offset = end_offset; + if (wav->end_offset > 0) { + wav->dataleft = wav->end_offset - wav->offset; + } else { + /* infinity; upstream will EOS when done */ + wav->dataleft = G_MAXUINT64; + } + exit: + gst_event_unref (event); + break; + } + case GST_EVENT_EOS: + /* stream leftover data in current segment */ + gst_wavparse_flush_data (wav); + /* fall-through */ + case GST_EVENT_FLUSH_STOP: + gst_adapter_clear (wav->adapter); + wav->discont = TRUE; + /* fall-through */ + default: + ret = gst_pad_event_default (wav->sinkpad, event); + break; + } + + return ret; +} + #if 0 /* convert and query stuff */ static const GstFormat * @@ -2089,6 +2306,8 @@ gst_wavparse_pad_query (GstPad * pad, GstQuery * query) return FALSE; } + GST_LOG_OBJECT (pad, "%s query", GST_QUERY_TYPE_NAME (query)); + switch (GST_QUERY_TYPE (query)) { case GST_QUERY_POSITION: { @@ -2152,19 +2371,30 @@ gst_wavparse_pad_query (GstPad * pad, GstQuery * query) } case GST_QUERY_SEEKING:{ GstFormat fmt; + gboolean seekable = FALSE; gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL); - if (fmt == GST_FORMAT_TIME) { - gboolean seekable = TRUE; - - if ((wav->bps == 0) && !wav->fact) { - seekable = FALSE; - } else if (!gst_wavparse_calculate_duration (wav)) { - seekable = FALSE; - } - gst_query_set_seeking (query, GST_FORMAT_TIME, seekable, - 0, wav->duration); + if (fmt == wav->segment.format) { res = TRUE; + if (wav->streaming) { + GstQuery *q; + + q = gst_query_new_seeking (GST_FORMAT_BYTES); + if ((res = gst_pad_peer_query (wav->sinkpad, q))) { + gst_query_parse_seeking (q, &fmt, &seekable, NULL, NULL); + GST_LOG_OBJECT (wav, "upstream BYTE seekable %d", seekable); + } + gst_query_unref (q); + } else { + GST_LOG_OBJECT (wav, "looping => seekable"); + seekable = TRUE; + res = TRUE; + } + } else if (fmt == GST_FORMAT_TIME) { + res = TRUE; + } + if (res) { + gst_query_set_seeking (query, fmt, seekable, 0, wav->segment.duration); } break; } From b50452fc37a74cab50a44948efa944edd077af92 Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Fri, 27 Feb 2009 11:17:50 -0800 Subject: [PATCH 45/52] rgvolume: ignore out-of-range peak values If the peak value is > 1 (and thus nonsensical) ignore it. Prevents rgvolume reducing volume to effectively silent on files with bogus peak values. --- gst/replaygain/gstrgvolume.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/replaygain/gstrgvolume.c b/gst/replaygain/gstrgvolume.c index 41fe441d4c..d569b4bb40 100644 --- a/gst/replaygain/gstrgvolume.c +++ b/gst/replaygain/gstrgvolume.c @@ -92,7 +92,7 @@ enum #define PEAK_FORMAT ".06f" #define VALID_GAIN(x) ((x) > -60.00 && (x) < 60.00) -#define VALID_PEAK(x) ((x) > 0.) +#define VALID_PEAK(x) ((x) > 0. && (x) < 1.) /* Same template caps as GstVolume, for I don't like having just ANY caps. */ From 5d9c947f923dc2f06020c2aaa0898855692dc2a1 Mon Sep 17 00:00:00 2001 From: LRN Date: Fri, 27 Feb 2009 20:24:53 +0100 Subject: [PATCH 46/52] udp: Don't set errno to EAFNOSUPPORT unconditionally Fixes bug #573342. --- gst/udp/gstudpnetutils.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gst/udp/gstudpnetutils.c b/gst/udp/gstudpnetutils.c index a1588caa6a..07268509e2 100644 --- a/gst/udp/gstudpnetutils.c +++ b/gst/udp/gstudpnetutils.c @@ -149,7 +149,11 @@ gst_udp_set_loop_ttl (int sockfd, gboolean loop, int ttl) break; } default: +#ifdef G_OS_WIN32 + WSASetLastError (WSAEAFNOSUPPORT); +#else errno = EAFNOSUPPORT; +#endif } #endif return ret; From 27d1ef8a865449346a8c88faa0273983f64cff8d Mon Sep 17 00:00:00 2001 From: LRN Date: Fri, 27 Feb 2009 20:40:31 +0100 Subject: [PATCH 47/52] directdrawsink: Fix type mismatches Fixes bug #573343. --- sys/directdraw/gstdirectdrawsink.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c index a128b31763..144f6595bc 100644 --- a/sys/directdraw/gstdirectdrawsink.c +++ b/sys/directdraw/gstdirectdrawsink.c @@ -610,7 +610,7 @@ gst_directdraw_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, !gst_directdraw_sink_surface_check (ddrawsink, surface)) ) { gst_directdraw_sink_surface_destroy (ddrawsink, surface); - gst_buffer_unref (surface); + gst_buffer_unref (GST_BUFFER_CAST (surface)); surface = NULL; } else { /* We found a suitable surface */ @@ -629,7 +629,7 @@ gst_directdraw_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, DDSURFACEDESC2 surface_desc; DDSURFACEDESC2 *sd; - if (!gst_structure_get_int (structure, "depth", &depth)) { + if (!gst_structure_get_int (structure, "depth", (gint *) & depth)) { GST_CAT_DEBUG_OBJECT (directdrawsink_debug, ddrawsink, "Can't get depth from buffer_alloc caps"); return GST_FLOW_ERROR; @@ -663,7 +663,7 @@ gst_directdraw_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, gint bpp, endianness, red_mask, green_mask, blue_mask; /* get new display mode properties */ - gst_structure_get_int (display_structure, "depth", &depth); + gst_structure_get_int (display_structure, "depth", (gint *) & depth); gst_structure_get_int (display_structure, "bpp", &bpp); gst_structure_get_int (display_structure, "endianness", &endianness); gst_structure_get_int (display_structure, "red_mask", &red_mask); @@ -997,7 +997,7 @@ gst_ddrawvideosink_get_format_from_caps (GstDirectDrawSink * ddrawsink, pPixelFormat->dwBBitMask = GUINT32_TO_BE (pPixelFormat->dwBBitMask); } } else if (gst_structure_has_name (structure, "video/x-raw-yuv")) { - gint fourcc; + guint32 fourcc; pPixelFormat->dwFlags = DDPF_FOURCC; ret &= gst_structure_get_fourcc (structure, "format", &fourcc); @@ -1894,7 +1894,7 @@ gst_directdraw_sink_bufferpool_clear (GstDirectDrawSink * ddrawsink) ddrawsink->buffer_pool = g_slist_delete_link (ddrawsink->buffer_pool, ddrawsink->buffer_pool); gst_directdraw_sink_surface_destroy (ddrawsink, surface); - gst_buffer_unref (surface); + gst_buffer_unref (GST_BUFFER_CAST (surface)); } g_mutex_unlock (ddrawsink->pool_lock); } From 9f3ad53ca868ce4e33efac104d77391a3a0cf57b Mon Sep 17 00:00:00 2001 From: David Schleef Date: Fri, 27 Feb 2009 23:25:32 -0800 Subject: [PATCH 48/52] Fix the field dominance PAL is TFF, NTSC is BFF. Some day I will learn to keep this straight. --- ext/dv/gstdvdec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/dv/gstdvdec.c b/ext/dv/gstdvdec.c index fad43be279..550b99d17e 100644 --- a/ext/dv/gstdvdec.c +++ b/ext/dv/gstdvdec.c @@ -469,9 +469,9 @@ gst_dvdec_chain (GstPad * pad, GstBuffer * buf) e_dv_color_yuv, outframe_ptrs, outframe_pitches); if (dvdec->PAL) { - GST_BUFFER_FLAG_UNSET (outbuf, GST_VIDEO_BUFFER_TFF); - } else { GST_BUFFER_FLAG_SET (outbuf, GST_VIDEO_BUFFER_TFF); + } else { + GST_BUFFER_FLAG_UNSET (outbuf, GST_VIDEO_BUFFER_TFF); } GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET (buf); From 157531d91e9c5fbff33c4357beba5af31623f35c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Stadler?= Date: Sat, 28 Feb 2009 15:26:00 +0200 Subject: [PATCH 49/52] rgvolume: Improve log message for peak values >1.0 by clamping explicitly. --- gst/replaygain/gstrgvolume.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/gst/replaygain/gstrgvolume.c b/gst/replaygain/gstrgvolume.c index d569b4bb40..cf5a914a9b 100644 --- a/gst/replaygain/gstrgvolume.c +++ b/gst/replaygain/gstrgvolume.c @@ -92,7 +92,7 @@ enum #define PEAK_FORMAT ".06f" #define VALID_GAIN(x) ((x) > -60.00 && (x) < 60.00) -#define VALID_PEAK(x) ((x) > 0. && (x) < 1.) +#define VALID_PEAK(x) ((x) > 0.) /* Same template caps as GstVolume, for I don't like having just ANY caps. */ @@ -563,6 +563,20 @@ gst_rg_volume_tag_event (GstRgVolume * self, GstEvent * event) has_album_peak = FALSE; } + /* Clamp peaks >1.0. Float based decoders can produce spurious samples >1.0, + * cutting these files back to 1.0 should not cause any audible distortion. + * This is most often seen with Vorbis files. */ + if (has_track_peak && self->track_peak > 1.) { + GST_DEBUG_OBJECT (self, + "clamping track peak %" PEAK_FORMAT " to 1.0", self->track_peak); + self->track_peak = 1.0; + } + if (has_album_peak && self->album_peak > 1.) { + GST_DEBUG_OBJECT (self, + "clamping album peak %" PEAK_FORMAT " to 1.0", self->album_peak); + self->album_peak = 1.0; + } + self->has_track_gain |= has_track_gain; self->has_track_peak |= has_track_peak; self->has_album_gain |= has_album_gain; From 7087da96dc850a931f7fca4c036fb0a2c58f04ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Sat, 14 Feb 2009 17:56:05 +0000 Subject: [PATCH 50/52] alawdec, mulawdec: demote some debug messages from ERROR to WARNING or DEBUG Non-ok flow returns may happen for a variety of perfectly legitimate and expected reasons (temporarily not linked, seeking, pipeline shutdown), so we really shouldn't spew ERROR debug messages to stderr in those cases. Fixes #570781. (Seems like someone already took care of some of these.) --- gst/law/alaw-decode.c | 7 +++---- gst/law/mulaw-decode.c | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/gst/law/alaw-decode.c b/gst/law/alaw-decode.c index f308cf70f9..ac4c6df5c5 100644 --- a/gst/law/alaw-decode.c +++ b/gst/law/alaw-decode.c @@ -293,14 +293,13 @@ gst_alaw_dec_chain (GstPad * pad, GstBuffer * buffer) not_negotiated: { gst_buffer_unref (buffer); - GST_ERROR_OBJECT (alawdec, "no format negotiated"); - ret = GST_FLOW_NOT_NEGOTIATED; - return ret; + GST_WARNING_OBJECT (alawdec, "no input format set: not-negotiated"); + return GST_FLOW_NOT_NEGOTIATED; } alloc_failed: { gst_buffer_unref (buffer); - GST_DEBUG_OBJECT (alawdec, "pad alloc failed %d (%s)", ret, + GST_DEBUG_OBJECT (alawdec, "pad alloc failed, flow: %s", gst_flow_get_name (ret)); return ret; } diff --git a/gst/law/mulaw-decode.c b/gst/law/mulaw-decode.c index 83b383979e..831ef0fa8a 100644 --- a/gst/law/mulaw-decode.c +++ b/gst/law/mulaw-decode.c @@ -258,13 +258,13 @@ gst_mulawdec_chain (GstPad * pad, GstBuffer * buffer) /* ERRORS */ not_negotiated: { - GST_ERROR_OBJECT (mulawdec, "no format negotiated"); + GST_WARNING_OBJECT (mulawdec, "no input format set: not-negotiated"); gst_buffer_unref (buffer); return GST_FLOW_NOT_NEGOTIATED; } alloc_failed: { - GST_DEBUG_OBJECT (mulawdec, "pad alloc failed %d (%s)", ret, + GST_DEBUG_OBJECT (mulawdec, "pad alloc failed, flow: %s", gst_flow_get_name (ret)); gst_buffer_unref (buffer); return ret; From b6755a70004a445a475e6c4b1c2d289e908cf2a9 Mon Sep 17 00:00:00 2001 From: Sjoerd Simons Date: Sun, 1 Mar 2009 19:55:26 +0100 Subject: [PATCH 51/52] Wait for a frame to become available before capturing it Use GstPoll to wait for the fd of the video device to become readable before trying to capture a frame. This speeds up stopping v4l2src a lot as it no longer has to wait for the next frame, especially when capturing with low framerates or when the video device just never generates a frame (which seems a common issue for uvcvideo devices) Fixes bug #563574. --- sys/v4l2/gstv4l2object.c | 4 +++ sys/v4l2/gstv4l2object.h | 1 + sys/v4l2/gstv4l2src.c | 53 ++++++++++++++++++++++++++++++++++++++++ sys/v4l2/v4l2_calls.c | 8 ++++++ sys/v4l2/v4l2src_calls.c | 31 +++++++++++++++++++++-- 5 files changed, 95 insertions(+), 2 deletions(-) diff --git a/sys/v4l2/gstv4l2object.c b/sys/v4l2/gstv4l2object.c index ffc1046d86..d848ccf33e 100644 --- a/sys/v4l2/gstv4l2object.c +++ b/sys/v4l2/gstv4l2object.c @@ -270,6 +270,7 @@ gst_v4l2_object_new (GstElement * element, v4l2object->update_fps_func = update_fps_func; v4l2object->video_fd = -1; + v4l2object->poll = gst_poll_new (TRUE); v4l2object->buffer = NULL; v4l2object->videodev = g_strdup (DEFAULT_PROP_DEVICE); @@ -290,6 +291,9 @@ gst_v4l2_object_destroy (GstV4l2Object * v4l2object) if (v4l2object->videodev) g_free (v4l2object->videodev); + if (v4l2object->poll) + gst_poll_free (v4l2object->poll); + if (v4l2object->channel) g_free (v4l2object->channel); diff --git a/sys/v4l2/gstv4l2object.h b/sys/v4l2/gstv4l2object.h index 5eb557ed67..c5bc3cb77d 100644 --- a/sys/v4l2/gstv4l2object.h +++ b/sys/v4l2/gstv4l2object.h @@ -71,6 +71,7 @@ struct _GstV4l2Object { /* the video-device's file descriptor */ gint video_fd; + GstPoll * poll; /* the video buffer (mmap()'ed) */ guint8 **buffer; diff --git a/sys/v4l2/gstv4l2src.c b/sys/v4l2/gstv4l2src.c index 9f96a211d6..141fb7bb88 100644 --- a/sys/v4l2/gstv4l2src.c +++ b/sys/v4l2/gstv4l2src.c @@ -240,6 +240,10 @@ static void gst_v4l2src_finalize (GstV4l2Src * v4l2src); /* basesrc methods */ static gboolean gst_v4l2src_start (GstBaseSrc * src); +static gboolean gst_v4l2src_unlock (GstBaseSrc * src); + +static gboolean gst_v4l2src_unlock_stop (GstBaseSrc * src); + static gboolean gst_v4l2src_stop (GstBaseSrc * src); static gboolean gst_v4l2src_set_caps (GstBaseSrc * src, GstCaps * caps); @@ -312,6 +316,8 @@ gst_v4l2src_class_init (GstV4l2SrcClass * klass) basesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_v4l2src_get_caps); basesrc_class->set_caps = GST_DEBUG_FUNCPTR (gst_v4l2src_set_caps); basesrc_class->start = GST_DEBUG_FUNCPTR (gst_v4l2src_start); + basesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_v4l2src_unlock); + basesrc_class->unlock_stop = GST_DEBUG_FUNCPTR (gst_v4l2src_unlock_stop); basesrc_class->stop = GST_DEBUG_FUNCPTR (gst_v4l2src_stop); basesrc_class->query = GST_DEBUG_FUNCPTR (gst_v4l2src_query); basesrc_class->fixate = GST_DEBUG_FUNCPTR (gst_v4l2src_fixate); @@ -1175,6 +1181,29 @@ gst_v4l2src_start (GstBaseSrc * src) return TRUE; } +static gboolean +gst_v4l2src_unlock (GstBaseSrc * src) +{ + GstV4l2Src *v4l2src = GST_V4L2SRC (src); + + GST_LOG_OBJECT (src, "Flushing"); + gst_poll_set_flushing (v4l2src->v4l2object->poll, TRUE); + + return TRUE; +} + +static gboolean +gst_v4l2src_unlock_stop (GstBaseSrc * src) +{ + GstV4l2Src *v4l2src = GST_V4L2SRC (src); + + GST_LOG_OBJECT (src, "No longer flushing"); + gst_poll_set_flushing (v4l2src->v4l2object->poll, FALSE); + + return TRUE; +} + + static gboolean gst_v4l2src_stop (GstBaseSrc * src) { @@ -1203,6 +1232,7 @@ static GstFlowReturn gst_v4l2src_get_read (GstV4l2Src * v4l2src, GstBuffer ** buf) { gint amount; + gint ret; gint buffersize; @@ -1211,6 +1241,18 @@ gst_v4l2src_get_read (GstV4l2Src * v4l2src, GstBuffer ** buf) *buf = gst_buffer_new_and_alloc (buffersize); do { + ret = gst_poll_wait (v4l2src->v4l2object->poll, GST_CLOCK_TIME_NONE); + if (G_UNLIKELY (ret < 0)) { + if (errno == EBUSY) + goto stopped; +#ifdef G_OS_WIN32 + if (WSAGetLastError () != WSAEINTR) + goto select_error; +#else + if (errno != EAGAIN && errno != EINTR) + goto select_error; +#endif + } amount = v4l2_read (v4l2src->v4l2object->video_fd, GST_BUFFER_DATA (*buf), buffersize); @@ -1270,6 +1312,17 @@ gst_v4l2src_get_read (GstV4l2Src * v4l2src, GstBuffer ** buf) return GST_FLOW_OK; /* ERRORS */ +select_error: + { + GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ, (NULL), + ("select error %d: %s (%d)", ret, g_strerror (errno), errno)); + return GST_FLOW_ERROR; + } +stopped: + { + GST_DEBUG ("stop called"); + return GST_FLOW_WRONG_STATE; + } read_error: { GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ, diff --git a/sys/v4l2/v4l2_calls.c b/sys/v4l2/v4l2_calls.c index a6b4b7dc77..b1875a88a4 100644 --- a/sys/v4l2/v4l2_calls.c +++ b/sys/v4l2/v4l2_calls.c @@ -400,6 +400,7 @@ gst_v4l2_open (GstV4l2Object * v4l2object) { struct stat st; int libv4l2_fd; + GstPollFD pollfd = GST_POLL_FD_INIT; GST_DEBUG_OBJECT (v4l2object->element, "Trying to open device %s", v4l2object->videodev); @@ -453,6 +454,10 @@ gst_v4l2_open (GstV4l2Object * v4l2object) "Opened device '%s' (%s) successfully", v4l2object->vcap.card, v4l2object->videodev); + pollfd.fd = v4l2object->video_fd; + gst_poll_add_fd (v4l2object->poll, &pollfd); + gst_poll_fd_ctl_read (v4l2object->poll, &pollfd, TRUE); + return TRUE; /* ERRORS */ @@ -508,6 +513,7 @@ error: gboolean gst_v4l2_close (GstV4l2Object * v4l2object) { + GstPollFD pollfd = GST_POLL_FD_INIT; GST_DEBUG_OBJECT (v4l2object->element, "Trying to close %s", v4l2object->videodev); @@ -516,6 +522,8 @@ gst_v4l2_close (GstV4l2Object * v4l2object) /* close device */ v4l2_close (v4l2object->video_fd); + pollfd.fd = v4l2object->video_fd; + gst_poll_remove_fd (v4l2object->poll, &pollfd); v4l2object->video_fd = -1; /* empty lists */ diff --git a/sys/v4l2/v4l2src_calls.c b/sys/v4l2/v4l2src_calls.c index 971868bf02..5abfda3109 100644 --- a/sys/v4l2/v4l2src_calls.c +++ b/sys/v4l2/v4l2src_calls.c @@ -976,7 +976,7 @@ default_frame_sizes: /****************************************************** * gst_v4l2src_grab_frame (): * grab a frame for capturing - * return value: GST_FLOW_OK or GST_FLOW_ERROR + * return value: GST_FLOW_OK, GST_FLOW_WRONG_STATE or GST_FLOW_ERROR ******************************************************/ GstFlowReturn gst_v4l2src_grab_frame (GstV4l2Src * v4l2src, GstBuffer ** buf) @@ -987,12 +987,28 @@ gst_v4l2src_grab_frame (GstV4l2Src * v4l2src, GstBuffer ** buf) GstBuffer *pool_buffer; gboolean need_copy; gint index; + gint ret; memset (&buffer, 0x00, sizeof (buffer)); buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buffer.memory = V4L2_MEMORY_MMAP; - while (v4l2_ioctl (v4l2src->v4l2object->video_fd, VIDIOC_DQBUF, &buffer) < 0) { + for (;;) { + ret = gst_poll_wait (v4l2src->v4l2object->poll, GST_CLOCK_TIME_NONE); + if (G_UNLIKELY (ret < 0)) { + if (errno == EBUSY) + goto stopped; +#ifdef G_OS_WIN32 + if (WSAGetLastError () != WSAEINTR) + goto select_error; +#else + if (errno != EAGAIN && errno != EINTR) + goto select_error; +#endif + } + + if (v4l2_ioctl (v4l2src->v4l2object->video_fd, VIDIOC_DQBUF, &buffer) >= 0) + break; GST_WARNING_OBJECT (v4l2src, "problem grabbing frame %d (ix=%d), trials=%d, pool-ct=%d, buf.flags=%d", @@ -1135,6 +1151,17 @@ gst_v4l2src_grab_frame (GstV4l2Src * v4l2src, GstBuffer ** buf) return GST_FLOW_OK; /* ERRORS */ +select_error: + { + GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ, (NULL), + ("select error %d: %s (%d)", ret, g_strerror (errno), errno)); + return GST_FLOW_ERROR; + } +stopped: + { + GST_DEBUG ("stop called"); + return GST_FLOW_WRONG_STATE; + } einval: { GST_ELEMENT_ERROR (v4l2src, RESOURCE, FAILED, From 0083b9e40569db889500a3c1abd7ec3ac8876fee Mon Sep 17 00:00:00 2001 From: David Schleef Date: Sun, 1 Mar 2009 12:47:37 -0800 Subject: [PATCH 52/52] Remove hardcoded definition of OBJC --- sys/osxvideo/Makefile.am | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/osxvideo/Makefile.am b/sys/osxvideo/Makefile.am index 5e6d4310cc..71fc6206bb 100644 --- a/sys/osxvideo/Makefile.am +++ b/sys/osxvideo/Makefile.am @@ -1,5 +1,3 @@ -# FIXME: clean up this crap -OBJC=gcc plugin_LTLIBRARIES = libgstosxvideosink.la