From: Alex Ashley Date: Fri, 19 Jul 2013 14:30:42 +0000 (+0100) Subject: hls: fix for assert failure when using encrypted HLS streams X-Git-Tag: 1.1.3~51 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ed16c9c560afb5feac1632a33e4d7fbde621eca0;p=platform%2Fupstream%2Fgst-plugins-bad.git hls: fix for assert failure when using encrypted HLS streams When using an HLS encrypted stream, an assertion failure is thrown: (gst-launch-1.0:31028): GLib-GObject-WARNING **: cannot register existing type `GstFragment' (gst-launch-1.0:31028): GLib-CRITICAL **: g_once_init_leave: assertion `result != 0' failed Eventually tracked this down to the call gst_fragment_new() in function gst_hls_demux_decrypt_fragment. The GstFragment class is defined in ext/hls/gstfragment.c and in gst-libs/gst/uridownloader/gstfragment.c. Having two class definitions with the same name causes the assert failure when trying to allocate GstFragment. Deleting the version from hls and editing the Makefile.am solves this assert failure. https://bugzilla.gnome.org/show_bug.cgi?id=704555 --- diff --git a/ext/hls/Makefile.am b/ext/hls/Makefile.am index 573b67b..508c775 100644 --- a/ext/hls/Makefile.am +++ b/ext/hls/Makefile.am @@ -4,7 +4,6 @@ plugin_LTLIBRARIES = libgstfragmented.la libgstfragmented_la_SOURCES = \ m3u8.c \ gsthlsdemux.c \ - gstfragment.c \ gstfragmentedplugin.c \ gsthlssink.c \ gstm3u8playlist.c @@ -20,7 +19,6 @@ libgstfragmented_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS) # headers we need but don't want installed noinst_HEADERS = \ gstfragmented.h \ - gstfragment.h \ gsthlsdemux.h \ gsthlssink.h \ gstm3u8playlist.h \ diff --git a/ext/hls/gstfragment.c b/ext/hls/gstfragment.c deleted file mode 100644 index 77f9e29..0000000 --- a/ext/hls/gstfragment.c +++ /dev/null @@ -1,264 +0,0 @@ -/* GStreamer - * Copyright (C) 2011 Andoni Morales Alastruey - * - * gstfragment.c: - * - * 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 -#include -#include "gstfragmented.h" -#include "gstfragment.h" - -#define GST_CAT_DEFAULT fragmented_debug - -#define GST_FRAGMENT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_FRAGMENT, GstFragmentPrivate)) - -enum -{ - PROP_0, - PROP_INDEX, - PROP_NAME, - PROP_DURATION, - PROP_DISCONTINOUS, - PROP_BUFFER, - PROP_CAPS, - PROP_LAST -}; - -struct _GstFragmentPrivate -{ - GstBuffer *buffer; - GstCaps *caps; - GMutex lock; -}; - -G_DEFINE_TYPE (GstFragment, gst_fragment, G_TYPE_OBJECT); - -static void gst_fragment_dispose (GObject * object); -static void gst_fragment_finalize (GObject * object); - -static void -gst_fragment_set_property (GObject * object, - guint property_id, const GValue * value, GParamSpec * pspec) -{ - GstFragment *fragment = GST_FRAGMENT (object); - - switch (property_id) { - case PROP_CAPS: - gst_fragment_set_caps (fragment, g_value_get_boxed (value)); - break; - - default: - /* We don't have any other property... */ - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -gst_fragment_get_property (GObject * object, - guint property_id, GValue * value, GParamSpec * pspec) -{ - GstFragment *fragment = GST_FRAGMENT (object); - - switch (property_id) { - case PROP_INDEX: - g_value_set_uint (value, fragment->index); - break; - - case PROP_NAME: - g_value_set_string (value, fragment->name); - break; - - case PROP_DURATION: - g_value_set_uint64 (value, fragment->stop_time - fragment->start_time); - break; - - case PROP_DISCONTINOUS: - g_value_set_boolean (value, fragment->discontinuous); - break; - - case PROP_BUFFER: - g_value_set_boxed (value, gst_fragment_get_buffer (fragment)); - break; - - case PROP_CAPS: - g_value_set_boxed (value, gst_fragment_get_caps (fragment)); - break; - - default: - /* We don't have any other property... */ - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - - - -static void -gst_fragment_class_init (GstFragmentClass * klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (GstFragmentPrivate)); - - gobject_class->set_property = gst_fragment_set_property; - gobject_class->get_property = gst_fragment_get_property; - gobject_class->dispose = gst_fragment_dispose; - gobject_class->finalize = gst_fragment_finalize; - - g_object_class_install_property (gobject_class, PROP_INDEX, - g_param_spec_uint ("index", "Index", "Index of the fragment", 0, - G_MAXUINT, 0, G_PARAM_READABLE)); - - g_object_class_install_property (gobject_class, PROP_NAME, - g_param_spec_string ("name", "Name", - "Name of the fragment (eg:fragment-12.ts)", NULL, G_PARAM_READABLE)); - - g_object_class_install_property (gobject_class, PROP_DISCONTINOUS, - g_param_spec_boolean ("discontinuous", "Discontinous", - "Whether this fragment has a discontinuity or not", - FALSE, G_PARAM_READABLE)); - - g_object_class_install_property (gobject_class, PROP_DURATION, - g_param_spec_uint64 ("duration", "Fragment duration", - "Duration of the fragment", 0, G_MAXUINT64, 0, G_PARAM_READABLE)); - - g_object_class_install_property (gobject_class, PROP_BUFFER, - g_param_spec_boxed ("buffer", "Buffer", - "The fragment's buffer", GST_TYPE_BUFFER, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, PROP_CAPS, - g_param_spec_boxed ("caps", "Fragment caps", - "The caps of the fragment's buffer. (NULL = detect)", GST_TYPE_CAPS, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); -} - -static void -gst_fragment_init (GstFragment * fragment) -{ - GstFragmentPrivate *priv; - - fragment->priv = priv = GST_FRAGMENT_GET_PRIVATE (fragment); - - g_mutex_init (&fragment->priv->lock); - priv->buffer = NULL; - fragment->download_start_time = gst_util_get_timestamp (); - fragment->start_time = 0; - fragment->stop_time = 0; - fragment->index = 0; - fragment->name = g_strdup (""); - fragment->completed = FALSE; - fragment->discontinuous = FALSE; -} - -GstFragment * -gst_fragment_new (void) -{ - return GST_FRAGMENT (g_object_new (GST_TYPE_FRAGMENT, NULL)); -} - -static void -gst_fragment_finalize (GObject * gobject) -{ - GstFragment *fragment = GST_FRAGMENT (gobject); - - g_free (fragment->name); - g_mutex_clear (&fragment->priv->lock); - - G_OBJECT_CLASS (gst_fragment_parent_class)->finalize (gobject); -} - -void -gst_fragment_dispose (GObject * object) -{ - GstFragmentPrivate *priv = GST_FRAGMENT (object)->priv; - - if (priv->buffer != NULL) { - gst_buffer_unref (priv->buffer); - priv->buffer = NULL; - } - - if (priv->caps != NULL) { - gst_caps_unref (priv->caps); - priv->caps = NULL; - } - - G_OBJECT_CLASS (gst_fragment_parent_class)->dispose (object); -} - -GstBuffer * -gst_fragment_get_buffer (GstFragment * fragment) -{ - g_return_val_if_fail (fragment != NULL, NULL); - - if (!fragment->completed) - return NULL; - - gst_buffer_ref (fragment->priv->buffer); - return fragment->priv->buffer; -} - -void -gst_fragment_set_caps (GstFragment * fragment, GstCaps * caps) -{ - g_return_if_fail (fragment != NULL); - - g_mutex_lock (&fragment->priv->lock); - gst_caps_replace (&fragment->priv->caps, caps); - g_mutex_unlock (&fragment->priv->lock); -} - -GstCaps * -gst_fragment_get_caps (GstFragment * fragment) -{ - g_return_val_if_fail (fragment != NULL, NULL); - - if (!fragment->completed) - return NULL; - - g_mutex_lock (&fragment->priv->lock); - if (fragment->priv->caps == NULL) - fragment->priv->caps = - gst_type_find_helper_for_buffer (NULL, fragment->priv->buffer, NULL); - gst_caps_ref (fragment->priv->caps); - g_mutex_unlock (&fragment->priv->lock); - - return fragment->priv->caps; -} - -gboolean -gst_fragment_add_buffer (GstFragment * fragment, GstBuffer * buffer) -{ - g_return_val_if_fail (fragment != NULL, FALSE); - g_return_val_if_fail (buffer != NULL, FALSE); - - if (fragment->completed) { - GST_WARNING ("Fragment is completed, could not add more buffers"); - return FALSE; - } - - GST_DEBUG ("Adding new buffer to the fragment"); - /* We steal the buffers you pass in */ - if (fragment->priv->buffer == NULL) - fragment->priv->buffer = buffer; - else - fragment->priv->buffer = gst_buffer_append (fragment->priv->buffer, buffer); - return TRUE; -} diff --git a/ext/hls/gstfragment.h b/ext/hls/gstfragment.h deleted file mode 100644 index d7292b4..0000000 --- a/ext/hls/gstfragment.h +++ /dev/null @@ -1,70 +0,0 @@ -/* GStreamer - * Copyright (C) 2011 Andoni Morales Alastruey - * - * gstfragment.h: - * - * 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 __GSTFRAGMENT_H__ -#define __GSTFRAGMENT_H__ - -#include -#include - -G_BEGIN_DECLS - -#define GST_TYPE_FRAGMENT (gst_fragment_get_type()) -#define GST_FRAGMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_FRAGMENT,GstFragment)) -#define GST_FRAGMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FRAGMENT,GstFragmentClass)) -#define GST_IS_FRAGMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FRAGMENT)) -#define GST_IS_FRAGMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FRAGMENT)) - -typedef struct _GstFragment GstFragment; -typedef struct _GstFragmentPrivate GstFragmentPrivate; -typedef struct _GstFragmentClass GstFragmentClass; - -struct _GstFragment -{ - GObject parent; - - gchar * name; /* Name of the fragment */ - gboolean completed; /* Whether the fragment is complete or not */ - guint64 download_start_time; /* Epoch time when the download started */ - guint64 download_stop_time; /* Epoch time when the download finished */ - guint64 start_time; /* Start time of the fragment */ - guint64 stop_time; /* Stop time of the fragment */ - gboolean index; /* Index of the fragment */ - gboolean discontinuous; /* Whether this fragment is discontinuous or not */ - - GstFragmentPrivate *priv; -}; - -struct _GstFragmentClass -{ - GObjectClass parent_class; -}; - -GType gst_fragment_get_type (void); - -GstBuffer * gst_fragment_get_buffer (GstFragment *fragment); -void gst_fragment_set_caps (GstFragment * fragment, GstCaps * caps); -GstCaps * gst_fragment_get_caps (GstFragment * fragment); -gboolean gst_fragment_add_buffer (GstFragment *fragment, GstBuffer *buffer); -GstFragment * gst_fragment_new (void); - -G_END_DECLS -#endif /* __GSTFRAGMENT_H__ */