Move dataurisrc element from -bad

https://bugzilla.gnome.org/show_bug.cgi?id=774527
This commit is contained in:
Tim-Philipp Müller 2016-11-28 11:18:39 +00:00
commit a837ff6581
3 changed files with 771 additions and 0 deletions

View file

@ -0,0 +1,477 @@
/* GStreamer
*
* Copyright (C) 2009 Igalia S.L
* Copyright (C) 2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
*
* 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 St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
/**
* SECTION:element-dataurisrc
*
* dataurisrc handles data: URIs, see <ulink url="http://tools.ietf.org/html/rfc2397">RFC 2397</ulink> for more information.
*
* <refsect2>
* <title>Example launch line</title>
* |[
* gst-launch-1.0 -v dataurisrc uri="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAfElEQVQ4je2MwQnAIAxFgziA4EnczIsO4MEROo/gzZWc4xdTbe1R6LGRR74heYS7iKElzfcMiRnt4hf8gk8EayB6luefue/HzlJfCA50XsNjYRxprZmenXNIKSGEsC+QUqK1hhgj521BzhnWWiilUGvdF5RS4L2HMQZCCJy8sHMm2TYdJAAAAABJRU5ErkJggg==" ! pngdec ! videoconvert ! imagefreeze ! videoconvert ! autovideosink
* ]| This pipeline displays a small 16x16 PNG image from the data URI.
* </refsect2>
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "gstdataurisrc.h"
#include <string.h>
#include <gst/base/gsttypefindhelper.h>
GST_DEBUG_CATEGORY (data_uri_src_debug);
#define GST_CAT_DEFAULT (data_uri_src_debug)
static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS_ANY);
enum
{
PROP_0,
PROP_URI,
};
static void gst_data_uri_src_finalize (GObject * object);
static void gst_data_uri_src_set_property (GObject * object,
guint prop_id, const GValue * value, GParamSpec * pspec);
static void gst_data_uri_src_get_property (GObject * object,
guint prop_id, GValue * value, GParamSpec * pspec);
static GstCaps *gst_data_uri_src_get_caps (GstBaseSrc * src, GstCaps * filter);
static gboolean gst_data_uri_src_get_size (GstBaseSrc * src, guint64 * size);
static gboolean gst_data_uri_src_is_seekable (GstBaseSrc * src);
static GstFlowReturn gst_data_uri_src_create (GstBaseSrc * src, guint64 offset,
guint size, GstBuffer ** buf);
static gboolean gst_data_uri_src_start (GstBaseSrc * src);
static void gst_data_uri_src_handler_init (gpointer g_iface,
gpointer iface_data);
static GstURIType gst_data_uri_src_get_uri_type (GType type);
static const gchar *const *gst_data_uri_src_get_protocols (GType type);
static gchar *gst_data_uri_src_get_uri (GstURIHandler * handler);
static gboolean gst_data_uri_src_set_uri (GstURIHandler * handler,
const gchar * uri, GError ** error);
#define gst_data_uri_src_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstDataURISrc, gst_data_uri_src, GST_TYPE_BASE_SRC,
G_IMPLEMENT_INTERFACE (GST_TYPE_URI_HANDLER,
gst_data_uri_src_handler_init));
static void
gst_data_uri_src_class_init (GstDataURISrcClass * klass)
{
GObjectClass *gobject_class = (GObjectClass *) klass;
GstElementClass *element_class = (GstElementClass *) klass;
GstBaseSrcClass *basesrc_class = (GstBaseSrcClass *) klass;
gobject_class->finalize = gst_data_uri_src_finalize;
gobject_class->set_property = gst_data_uri_src_set_property;
gobject_class->get_property = gst_data_uri_src_get_property;
g_object_class_install_property (gobject_class, PROP_URI,
g_param_spec_string ("uri",
"URI",
"URI that should be used",
NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gst_element_class_add_static_pad_template (element_class, &src_template);
gst_element_class_set_static_metadata (element_class,
"data: URI source element", "Source", "Handles data: uris",
"Philippe Normand <pnormand@igalia.com>, "
"Sebastian Dröge <sebastian.droege@collabora.co.uk>");
GST_DEBUG_CATEGORY_INIT (data_uri_src_debug, "dataurisrc", 0,
"data: URI source");
basesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_data_uri_src_get_caps);
basesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_data_uri_src_get_size);
basesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_data_uri_src_is_seekable);
basesrc_class->create = GST_DEBUG_FUNCPTR (gst_data_uri_src_create);
basesrc_class->start = GST_DEBUG_FUNCPTR (gst_data_uri_src_start);
}
static void
gst_data_uri_src_init (GstDataURISrc * src)
{
}
static void
gst_data_uri_src_finalize (GObject * object)
{
GstDataURISrc *src = GST_DATA_URI_SRC (object);
g_free (src->uri);
src->uri = NULL;
if (src->buffer)
gst_buffer_unref (src->buffer);
src->buffer = NULL;
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
gst_data_uri_src_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstDataURISrc *src = GST_DATA_URI_SRC (object);
switch (prop_id) {
case PROP_URI:
gst_data_uri_src_set_uri (GST_URI_HANDLER (src),
g_value_get_string (value), NULL);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_data_uri_src_get_property (GObject * object,
guint prop_id, GValue * value, GParamSpec * pspec)
{
GstDataURISrc *src = GST_DATA_URI_SRC (object);
switch (prop_id) {
case PROP_URI:
g_value_set_string (value,
gst_data_uri_src_get_uri (GST_URI_HANDLER (src)));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static GstCaps *
gst_data_uri_src_get_caps (GstBaseSrc * basesrc, GstCaps * filter)
{
GstDataURISrc *src = GST_DATA_URI_SRC (basesrc);
GstCaps *caps;
GST_OBJECT_LOCK (src);
caps = gst_pad_get_current_caps (GST_BASE_SRC_PAD (basesrc));
if (!caps)
caps = gst_caps_new_any ();
GST_OBJECT_UNLOCK (src);
return caps;
}
static gboolean
gst_data_uri_src_get_size (GstBaseSrc * basesrc, guint64 * size)
{
GstDataURISrc *src = GST_DATA_URI_SRC (basesrc);
gboolean ret;
GST_OBJECT_LOCK (src);
if (!src->buffer) {
ret = FALSE;
*size = -1;
} else {
ret = TRUE;
*size = gst_buffer_get_size (src->buffer);
}
GST_OBJECT_UNLOCK (src);
return ret;
}
static gboolean
gst_data_uri_src_is_seekable (GstBaseSrc * basesrc)
{
return TRUE;
}
static GstFlowReturn
gst_data_uri_src_create (GstBaseSrc * basesrc, guint64 offset, guint size,
GstBuffer ** buf)
{
GstDataURISrc *src = GST_DATA_URI_SRC (basesrc);
GstFlowReturn ret;
GST_OBJECT_LOCK (src);
if (!src->buffer)
goto no_buffer;
/* This is only correct because GstBaseSrc already clips size for us to be no
* larger than the max. available size if a segment at the end is requested */
if (offset + size > gst_buffer_get_size (src->buffer)) {
ret = GST_FLOW_EOS;
} else if (*buf != NULL) {
GstMapInfo src_info;
GstMapInfo dest_info;
gsize fill_size;
gst_buffer_map (src->buffer, &src_info, GST_MAP_READ);
gst_buffer_map (*buf, &dest_info, GST_MAP_WRITE);
fill_size = gst_buffer_fill (*buf, 0, src_info.data + offset, size);
gst_buffer_unmap (*buf, &dest_info);
gst_buffer_unmap (src->buffer, &src_info);
gst_buffer_set_size (*buf, fill_size);
ret = GST_FLOW_OK;
} else {
*buf =
gst_buffer_copy_region (src->buffer, GST_BUFFER_COPY_ALL, offset, size);
ret = GST_FLOW_OK;
}
GST_OBJECT_UNLOCK (src);
return ret;
/* ERRORS */
no_buffer:
{
GST_OBJECT_UNLOCK (src);
GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL), (NULL));
return GST_FLOW_NOT_NEGOTIATED;
}
}
static gboolean
gst_data_uri_src_start (GstBaseSrc * basesrc)
{
GstDataURISrc *src = GST_DATA_URI_SRC (basesrc);
GST_OBJECT_LOCK (src);
if (src->uri == NULL || *src->uri == '\0' || src->buffer == NULL)
goto no_uri;
GST_OBJECT_UNLOCK (src);
return TRUE;
/* ERRORS */
no_uri:
{
GST_OBJECT_UNLOCK (src);
GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
("No valid data URI specified, or the data URI could not be parsed."),
("%s", src->uri));
return FALSE;
}
}
static GstURIType
gst_data_uri_src_get_uri_type (GType type)
{
return GST_URI_SRC;
}
static const gchar *const *
gst_data_uri_src_get_protocols (GType type)
{
static const gchar *protocols[] = { "data", 0 };
return protocols;
}
static gchar *
gst_data_uri_src_get_uri (GstURIHandler * handler)
{
GstDataURISrc *src = GST_DATA_URI_SRC (handler);
gchar *src_uri = NULL;
GST_OBJECT_LOCK (src);
src_uri = g_strdup (src->uri);
GST_OBJECT_UNLOCK (src);
return src_uri;
}
static gboolean
gst_data_uri_src_set_uri (GstURIHandler * handler, const gchar * uri,
GError ** error)
{
GstDataURISrc *src = GST_DATA_URI_SRC (handler);
gboolean ret = FALSE;
gchar *mimetype = NULL;
const gchar *parameters_start;
const gchar *data_start;
const gchar *orig_uri = uri;
GstCaps *caps;
GstBuffer *buffer;
gboolean base64 = FALSE;
gchar *charset = NULL;
gpointer bdata;
gsize bsize;
GST_OBJECT_LOCK (src);
if (GST_STATE (src) >= GST_STATE_PAUSED)
goto wrong_state;
GST_OBJECT_UNLOCK (src);
/* uri must be an URI as defined in RFC 2397
* data:[<mediatype>][;base64],<data>
*/
if (strncmp ("data:", uri, 5) != 0)
goto invalid_uri;
uri += 5;
parameters_start = strchr (uri, ';');
data_start = strchr (uri, ',');
if (data_start == NULL)
goto invalid_uri;
if (data_start != uri && parameters_start != uri)
mimetype =
g_strndup (uri,
(parameters_start ? parameters_start : data_start) - uri);
else
mimetype = g_strdup ("text/plain");
GST_DEBUG_OBJECT (src, "Mimetype: %s", mimetype);
if (parameters_start != NULL) {
gchar **walk;
gchar *parameters =
g_strndup (parameters_start + 1, data_start - parameters_start - 1);
gchar **parameters_strv;
parameters_strv = g_strsplit (parameters, ";", -1);
GST_DEBUG_OBJECT (src, "Parameters: ");
walk = parameters_strv;
while (*walk) {
GST_DEBUG_OBJECT (src, "\t %s", *walk);
if (strcmp ("base64", *walk) == 0) {
base64 = TRUE;
} else if (strncmp ("charset=", *walk, 8) == 0) {
charset = g_strdup (*walk + 8);
}
walk++;
}
g_free (parameters);
g_strfreev (parameters_strv);
}
/* Skip comma */
data_start += 1;
if (base64) {
bdata = g_base64_decode (data_start, &bsize);
} else {
/* URI encoded, i.e. "percent" encoding */
bdata = g_uri_unescape_string (data_start, NULL);
if (bdata == NULL)
goto invalid_uri_encoded_data;
bsize = strlen (bdata) + 1;
}
/* Convert to UTF8 */
if (strcmp ("text/plain", mimetype) == 0 &&
charset && g_ascii_strcasecmp ("US-ASCII", charset) != 0
&& g_ascii_strcasecmp ("UTF-8", charset) != 0) {
gsize read;
gsize written;
gpointer data;
data =
g_convert_with_fallback (bdata, -1, "UTF-8", charset, (char *) "*",
&read, &written, NULL);
g_free (bdata);
bdata = data;
bsize = written;
}
buffer = gst_buffer_new_wrapped (bdata, bsize);
caps = gst_type_find_helper_for_buffer (GST_OBJECT (src), buffer, NULL);
if (!caps)
caps = gst_caps_new_empty_simple (mimetype);
gst_base_src_set_caps (GST_BASE_SRC_CAST (src), caps);
gst_caps_unref (caps);
GST_OBJECT_LOCK (src);
gst_buffer_replace (&src->buffer, buffer);
gst_buffer_unref (buffer);
g_free (src->uri);
src->uri = g_strdup (orig_uri);
GST_OBJECT_UNLOCK (src);
ret = TRUE;
out:
g_free (mimetype);
g_free (charset);
return ret;
wrong_state:
{
GST_WARNING_OBJECT (src, "Can't set URI in %s state",
gst_element_state_get_name (GST_STATE (src)));
GST_OBJECT_UNLOCK (src);
g_set_error (error, GST_URI_ERROR, GST_URI_ERROR_BAD_STATE,
"Changing the 'uri' property on dataurisrc while it is running "
"is not supported");
goto out;
}
invalid_uri:
{
GST_WARNING_OBJECT (src, "invalid URI '%s'", uri);
g_set_error (error, GST_URI_ERROR, GST_URI_ERROR_BAD_URI,
"Invalid data URI");
goto out;
}
invalid_uri_encoded_data:
{
GST_WARNING_OBJECT (src, "Failed to parse data encoded in URI '%s'", uri);
g_set_error (error, GST_URI_ERROR, GST_URI_ERROR_BAD_URI,
"Could not parse data encoded in data URI");
goto out;
}
}
static void
gst_data_uri_src_handler_init (gpointer g_iface, gpointer iface_data)
{
GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
iface->get_type = gst_data_uri_src_get_uri_type;
iface->get_protocols = gst_data_uri_src_get_protocols;
iface->get_uri = gst_data_uri_src_get_uri;
iface->set_uri = gst_data_uri_src_set_uri;
}
static gboolean
plugin_init (GstPlugin * plugin)
{
return gst_element_register (plugin, "dataurisrc",
GST_RANK_PRIMARY, GST_TYPE_DATA_URI_SRC);
}
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
GST_VERSION_MINOR,
dataurisrc,
"data: URI source",
plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN);

View file

@ -0,0 +1,61 @@
/* GStreamer
*
* Copyright (C) 2009 Igalia S.L
* Copyright (C) 2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
*
* 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 St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef __GST_DATA_URI_SRC__
#define __GST_DATA_URI_SRC__
#include <gst/gst.h>
#include <gst/base/gstbasesrc.h>
G_BEGIN_DECLS
#define GST_TYPE_DATA_URI_SRC \
(gst_data_uri_src_get_type())
#define GST_DATA_URI_SRC(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DATA_URI_SRC,GstDataURISrc))
#define GST_DATA_URI_SRC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_DATA_URI_SRC,GstDataURISrcClass))
#define GST_IS_DATA_URI_SRC(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DATA_URI_SRC))
#define GST_IS_DATA_URI_SRC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_DATA_URI_SRC))
typedef struct _GstDataURISrc GstDataURISrc;
typedef struct _GstDataURISrcClass GstDataURISrcClass;
struct _GstDataURISrc
{
GstBaseSrc parent;
/* <private> */
gchar *uri;
GstBuffer *buffer;
};
struct _GstDataURISrcClass
{
GstBaseSrcClass parent_class;
};
GType gst_data_uri_src_get_type (void);
G_END_DECLS
#endif /* __GST_DATA_URI_SRC__ */

View file

@ -0,0 +1,233 @@
/* GStreamer unit test for dataurisrc
*
* Copyright (C) 2010 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 St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <unistd.h>
#include <gst/check/gstcheck.h>
/* sine wave encoded in ogg/vorbis, created with:
* gst-launch-1.0 audiotestsrc num-buffers=110 ! audioconvert ! \
* audio/x-raw,channels=1 ! vorbisenc ! oggmux ! \
* filesink location=sine.ogg
* and then encoded to base64 */
const gchar data_uri[] = "data:audio/ogg;base64,"
"T2dnUwACAAAAAAAAAACVWbd7AAAAAHgH02kBHgF2b3JiaXMAAAAAAUSsAAAAAAAAgDgBAAAAAAC4"
"AU9nZ1MAAAAAAAAAAAAAlVm3ewEAAADrU8FRDkv///////////////+BA3ZvcmJpcx0AAABYaXBo"
"Lk9yZyBsaWJWb3JiaXMgSSAyMDA5MDcwOQEAAAAaAAAAREVTQ1JJUFRJT049YXVkaW90ZXN0IHdh"
"dmUBBXZvcmJpcyJCQ1YBAEAAACRzGCpGpXMWhBAaQlAZ4xxCzmvsGUJMEYIcMkxbyyVzkCGkoEKI"
"WyiB0JBVAABAAACHQXgUhIpBCCGEJT1YkoMnPQghhIg5eBSEaUEIIYQQQgghhBBCCCGERTlokoMn"
"QQgdhOMwOAyD5Tj4HIRFOVgQgydB6CCED0K4moOsOQghhCQ1SFCDBjnoHITCLCiKgsQwuBaEBDUo"
"jILkMMjUgwtCiJqDSTX4GoRnQXgWhGlBCCGEJEFIkIMGQcgYhEZBWJKDBjm4FITLQagahCo5CB+E"
"IDRkFQCQAACgoiiKoigKEBqyCgDIAAAQQFEUx3EcyZEcybEcCwgNWQUAAAEACAAAoEiKpEiO5EiS"
"JFmSJVmSJVmS5omqLMuyLMuyLMsyEBqyCgBIAABQUQxFcRQHCA1ZBQBkAAAIoDiKpViKpWiK54iO"
"CISGrAIAgAAABAAAEDRDUzxHlETPVFXXtm3btm3btm3btm3btm1blmUZCA1ZBQBAAAAQ0mlmqQaI"
"MAMZBkJDVgEACAAAgBGKMMSA0JBVAABAAACAGEoOogmtOd+c46BZDppKsTkdnEi1eZKbirk555xz"
"zsnmnDHOOeecopxZDJoJrTnnnMSgWQqaCa0555wnsXnQmiqtOeeccc7pYJwRxjnnnCateZCajbU5"
"55wFrWmOmkuxOeecSLl5UptLtTnnnHPOOeecc84555zqxekcnBPOOeecqL25lpvQxTnnnE/G6d6c"
"EM4555xzzjnnnHPOOeecIDRkFQAABABAEIaNYdwpCNLnaCBGEWIaMulB9+gwCRqDnELq0ehopJQ6"
"CCWVcVJKJwgNWQUAAAIAQAghhRRSSCGFFFJIIYUUYoghhhhyyimnoIJKKqmooowyyyyzzDLLLLPM"
"Ouyssw47DDHEEEMrrcRSU2011lhr7jnnmoO0VlprrbVSSimllFIKQkNWAQAgAAAEQgYZZJBRSCGF"
"FGKIKaeccgoqqIDQkFUAACAAgAAAAABP8hzRER3RER3RER3RER3R8RzPESVREiVREi3TMjXTU0VV"
"dWXXlnVZt31b2IVd933d933d+HVhWJZlWZZlWZZlWZZlWZZlWZYgNGQVAAACAAAghBBCSCGFFFJI"
"KcYYc8w56CSUEAgNWQUAAAIACAAAAHAUR3EcyZEcSbIkS9IkzdIsT/M0TxM9URRF0zRV0RVdUTdt"
"UTZl0zVdUzZdVVZtV5ZtW7Z125dl2/d93/d93/d93/d93/d9XQdCQ1YBABIAADqSIymSIimS4ziO"
"JElAaMgqAEAGAEAAAIriKI7jOJIkSZIlaZJneZaomZrpmZ4qqkBoyCoAABAAQAAAAAAAAIqmeIqp"
"eIqoeI7oiJJomZaoqZoryqbsuq7ruq7ruq7ruq7ruq7ruq7ruq7ruq7ruq7ruq7ruq7ruq4LhIas"
"AgAkAAB0JEdyJEdSJEVSJEdygNCQVQCADACAAAAcwzEkRXIsy9I0T/M0TxM90RM901NFV3SB0JBV"
"AAAgAIAAAAAAAAAMybAUy9EcTRIl1VItVVMt1VJF1VNVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV"
"VVVVVVVVVVVN0zRNEwgNWQkAAAEA0FpzzK2XjkHorJfIKKSg10455qTXzCiCnOcQMWOYx1IxQwzG"
"lkGElAVCQ1YEAFEAAIAxyDHEHHLOSeokRc45Kh2lxjlHqaPUUUqxplo7SqW2VGvjnKPUUcoopVpL"
"qx2lVGuqsQAAgAAHAIAAC6HQkBUBQBQAAIEMUgophZRizinnkFLKOeYcYoo5p5xjzjkonZTKOSed"
"kxIppZxjzinnnJTOSeack9JJKAAAIMABACDAQig0ZEUAECcA4HAcTZM0TRQlTRNFTxRd1xNF1ZU0"
"zTQ1UVRVTRRN1VRVWRZNVZYlTTNNTRRVUxNFVRVVU5ZNVbVlzzRt2VRV3RZV1bZlW/Z9V5Z13TNN"
"2RZV1bZNVbV1V5Z1XbZt3Zc0zTQ1UVRVTRRV11RV2zZV1bY1UXRdUVVlWVRVWXZdWddVV9Z9TRRV"
"1VNN2RVVVZZV2dVlVZZ1X3RV3VZd2ddVWdZ929aFX9Z9wqiqum7Krq6rsqz7si77uu3rlEnTTFMT"
"RVXVRFFVTVe1bVN1bVsTRdcVVdWWRVN1ZVWWfV91ZdnXRNF1RVWVZVFVZVmVZV13ZVe3RVXVbVV2"
"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";
GST_START_TEST (test_playbin)
{
GstElement *playbin, *sink;
int loops = 2;
playbin = gst_element_factory_make ("playbin", NULL);
sink = gst_element_factory_make ("fakesink", NULL);
if (playbin == NULL || sink == NULL) {
GST_WARNING ("skipping test, no playbin or fakesink element(s)");
return;
}
g_object_set (playbin, "uri", data_uri, "audio-sink", sink, NULL);
do {
GstMessage *msg;
/* not checking return val on purpose, should always get an error on bus */
gst_element_set_state (playbin, GST_STATE_PLAYING);
msg = gst_bus_timed_pop_filtered (GST_ELEMENT_BUS (playbin),
GST_CLOCK_TIME_NONE, GST_MESSAGE_EOS | GST_MESSAGE_ERROR);
GST_INFO ("message: %" GST_PTR_FORMAT, msg);
if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR) {
GError *err = NULL;
gst_message_parse_error (msg, &err, NULL);
fail_unless (err->code == GST_CORE_ERROR_MISSING_PLUGIN ||
err->code == GST_STREAM_ERROR_CODEC_NOT_FOUND,
"Got unexpected error: %s", err->message);
g_error_free (err);
}
gst_message_unref (msg);
gst_element_set_state (playbin, GST_STATE_NULL);
--loops;
GST_INFO ("done, %d rounds left", loops);
} while (loops > 0);
gst_element_set_state (playbin, GST_STATE_NULL);
gst_object_unref (playbin);
}
GST_END_TEST;
static Suite *
dataurisrc_suite (void)
{
Suite *s = suite_create ("dataurisrc");
TCase *tc_chain = tcase_create ("general");
suite_add_tcase (s, tc_chain);
tcase_add_test (tc_chain, test_playbin);
return s;
}
GST_CHECK_MAIN (dataurisrc);