diff options
46 files changed, 932 insertions, 506 deletions
diff --git a/Makefile.am b/Makefile.am index 46c6f5bb..4247a971 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/common b/common -Subproject 80c627dfabb45c3f40727dce755c81bed1e38e3 +Subproject 57c83f2ced9890f1f8c4c64cd6c0b70f952e6a5 diff --git a/configure.ac b/configure.ac index 43c12c50..5412d796 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) @@ -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 **** @@ -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],[enable])  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 @@ -1140,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/docs/plugins/Makefile.am b/docs/plugins/Makefile.am index 82d27d9e..753fd1b7 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. diff --git a/ext/dv/gstdvdec.c b/ext/dv/gstdvdec.c index ade97966..550b99d1 100644 --- a/ext/dv/gstdvdec.c +++ b/ext/dv/gstdvdec.c @@ -43,6 +43,7 @@  #endif  #include <string.h>  #include <math.h> +#include <gst/video/video.h>  #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_SET (outbuf, GST_VIDEO_BUFFER_TFF); +  } else { +    GST_BUFFER_FLAG_UNSET (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 5f166a14..de8481d9 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; diff --git a/ext/gconf/Makefile.am b/ext/gconf/Makefile.am index 4f6f63ad..330cf29f 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 index e7214e2d..eee80c9d 100644 --- a/ext/gconf/gconf.c +++ b/ext/gconf/gstgconf.c @@ -29,7 +29,7 @@  #include <gst/gst.h> -#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 index b1153e93..b1153e93 100644 --- a/ext/gconf/gconf.h +++ b/ext/gconf/gstgconf.h diff --git a/ext/gconf/gstgconfelements.h b/ext/gconf/gstgconfelements.h index 1b3efe3c..872b2f2d 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 <gconf.h> +#include "gstgconf.h"  GST_DEBUG_CATEGORY_EXTERN (gconf_debug);  #define GST_CAT_DEFAULT gconf_debug diff --git a/ext/gconf/gstgconfvideosink.c b/ext/gconf/gstgconfvideosink.c index 4090cc91..1b05fd37 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 8f69c81a..2461e652 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 fe177d86..6192d73d 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 6f64e6d1..4a2c8cdd 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; diff --git a/ext/jpeg/gstjpegenc.c b/ext/jpeg/gstjpegenc.c index 908c7e00..5edb11f1 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");  } @@ -429,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); @@ -497,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 @@ -557,7 +566,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; @@ -575,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; diff --git a/ext/jpeg/gstjpegenc.h b/ext/jpeg/gstjpegenc.h index 719b88b0..99341569 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]; diff --git a/ext/pulse/pulsemixerctrl.c b/ext/pulse/pulsemixerctrl.c index 41b68cfc..ae807c66 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); diff --git a/ext/raw1394/gsthdv1394src.c b/ext/raw1394/gsthdv1394src.c index cbb02136..30f59d59 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++; diff --git a/gst/avi/gstavidemux.c b/gst/avi/gstavidemux.c index 7a3166cf..adea05fd 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: @@ -1707,7 +1711,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 +1803,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 || @@ -3599,7 +3603,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 +3620,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)) { @@ -4239,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 { @@ -4250,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");    } diff --git a/gst/law/alaw-decode.c b/gst/law/alaw-decode.c index 9b990f7e..ac4c6df5 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);  } @@ -238,14 +293,14 @@ 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_ERROR_OBJECT (alawdec, "pad alloc failed"); +    GST_DEBUG_OBJECT (alawdec, "pad alloc failed, flow: %s", +        gst_flow_get_name (ret));      return ret;    }  } diff --git a/gst/law/alaw-encode.c b/gst/law/alaw-encode.c index ba8587a2..b98d8e2e 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-decode.c b/gst/law/mulaw-decode.c index 42b208f6..831ef0fa 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);  } @@ -205,13 +258,14 @@ 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_ERROR_OBJECT (mulawdec, "pad alloc failed"); +    GST_DEBUG_OBJECT (mulawdec, "pad alloc failed, flow: %s", +        gst_flow_get_name (ret));      gst_buffer_unref (buffer);      return ret;    } diff --git a/gst/law/mulaw-encode.c b/gst/law/mulaw-encode.c index f60e0b2e..022e96f1 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); diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c index 3c656c2c..50011cff 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; @@ -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); diff --git a/gst/matroska/matroska-mux.c b/gst/matroska/matroska-mux.c index 746e3d19..1b958d69 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, diff --git a/gst/qtdemux/qtdemux.c b/gst/qtdemux/qtdemux.c index fe555a19..1cff4148 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 b4dabd73..cbf5b15f 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') diff --git a/gst/replaygain/gstrgvolume.c b/gst/replaygain/gstrgvolume.c index 41fe441d..cf5a914a 100644 --- a/gst/replaygain/gstrgvolume.c +++ b/gst/replaygain/gstrgvolume.c @@ -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; diff --git a/gst/rtp/gstrtph264pay.c b/gst/rtp/gstrtph264pay.c index f0cd9ee8..a788316b 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 */    }  } @@ -467,89 +469,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); -  } else { -    GST_DEBUG ("NAL payload len=%u", size); +  GST_DEBUG ("NAL payload len=%u", size); -    /* 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 = size; +  header = data[0]; +  type = header & 0x1f; -      len = next_start_code (data, 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: %x %x %x Len = %u", (header >> 7), -            (header >> 5) & 3, type, len); -      } +  /* 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); -      /* end of loop */ -      if (len >= size - 4) { -        break; -      } +    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); -      /* next NAL start */ -      data += len + 4; -      size -= len + 4; -    } +    pps = data; +    pps_len = len; +  } else { +    GST_DEBUG ("NAL: %x %x %x Len = %u", (header >> 7), +        (header >> 5) & 3, type, len); +  } -    /* 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]; -        GST_DEBUG ("Profile level IDC = %06x", payloader->profile); +  /* 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 (payloader->sps_len) -          g_free (payloader->sps); +      GST_DEBUG ("Profile level IDC = %06x", payloader->profile); -        payloader->sps = sps_len ? g_new (guint8, sps_len) : NULL; -        memcpy (payloader->sps, sps, sps_len); -        payloader->sps_len = sps_len; -        *updated = TRUE; -      } +      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); +  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;      }    }  } diff --git a/gst/rtp/gstrtpvrawdepay.c b/gst/rtp/gstrtpvrawdepay.c index 35e68a3e..3f599f5d 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"); diff --git a/gst/rtp/gstrtpvrawpay.c b/gst/rtp/gstrtpvrawpay.c index 19c14c2b..0f0ef7e8 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) { diff --git a/gst/rtsp/gstrtspext.c b/gst/rtsp/gstrtspext.c index 0ad81b56..a3216794 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 fa7f6892..f30b302f 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 diff --git a/gst/rtsp/gstrtspsrc.c b/gst/rtsp/gstrtspsrc.c index 02970c42..7c5ef8a6 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); @@ -2536,20 +2557,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); + +  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; -  GST_DEBUG_OBJECT (src, "replying with OK"); +    GST_DEBUG_OBJECT (src, "replying with OK"); -  if (src->debug) -    gst_rtsp_message_dump (&response); +    if (src->debug) +      gst_rtsp_message_dump (&response); -  res = gst_rtspsrc_connection_send (src, &response, NULL); -  if (res < 0) -    goto send_error; +    res = gst_rtspsrc_connection_send (src, &response, NULL); +    if (res < 0) +      goto send_error; +  }    return GST_RTSP_OK; @@ -3785,7 +3811,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; @@ -3814,8 +3841,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 (""); @@ -3875,6 +3907,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. */ @@ -3887,9 +3920,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; @@ -3930,6 +3965,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) @@ -3939,7 +3975,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; @@ -3966,8 +4003,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 */ @@ -4024,13 +4070,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 */ diff --git a/gst/rtsp/gstrtspsrc.h b/gst/rtsp/gstrtspsrc.h index 95dd9869..40a368c6 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; diff --git a/gst/udp/gstudpnetutils.c b/gst/udp/gstudpnetutils.c index a1588caa..5fa7593a 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 = @@ -149,9 +154,12 @@ gst_udp_set_loop_ttl (int sockfd, gboolean loop, int ttl)        break;      }      default: +#ifdef G_OS_WIN32 +      WSASetLastError (WSAEAFNOSUPPORT); +#else        errno = EAFNOSUPPORT; -  }  #endif +  }    return ret;  } diff --git a/gst/udp/gstudpsrc.c b/gst/udp/gstudpsrc.c index bcdbc359..8d92241e 100644 --- a/gst/udp/gstudpsrc.c +++ b/gst/udp/gstudpsrc.c @@ -357,13 +357,50 @@ gst_udpsrc_getcaps (GstBaseSrc * src)      return gst_caps_new_any ();  } +/* read a message from the error queue */ +static void +clear_error (GstUDPSrc * udpsrc) +{ +#if defined (MSG_ERRQUEUE) +  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); +#endif +} +  static GstFlowReturn  gst_udpsrc_create (GstPushSrc * psrc, GstBuffer ** buf)  {    GstUDPSrc *udpsrc;    GstNetBuffer *outbuf; -  struct sockaddr_storage tmpaddr; -  socklen_t len; +  union gst_sockaddr +  { +    struct sockaddr sa; +    struct sockaddr_in sa_in; +    struct sockaddr_in6 sa_in6; +    struct sockaddr_storage sa_stor; +  } sa; +  socklen_t slen;    guint8 *pktdata;    gint pktsize;  #ifdef G_OS_UNIX @@ -434,8 +471,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); @@ -444,13 +483,13 @@ no_select:    pktsize = readsize;    while (TRUE) { -    len = sizeof (struct sockaddr); +    slen = sizeof (sa);  #ifdef G_OS_WIN32 -    ret = recvfrom (udpsrc->sock.fd, (char *) pktdata, pktsize, +    ret = recvfrom (udpsrc->sock.fd, (char *) pktdata, pktsize, 0, &sa.sa, +        &slen);  #else -    ret = recvfrom (udpsrc->sock.fd, pktdata, pktsize, +    ret = recvfrom (udpsrc->sock.fd, pktdata, pktsize, 0, &sa.sa, &slen);  #endif -        0, (struct sockaddr *) &tmpaddr, &len);      if (G_UNLIKELY (ret < 0)) {  #ifdef G_OS_WIN32        /* WSAECONNRESET for a UDP socket means that a packet sent with udpsink @@ -486,22 +525,19 @@ no_select:    GST_BUFFER_DATA (outbuf) = pktdata;    GST_BUFFER_SIZE (outbuf) = ret; -  switch (tmpaddr.ss_family) { +  switch (sa.sa.sa_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: @@ -730,6 +766,7 @@ static gboolean  gst_udpsrc_start (GstBaseSrc * bsrc)  {    guint bc_val; +  guint err_val;    gint reuse;    int port;    GstUDPSrc *src; @@ -821,6 +858,17 @@ gst_udpsrc_start (GstBaseSrc * bsrc)              g_strerror (errno), errno));    } +  /* 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);      ret = gst_udp_join_group (src->sock.fd, &src->myaddr); diff --git a/gst/wavparse/gstwavparse.c b/gst/wavparse/gstwavparse.c index 266c430f..c8e7c756 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,20 +2371,31 @@ 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 (fmt == wav->segment.format) { +        res = TRUE; +        if (wav->streaming) { +          GstQuery *q; -        if ((wav->bps == 0) && !wav->fact) { -          seekable = FALSE; -        } else if (!gst_wavparse_calculate_duration (wav)) { -          seekable = FALSE; +          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;          } -        gst_query_set_seeking (query, GST_FORMAT_TIME, seekable, -            0, wav->duration); +      } else if (fmt == GST_FORMAT_TIME) {          res = TRUE;        } +      if (res) { +        gst_query_set_seeking (query, fmt, seekable, 0, wav->segment.duration); +      }        break;      }      default: diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c index a128b317..144f6595 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);  } diff --git a/sys/osxvideo/Makefile.am b/sys/osxvideo/Makefile.am index 5e6d4310..71fc6206 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 diff --git a/sys/v4l2/gstv4l2object.c b/sys/v4l2/gstv4l2object.c index ffc1046d..d848ccf3 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 5eb557ed..c5bc3cb7 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 a90ddf81..141fb7bb 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)) @@ -237,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); @@ -309,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); @@ -688,6 +697,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 +737,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 +986,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; @@ -1159,6 +1182,29 @@ gst_v4l2src_start (GstBaseSrc * src)  }  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)  {    GstV4l2Src *v4l2src = GST_V4L2SRC (src); @@ -1186,6 +1232,7 @@ static GstFlowReturn  gst_v4l2src_get_read (GstV4l2Src * v4l2src, GstBuffer ** buf)  {    gint amount; +  gint ret;    gint buffersize; @@ -1194,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); @@ -1253,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 a6b4b7dc..b1875a88 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 c247c497..5abfda31 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, @@ -974,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) @@ -985,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", @@ -1133,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, diff --git a/win32/common/config.h.in b/win32/common/config.h.in deleted file mode 100644 index 21b60390..00000000 --- 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 <dlfcn.h> 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 <inttypes.h> 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 <memory.h> 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 <netinet/in.h> 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 <stdint.h> header file. */ -#undef HAVE_STDINT_H - -/* Define to 1 if you have the <stdlib.h> header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the <strings.h> header file. */ -#undef HAVE_STRINGS_H - -/* Define to 1 if you have the <string.h> header file. */ -#define HAVE_STRING_H 1 - -/* support for features: sunaudiosink */ -/* #undef HAVE_SUNAUDIO */ - -/* Define to 1 if you have the <sys/socket.h> header file. */ -#undef HAVE_SYS_SOCKET_H - -/* Define to 1 if you have the <sys/stat.h> header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the <sys/types.h> header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* support for features: taglib */ -#define HAVE_TAGLIB  - -/* Define to 1 if you have the <unistd.h> header file. */ -#undef HAVE_UNISTD_H - -/* Define if valgrind should be used */ -#undef HAVE_VALGRIND - -/* Define to 1 if you have the <winsock2.h> 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  | 
