Merge branch 'master' into 0.11
authorWim Taymans <wim.taymans@collabora.co.uk>
Thu, 22 Mar 2012 10:53:24 +0000 (11:53 +0100)
committerWim Taymans <wim.taymans@collabora.co.uk>
Thu, 22 Mar 2012 10:53:24 +0000 (11:53 +0100)
unport gdkpixbuf
not merged: https://bugzilla.gnome.org/show_bug.cgi?id=654850

Conflicts:
docs/plugins/Makefile.am
docs/plugins/gst-plugins-good-plugins-docs.sgml
docs/plugins/gst-plugins-good-plugins-sections.txt
docs/plugins/gst-plugins-good-plugins.hierarchy
docs/plugins/inspect/plugin-avi.xml
docs/plugins/inspect/plugin-png.xml
ext/flac/gstflacdec.c
ext/flac/gstflacdec.h
ext/libpng/gstpngdec.c
ext/libpng/gstpngenc.c
ext/speex/gstspeexdec.c
gst/audioparsers/gstflacparse.c
gst/flv/gstflvmux.c
gst/rtp/gstrtpdvdepay.c
gst/rtp/gstrtph264depay.c

28 files changed:
1  2 
configure.ac
docs/plugins/gst-plugins-good-plugins.args
docs/plugins/inspect/plugin-audioparsers.xml
docs/plugins/inspect/plugin-avi.xml
docs/plugins/inspect/plugin-gdkpixbuf.xml
docs/plugins/inspect/plugin-png.xml
docs/plugins/inspect/plugin-wavpack.xml
ext/flac/gstflacdec.c
ext/flac/gstflacdec.h
ext/flac/gstflacenc.c
ext/gdk_pixbuf/Makefile.am
ext/gdk_pixbuf/gstgdkpixbuf.c
ext/gdk_pixbuf/gstgdkpixbufoverlay.c
ext/libpng/gstpngdec.c
ext/libpng/gstpngenc.c
ext/libpng/gstpngenc.h
ext/speex/gstspeexdec.c
gst/audioparsers/gstflacparse.c
gst/deinterlace/gstdeinterlace.c
gst/flv/gstflvmux.c
gst/isomp4/gstqtmux.c
gst/matroska/matroska-demux.c
gst/matroska/matroska-mux.c
gst/rtp/gstrtpdvdepay.c
gst/rtsp/gstrtspsrc.c
gst/rtsp/gstrtspsrc.h
gst/smpte/gstsmpte.c
sys/ximage/gstximagesrc.c

diff --cc configure.ac
@@@ -309,18 -330,9 +309,18 @@@ AG_GST_DEFAULT_ELEMENT
  
  dnl *** plug-ins to include ***
  
-  cairo cairo_gobject dv1394 \
 +dnl Non ported plugins (non-dependant, then dependant)
 +dnl Make sure you have a space before and after all plugins
 +GST_PLUGINS_NONPORTED="deinterlace interleave flx \
 + smpte \
 + videobox \
++ cairo cairo_gobject dv1394 gdk_pixbuf \
 + oss oss4 \
 + osx_video osx_audio "
 +AC_SUBST(GST_PLUGINS_NONPORTED)
 +
  dnl these are all the gst plug-ins, compilable without additional libs
  dnl videofilter is at the top because others depend on it
 -AG_GST_CHECK_PLUGIN(videofilter)
  AG_GST_CHECK_PLUGIN(alpha)
  AG_GST_CHECK_PLUGIN(apetag)
  AG_GST_CHECK_PLUGIN(audiofx)
@@@ -91,4 -91,4 +91,4 @@@
        </pads>
      </element>
    </elements>
--</plugin>
++</plugin>
@@@ -52,4 -52,4 +52,4 @@@
        </pads>
      </element>
    </elements>
--</plugin>
++</plugin>
@@@ -415,7 -483,115 +415,27 @@@ gst_flac_dec_scan_got_frame (GstFlacDe
    return TRUE;
  }
  
 -#define SCANBLOCK_SIZE  (64*1024)
 -
 -static void
 -gst_flac_dec_scan_for_last_block (GstFlacDec * flacdec, gint64 * samples)
 -{
 -  GstFormat format = GST_FORMAT_BYTES;
 -  gint64 file_size, offset;
 -
 -  GST_INFO_OBJECT (flacdec, "total number of samples unknown, scanning file");
 -
 -  if (!gst_pad_query_peer_duration (flacdec->sinkpad, &format, &file_size)) {
 -    GST_WARNING_OBJECT (flacdec, "failed to query upstream size!");
 -    return;
 -  }
 -
 -  if (flacdec->min_blocksize != flacdec->max_blocksize) {
 -    GST_WARNING_OBJECT (flacdec, "scanning for last sample only works "
 -        "for FLAC files with constant blocksize");
 -    return;
 -  }
 -
 -  GST_DEBUG_OBJECT (flacdec, "upstream size: %" G_GINT64_FORMAT, file_size);
 -
 -  offset = file_size - 1;
 -  while (offset >= MAX (SCANBLOCK_SIZE / 2, file_size / 2)) {
 -    GstFlowReturn flow;
 -    GstBuffer *buf = NULL;
 -    guint8 *data;
 -    guint size;
 -
 -    /* divide by 2 = not very sophisticated way to deal with overlapping */
 -    offset -= SCANBLOCK_SIZE / 2;
 -    GST_LOG_OBJECT (flacdec, "looking for frame at %" G_GINT64_FORMAT
 -        "-%" G_GINT64_FORMAT, offset, offset + SCANBLOCK_SIZE);
 -
 -    flow = gst_pad_pull_range (flacdec->sinkpad, offset, SCANBLOCK_SIZE, &buf);
 -    if (flow != GST_FLOW_OK) {
 -      GST_DEBUG_OBJECT (flacdec, "flow = %s", gst_flow_get_name (flow));
 -      return;
 -    }
 -
 -    size = GST_BUFFER_SIZE (buf);
 -    data = GST_BUFFER_DATA (buf);
 -
 -    while (size > 16) {
 -      if (gst_flac_dec_scan_got_frame (flacdec, data, size, samples)) {
 -        GST_DEBUG_OBJECT (flacdec, "frame sync at offset %" G_GINT64_FORMAT,
 -            offset + GST_BUFFER_SIZE (buf) - size);
 -        gst_buffer_unref (buf);
 -        return;
 -      }
 -      ++data;
 -      --size;
 -    }
 -
 -    gst_buffer_unref (buf);
 -  }
 -}
 -
+ static gboolean
+ gst_flac_dec_handle_decoder_error (GstFlacDec * dec, gboolean msg)
+ {
+   gboolean ret;
+   dec->error_count++;
+   if (dec->error_count > 10) {
+     if (msg)
+       GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), (NULL));
+     dec->last_flow = GST_FLOW_ERROR;
+     ret = TRUE;
+   } else {
+     GST_DEBUG_OBJECT (dec, "ignoring error for now at count %d",
+         dec->error_count);
+     ret = FALSE;
+   }
+   return ret;
+ }
  static void
 -gst_flac_extract_picture_buffer (GstFlacDec * dec,
 -    const FLAC__StreamMetadata * metadata)
 -{
 -  FLAC__StreamMetadata_Picture picture;
 -  GstTagList *tags;
 -
 -  g_return_if_fail (metadata->type == FLAC__METADATA_TYPE_PICTURE);
 -
 -  GST_LOG_OBJECT (dec, "Got PICTURE block");
 -  picture = metadata->data.picture;
 -
 -  GST_DEBUG_OBJECT (dec, "declared MIME type is: '%s'",
 -      GST_STR_NULL (picture.mime_type));
 -  GST_DEBUG_OBJECT (dec, "image data is %u bytes", picture.data_length);
 -
 -  tags = gst_tag_list_new ();
 -
 -  gst_tag_list_add_id3_image (tags, (guint8 *) picture.data,
 -      picture.data_length, picture.type);
 -
 -  if (!gst_tag_list_is_empty (tags)) {
 -    gst_element_found_tags_for_pad (GST_ELEMENT (dec), dec->srcpad, tags);
 -  } else {
 -    GST_DEBUG_OBJECT (dec, "problem parsing PICTURE block, skipping");
 -    gst_tag_list_free (tags);
 -  }
 -}
 -
 -static void
  gst_flac_dec_metadata_cb (const FLAC__StreamDecoder * decoder,
      const FLAC__StreamMetadata * metadata, void *client_data)
  {
@@@ -495,10 -692,125 +515,10 @@@ gst_flac_dec_error_cb (const FLAC__Stre
        break;
    }
  
-   GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("%s (%d)", error, status));
-   dec->last_flow = GST_FLOW_ERROR;
+   if (gst_flac_dec_handle_decoder_error (dec, FALSE))
+     GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("%s (%d)", error, status));
  }
  
 -static FLAC__StreamDecoderSeekStatus
 -gst_flac_dec_seek (const FLAC__StreamDecoder * decoder,
 -    FLAC__uint64 position, void *client_data)
 -{
 -  GstFlacDec *flacdec;
 -
 -  flacdec = GST_FLAC_DEC (client_data);
 -
 -  GST_DEBUG_OBJECT (flacdec, "seek %" G_GUINT64_FORMAT, (guint64) position);
 -  flacdec->offset = position;
 -
 -  return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
 -}
 -
 -static FLAC__StreamDecoderTellStatus
 -gst_flac_dec_tell (const FLAC__StreamDecoder * decoder,
 -    FLAC__uint64 * position, void *client_data)
 -{
 -  GstFlacDec *flacdec;
 -
 -  flacdec = GST_FLAC_DEC (client_data);
 -
 -  *position = flacdec->offset;
 -
 -  GST_DEBUG_OBJECT (flacdec, "tell %" G_GINT64_FORMAT, (gint64) * position);
 -
 -  return FLAC__STREAM_DECODER_TELL_STATUS_OK;
 -}
 -
 -static FLAC__StreamDecoderLengthStatus
 -gst_flac_dec_length (const FLAC__StreamDecoder * decoder,
 -    FLAC__uint64 * length, void *client_data)
 -{
 -  GstFlacDec *flacdec;
 -  GstFormat fmt = GST_FORMAT_BYTES;
 -  gint64 len = -1;
 -
 -  flacdec = GST_FLAC_DEC (client_data);
 -
 -  if (!gst_pad_query_peer_duration (flacdec->sinkpad, &fmt, &len) ||
 -      (fmt != GST_FORMAT_BYTES || len == -1))
 -    return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
 -
 -  *length = len;
 -
 -  GST_DEBUG_OBJECT (flacdec, "encoded byte length %" G_GINT64_FORMAT,
 -      (gint64) * length);
 -
 -  return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
 -}
 -
 -static FLAC__bool
 -gst_flac_dec_eof (const FLAC__StreamDecoder * decoder, void *client_data)
 -{
 -  GstFlacDec *flacdec;
 -  GstFormat fmt;
 -  GstPad *peer;
 -  gboolean ret = FALSE;
 -  gint64 len;
 -
 -  flacdec = GST_FLAC_DEC (client_data);
 -
 -  if (!(peer = gst_pad_get_peer (flacdec->sinkpad))) {
 -    GST_WARNING_OBJECT (flacdec, "no peer pad, returning EOF");
 -    return TRUE;
 -  }
 -
 -  fmt = GST_FORMAT_BYTES;
 -  if (gst_pad_query_duration (peer, &fmt, &len) && fmt == GST_FORMAT_BYTES &&
 -      len != -1 && flacdec->offset >= len) {
 -    GST_DEBUG_OBJECT (flacdec,
 -        "offset=%" G_GINT64_FORMAT ", len=%" G_GINT64_FORMAT
 -        ", returning EOF", flacdec->offset, len);
 -    ret = TRUE;
 -  }
 -
 -  gst_object_unref (peer);
 -
 -  return ret;
 -}
 -
 -static FLAC__StreamDecoderReadStatus
 -gst_flac_dec_read_seekable (const FLAC__StreamDecoder * decoder,
 -    FLAC__byte buffer[], size_t * bytes, void *client_data)
 -{
 -  GstFlowReturn flow;
 -  GstFlacDec *flacdec;
 -  GstBuffer *buf;
 -
 -  flacdec = GST_FLAC_DEC (client_data);
 -
 -  flow = gst_pad_pull_range (flacdec->sinkpad, flacdec->offset, *bytes, &buf);
 -
 -  GST_PAD_STREAM_LOCK (flacdec->sinkpad);
 -  flacdec->pull_flow = flow;
 -  GST_PAD_STREAM_UNLOCK (flacdec->sinkpad);
 -
 -  if (G_UNLIKELY (flow != GST_FLOW_OK)) {
 -    GST_INFO_OBJECT (flacdec, "pull_range flow: %s", gst_flow_get_name (flow));
 -    if (flow == GST_FLOW_UNEXPECTED)
 -      return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
 -    else
 -      return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
 -  }
 -
 -  GST_DEBUG_OBJECT (flacdec, "Read %d bytes at %" G_GUINT64_FORMAT,
 -      GST_BUFFER_SIZE (buf), flacdec->offset);
 -  memcpy (buffer, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
 -  *bytes = GST_BUFFER_SIZE (buf);
 -  gst_buffer_unref (buf);
 -  flacdec->offset += *bytes;
 -
 -  return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
 -}
 -
  static FLAC__StreamDecoderReadStatus
  gst_flac_dec_read_stream (const FLAC__StreamDecoder * decoder,
      FLAC__byte buffer[], size_t * bytes, void *client_data)
@@@ -671,14 -1042,39 +691,16 @@@ gst_flac_dec_write (GstFlacDec * flacde
    } else {
      g_assert_not_reached ();
    }
 +  gst_buffer_unmap (outbuf, &map);
  
 +  GST_DEBUG_OBJECT (flacdec, "pushing %d samples", samples);
+   if (flacdec->error_count)
+     flacdec->error_count--;
  
 -  if (!flacdec->seeking) {
 -    GST_DEBUG_OBJECT (flacdec, "pushing %d samples at offset %" G_GINT64_FORMAT
 -        " (%" GST_TIME_FORMAT " + %" GST_TIME_FORMAT ")",
 -        samples, GST_BUFFER_OFFSET (outbuf),
 -        GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
 -        GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)));
 -
 -    if (flacdec->discont) {
 -      GST_DEBUG_OBJECT (flacdec, "marking discont");
 -      outbuf = gst_buffer_make_metadata_writable (outbuf);
 -      GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
 -      flacdec->discont = FALSE;
 -    }
 -    ret = gst_pad_push (flacdec->srcpad, outbuf);
 -    GST_DEBUG_OBJECT (flacdec, "returned %s", gst_flow_get_name (ret));
 -    flacdec->segment.last_stop += samples;
 -  } else {
 -    GST_DEBUG_OBJECT (flacdec,
 -        "not pushing %d samples at offset %" G_GINT64_FORMAT
 -        " (in seek)", samples, GST_BUFFER_OFFSET (outbuf));
 -    gst_buffer_replace (&flacdec->pending, outbuf);
 -    gst_buffer_unref (outbuf);
 -    flacdec->pending_samples = samples;
 -    ret = GST_FLOW_OK;
 -  }
 +  ret = gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (flacdec), outbuf, 1);
  
 -  if (ret != GST_FLOW_OK) {
 -    GST_DEBUG_OBJECT (flacdec, "gst_pad_push() returned %s",
 -        gst_flow_get_name (ret));
 +  if (G_UNLIKELY (ret != GST_FLOW_OK)) {
 +    GST_DEBUG_OBJECT (flacdec, "finish_frame flow %s", gst_flow_get_name (ret));
    }
  
  done:
@@@ -58,6 -86,10 +58,8 @@@ struct _GstFlacDec 
    /* from the stream info, needed for scanning */
    guint16        min_blocksize;
    guint16        max_blocksize;
 -  gint64         cur_granulepos; /* only used in framed mode (flac-in-ogg) */
 -
+   gint           error_count;
  };
  
  struct _GstFlacDecClass {
Simple merge
@@@ -14,6 -17,7 +17,7 @@@ libgstgdkpixbuf_la_LIBTOOLFLAGS = --tag
  
  noinst_HEADERS = \
        gstgdkpixbuf.h \
 -      gstgdkpixbufoverlay.c \
++      gstgdkpixbufoverlay.h \
        gstgdkpixbufsink.h \
        pixbufscale.h \
        gstgdkanimation.h
Simple merge
index 0000000,0e844f4..6ea95c7
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,509 +1,508 @@@
 -#include <gst/controller/gstcontroller.h>
+ /* GStreamer GdkPixbuf overlay
+  * Copyright (C) 2012 Tim-Philipp Müller <tim centricular net>
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+  * License as published by the Free Software Foundation; either
+  * version 2 of the License, or (at your option) any later version.
+  *
+  * This library is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  * Library General Public License for more details.
+  *
+  * You should have received a copy of the GNU Library General Public
+  * License along with this library; if not, write to the
+  * Free Software Foundation, Inc., 51 Franklin Street, Suite 500,
+  * Boston, MA 02110-1335, USA.
+  */
+ /**
+  * SECTION:element-gdkpixbufoverlay
+  * @see_also:
+  *
+  * The gdkpixbufoverlay element overlays an image loaded from file onto
+  * a video stream.
+  *
+  * Changing the positioning or overlay width and height properties at runtime
+  * is supported, but it might be prudent to to protect the property setting
+  * code with GST_BASE_TRANSFORM_LOCK and GST_BASE_TRANSFORM_UNLOCK, as
+  * g_object_set() is not atomic for multiple properties passed in one go.
+  *
+  * Changing the image at runtime is currently not supported.
+  *
+  * Negative offsets are also not yet supported.
+  *
+  * <refsect2>
+  * <title>Example launch line</title>
+  * |[
+  * gst-launch -v videotestsrc ! gdkpixbufoverlay location=image.png ! autovideosink
+  * ]|
+  * Overlays the image in image.png onto the test video picture produced by
+  * videotestsrc.
+  * </refsect2>
+  *
+  * Since: 0.10.33
+  */
+ #ifdef HAVE_CONFIG_H
+ #include "config.h"
+ #endif
+ #include <gst/gst.h>
+ #include "gstgdkpixbufoverlay.h"
+ GST_DEBUG_CATEGORY_STATIC (gdkpixbufoverlay_debug);
+ #define GST_CAT_DEFAULT gdkpixbufoverlay_debug
+ static void gst_gdk_pixbuf_overlay_set_property (GObject * object,
+     guint property_id, const GValue * value, GParamSpec * pspec);
+ static void gst_gdk_pixbuf_overlay_get_property (GObject * object,
+     guint property_id, GValue * value, GParamSpec * pspec);
+ static void gst_gdk_pixbuf_overlay_finalize (GObject * object);
+ static gboolean gst_gdk_pixbuf_overlay_start (GstBaseTransform * trans);
+ static gboolean gst_gdk_pixbuf_overlay_stop (GstBaseTransform * trans);
+ static GstFlowReturn
+ gst_gdk_pixbuf_overlay_transform_ip (GstBaseTransform * trans, GstBuffer * buf);
+ static void gst_gdk_pixbuf_overlay_before_transform (GstBaseTransform * trans,
+     GstBuffer * outbuf);
+ static gboolean
+ gst_gdk_pixbuf_overlay_set_caps (GstBaseTransform * trans, GstCaps * incaps,
+     GstCaps * outcaps);
+ enum
+ {
+   PROP_0,
+   PROP_LOCATION,
+   PROP_OFFSET_X,
+   PROP_OFFSET_Y,
+   PROP_RELATIVE_X,
+   PROP_RELATIVE_Y,
+   PROP_OVERLAY_WIDTH,
+   PROP_OVERLAY_HEIGHT
+ };
+ #define VIDEO_CAPS \
+     GST_VIDEO_CAPS_BGRx ";" \
+     GST_VIDEO_CAPS_RGB ";" \
+     GST_VIDEO_CAPS_BGR ";" \
+     GST_VIDEO_CAPS_RGBx ";" \
+     GST_VIDEO_CAPS_xRGB ";" \
+     GST_VIDEO_CAPS_xBGR ";" \
+     GST_VIDEO_CAPS_RGBA ";" \
+     GST_VIDEO_CAPS_BGRA ";" \
+     GST_VIDEO_CAPS_ARGB ";" \
+     GST_VIDEO_CAPS_ABGR ";" \
+     GST_VIDEO_CAPS_YUV ("{I420, YV12, AYUV, YUY2, UYVY, v308, v210," \
+         " v216, Y41B, Y42B, Y444, Y800, Y16, NV12, NV21, UYVP, A420," \
+         " YUV9, IYU1}")
+ static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
+     GST_PAD_SINK,
+     GST_PAD_ALWAYS,
+     GST_STATIC_CAPS (VIDEO_CAPS)
+     );
+ static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
+     GST_PAD_SRC,
+     GST_PAD_ALWAYS,
+     GST_STATIC_CAPS (VIDEO_CAPS)
+     );
+ GST_BOILERPLATE (GstGdkPixbufOverlay, gst_gdk_pixbuf_overlay,
+     GstVideoFilter, GST_TYPE_VIDEO_FILTER);
+ static void
+ gst_gdk_pixbuf_overlay_base_init (gpointer g_class)
+ {
+   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
+   gst_element_class_add_static_pad_template (element_class, &sink_template);
+   gst_element_class_add_static_pad_template (element_class, &src_template);
+   gst_element_class_set_details_simple (element_class,
+       "GdkPixbuf Overlay", "Filter/Effect/Video",
+       "Overlay an image onto a video stream",
+       "Tim-Philipp Müller <tim centricular net>");
+ }
+ static void
+ gst_gdk_pixbuf_overlay_class_init (GstGdkPixbufOverlayClass * klass)
+ {
+   GstBaseTransformClass *basetrans_class = GST_BASE_TRANSFORM_CLASS (klass);
+   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+   gobject_class->set_property = gst_gdk_pixbuf_overlay_set_property;
+   gobject_class->get_property = gst_gdk_pixbuf_overlay_get_property;
+   gobject_class->finalize = gst_gdk_pixbuf_overlay_finalize;
+   basetrans_class->start = GST_DEBUG_FUNCPTR (gst_gdk_pixbuf_overlay_start);
+   basetrans_class->stop = GST_DEBUG_FUNCPTR (gst_gdk_pixbuf_overlay_stop);
+   basetrans_class->set_caps =
+       GST_DEBUG_FUNCPTR (gst_gdk_pixbuf_overlay_set_caps);
+   basetrans_class->transform_ip =
+       GST_DEBUG_FUNCPTR (gst_gdk_pixbuf_overlay_transform_ip);
+   basetrans_class->before_transform =
+       GST_DEBUG_FUNCPTR (gst_gdk_pixbuf_overlay_before_transform);
+   g_object_class_install_property (gobject_class, PROP_LOCATION,
+       g_param_spec_string ("location", "location",
+           "Location of image file to overlay", NULL,
+           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+   g_object_class_install_property (gobject_class, PROP_OFFSET_X,
+       g_param_spec_int ("offset-x", "X Offset",
+           "Horizontal offset of overlay image in pixels from top-left corner "
+           "of video image", G_MININT, G_MAXINT, 0,
+           GST_PARAM_CONTROLLABLE | GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE
+           | G_PARAM_STATIC_STRINGS));
+   g_object_class_install_property (gobject_class, PROP_OFFSET_Y,
+       g_param_spec_int ("offset-y", "Y Offset",
+           "Vertical offset of overlay image in pixels from top-left corner "
+           "of video image", G_MININT, G_MAXINT, 0,
+           GST_PARAM_CONTROLLABLE | GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE
+           | G_PARAM_STATIC_STRINGS));
+   g_object_class_install_property (gobject_class, PROP_RELATIVE_X,
+       g_param_spec_double ("relative-x", "Relative X Offset",
+           "Horizontal offset of overlay image in fractions of video image "
+           "width, from top-left corner of video image", 0.0, 1.0, 0.0,
+           GST_PARAM_CONTROLLABLE | GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE
+           | G_PARAM_STATIC_STRINGS));
+   g_object_class_install_property (gobject_class, PROP_RELATIVE_Y,
+       g_param_spec_double ("relative-y", "Relative Y Offset",
+           "Vertical offset of overlay image in fractions of video image "
+           "height, from top-left corner of video image", 0.0, 1.0, 0.0,
+           GST_PARAM_CONTROLLABLE | GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE
+           | G_PARAM_STATIC_STRINGS));
+   g_object_class_install_property (gobject_class, PROP_OVERLAY_WIDTH,
+       g_param_spec_int ("overlay-width", "Overlay Width",
+           "Width of overlay image in pixels (0 = same as overlay image)", 0,
+           G_MAXINT, 0,
+           GST_PARAM_CONTROLLABLE | GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE
+           | G_PARAM_STATIC_STRINGS));
+   g_object_class_install_property (gobject_class, PROP_OVERLAY_HEIGHT,
+       g_param_spec_int ("overlay-height", "Overlay Height",
+           "Height of overlay image in pixels (0 = same as overlay image)", 0,
+           G_MAXINT, 0,
+           GST_PARAM_CONTROLLABLE | GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE
+           | G_PARAM_STATIC_STRINGS));
+   GST_DEBUG_CATEGORY_INIT (gdkpixbufoverlay_debug, "gdkpixbufoverlay", 0,
+       "debug category for gdkpixbufoverlay element");
+ }
+ static void
+ gst_gdk_pixbuf_overlay_init (GstGdkPixbufOverlay * overlay,
+     GstGdkPixbufOverlayClass * overlay_class)
+ {
+   overlay->offset_x = 0;
+   overlay->offset_y = 0;
+   overlay->relative_x = 0.0;
+   overlay->relative_y = 0.0;
+   overlay->overlay_width = 0;
+   overlay->overlay_height = 0;
+ }
+ void
+ gst_gdk_pixbuf_overlay_set_property (GObject * object, guint property_id,
+     const GValue * value, GParamSpec * pspec)
+ {
+   GstGdkPixbufOverlay *overlay = GST_GDK_PIXBUF_OVERLAY (object);
+   GST_OBJECT_LOCK (overlay);
+   switch (property_id) {
+     case PROP_LOCATION:
+       g_free (overlay->location);
+       overlay->location = g_value_dup_string (value);
+       break;
+     case PROP_OFFSET_X:
+       overlay->offset_x = g_value_get_int (value);
+       overlay->update_composition = TRUE;
+       break;
+     case PROP_OFFSET_Y:
+       overlay->offset_y = g_value_get_int (value);
+       overlay->update_composition = TRUE;
+       break;
+     case PROP_RELATIVE_X:
+       overlay->relative_x = g_value_get_double (value);
+       overlay->update_composition = TRUE;
+       break;
+     case PROP_RELATIVE_Y:
+       overlay->relative_y = g_value_get_double (value);
+       overlay->update_composition = TRUE;
+       break;
+     case PROP_OVERLAY_WIDTH:
+       overlay->overlay_width = g_value_get_int (value);
+       overlay->update_composition = TRUE;
+       break;
+     case PROP_OVERLAY_HEIGHT:
+       overlay->overlay_height = g_value_get_int (value);
+       overlay->update_composition = TRUE;
+       break;
+     default:
+       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+       break;
+   }
+   GST_OBJECT_UNLOCK (overlay);
+ }
+ void
+ gst_gdk_pixbuf_overlay_get_property (GObject * object, guint property_id,
+     GValue * value, GParamSpec * pspec)
+ {
+   GstGdkPixbufOverlay *overlay = GST_GDK_PIXBUF_OVERLAY (object);
+   GST_OBJECT_LOCK (overlay);
+   switch (property_id) {
+     case PROP_LOCATION:
+       g_value_set_string (value, overlay->location);
+       break;
+     case PROP_OFFSET_X:
+       g_value_set_int (value, overlay->offset_x);
+       break;
+     case PROP_OFFSET_Y:
+       g_value_set_int (value, overlay->offset_y);
+       break;
+     case PROP_RELATIVE_X:
+       g_value_set_double (value, overlay->relative_x);
+       break;
+     case PROP_RELATIVE_Y:
+       g_value_set_double (value, overlay->relative_y);
+       break;
+     case PROP_OVERLAY_WIDTH:
+       g_value_set_int (value, overlay->overlay_width);
+       break;
+     case PROP_OVERLAY_HEIGHT:
+       g_value_set_int (value, overlay->overlay_height);
+       break;
+     default:
+       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+       break;
+   }
+   GST_OBJECT_UNLOCK (overlay);
+ }
+ void
+ gst_gdk_pixbuf_overlay_finalize (GObject * object)
+ {
+   GstGdkPixbufOverlay *overlay = GST_GDK_PIXBUF_OVERLAY (object);
+   g_free (overlay->location);
+   overlay->location = NULL;
+   G_OBJECT_CLASS (parent_class)->finalize (object);
+ }
+ static gboolean
+ gst_gdk_pixbuf_overlay_load_image (GstGdkPixbufOverlay * overlay, GError ** err)
+ {
+   GdkPixbuf *pixbuf;
+   guint8 *pixels, *p;
+   gint width, height, stride, w, h;
+   pixbuf = gdk_pixbuf_new_from_file (overlay->location, err);
+   if (pixbuf == NULL)
+     return FALSE;
+   if (!gdk_pixbuf_get_has_alpha (pixbuf)) {
+     GdkPixbuf *alpha_pixbuf;
+     /* FIXME: we could do this much more efficiently ourselves below, but
+      * we're lazy for now */
+     /* FIXME: perhaps expose substitute_color via properties */
+     alpha_pixbuf = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0);
+     g_object_unref (pixbuf);
+     pixbuf = alpha_pixbuf;
+   }
+   width = gdk_pixbuf_get_width (pixbuf);
+   height = gdk_pixbuf_get_height (pixbuf);
+   stride = gdk_pixbuf_get_rowstride (pixbuf);
+   pixels = gdk_pixbuf_get_pixels (pixbuf);
+   /* the memory layout in GdkPixbuf is R-G-B-A, we want:
+    *  - B-G-R-A on little-endian platforms
+    *  - A-R-G-B on big-endian platforms
+    */
+   for (h = 0; h < height; ++h) {
+     p = pixels + (h * stride);
+     for (w = 0; w < width; ++w) {
+       guint8 tmp;
+       /* R-G-B-A ==> B-G-R-A */
+       tmp = p[0];
+       p[0] = p[2];
+       p[2] = tmp;
+       if (G_BYTE_ORDER == G_BIG_ENDIAN) {
+         /* B-G-R-A ==> A-R-G-B */
+         /* we can probably assume sane alignment */
+         *((guint32 *) p) = GUINT32_SWAP_LE_BE (*((guint32 *) p));
+       }
+       p += 4;
+     }
+   }
+   overlay->pixels = gst_buffer_new ();
+   GST_BUFFER_DATA (overlay->pixels) = pixels;
+   /* assume we have row padding even for the last row */
+   GST_BUFFER_SIZE (overlay->pixels) = height * stride;
+   /* transfer ownership of pixbuf to buffer */
+   GST_BUFFER_MALLOCDATA (overlay->pixels) = (guint8 *) pixbuf;
+   GST_BUFFER_FREE_FUNC (overlay->pixels) = (GFreeFunc) g_object_unref;
+   overlay->pixels_width = width;
+   overlay->pixels_height = height;
+   overlay->pixels_stride = stride;
+   overlay->update_composition = TRUE;
+   GST_INFO_OBJECT (overlay, "Loaded image, %d x %d", width, height);
+   return TRUE;
+ }
+ static gboolean
+ gst_gdk_pixbuf_overlay_start (GstBaseTransform * trans)
+ {
+   GstGdkPixbufOverlay *overlay = GST_GDK_PIXBUF_OVERLAY (trans);
+   GError *err = NULL;
+   if (overlay->location != NULL) {
+     if (!gst_gdk_pixbuf_overlay_load_image (overlay, &err))
+       goto error_loading_image;
+     gst_base_transform_set_passthrough (trans, FALSE);
+   } else {
+     GST_WARNING_OBJECT (overlay, "no image location set, doing nothing");
+     gst_base_transform_set_passthrough (trans, TRUE);
+   }
+   return TRUE;
+ /* ERRORS */
+ error_loading_image:
+   {
+     GST_ELEMENT_ERROR (overlay, RESOURCE, OPEN_READ,
+         ("Could not load overlay image."), ("%s", err->message));
+     g_error_free (err);
+     return FALSE;
+   }
+ }
+ static gboolean
+ gst_gdk_pixbuf_overlay_stop (GstBaseTransform * trans)
+ {
+   GstGdkPixbufOverlay *overlay = GST_GDK_PIXBUF_OVERLAY (trans);
+   if (overlay->comp) {
+     gst_video_overlay_composition_unref (overlay->comp);
+     overlay->comp = NULL;
+   }
+   gst_buffer_replace (&overlay->pixels, NULL);
+   return TRUE;
+ }
+ static gboolean
+ gst_gdk_pixbuf_overlay_set_caps (GstBaseTransform * trans, GstCaps * incaps,
+     GstCaps * outcaps)
+ {
+   GstGdkPixbufOverlay *overlay = GST_GDK_PIXBUF_OVERLAY (trans);
+   GstVideoFormat video_format;
+   int w, h;
+   if (!gst_video_format_parse_caps (incaps, &video_format, &w, &h))
+     return FALSE;
+   overlay->format = video_format;
+   overlay->width = w;
+   overlay->height = h;
+   return TRUE;
+ }
+ static void
+ gst_gdk_pixbuf_overlay_update_composition (GstGdkPixbufOverlay * overlay)
+ {
+   GstVideoOverlayComposition *comp;
+   GstVideoOverlayRectangle *rect;
+   gint x, y, width, height;
+   x = overlay->offset_x + (overlay->relative_x * overlay->pixels_width);
+   y = overlay->offset_y + (overlay->relative_y * overlay->pixels_height);
+   /* FIXME: this should work, but seems to crash */
+   if (x < 0)
+     x = 0;
+   if (y < 0)
+     y = 0;
+   width = overlay->overlay_width;
+   if (width == 0)
+     width = overlay->pixels_width;
+   height = overlay->overlay_height;
+   if (height == 0)
+     height = overlay->pixels_height;
+   GST_DEBUG_OBJECT (overlay, "overlay image dimensions: %d x %d",
+       overlay->pixels_width, overlay->pixels_height);
+   GST_DEBUG_OBJECT (overlay, "properties: x,y: %d,%d (%g%%,%g%%) - WxH: %dx%d",
+       overlay->offset_x, overlay->offset_y,
+       overlay->relative_x * 100.0, overlay->relative_y * 100.0,
+       overlay->overlay_height, overlay->overlay_width);
+   GST_DEBUG_OBJECT (overlay, "overlay rendered: %d x %d @ %d,%d (onto %d x %d)",
+       width, height, x, y, overlay->width, overlay->height);
+   rect = gst_video_overlay_rectangle_new_argb (overlay->pixels,
+       overlay->pixels_width, overlay->pixels_height, overlay->pixels_stride,
+       x, y, width, height, GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE);
+   comp = gst_video_overlay_composition_new (rect);
+   gst_video_overlay_rectangle_unref (rect);
+   if (overlay->comp)
+     gst_video_overlay_composition_unref (overlay->comp);
+   overlay->comp = comp;
+ }
+ static void
+ gst_gdk_pixbuf_overlay_before_transform (GstBaseTransform * trans,
+     GstBuffer * outbuf)
+ {
+   GstClockTime stream_time;
+   stream_time = gst_segment_to_stream_time (&trans->segment, GST_FORMAT_TIME,
+       GST_BUFFER_TIMESTAMP (outbuf));
+   if (GST_CLOCK_TIME_IS_VALID (stream_time))
+     gst_object_sync_values (G_OBJECT (trans), stream_time);
+ }
+ static GstFlowReturn
+ gst_gdk_pixbuf_overlay_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
+ {
+   GstGdkPixbufOverlay *overlay = GST_GDK_PIXBUF_OVERLAY (trans);
+   GST_OBJECT_LOCK (overlay);
+   if (G_UNLIKELY (overlay->update_composition)) {
+     gst_gdk_pixbuf_overlay_update_composition (overlay);
+     overlay->update_composition = FALSE;
+   }
+   GST_OBJECT_UNLOCK (overlay);
+   gst_video_overlay_composition_blend (overlay->comp, buf);
+   return GST_FLOW_OK;
+ }
@@@ -48,20 -52,43 +48,21 @@@ static gboolean gst_pngdec_sink_activat
  static GstFlowReturn gst_pngdec_caps_create_and_set (GstPngDec * pngdec);
  
  static void gst_pngdec_task (GstPad * pad);
 -static GstFlowReturn gst_pngdec_chain (GstPad * pad, GstBuffer * buffer);
 -static gboolean gst_pngdec_sink_event (GstPad * pad, GstEvent * event);
 -static gboolean gst_pngdec_sink_setcaps (GstPad * pad, GstCaps * caps);
 -
 -static GstElementClass *parent_class = NULL;
 +static GstFlowReturn gst_pngdec_chain (GstPad * pad, GstObject * parent,
 +    GstBuffer * buffer);
 +static gboolean gst_pngdec_sink_event (GstPad * pad, GstObject * parent,
 +    GstEvent * event);
 +static gboolean gst_pngdec_sink_setcaps (GstPngDec * pngdec, GstCaps * caps);
  
 -GType
 -gst_pngdec_get_type (void)
 -{
 -  static GType pngdec_type = 0;
 -
 -  if (!pngdec_type) {
 -    static const GTypeInfo pngdec_info = {
 -      sizeof (GstPngDecClass),
 -      gst_pngdec_base_init,
 -      NULL,
 -      (GClassInitFunc) gst_pngdec_class_init,
 -      NULL,
 -      NULL,
 -      sizeof (GstPngDec),
 -      0,
 -      (GInstanceInitFunc) gst_pngdec_init,
 -    };
 -
 -    pngdec_type = g_type_register_static (GST_TYPE_ELEMENT, "GstPngDec",
 -        &pngdec_info, 0);
 -  }
 -  return pngdec_type;
 -}
 +static GstFlowReturn gst_pngdec_negotiate_pool (GstPngDec * dec,
 +    GstCaps * caps, GstVideoInfo * info);
  
  static GstStaticPadTemplate gst_pngdec_src_pad_template =
 -    GST_STATIC_PAD_TEMPLATE ("src",
 +GST_STATIC_PAD_TEMPLATE ("src",
      GST_PAD_SRC,
      GST_PAD_ALWAYS,
-     GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ RGBA, RGB }"))
 -    GST_STATIC_CAPS (GST_VIDEO_CAPS_RGBA ";" GST_VIDEO_CAPS_RGB ";"
 -        GST_VIDEO_CAPS_ARGB_64 ";"
 -        GST_VIDEO_CAPS_GRAY8 ";" GST_VIDEO_CAPS_GRAY16 ("BIG_ENDIAN"))
++    GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE
++        ("{ RGBA, RGB, ARGB64, GRAY8, GRAY16_BE }"))
      );
  
  static GstStaticPadTemplate gst_pngdec_sink_pad_template =
@@@ -462,11 -433,17 +468,22 @@@ gst_pngdec_caps_create_and_set (GstPngD
    switch (pngdec->color_type) {
      case PNG_COLOR_TYPE_RGB:
        GST_LOG_OBJECT (pngdec, "we have no alpha channel, depth is 24 bits");
 -      pngdec->bpp = 3 * bpc;
 +      format = GST_VIDEO_FORMAT_RGB;
        break;
      case PNG_COLOR_TYPE_RGB_ALPHA:
 -      GST_LOG_OBJECT (pngdec,
 -          "we have an alpha channel, depth is 32 or 64 bits");
 -      pngdec->bpp = 4 * bpc;
 +      GST_LOG_OBJECT (pngdec, "we have an alpha channel, depth is 32 bits");
-       format = GST_VIDEO_FORMAT_RGBA;
++      if (bpc == 1)
++        format = GST_VIDEO_FORMAT_RGBA;
++      else
++        format = GST_VIDEO_FORMAT_ARGB64;
+       break;
+     case PNG_COLOR_TYPE_GRAY:
+       GST_LOG_OBJECT (pngdec,
+           "We have an gray image, depth is 8 or 16 (be) bits");
 -      pngdec->bpp = bpc;
++      if (bpc == 1)
++        format = GST_VIDEO_FORMAT_GRAY8;
++      else
++        format = GST_VIDEO_FORMAT_GRAY16_BE;
        break;
      default:
        GST_ELEMENT_ERROR (pngdec, STREAM, NOT_IMPLEMENTED, (NULL),
@@@ -61,10 -62,11 +61,10 @@@ GST_STATIC_PAD_TEMPLATE ("src"
      );
  
  static GstStaticPadTemplate pngenc_sink_template =
 -    GST_STATIC_PAD_TEMPLATE ("sink",
 +GST_STATIC_PAD_TEMPLATE ("sink",
      GST_PAD_SINK,
      GST_PAD_ALWAYS,
-     GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ RGBA, RGB, GRAY8 }"))
 -    GST_STATIC_CAPS (GST_VIDEO_CAPS_RGBA ";" GST_VIDEO_CAPS_RGB ";"
 -        GST_VIDEO_CAPS_GRAY8 ";" GST_VIDEO_CAPS_GRAY16 ("BIG_ENDIAN"))
++    GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ RGBA, RGB, GRAY8, GRAY16_BE }"))
      );
  
  /* static GstElementClass *parent_class = NULL; */
@@@ -148,17 -159,16 +148,24 @@@ gst_pngenc_setcaps (GstPngEnc * pngenc
    if (G_UNLIKELY (!ret))
      goto done;
  
 -  switch (format) {
 +  pngenc->info = info;
 +
 +  switch (GST_VIDEO_INFO_FORMAT (&info)) {
      case GST_VIDEO_FORMAT_RGBA:
        pngenc->png_color_type = PNG_COLOR_TYPE_RGBA;
++      pngenc->depth = 8;
        break;
      case GST_VIDEO_FORMAT_RGB:
        pngenc->png_color_type = PNG_COLOR_TYPE_RGB;
++      pngenc->depth = 8;
        break;
      case GST_VIDEO_FORMAT_GRAY8:
 +      pngenc->png_color_type = PNG_COLOR_TYPE_GRAY;
++      pngenc->depth = 8;
++      break;
+     case GST_VIDEO_FORMAT_GRAY16_BE:
+       pngenc->png_color_type = PNG_COLOR_TYPE_GRAY;
++      pngenc->depth = 16;
        break;
      default:
        ret = FALSE;
@@@ -50,10 -49,11 +50,11 @@@ struct _GstPngEn
    png_structp png_struct_ptr;
    png_infop png_info_ptr;
  
 +  GstVideoInfo info;
    gint png_color_type;
+   gint depth;
    gint width;
    gint height;
 -  gint stride;
    guint compression_level;
  
    gboolean snapshot;
Simple merge
@@@ -620,46 -626,54 +623,54 @@@ gst_flac_parse_frame_is_valid (GstFlacP
    guint i, search_start, search_end;
    FrameHeaderCheckReturn header_ret;
    guint16 block_size;
+   gboolean suspect_start = FALSE, suspect_end = FALSE;
 +  gboolean result = FALSE;
  
    buffer = frame->buffer;
 -  data = GST_BUFFER_DATA (buffer);
 -  size = GST_BUFFER_SIZE (buffer);
 +  gst_buffer_map (buffer, &map, GST_MAP_READ);
  
 -  if (size < flacparse->min_framesize)
 +  if (map.size < flacparse->min_framesize)
      goto need_more;
  
    header_ret =
 -      gst_flac_parse_frame_header_is_valid (flacparse, data, size, TRUE,
 +      gst_flac_parse_frame_header_is_valid (flacparse, map.data, map.size, TRUE,
-       &block_size);
+       &block_size, &suspect_start);
    if (header_ret == FRAME_HEADER_INVALID) {
      *ret = 0;
 -    return FALSE;
 -  } else if (header_ret == FRAME_HEADER_MORE_DATA) {
 -    goto need_more;
 +    goto cleanup;
    }
 +  if (header_ret == FRAME_HEADER_MORE_DATA)
 +    goto need_more;
  
    /* mind unknown framesize */
    search_start = MAX (2, flacparse->min_framesize);
    if (flacparse->max_framesize)
 -    search_end = MIN (size, flacparse->max_framesize + 9 + 2);
 +    search_end = MIN (map.size, flacparse->max_framesize + 9 + 2);
    else
 -    search_end = size;
 +    search_end = map.size;
    search_end -= 2;
  
 -  remaining = size;
 +  remaining = map.size;
  
    for (i = search_start; i < search_end; i++, remaining--) {
 -    if ((GST_READ_UINT16_BE (data + i) & 0xfffe) == 0xfff8) {
 +    if ((GST_READ_UINT16_BE (map.data + i) & 0xfffe) == 0xfff8) {
+       GST_LOG_OBJECT (flacparse, "possible frame end at offset %d", i);
+       suspect_end = FALSE;
        header_ret =
 -          gst_flac_parse_frame_header_is_valid (flacparse, data + i, remaining,
 -          FALSE, NULL, &suspect_end);
 +          gst_flac_parse_frame_header_is_valid (flacparse, map.data + i,
-           remaining, FALSE, NULL);
++          remaining, FALSE, NULL, &suspect_end);
        if (header_ret == FRAME_HEADER_VALID) {
 -        if (flacparse->check_frame_checksums || suspect_start || suspect_end) {
 -          guint16 actual_crc = gst_flac_calculate_crc16 (data, i - 2);
 -          guint16 expected_crc = GST_READ_UINT16_BE (data + i - 2);
 +        if (flacparse->check_frame_checksums) {
 +          guint16 actual_crc = gst_flac_calculate_crc16 (map.data, i - 2);
 +          guint16 expected_crc = GST_READ_UINT16_BE (map.data + i - 2);
  
-           if (actual_crc != expected_crc)
+           GST_LOG_OBJECT (flacparse,
+               "checking checksum, frame suspect (%d, %d)",
+               suspect_start, suspect_end);
+           if (actual_crc != expected_crc) {
+             GST_DEBUG_OBJECT (flacparse, "checksum did not match");
              continue;
+           }
          }
          *ret = i;
          flacparse->block_size = block_size;
@@@ -1397,7 -1333,7 +1417,7 @@@ gst_flac_parse_parse_frame (GstBasePars
        flacparse->offset = GST_BUFFER_OFFSET (buffer);
        ret =
            gst_flac_parse_frame_header_is_valid (flacparse,
-           map.data, map.size, TRUE, NULL);
 -          GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer), TRUE, NULL, NULL);
++          map.data, map.size, TRUE, NULL, NULL);
        if (ret != FRAME_HEADER_VALID) {
          GST_ERROR_OBJECT (flacparse,
              "Baseclass didn't provide a complete frame");
Simple merge
@@@ -1153,18 -1113,19 +1153,19 @@@ gst_flv_mux_write_header (GstFlvMux * m
      if (gst_pad_peer_query (mux->srcpad, query)) {
        gst_query_parse_seeking (query, NULL, &seekable, NULL, NULL);
        GST_INFO_OBJECT (mux, "downstream is %sseekable", seekable ? "" : "not ");
 -      if (!seekable) {
 -        mux->streamable = TRUE;
 -        g_object_notify (G_OBJECT (mux), "streamable");
 -        GST_WARNING_OBJECT (mux, "downstream is not seekable, but "
 -            "streamable=false. Will ignore that and create streamable output "
 -            "instead");
 -      }
      } else {
        /* have to assume seeking is supported if query not handled downstream */
 -      /* FIXME 0.11: change to query not handled => seeking not supported */
        GST_WARNING_OBJECT (mux, "downstream did not handle seeking query");
 +      seekable = FALSE;
 +    }
 +    if (!seekable) {
 +      mux->streamable = TRUE;
 +      g_object_notify (G_OBJECT (mux), "streamable");
 +      GST_WARNING_OBJECT (mux, "downstream is not seekable, but "
 +          "streamable=false. Will ignore that and create streamable output "
 +          "instead");
      }
+     gst_query_unref (query);
    }
  
    header = gst_flv_mux_create_header (mux);
@@@ -1642,18 -1623,19 +1642,19 @@@ gst_qt_mux_start_file (GstQTMux * qtmux
        gst_query_parse_seeking (query, NULL, &seekable, NULL, NULL);
        GST_INFO_OBJECT (qtmux, "downstream is %sseekable",
            seekable ? "" : "not ");
 -      if (!seekable) {
 -        qtmux->streamable = TRUE;
 -        g_object_notify (G_OBJECT (qtmux), "streamable");
 -        GST_WARNING_OBJECT (qtmux, "downstream is not seekable, but "
 -            "streamable=false. Will ignore that and create streamable output "
 -            "instead");
 -      }
      } else {
        /* have to assume seeking is supported if query not handled downstream */
 -      /* FIXME 0.11: change to query not handled => seeking not supported */
        GST_WARNING_OBJECT (qtmux, "downstream did not handle seeking query");
 +      seekable = FALSE;
 +    }
 +    if (!seekable) {
 +      qtmux->streamable = TRUE;
 +      g_object_notify (G_OBJECT (qtmux), "streamable");
 +      GST_WARNING_OBJECT (qtmux, "downstream is not seekable, but "
 +          "streamable=false. Will ignore that and create streamable output "
 +          "instead");
      }
+     gst_query_unref (query);
    }
  
    /* let downstream know we think in BYTES and expect to do seeking later on */
Simple merge
@@@ -2349,18 -2364,19 +2349,19 @@@ gst_matroska_mux_start (GstMatroskaMux 
      if (gst_pad_peer_query (mux->srcpad, query)) {
        gst_query_parse_seeking (query, NULL, &seekable, NULL, NULL);
        GST_INFO_OBJECT (mux, "downstream is %sseekable", seekable ? "" : "not ");
 -      if (!seekable) {
 -        mux->streamable = TRUE;
 -        g_object_notify (G_OBJECT (mux), "streamable");
 -        GST_WARNING_OBJECT (mux, "downstream is not seekable, but "
 -            "streamable=false. Will ignore that and create streamable output "
 -            "instead");
 -      }
      } else {
        /* have to assume seeking is supported if query not handled downstream */
 -      /* FIXME 0.11: change to query not handled => seeking not supported */
        GST_WARNING_OBJECT (mux, "downstream did not handle seeking query");
 +      seekable = FALSE;
 +    }
 +    if (!seekable) {
 +      mux->streamable = TRUE;
 +      g_object_notify (G_OBJECT (mux), "streamable");
 +      GST_WARNING_OBJECT (mux, "downstream is not seekable, but "
 +          "streamable=false. Will ignore that and create streamable output "
 +          "instead");
      }
+     gst_query_unref (query);
    }
  
    if (!strcmp (mux->doctype, GST_MATROSKA_DOCTYPE_WEBM)) {
@@@ -336,12 -336,14 +336,14 @@@ gst_rtp_dv_depay_process (GstRTPBaseDep
        GST_LOG_OBJECT (dvdepay, "got block at location %d", location);
      }
  
-     /* get the byte offset of the dif block */
-     offset = location * 80;
+     if (location != -1) {
+       /* get the byte offset of the dif block */
+       offset = location * 80;
  
-     /* And copy it in, provided the location is sane. */
-     if (offset >= 0 && offset <= dvdepay->frame_size - 80)
-       gst_buffer_fill (dvdepay->acc, offset, payload, 80);
+       /* And copy it in, provided the location is sane. */
+       if (offset <= dvdepay->frame_size - 80)
 -        memcpy (GST_BUFFER_DATA (dvdepay->acc) + offset, payload, 80);
++        gst_buffer_fill (dvdepay->acc, offset, payload, 80);
+     }
  
      payload += 80;
      payload_len -= 80;
Simple merge
@@@ -201,9 -201,10 +201,10 @@@ struct _GstRTSPSrc 
    GTimeVal          tcp_timeout;
    GTimeVal         *ptcp_timeout;
    guint             latency;
 -  guint             connection_speed;
 +  guint64           connection_speed;
    GstRTSPNatMethod  nat_method;
    gboolean          do_rtcp;
+   gboolean          do_rtsp_keep_alive;
    gchar            *proxy_host;
    guint             proxy_port;
    gchar            *proxy_user;
Simple merge
Simple merge