API: add TOC support (video chapters)

This commit is contained in:
Rafał Dzięgiel
2021-01-27 23:37:33 +01:00
parent 5cc312130d
commit 3abfd2a5df
4 changed files with 69 additions and 11 deletions

View File

@@ -100,6 +100,7 @@ struct _GstClapperMediaInfo
gchar *container;
gboolean seekable, is_live;
GstTagList *tags;
GstToc *toc;
GstSample *image_sample;
GList *stream_list;

View File

@@ -423,26 +423,21 @@ gst_clapper_media_info_finalize (GObject * object)
GstClapperMediaInfo *info = GST_CLAPPER_MEDIA_INFO (object);
g_free (info->uri);
g_free (info->title);
g_free (info->container);
if (info->tags)
gst_tag_list_unref (info->tags);
g_free (info->title);
g_free (info->container);
if (info->toc)
gst_toc_unref (info->toc);
if (info->image_sample)
gst_sample_unref (info->image_sample);
if (info->audio_stream_list)
g_list_free (info->audio_stream_list);
if (info->video_stream_list)
g_list_free (info->video_stream_list);
if (info->subtitle_stream_list)
g_list_free (info->subtitle_stream_list);
if (info->stream_list)
g_list_free_full (info->stream_list, g_object_unref);
@@ -567,6 +562,8 @@ gst_clapper_media_info_copy (GstClapperMediaInfo * ref)
info->is_live = ref->is_live;
if (ref->tags)
info->tags = gst_tag_list_ref (ref->tags);
if (ref->toc)
info->toc = gst_toc_ref (ref->toc);
if (ref->title)
info->title = g_strdup (ref->title);
if (ref->container)
@@ -752,6 +749,20 @@ gst_clapper_media_info_get_tags (const GstClapperMediaInfo * info)
return info->tags;
}
/**
* gst_clapper_media_info_get_toc:
* @info: a #GstClapperMediaInfo
*
* Returns: (transfer none): the toc contained in media info.
*/
GstToc *
gst_clapper_media_info_get_toc (const GstClapperMediaInfo * info)
{
g_return_val_if_fail (GST_IS_CLAPPER_MEDIA_INFO (info), NULL);
return info->toc;
}
/**
* gst_clapper_media_info_get_title:
* @info: a #GstClapperMediaInfo

View File

@@ -233,6 +233,9 @@ guint gst_clapper_media_info_get_number_of_subtitle_streams (const GstCl
GST_CLAPPER_API
GstTagList * gst_clapper_media_info_get_tags (const GstClapperMediaInfo *info);
GST_CLAPPER_API
GstToc * gst_clapper_media_info_get_toc (const GstClapperMediaInfo *info);
GST_CLAPPER_API
const gchar * gst_clapper_media_info_get_title (const GstClapperMediaInfo *info);

View File

@@ -170,6 +170,7 @@ struct _GstClapper
gint buffering;
GstTagList *global_tags;
GstToc *global_toc;
GstClapperMediaInfo *media_info;
GstElement *current_vis_element;
@@ -530,6 +531,8 @@ gst_clapper_finalize (GObject * object)
g_free (self->subtitle_sid);
if (self->global_tags)
gst_tag_list_unref (self->global_tags);
if (self->global_toc)
gst_toc_unref (self->global_toc);
if (self->video_renderer)
g_object_unref (self->video_renderer);
if (self->signal_dispatcher)
@@ -1102,12 +1105,14 @@ emit_error (GstClapper * self, GError * err)
g_object_unref (self->media_info);
self->media_info = NULL;
}
if (self->global_tags) {
gst_tag_list_unref (self->global_tags);
self->global_tags = NULL;
}
if (self->global_toc) {
gst_toc_unref (self->global_toc);
self->global_toc = NULL;
}
self->seek_pending = FALSE;
remove_seek_source (self);
self->seek_position = GST_CLOCK_TIME_NONE;
@@ -1807,6 +1812,37 @@ tags_cb (G_GNUC_UNUSED GstBus * bus, GstMessage * msg, gpointer user_data)
gst_tag_list_unref (tags);
}
static void
toc_cb (G_GNUC_UNUSED GstBus * bus, GstMessage * msg, gpointer user_data)
{
GstClapper *self = GST_CLAPPER (user_data);
GstToc *toc = NULL;
gst_message_parse_toc (msg, &toc, NULL);
GST_DEBUG_OBJECT (self, "received %s toc",
gst_toc_get_scope (toc) == GST_TOC_SCOPE_GLOBAL ? "global" : "stream");
if (gst_toc_get_scope (toc) == GST_TOC_SCOPE_GLOBAL) {
g_mutex_lock (&self->lock);
if (self->media_info) {
if (self->media_info->toc)
gst_toc_unref (self->media_info->toc);
self->media_info->toc = gst_toc_ref (toc);
media_info_update (self, self->media_info);
g_mutex_unlock (&self->lock);
emit_media_info_updated_signal (self);
} else {
if (self->global_toc)
gst_toc_unref (self->global_toc);
self->global_toc = gst_toc_ref (toc);
g_mutex_unlock (&self->lock);
}
}
gst_toc_unref (toc);
}
static void
element_cb (G_GNUC_UNUSED GstBus * bus, GstMessage * msg, gpointer user_data)
{
@@ -2731,8 +2767,10 @@ gst_clapper_media_info_create (GstClapper * self)
media_info = gst_clapper_media_info_new (self->uri);
media_info->duration = gst_clapper_get_duration (self);
media_info->tags = self->global_tags;
media_info->toc = self->global_toc;
media_info->is_live = self->is_live;
self->global_tags = NULL;
self->global_toc = NULL;
query = gst_query_new_seeking (GST_FORMAT_TIME);
if (gst_element_query (self->playbin, query))
@@ -2953,6 +2991,7 @@ gst_clapper_main (gpointer data)
g_signal_connect (G_OBJECT (bus), "message::element",
G_CALLBACK (element_cb), self);
g_signal_connect (G_OBJECT (bus), "message::tag", G_CALLBACK (tags_cb), self);
g_signal_connect (G_OBJECT (bus), "message::toc", G_CALLBACK (toc_cb), self);
if (self->use_playbin3) {
g_signal_connect (G_OBJECT (bus), "message::stream-collection",
@@ -3256,6 +3295,10 @@ gst_clapper_stop_internal (GstClapper * self, gboolean transient)
gst_tag_list_unref (self->global_tags);
self->global_tags = NULL;
}
if (self->global_toc) {
gst_toc_unref (self->global_toc);
self->global_toc = NULL;
}
self->seek_pending = FALSE;
remove_seek_source (self);
self->seek_position = GST_CLOCK_TIME_NONE;