Commit d82ae694 authored by Chris Bass's avatar Chris Bass Committed by Sebastian Dröge

ttml: Add plugin that supports TTML subtitles

Add a parser (ttmlparse) and renderer (ttmlrender) element that handle
subtitles that use the EBU-TT-D profile of TTML1.

https://bugzilla.gnome.org/show_bug.cgi?id=758232
parent 280b4ac2
......@@ -2456,6 +2456,16 @@ AG_GST_CHECK_FEATURE(DTLS, [DTLS plugin], dtls, [
])
])
dnl *** ttml ***
translit(dnm, m, l) AM_CONDITIONAL(USE_TTML, true)
AG_GST_CHECK_FEATURE(TTML, [TTML plugin], ttml, [
PKG_CHECK_MODULES(TTML, [ libxml-2.0 pango cairo pangocairo ], [
HAVE_TTML="yes"
], [
HAVE_TTML="no"
])
])
dnl *** linsys ***
translit(dnm, m, l) AM_CONDITIONAL(USE_LINSYS, true)
AG_GST_CHECK_FEATURE(LINSYS, [Linear Systems SDI plugin], linsys, [
......@@ -3529,6 +3539,7 @@ AM_CONDITIONAL(USE_OPENH264, false)
AM_CONDITIONAL(USE_X265, false)
AM_CONDITIONAL(USE_DTLS, false)
AM_CONDITIONAL(USE_VULKAN, false)
AM_CONDITIONAL(USE_TTML, false)
fi dnl of EXT plugins
......@@ -3841,6 +3852,7 @@ ext/xvid/Makefile
ext/zbar/Makefile
ext/dtls/Makefile
ext/webrtcdsp/Makefile
ext/ttml/Makefile
po/Makefile.in
docs/Makefile
docs/plugins/Makefile
......
......@@ -152,6 +152,8 @@
<xi:include href="xml/element-wavescope.xml" />
<xi:include href="xml/element-webrtcdsp.xml" />
<xi:include href="xml/element-webrtcechoprobe.xml" />
<xi:include href="xml/element-ttmlparse.xml" />
<xi:include href="xml/element-ttmlrender.xml" />
</chapter>
<chapter>
......@@ -203,5 +205,6 @@
<xi:include href="xml/plugin-voamrwbenc.xml" />
<xi:include href="xml/plugin-webrtcdsp.xml" />
<xi:include href="xml/plugin-zbar.xml" />
<xi:include href="xml/plugin-ttmlsubs.xml" />
</chapter>
</book>
......@@ -4805,3 +4805,22 @@ GST_TYPE_FFECTS_XRAY
gst_ffects_xray_get_type
</SECTION>
<SECTION>
<FILE>element-ttmlparse</FILE>
<TITLE>ttmlparse</TITLE>
GstTtmlParse
<SUBSECTION Standard>
GstTtmlParseClass
GST_TYPE_TTML_PARSE
gst_ttml_parse_get_type
</SECTION>
<SECTION>
<FILE>element-ttmlrender</FILE>
<TITLE>ttmlrender</TITLE>
GstTtmlRender
<SUBSECTION Standard>
GstTtmlRenderClass
GST_TYPE_TTML_RENDER
gst_ttml_render_get_type
</SECTION>
<plugin>
<name>ttmlsubs</name>
<description>TTML subtitle handling</description>
<filename>../../ext/ttml/.libs/libgstttmlsubs.so</filename>
<basename>libgstttmlsubs.so</basename>
<version>1.9.90</version>
<license>LGPL</license>
<source>gst-plugins-bad</source>
<package>gst-ttml</package>
<origin>http://www.bbc.co.uk/rd</origin>
<elements>
<element>
<name>ttmlparse</name>
<longname>TTML subtitle parser</longname>
<class>Codec/Parser/Subtitle</class>
<description>Parses TTML subtitle files</description>
<author>GStreamer maintainers &lt;gstreamer-devel@lists.sourceforge.net&gt;, Chris Bass &lt;dash@rd.bbc.co.uk&gt;</author>
<pads>
<caps>
<name>sink</name>
<direction>sink</direction>
<presence>always</presence>
<details>application/ttml+xml</details>
</caps>
<caps>
<name>src</name>
<direction>source</direction>
<presence>always</presence>
<details>text/x-raw(meta:GstSubtitleMeta)</details>
</caps>
</pads>
</element>
<element>
<name>ttmlrender</name>
<longname>TTML subtitle renderer</longname>
<class>Overlay/Subtitle</class>
<description>Renders timed-text subtitles on top of video buffers</description>
<author>David Schleef &lt;ds@schleef.org&gt;, Zeeshan Ali &lt;zeeshan.ali@nokia.com&gt;, Chris Bass &lt;dash@rd.bbc.co.uk&gt;</author>
<pads>
<caps>
<name>text_sink</name>
<direction>sink</direction>
<presence>always</presence>
<details>text/x-raw(meta:GstSubtitleMeta)</details>
</caps>
<caps>
<name>video_sink</name>
<direction>sink</direction>
<presence>always</presence>
<details>video/x-raw, format=(string){ BGRx, RGBx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, I420, YV12, AYUV, YUY2, UYVY, v308, Y41B, Y42B, Y444, NV12, NV21, A420, YUV9, YVU9, IYU1, GRAY8 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, IYU2, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE, P010_10LE, P010_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
</caps>
<caps>
<name>src</name>
<direction>source</direction>
<presence>always</presence>
<details>video/x-raw, format=(string){ BGRx, RGBx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, I420, YV12, AYUV, YUY2, UYVY, v308, Y41B, Y42B, Y444, NV12, NV21, A420, YUV9, YVU9, IYU1, GRAY8 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, IYU2, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE, P010_10LE, P010_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
</caps>
</pads>
</element>
</elements>
</plugin>
\ No newline at end of file
......@@ -424,6 +424,12 @@ else
WEBRTCDSP_DIR=
endif
if USE_TTML
TTML_DIR=ttml
else
TTML_DIR=
endif
SUBDIRS=\
$(VOAACENC_DIR) \
$(ASSRENDER_DIR) \
......@@ -495,7 +501,8 @@ SUBDIRS=\
$(X265_DIR) \
$(DTLS_DIR) \
$(VULKAN_DIR) \
$(WEBRTCDSP_DIR)
$(WEBRTCDSP_DIR) \
$(TTML_DIR)
DIST_SUBDIRS = \
assrender \
......@@ -565,6 +572,7 @@ DIST_SUBDIRS = \
x265 \
dtls \
vulkan \
webrtcdsp
webrtcdsp \
ttml
include $(top_srcdir)/common/parallel-subdirs.mak
plugin_LTLIBRARIES = libgstttmlsubs.la
# sources used to compile this plug-in
libgstttmlsubs_la_SOURCES = \
subtitle.c \
subtitlemeta.c \
gstttmlparse.c \
gstttmlparse.h \
ttmlparse.c \
ttmlparse.h \
gstttmlrender.c \
gstttmlplugin.c
# compiler and linker flags used to compile this plugin, set in configure.ac
libgstttmlsubs_la_CFLAGS = \
$(GST_PLUGINS_BASE_CFLAGS) \
$(GST_BASE_CFLAGS) \
$(GST_CFLAGS) \
$(TTML_CFLAGS)
libgstttmlsubs_la_LIBADD = \
$(GST_BASE_LIBS) \
$(GST_LIBS) \
-lgstvideo-$(GST_API_VERSION) \
$(TTML_LIBS)
libgstttmlsubs_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstttmlsubs_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
# headers we need but don't want installed
noinst_HEADERS = \
subtitle.h \
subtitlemeta.h \
gstttmlparse.h \
ttmlparse.h \
gstttmlrender.h
This diff is collapsed.
/* GStreamer
* Copyright (C) <2002> David A. Schleef <ds@schleef.org>
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
* Copyright (C) <2015> British Broadcasting Corporation
*
* 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_TTML_PARSE_H__
#define __GST_TTML_PARSE_H__
#include <gst/gst.h>
#include <gst/base/gstadapter.h>
G_BEGIN_DECLS
#define GST_TYPE_TTML_PARSE \
(gst_ttml_parse_get_type ())
#define GST_TTML_PARSE(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_TTML_PARSE, GstTtmlParse))
#define GST_TTML_PARSE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_TTML_PARSE, GstTtmlParseClass))
#define GST_IS_TTML_PARSE(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TTML_PARSE))
#define GST_IS_TTML_PARSE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_TTML_PARSE))
typedef struct _GstTtmlParse GstTtmlParse;
typedef struct _GstTtmlParseClass GstTtmlParseClass;
struct _GstTtmlParse {
GstElement element;
GstPad *sinkpad, *srcpad;
/* contains the input in the input encoding */
GstAdapter *adapter;
/* contains the UTF-8 decoded input */
GString *textbuf;
/* seek */
guint64 offset;
/* Segment */
GstSegment segment;
gboolean need_segment;
gboolean valid_utf8;
gchar *detected_encoding;
gchar *encoding;
gboolean first_buffer;
};
struct _GstTtmlParseClass {
GstElementClass parent_class;
};
GType gst_ttml_parse_get_type (void);
G_END_DECLS
#endif /* __GST_TTML_PARSE_H__ */
/* GStreamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
* Copyright (C) 2004 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
* Copyright (C) 2006 Tim-Philipp Müller <tim centricular net>
* Copyright (C) <2015> British Broadcasting Corporation <dash@rd.bbc.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.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "gstttmlparse.h"
#include "gstttmlrender.h"
GST_DEBUG_CATEGORY (ttmlparse_debug);
GST_DEBUG_CATEGORY (ttmlrender_debug);
static gboolean
plugin_init (GstPlugin * plugin)
{
if (!gst_element_register (plugin, "ttmlparse", GST_RANK_PRIMARY,
GST_TYPE_TTML_PARSE))
return FALSE;
if (!gst_element_register (plugin, "ttmlrender", GST_RANK_PRIMARY,
GST_TYPE_TTML_RENDER))
return FALSE;
GST_DEBUG_CATEGORY_INIT (ttmlparse_debug, "ttmlparse", 0, "TTML parser");
GST_DEBUG_CATEGORY_INIT (ttmlrender_debug, "ttmlrender", 0, "TTML renderer");
return TRUE;
}
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
GST_VERSION_MINOR,
ttmlsubs,
"TTML subtitle handling",
plugin_init, VERSION, "LGPL", "gst-ttml", "http://www.bbc.co.uk/rd")
This diff is collapsed.
/* GStreamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
* Copyright (C) <2003> David Schleef <ds@schleef.org>
* Copyright (C) <2006> Julien Moutte <julien@moutte.net>
* Copyright (C) <2006> Zeeshan Ali <zeeshan.ali@nokia.com>
* Copyright (C) <2006-2008> Tim-Philipp Müller <tim centricular net>
* Copyright (C) <2009> Young-Ho Cha <ganadist@gmail.com>
* Copyright (C) <2015> British Broadcasting Corporation <dash@rd.bbc.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_TTML_RENDER_H__
#define __GST_TTML_RENDER_H__
#include <gst/gst.h>
#include <gst/video/video.h>
#include <pango/pango.h>
G_BEGIN_DECLS
#define GST_TYPE_TTML_RENDER (gst_ttml_render_get_type())
#define GST_TTML_RENDER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),\
GST_TYPE_TTML_RENDER, GstTtmlRender))
#define GST_TTML_RENDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),\
GST_TYPE_TTML_RENDER, \
GstTtmlRenderClass))
#define GST_TTML_RENDER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),\
GST_TYPE_TTML_RENDER, \
GstTtmlRenderClass))
#define GST_IS_TTML_RENDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),\
GST_TYPE_TTML_RENDER))
#define GST_IS_TTML_RENDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),\
GST_TYPE_TTML_RENDER))
typedef struct _GstTtmlRender GstTtmlRender;
typedef struct _GstTtmlRenderClass GstTtmlRenderClass;
typedef struct _GstTtmlRenderRenderedImage GstTtmlRenderRenderedImage;
typedef struct _GstTtmlRenderRenderedText GstTtmlRenderRenderedText;
struct _GstTtmlRenderRenderedImage {
GstBuffer *image;
gint x;
gint y;
guint width;
guint height;
};
struct _GstTtmlRenderRenderedText {
GstTtmlRenderRenderedImage *text_image;
/* In order to get the positions of characters within a paragraph rendered by
* pango we need to retain a reference to the PangoLayout object that was
* used to render that paragraph. */
PangoLayout *layout;
/* The coordinates in @layout will be offset horizontally with respect to the
* position of those characters in @text_image. Store that offset here so
* that the information in @layout can be used to locate the position and
* extent of text areas in @text_image. */
guint horiz_offset;
};
struct _GstTtmlRender {
GstElement element;
GstPad *video_sinkpad;
GstPad *text_sinkpad;
GstPad *srcpad;
GstSegment segment;
GstSegment text_segment;
GstBuffer *text_buffer;
gboolean text_linked;
gboolean video_flushing;
gboolean video_eos;
gboolean text_flushing;
gboolean text_eos;
GMutex lock;
GCond cond; /* to signal removal of a queued text
* buffer, arrival of a text buffer,
* a text segment update, or a change
* in status (e.g. shutdown, flushing) */
GstVideoInfo info;
GstVideoFormat format;
gint width;
gint height;
gboolean want_background;
gboolean wait_text;
gboolean need_render;
GList * compositions;
};
struct _GstTtmlRenderClass {
GstElementClass parent_class;
PangoContext *pango_context;
GMutex *pango_lock;
};
GType gst_ttml_render_get_type(void) G_GNUC_CONST;
G_END_DECLS
#endif /* __GST_TTML_RENDER_H */
/* GStreamer
* Copyright (C) <2015> British Broadcasting Corporation
* Author: Chris Bass <dash@rd.bbc.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:gstsubtitle
* @short_description: Library for describing sets of static subtitles.
*
* This library enables the description of static text scenes made up of a
* number of regions, which may contain a number of block and inline text
* elements. It is derived from the concepts and features defined in the Timed
* Text Markup Language 1 (TTML1), Second Edition
* (http://www.w3.org/TR/ttaf1-dfxp), and the EBU-TT-D profile of TTML1
* (https://tech.ebu.ch/files/live/sites/tech/files/shared/tech/tech3380.pdf).
*/
#include "subtitle.h"
/**
* gst_subtitle_style_set_new:
*
* Create a new #GstSubtitleStyleSet with default values for all properties.
*
* Returns: (transfer full): A newly-allocated #GstSubtitleStyleSet.
*/
GstSubtitleStyleSet *
gst_subtitle_style_set_new (void)
{
GstSubtitleStyleSet *ret = g_slice_new0 (GstSubtitleStyleSet);
GstSubtitleColor white = { 255, 255, 255, 255 };
GstSubtitleColor transparent = { 0, 0, 0, 0 };
ret->font_family = g_strdup ("default");
ret->font_size = 1.0;
ret->line_height = 1.25;
ret->color = white;
ret->background_color = transparent;
ret->line_padding = 0.0;
ret->origin_x = ret->origin_y = 0.0;
ret->extent_w = ret->extent_h = 0.0;
ret->padding_start = ret->padding_end
= ret->padding_before = ret->padding_after = 0.0;
return ret;
}
/**
* gst_subtitle_style_set_free:
* @style_set: A #GstSubtitleStyleSet.
*
* Free @style_set and its associated memory.
*/
void
gst_subtitle_style_set_free (GstSubtitleStyleSet * style_set)
{
g_return_if_fail (style_set != NULL);
g_free (style_set->font_family);
g_slice_free (GstSubtitleStyleSet, style_set);
}
static void
_gst_subtitle_element_free (GstSubtitleElement * element)
{
g_return_if_fail (element != NULL);
gst_subtitle_style_set_free (element->style_set);
g_slice_free (GstSubtitleElement, element);
}
GST_DEFINE_MINI_OBJECT_TYPE (GstSubtitleElement, gst_subtitle_element);
/**
* gst_subtitle_element_new:
* @style_set: (transfer full): A #GstSubtitleStyleSet that defines the styling
* and layout associated with this inline text element.
* @text_index: The index within a #GstBuffer of the #GstMemory that contains
* the text of this inline text element.
*
* Allocates a new #GstSubtitleElement.
*
* Returns: (transfer full): A newly-allocated #GstSubtitleElement. Unref
* with gst_subtitle_element_unref() when no longer needed.
*/
GstSubtitleElement *
gst_subtitle_element_new (GstSubtitleStyleSet * style_set,
guint text_index, gboolean suppress_whitespace)
{
GstSubtitleElement *element;
g_return_val_if_fail (style_set != NULL, NULL);
element = g_slice_new0 (GstSubtitleElement);
gst_mini_object_init (GST_MINI_OBJECT_CAST (element), 0,
gst_subtitle_element_get_type (), NULL, NULL,
(GstMiniObjectFreeFunction) _gst_subtitle_element_free);
element->style_set = style_set;
element->text_index = text_index;
element->suppress_whitespace = suppress_whitespace;
return element;
}
static void
_gst_subtitle_block_free (GstSubtitleBlock * block)
{
g_return_if_fail (block != NULL);
gst_subtitle_style_set_free (block->style_set);
g_ptr_array_unref (block->elements);
g_slice_free (GstSubtitleBlock, block);
}
GST_DEFINE_MINI_OBJECT_TYPE (GstSubtitleBlock, gst_subtitle_block);
/**
* gst_subtitle_block_new:
* @style_set: (transfer full): A #GstSubtitleStyleSet that defines the styling
* and layout associated with this block of text elements.
*
* Allocates a new #GstSubtitleBlock.
*
* Returns: (transfer full): A newly-allocated #GstSubtitleBlock. Unref
* with gst_subtitle_block_unref() when no longer needed.
*/
GstSubtitleBlock *
gst_subtitle_block_new (GstSubtitleStyleSet * style_set)
{
GstSubtitleBlock *block;
g_return_val_if_fail (style_set != NULL, NULL);
block = g_slice_new0 (GstSubtitleBlock);
gst_mini_object_init (GST_MINI_OBJECT_CAST (block), 0,
gst_subtitle_block_get_type (), NULL, NULL,
(GstMiniObjectFreeFunction) _gst_subtitle_block_free);
block->style_set = style_set;
block->elements = g_ptr_array_new_with_free_func (
(GDestroyNotify) gst_subtitle_element_unref);
return block;
}
/**
* gst_subtitle_block_add_element:
* @block: A #GstSubtitleBlock.
* @element: (transfer full): A #GstSubtitleElement to add.
*
* Adds a #GstSubtitleElement to @block.
*/
void
gst_subtitle_block_add_element (GstSubtitleBlock * block,
GstSubtitleElement * element)
{
g_return_if_fail (block != NULL);
g_return_if_fail (element != NULL);
g_ptr_array_add (block->elements, element);
}
/**
* gst_subtitle_block_get_element_count:
* @block: A #GstSubtitleBlock.
*
* Returns: The number of #GstSubtitleElements in @block.
*/
guint
gst_subtitle_block_get_element_count (const GstSubtitleBlock * block)
{
g_return_val_if_fail (block != NULL, 0);
return block->elements->len;
}
/**
* gst_subtitle_block_get_element:
* @block: A #GstSubtitleBlock.
* @index: Index of the element to get.
*
* Gets the #GstSubtitleElement at @index in the array of elements held by
* @block.
*
* Returns: (transfer none): The #GstSubtitleElement at @index in the array of
* elements held by @block, or %NULL if @index is out-of-bounds. The
* function does not return a reference; the caller should obtain a reference
* using gst_subtitle_element_ref(), if needed.
*/
const GstSubtitleElement *
gst_subtitle_block_get_element (const GstSubtitleBlock * block, guint index)
{
g_return_val_if_fail (block != NULL, NULL);
if (index >= block->elements->len)
return NULL;
else
return g_ptr_array_index (block->elements, index);
}
static void
_gst_subtitle_region_free (GstSubtitleRegion * region)
{
g_return_if_fail (region != NULL);
gst_subtitle_style_set_free (region->style_set);
g_ptr_array_unref (region->blocks);
g_slice_free (GstSubtitleRegion, region);
}
GST_DEFINE_MINI_OBJECT_TYPE (GstSubtitleRegion, gst_subtitle_region);
/**
* gst_subtitle_region_new:
* @style_set: (transfer full): A #GstSubtitleStyleSet that defines the styling
* and layout associated with this region.
*
* Allocates a new #GstSubtitleRegion.
*
* Returns: (transfer full): A newly-allocated #GstSubtitleRegion. Unref
* with gst_subtitle_region_unref() when no longer needed.
*/
GstSubtitleRegion *
gst_subtitle_region_new (GstSubtitleStyleSet * style_set)
{
GstSubtitleRegion *region;
g_return_val_if_fail (style_set != NULL, NULL);
region = g_slice_new0 (GstSubtitleRegion);
gst_mini_object_init (GST_MINI_OBJECT_CAST (region), 0,
gst_subtitle_region_get_type (), NULL, NULL,
(GstMiniObjectFreeFunction) _gst_subtitle_region_free);
region->style_set = style_set;
region->blocks = g_ptr_array_new_with_free_func (
(GDestroyNotify) gst_subtitle_block_unref);
return region;
}
/**
* gst_subtitle_region_add_block:
* @region: A #GstSubtitleRegion.
* @block: (transfer full): A #GstSubtitleBlock which should be added
* to @region's array of blocks.
*
* Adds a #GstSubtitleBlock to the end of the array of blocks held by @region.
* @region will take ownership of @block, and will unref it when @region
* is freed.
*/
void
gst_subtitle_region_add_block (GstSubtitleRegion * region,
GstSubtitleBlock * block)
{
g_return_if_fail (region != NULL);
g_return_if_fail (block != NULL);
g_ptr_array_add (region->blocks, block);
}
/**
* gst_subtitle_region_get_block_count:
* @region: A #GstSubtitleRegion.
*
* Returns: The number of blocks in @region.
*/
guint
gst_subtitle_region_get_block_count (const GstSubtitleRegion * region)
{
g_return_val_if_fail (region != NULL, 0);
return region->blocks->len;
}
/**
* gst_subtitle_region_get_block:
* @region: A #GstSubtitleRegion.
* @index: Index of the block to get.
*