| /* 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 |
| * @title: 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_free: |
| * @style_set: A #GstSubtitleStyleSet. |
| * |
| * Free @style_set and its associated memory. |
| */ |
| static 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); |
| } |
| |
| GST_DEFINE_MINI_OBJECT_TYPE (GstSubtitleStyleSet, gst_subtitle_style_set); |
| |
| /** |
| * 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 }; |
| |
| gst_mini_object_init (GST_MINI_OBJECT_CAST (ret), 0, |
| gst_subtitle_style_set_get_type (), NULL, NULL, |
| (GstMiniObjectFreeFunction) _gst_subtitle_style_set_free); |
| |
| ret->font_family = g_strdup ("default"); |
| ret->font_size = 1.0; |
| ret->line_height = -1; |
| 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; |
| ret->fill_line_gap = FALSE; |
| |
| return ret; |
| } |
| |
| |
| static void |
| _gst_subtitle_element_free (GstSubtitleElement * element) |
| { |
| g_return_if_fail (element != NULL); |
| gst_subtitle_style_set_unref (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_unref (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. |
| */ |
| 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_unref (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. |
| * |
| * Gets the block at @index in the array of blocks held by @region. |
| * |
| * Returns: (transfer none): The #GstSubtitleBlock at @index in the array of |
| * blocks held by @region, or %NULL if @index is out-of-bounds. The |
| * function does not return a reference; the caller should obtain a reference |
| * using gst_subtitle_block_ref(), if needed. |
| */ |
| const GstSubtitleBlock * |
| gst_subtitle_region_get_block (const GstSubtitleRegion * region, guint index) |
| { |
| g_return_val_if_fail (region != NULL, NULL); |
| |
| if (index >= region->blocks->len) |
| return NULL; |
| else |
| return g_ptr_array_index (region->blocks, index); |
| } |