Merge branch 'master' into 0.11
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Mon, 16 May 2011 15:06:22 +0000 (17:06 +0200)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Mon, 16 May 2011 15:06:22 +0000 (17:06 +0200)
Conflicts:
configure.ac
ext/alsa/gstalsasrc.c
gst-libs/gst/audio/gstbaseaudiosink.c
gst-libs/gst/tag/gstxmptag.c
gst/playback/gstsubtitleoverlay.c
gst/videorate/gstvideorate.c
sys/xvimage/xvimagesink.c

14 files changed:
1  2 
configure.ac
ext/alsa/gstalsasrc.c
gst-libs/gst/audio/gstbaseaudiosink.c
gst-libs/gst/audio/gstringbuffer.c
gst-libs/gst/audio/gstringbuffer.h
gst-libs/gst/tag/gstxmptag.c
gst/encoding/gstencodebin.c
gst/playback/gstdecodebin2.c
gst/playback/gstplaybin2.c
gst/playback/gstplaysink.c
gst/playback/gstsubtitleoverlay.c
gst/playback/gsturidecodebin.c
gst/videorate/gstvideorate.c
tests/check/libs/tag.c

diff --cc configure.ac
Simple merge
@@@ -199,14 -220,10 +207,17 @@@ gst_alsasrc_class_init (GstAlsaSrcClas
    gobject_class->get_property = gst_alsasrc_get_property;
    gobject_class->set_property = gst_alsasrc_set_property;
  
 +  gst_element_class_set_details_simple (gstelement_class,
 +      "Audio source (ALSA)", "Source/Audio",
 +      "Read from a sound card via ALSA", "Wim Taymans <wim@fluendo.com>");
 +
 +  gst_element_class_add_pad_template (gstelement_class,
 +      gst_static_pad_template_get (&alsasrc_src_factory));
 +
+   gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_alsasrc_change_state);
    gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_alsasrc_getcaps);
+   gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_alsasrc_create);
  
    gstaudiosrc_class->open = GST_DEBUG_FUNCPTR (gst_alsasrc_open);
    gstaudiosrc_class->prepare = GST_DEBUG_FUNCPTR (gst_alsasrc_prepare);
@@@ -282,8 -342,59 +336,59 @@@ gst_alsasrc_get_property (GObject * obj
    }
  }
  
+ static GstStateChangeReturn
+ gst_alsasrc_change_state (GstElement * element, GstStateChange transition)
+ {
+   GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
+   GstBaseAudioSrc *src = GST_BASE_AUDIO_SRC (element);
+   GstAlsaSrc *asrc = GST_ALSA_SRC (element);
+   GstClock *clk;
+   switch (transition) {
+       /* Show the compiler that we care */
+     case GST_STATE_CHANGE_NULL_TO_READY:
+     case GST_STATE_CHANGE_READY_TO_PAUSED:
+     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
+     case GST_STATE_CHANGE_PAUSED_TO_READY:
+     case GST_STATE_CHANGE_READY_TO_NULL:
+       break;
+     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
+       clk = src->clock;
+       asrc->driver_timestamps = FALSE;
+       if (GST_IS_SYSTEM_CLOCK (clk)) {
+         gint clocktype;
+         g_object_get (clk, "clock-type", &clocktype, NULL);
+         if (clocktype == GST_CLOCK_TYPE_MONOTONIC) {
+           asrc->driver_timestamps = TRUE;
+         }
+       }
+       break;
+   }
+   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+   return ret;
+ }
+ static GstFlowReturn
+ gst_alsasrc_create (GstBaseSrc * bsrc, guint64 offset, guint length,
+     GstBuffer ** outbuf)
+ {
+   GstFlowReturn ret = GST_FLOW_OK;
+   GstAlsaSrc *asrc = GST_ALSA_SRC (bsrc);
+   ret =
+       GST_BASE_SRC_CLASS (parent_class)->create (bsrc, offset, length, outbuf);
+   if (asrc->driver_timestamps == TRUE && *outbuf) {
+     GST_BUFFER_TIMESTAMP (*outbuf) =
+         gst_alsasrc_get_timestamp ((GstAlsaSrc *) bsrc);
+   }
+   return ret;
+ }
  static void
 -gst_alsasrc_init (GstAlsaSrc * alsasrc, GstAlsaSrcClass * g_class)
 +gst_alsasrc_init (GstAlsaSrc * alsasrc)
  {
    GST_DEBUG_OBJECT (alsasrc, "initializing");
  
@@@ -1345,13 -1376,12 +1345,14 @@@ gst_base_audio_sink_render (GstBaseSin
    guint64 in_offset;
    GstClockTime time, stop, render_start, render_stop, sample_offset;
    GstClockTimeDiff sync_offset, ts_offset;
+   GstBaseAudioSinkClass *bclass;
    GstBaseAudioSink *sink;
    GstRingBuffer *ringbuf;
 -  gint64 diff, align, ctime, cstop;
 +  gint64 diff, align;
 +  guint64 ctime, cstop;
 +  gsize offset;
    guint8 *data;
 -  guint size;
 +  gsize size;
    guint samples, written;
    gint bps;
    gint accum;
      GST_OBJECT_UNLOCK (sink);
    }
  
+   /* Before we go on, let's see if we need to payload the data. If yes, we also
+    * need to unref the output buffer before leaving. */
+   if (bclass->payload) {
+     out = bclass->payload (sink, buf);
+     if (!out)
+       goto payload_failed;
+     buf = out;
+   }
    bps = ringbuf->spec.bytes_per_sample;
  
 -  size = GST_BUFFER_SIZE (buf);
 +  size = gst_buffer_get_size (buf);
    if (G_UNLIKELY (size % bps) != 0)
      goto wrong_size;
  
@@@ -1698,8 -1756,7 +1727,8 @@@ stopping
    {
      GST_DEBUG_OBJECT (sink, "preroll got interrupted: %d (%s)", ret,
          gst_flow_get_name (ret));
-     return ret;
 +    gst_buffer_unmap (buf, data, size);
+     goto done;
    }
  sync_latency_failed:
    {
Simple merge
Simple merge
@@@ -1211,24 -1261,29 +1261,36 @@@ gst_tag_list_from_xmp_buffer (GstBuffe
    XmpTag *last_xmp_tag = NULL;
    GSList *pending_tags = NULL;
  
+   /* Used for strucuture xmp tags */
+   XmpTag *context_tag = NULL;
    GstXmpNamespaceMap ns_map[] = {
--    {"dc", NULL},
--    {"exif", NULL},
--    {"tiff", NULL},
--    {"xap", NULL},
--    {"photoshop", NULL},
--    {"Iptc4xmpCore", NULL},
 -    {"Iptc4xmpExt", NULL},
++    {"dc", NULL}
++    ,
++    {"exif", NULL}
++    ,
++    {"tiff", NULL}
++    ,
++    {"xap", NULL}
++    ,
++    {"photoshop", NULL}
++    ,
++    {"Iptc4xmpCore", NULL}
++    ,
++    {"Iptc4xmpExt", NULL}
++    ,
      {NULL, NULL}
    };
  
    xmp_tags_initialize ();
  
    g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL);
 -  g_return_val_if_fail (GST_BUFFER_SIZE (buffer) > 0, NULL);
  
 -  xps = (const gchar *) GST_BUFFER_DATA (buffer);
 -  len = GST_BUFFER_SIZE (buffer);
+   GST_LOG ("Starting xmp parsing");
 +  xps = gst_buffer_map (buffer, &len, NULL, GST_MAP_READ);
 +  g_return_val_if_fail (len > 0, NULL);
 +
    xpe = &xps[len + 1];
  
    /* check header and footer */
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -1639,16 -1684,22 +1639,16 @@@ gst_subtitle_overlay_video_sink_event (
      self->fps_n = self->fps_d = 0;
    }
  
-   ret = self->video_sink_event (pad, gst_event_ref (event));
+   ret = gst_proxy_pad_event_default (pad, gst_event_ref (event));
  
 -  if (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT) {
 -    gboolean update;
 -    gdouble rate, applied_rate;
 -    GstFormat format;
 -    gint64 start, stop, position;
 +  if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) {
  
 -    GST_DEBUG_OBJECT (pad, "Newsegment event: %" GST_PTR_FORMAT,
 -        event->structure);
 -    gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
 -        &format, &start, &stop, &position);
 +    GST_DEBUG_OBJECT (pad, "segment event: %" GST_PTR_FORMAT, event);
 +    gst_event_parse_segment (event, &self->video_segment);
  
 -    if (format != GST_FORMAT_TIME) {
 +    if (self->video_segment.format != GST_FORMAT_TIME) {
        GST_ERROR_OBJECT (pad, "Newsegment event in non-time format: %s",
 -          gst_format_get_name (format));
 +          gst_format_get_name (self->video_segment.format));
        gst_object_unref (event);
        gst_object_unref (self);
        return FALSE;
@@@ -1924,11 -1993,29 +1924,11 @@@ gst_subtitle_overlay_subtitle_sink_even
        break;
    }
  
-   ret = self->subtitle_sink_event (pad, gst_event_ref (event));
+   ret = gst_proxy_pad_event_default (pad, gst_event_ref (event));
  
 -  if (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT) {
 -    gboolean update;
 -    gdouble rate, applied_rate;
 -    gint64 start, stop, position;
 -
 -    GST_DEBUG_OBJECT (pad, "Newsegment event: %" GST_PTR_FORMAT,
 -        event->structure);
 -    gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
 -        &format, &start, &stop, &position);
 -
 -    GST_DEBUG_OBJECT (pad, "Old subtitle segment: %" GST_SEGMENT_FORMAT,
 -        &self->subtitle_segment);
 -    if (self->subtitle_segment.format != format) {
 -      GST_DEBUG_OBJECT (pad, "Subtitle segment format changed: %s -> %s",
 -          gst_format_get_name (self->subtitle_segment.format),
 -          gst_format_get_name (format));
 -      gst_segment_init (&self->subtitle_segment, format);
 -    }
 -
 -    gst_segment_set_newsegment_full (&self->subtitle_segment, update, rate,
 -        applied_rate, format, start, stop, position);
 +  if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) {
 +    GST_DEBUG_OBJECT (pad, "segment event: %" GST_PTR_FORMAT, event);
 +    gst_event_parse_segment (event, &self->subtitle_segment);
      GST_DEBUG_OBJECT (pad, "New subtitle segment: %" GST_SEGMENT_FORMAT,
          &self->subtitle_segment);
    }
  }
  
  static void
 -gst_subtitle_overlay_init (GstSubtitleOverlay * self,
 -    GstSubtitleOverlayClass * klass)
 +gst_subtitle_overlay_init (GstSubtitleOverlay * self)
  {
    GstPadTemplate *templ;
-   GstIterator *it;
-   GValue item = { 0, };
    GstPad *proxypad = NULL;
  
    self->lock = g_mutex_new ();
    gst_pad_set_chain_function (self->video_sinkpad,
        GST_DEBUG_FUNCPTR (gst_subtitle_overlay_video_sink_chain));
  
-   proxypad = NULL;
-   it = gst_pad_iterate_internal_links (self->video_sinkpad);
-   if (G_UNLIKELY (!it
-           || gst_iterator_next (it, &item) != GST_ITERATOR_OK
-           || ((proxypad = g_value_dup_object (&item)) == NULL))) {
-     GST_ERROR_OBJECT (self,
-         "Failed to get internally linked pad from video sinkpad");
-   }
-   if (it)
-     gst_iterator_free (it);
+   proxypad =
+       GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD
+           (self->video_sinkpad)));
    self->video_block_pad = proxypad;
-   g_value_unset (&item);
++
    gst_element_add_pad (GST_ELEMENT_CAST (self), self->video_sinkpad);
  
    templ = gst_static_pad_template_get (&subtitle_sinktemplate);
        GST_DEBUG_FUNCPTR (gst_subtitle_overlay_subtitle_sink_getcaps));
    gst_pad_set_acceptcaps_function (self->subtitle_sinkpad,
        GST_DEBUG_FUNCPTR (gst_subtitle_overlay_subtitle_sink_acceptcaps));
 -  gst_pad_set_bufferalloc_function (self->subtitle_sinkpad, NULL);
  
-   proxypad = NULL;
-   it = gst_pad_iterate_internal_links (self->subtitle_sinkpad);
-   if (G_UNLIKELY (!it
-           || gst_iterator_next (it, &item) != GST_ITERATOR_OK
-           || ((proxypad = g_value_dup_object (&item)) == NULL))) {
-     GST_ERROR_OBJECT (self,
-         "Failed to get internally linked pad from subtitle sinkpad");
-   }
-   if (it)
-     gst_iterator_free (it);
-   g_value_unset (&item);
+   proxypad =
+       GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD
+           (self->subtitle_sinkpad)));
    self->subtitle_block_pad = proxypad;
  
    gst_element_add_pad (GST_ELEMENT_CAST (self), self->subtitle_sinkpad);
Simple merge
@@@ -184,16 -203,33 +188,43 @@@ gst_video_rate_class_init (GstVideoRate
            "Don't produce buffers before the first one we receive",
            DEFAULT_SKIP_TO_FIRST, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  
 +  gst_element_class_set_details_simple (element_class,
 +      "Video rate adjuster", "Filter/Effect/Video",
 +      "Drops/duplicates/adjusts timestamps on video frames to make a perfect stream",
 +      "Wim Taymans <wim@fluendo.com>");
 +
 +  gst_element_class_add_pad_template (element_class,
 +      gst_static_pad_template_get (&gst_video_rate_sink_template));
 +  gst_element_class_add_pad_template (element_class,
 +      gst_static_pad_template_get (&gst_video_rate_src_template));
 +
+   /**
+    * GstVideoRate:drop-only:
+    *
+    * Only drop frames, no duplicates are produced.
+    *
+    * Since: 0.10.34
+    */
+   g_object_class_install_property (object_class, ARG_DROP_ONLY,
+       g_param_spec_boolean ("drop-only", "Only Drop",
+           "Only drop frames, no duplicates are produced",
+           DEFAULT_DROP_ONLY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+   /**
+    * GstVideoRate:average-period:
+    *
+    * Arrange for maximum framerate by dropping frames beyond a certain framerate,
+    * where the framerate is calculated using a moving average over the
+    * configured.
+    *
+    * Since: 0.10.34
+    */
+   g_object_class_install_property (object_class, ARG_AVERAGE_PERIOD,
+       g_param_spec_uint64 ("average-period", "Period over which to average",
+           "Period over which to average the framerate (in ns) (0 = disabled)",
+           0, G_MAXINT64, DEFAULT_AVERAGE_PERIOD,
+           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
    element_class->change_state = GST_DEBUG_FUNCPTR (gst_video_rate_change_state);
  }
  
@@@ -513,8 -537,12 +549,11 @@@ gst_video_rate_flush_prev (GstVideoRat
      GST_BUFFER_DURATION (outbuf) = videorate->next_ts - push_ts;
    }
  
-   /* adapt for looping, bring back to time in current segment. */
-   GST_BUFFER_TIMESTAMP (outbuf) = push_ts - videorate->segment.base;
+   /* We do not need to update time in VFR (variable frame rate) mode */
+   if (!videorate->drop_only) {
+     /* adapt for looping, bring back to time in current segment. */
+     GST_BUFFER_TIMESTAMP (outbuf) = push_ts - videorate->segment.accum;
+   }
 -  gst_buffer_set_caps (outbuf, GST_PAD_CAPS (videorate->srcpad));
  
    GST_LOG_OBJECT (videorate,
        "old is best, dup, pushing buffer outgoing ts %" GST_TIME_FORMAT,
Simple merge