Merge branch 'master' into 0.11
authorWim Taymans <wim.taymans@collabora.co.uk>
Mon, 4 Apr 2011 09:31:33 +0000 (11:31 +0200)
committerWim Taymans <wim.taymans@collabora.co.uk>
Mon, 4 Apr 2011 09:31:33 +0000 (11:31 +0200)
Conflicts:
gst-libs/gst/tag/gstvorbistag.c

1  2 
ext/ogg/gstoggmux.c
ext/pango/gsttextoverlay.c
gst-libs/gst/audio/gstbaseaudiosink.c
gst-libs/gst/audio/gstbaseaudiosrc.c
gst-libs/gst/rtp/gstrtcpbuffer.c
gst-libs/gst/tag/gstvorbistag.c
tests/check/libs/video.c

Simple merge
@@@ -1835,15 -1936,45 +1940,45 @@@ gst_text_overlay_push_frame (GstTextOve
              ypos, ypos + overlay->image_height);
          break;
        case GST_VIDEO_FORMAT_xRGB:
 -        gst_text_overlay_shade_xRGB (overlay,
 -            GST_BUFFER_DATA (video_frame), xpos, xpos + overlay->image_width,
 +        gst_text_overlay_shade_xRGB (overlay, data,
 +            xpos, xpos + overlay->image_width,
              ypos, ypos + overlay->image_height);
          break;
+       case GST_VIDEO_FORMAT_xBGR:
+         gst_text_overlay_shade_xBGR (overlay,
+             GST_BUFFER_DATA (video_frame), xpos, xpos + overlay->image_width,
+             ypos, ypos + overlay->image_height);
+         break;
        case GST_VIDEO_FORMAT_BGRx:
 -        gst_text_overlay_shade_BGRx (overlay,
 -            GST_BUFFER_DATA (video_frame), xpos, xpos + overlay->image_width,
 +        gst_text_overlay_shade_BGRx (overlay, data,
 +            xpos, xpos + overlay->image_width,
              ypos, ypos + overlay->image_height);
          break;
+       case GST_VIDEO_FORMAT_RGBx:
+         gst_text_overlay_shade_RGBx (overlay,
+             GST_BUFFER_DATA (video_frame), xpos, xpos + overlay->image_width,
+             ypos, ypos + overlay->image_height);
+         break;
+       case GST_VIDEO_FORMAT_ARGB:
+         gst_text_overlay_shade_ARGB (overlay,
+             GST_BUFFER_DATA (video_frame), xpos, xpos + overlay->image_width,
+             ypos, ypos + overlay->image_height);
+         break;
+       case GST_VIDEO_FORMAT_ABGR:
+         gst_text_overlay_shade_ABGR (overlay,
+             GST_BUFFER_DATA (video_frame), xpos, xpos + overlay->image_width,
+             ypos, ypos + overlay->image_height);
+         break;
+       case GST_VIDEO_FORMAT_RGBA:
+         gst_text_overlay_shade_RGBA (overlay,
+             GST_BUFFER_DATA (video_frame), xpos, xpos + overlay->image_width,
+             ypos, ypos + overlay->image_height);
+         break;
+       case GST_VIDEO_FORMAT_BGRA:
+         gst_text_overlay_shade_BGRA (overlay,
+             GST_BUFFER_DATA (video_frame), xpos, xpos + overlay->image_width,
+             ypos, ypos + overlay->image_height);
+         break;
        default:
          g_assert_not_reached ();
      }
          break;
        case GST_VIDEO_FORMAT_NV12:
        case GST_VIDEO_FORMAT_NV21:
 -        gst_text_overlay_blit_NV12_NV21 (overlay,
 -            GST_BUFFER_DATA (video_frame), xpos, ypos);
 +        gst_text_overlay_blit_NV12_NV21 (overlay, data, xpos, ypos);
          break;
        case GST_VIDEO_FORMAT_UYVY:
 -        gst_text_overlay_blit_UYVY (overlay,
 -            GST_BUFFER_DATA (video_frame), xpos, ypos);
 +        gst_text_overlay_blit_UYVY (overlay, data, xpos, ypos);
          break;
        case GST_VIDEO_FORMAT_AYUV:
 -        gst_text_overlay_blit_AYUV (overlay,
 -            GST_BUFFER_DATA (video_frame), xpos, ypos);
 +        gst_text_overlay_blit_AYUV (overlay, data, xpos, ypos);
          break;
        case GST_VIDEO_FORMAT_BGRx:
 -        gst_text_overlay_blit_BGRx (overlay,
 -            GST_BUFFER_DATA (video_frame), xpos, ypos);
 +        gst_text_overlay_blit_BGRx (overlay, data, xpos, ypos);
          break;
        case GST_VIDEO_FORMAT_xRGB:
 -        gst_text_overlay_blit_xRGB (overlay,
 -            GST_BUFFER_DATA (video_frame), xpos, ypos);
 +        gst_text_overlay_blit_xRGB (overlay, data, xpos, ypos);
          break;
+       case GST_VIDEO_FORMAT_RGBx:
+         gst_text_overlay_blit_RGBx (overlay,
+             GST_BUFFER_DATA (video_frame), xpos, ypos);
+         break;
+       case GST_VIDEO_FORMAT_xBGR:
+         gst_text_overlay_blit_xBGR (overlay,
+             GST_BUFFER_DATA (video_frame), xpos, ypos);
+         break;
+       case GST_VIDEO_FORMAT_ARGB:
+         gst_text_overlay_blit_ARGB (overlay,
+             GST_BUFFER_DATA (video_frame), xpos, ypos);
+         break;
+       case GST_VIDEO_FORMAT_ABGR:
+         gst_text_overlay_blit_ABGR (overlay,
+             GST_BUFFER_DATA (video_frame), xpos, ypos);
+         break;
+       case GST_VIDEO_FORMAT_RGBA:
+         gst_text_overlay_blit_RGBA (overlay,
+             GST_BUFFER_DATA (video_frame), xpos, ypos);
+         break;
+       case GST_VIDEO_FORMAT_BGRA:
+         gst_text_overlay_blit_BGRA (overlay,
+             GST_BUFFER_DATA (video_frame), xpos, ypos);
+         break;
        default:
          g_assert_not_reached ();
      }
@@@ -1326,6 -1319,56 +1326,57 @@@ flushing
    }
  }
  
 -gst_base_audio_sink_get_alignment (GstBaseAudioSink * sink, GstClockTime sample_offset)
+ static gint64
 -    gint64 diff_s = gst_util_uint64_scale_int (diff, GST_SECOND, ringbuf->spec.rate);
++gst_base_audio_sink_get_alignment (GstBaseAudioSink * sink,
++    GstClockTime sample_offset)
+ {
+   GstRingBuffer *ringbuf = sink->ringbuffer;
+   gint64 align;
+   gint64 diff;
+   gint64 maxdrift;
+   gint segdone = g_atomic_int_get (&ringbuf->segdone) - ringbuf->segbase;
+   gint64 samples_done = segdone * ringbuf->samples_per_seg;
+   gint64 headroom = sample_offset - samples_done;
+   gboolean allow_align = TRUE;
+   /* now try to align the sample to the previous one, first see how big the
+    * difference is. */
+   if (sample_offset >= sink->next_sample)
+     diff = sample_offset - sink->next_sample;
+   else
+     diff = sink->next_sample - sample_offset;
+   /* calculate the max allowed drift in units of samples. By default this is
+    * 20ms and should be anough to compensate for timestamp rounding errors. */
+   maxdrift = (ringbuf->spec.rate * sink->priv->drift_tolerance) / GST_MSECOND;
+   /* calc align with previous sample */
+   align = sink->next_sample - sample_offset;
+   /* don't align if it means writing behind the read-segment */
+   if (diff > headroom && align < 0)
+     allow_align = FALSE;
+   if (G_LIKELY (diff < maxdrift && allow_align)) {
+     GST_DEBUG_OBJECT (sink,
+         "align with prev sample, ABS (%" G_GINT64_FORMAT ") < %"
+         G_GINT64_FORMAT, align, maxdrift);
+   } else {
+     /* calculate sample diff in seconds for error message */
 -        sample_offset > sink->next_sample ? "+" : "-",
 -        GST_TIME_ARGS (diff_s));
++    gint64 diff_s =
++        gst_util_uint64_scale_int (diff, GST_SECOND, ringbuf->spec.rate);
+     /* timestamps drifted apart from previous samples too much, we need to
+      * resync. We log this as an element warning. */
+     GST_WARNING_OBJECT (sink,
+         "Unexpected discontinuity in audio timestamps of "
+         "%s%" GST_TIME_FORMAT ", resyncing",
++        sample_offset > sink->next_sample ? "+" : "-", GST_TIME_ARGS (diff_s));
+     align = 0;
+   }
+   return align;
+ }
  static GstFlowReturn
  gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf)
  {
@@@ -560,8 -560,12 +560,11 @@@ gst_base_audio_src_setcaps (GstBaseSrc 
    spec->buffer_time = src->buffer_time;
    spec->latency_time = src->latency_time;
  
-   if (!gst_ring_buffer_parse_caps (spec, caps))
+   GST_OBJECT_LOCK (src);
 -  if (!gst_ring_buffer_parse_caps (spec, caps))
 -  {
++  if (!gst_ring_buffer_parse_caps (spec, caps)) {
+     GST_OBJECT_UNLOCK (src);
      goto parse_error;
+   }
  
    /* calculate suggested segsize and segtotal */
    spec->segsize =
Simple merge
@@@ -363,10 -357,68 +357,69 @@@ convert_failed
    }
  }
  
+ /* Standardized way of adding pictures to vorbiscomments:
+  * http://wiki.xiph.org/VorbisComment#METADATA_BLOCK_PICTURE
+  */
+ static void
+ gst_vorbis_tag_add_metadata_block_picture (GstTagList * tags,
+     gchar * value, gint value_len)
+ {
+   GstByteReader reader;
+   guint32 img_len = 0, img_type = 0;
+   guint32 img_mimetype_len = 0, img_description_len = 0;
+   gsize decoded_len;
+   const guint8 *data;
+   /* img_data_base64 points to a temporary copy of the base64 encoded data, so
+    * it's safe to do inpace decoding here
+    */
+   g_base64_decode_inplace (value, &decoded_len);
+   if (decoded_len == 0)
+     goto decode_failed;
+   gst_byte_reader_init (&reader, (guint8 *) value, decoded_len);
+   if (!gst_byte_reader_get_uint32_be (&reader, &img_type))
+     goto error;
+   if (!gst_byte_reader_get_uint32_be (&reader, &img_mimetype_len))
+     goto error;
+   if (!gst_byte_reader_skip (&reader, img_mimetype_len))
+     goto error;
+   if (!gst_byte_reader_get_uint32_be (&reader, &img_description_len))
+     goto error;
+   if (!gst_byte_reader_skip (&reader, img_description_len))
+     goto error;
+   /* Skip width, height, color depth and number of colors for
+    * indexed formats */
+   if (!gst_byte_reader_skip (&reader, 4 * 4))
+     goto error;
+   if (!gst_byte_reader_get_uint32_be (&reader, &img_len))
+     goto error;
+   if (!gst_byte_reader_get_data (&reader, img_len, &data))
+     goto error;
+   gst_tag_list_add_id3_image (tags, data, img_len, img_type);
+   return;
+ error:
+   GST_WARNING
+       ("Couldn't extract image or image type from METADATA_BLOCK_PICTURE tag");
+   return;
+ decode_failed:
+   GST_WARNING ("Failed to decode Base64 data from METADATA_BLOCK_PICTURE tag");
+   return;
+ }
  /**
 - * gst_tag_list_from_vorbiscomment_buffer:
 - * @buffer: buffer to convert
 + * gst_tag_list_from_vorbiscomment:
 + * @data: data to convert
 + * @size: size of @data
   * @id_data: identification data at start of stream
   * @id_data_length: length of identification data
   * @vendor_string: pointer to a string that should take the vendor string
@@@ -500,31 -528,65 +557,70 @@@ gst_tag_to_metadata_block_picture (cons
    GstStructure *mime_struct;
    GstBuffer *buffer;
    GList *l = NULL;
 +  guint8 *data;
 +  gsize size;
+   GstByteWriter writer;
+   GstTagImageType image_type = GST_TAG_IMAGE_TYPE_NONE;
+   gint width = 0, height = 0;
+   guint8 *metadata_block;
+   guint metadata_block_len;
  
    g_return_val_if_fail (image_value != NULL, NULL);
  
    buffer = gst_value_get_buffer (image_value);
    g_return_val_if_fail (gst_caps_is_fixed (buffer->caps), NULL);
    mime_struct = gst_caps_get_structure (buffer->caps, 0);
    mime_type = gst_structure_get_name (mime_struct);
+   if (strcmp (mime_type, "text/uri-list") == 0)
+     mime_type = "-->";
+   mime_type_len = strlen (mime_type);
  
-   data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
-   if (strcmp (mime_type, "text/uri-list") == 0) {
-     /* URI reference */
-     coverart_data = g_strndup ((gchar *) data, size);
+   gst_structure_get (mime_struct, "image-type", GST_TYPE_TAG_IMAGE_TYPE,
+       &image_type, "width", G_TYPE_INT, &width, "height", G_TYPE_INT, &height,
+       NULL);
+   metadata_block_len = 32 + mime_type_len + GST_BUFFER_SIZE (buffer);
+   gst_byte_writer_init_with_size (&writer, metadata_block_len, TRUE);
+   if (image_type == GST_TAG_IMAGE_TYPE_NONE
+       && strcmp (tag, GST_TAG_PREVIEW_IMAGE) == 0) {
+     gst_byte_writer_put_uint32_be_unchecked (&writer, 0x01);
    } else {
-     coverart_data = g_base64_encode (data, size);
+     /* Convert to ID3v2 APIC image type */
+     if (image_type == GST_TAG_IMAGE_TYPE_NONE)
+       image_type = GST_TAG_IMAGE_TYPE_UNDEFINED;
+     else
+       image_type = image_type + 2;
+     gst_byte_writer_put_uint32_be_unchecked (&writer, image_type);
    }
 -  gst_byte_writer_put_uint32_be_unchecked (&writer, GST_BUFFER_SIZE (buffer));
 -  gst_byte_writer_put_data_unchecked (&writer, GST_BUFFER_DATA (buffer),
 -      GST_BUFFER_SIZE (buffer));
+   gst_byte_writer_put_uint32_be_unchecked (&writer, mime_type_len);
+   gst_byte_writer_put_data_unchecked (&writer, (guint8 *) mime_type,
+       mime_type_len);
+   /* description length */
+   gst_byte_writer_put_uint32_be_unchecked (&writer, 0);
+   gst_byte_writer_put_uint32_be_unchecked (&writer, width);
+   gst_byte_writer_put_uint32_be_unchecked (&writer, height);
+   /* color depth */
+   gst_byte_writer_put_uint32_be_unchecked (&writer, 0);
+   /* for indexed formats the number of colors */
+   gst_byte_writer_put_uint32_be_unchecked (&writer, 0);
-   data_result = g_strdup_printf ("COVERART=%s", coverart_data);
-   mime_result = g_strdup_printf ("COVERARTMIME=%s", mime_type);
-   g_free (coverart_data);
++
++  data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
++  gst_byte_writer_put_uint32_be_unchecked (&writer, size);
++  gst_byte_writer_put_data_unchecked (&writer, data, size);
 +  gst_buffer_unmap (buffer, data, size);
 +
+   g_assert (gst_byte_writer_get_pos (&writer) == metadata_block_len);
+   metadata_block = gst_byte_writer_reset_and_get_data (&writer);
+   comment_data = g_base64_encode (metadata_block, metadata_block_len);
+   g_free (metadata_block);
+   data_result = g_strdup_printf ("METADATA_BLOCK_PICTURE=%s", comment_data);
+   g_free (comment_data);
  
    l = g_list_append (l, data_result);
-   l = g_list_append (l, mime_result);
  
    return l;
  }
Simple merge