summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorChris Bass <floobleflam@gmail.com>2017-03-21 15:05:18 +0000
committerSebastian Dröge <sebastian@centricular.com>2017-04-09 10:42:08 +0300
commit2a4a18b2abb0b479a4b6f55c58fc4e87c882c3d5 (patch)
tree231c31678e3a3b9ac64fe9f2b3b6ad1b133e426d /ext
parentce532ddcfd8aac684cd778c7300a68b0687498d1 (diff)
downloadgstreamer-plugins-bad-2a4a18b2abb0b479a4b6f55c58fc4e87c882c3d5.tar.gz
ttmlrender: add facility to stitch images in both directions
https://bugzilla.gnome.org/show_bug.cgi?id=780402
Diffstat (limited to 'ext')
-rw-r--r--ext/ttml/gstttmlrender.c89
1 files changed, 66 insertions, 23 deletions
diff --git a/ext/ttml/gstttmlrender.c b/ext/ttml/gstttmlrender.c
index da0922973..96e31fb49 100644
--- a/ext/ttml/gstttmlrender.c
+++ b/ext/ttml/gstttmlrender.c
@@ -94,6 +94,13 @@ GST_STATIC_PAD_TEMPLATE ("text_sink",
#define GST_TTML_RENDER_BROADCAST(ov)(g_cond_broadcast (GST_TTML_RENDER_GET_COND (ov)))
+typedef enum
+{
+ GST_TTML_DIRECTION_INLINE,
+ GST_TTML_DIRECTION_BLOCK
+} GstTtmlDirection;
+
+
typedef struct
{
guint height;
@@ -149,6 +156,8 @@ static GstTtmlRenderRenderedImage *gst_ttml_render_rendered_image_copy
(GstTtmlRenderRenderedImage * image);
static void gst_ttml_render_rendered_image_free
(GstTtmlRenderRenderedImage * image);
+static GstTtmlRenderRenderedImage *gst_ttml_render_stitch_images (GPtrArray *
+ images, GstTtmlDirection direction);
GType
gst_ttml_render_get_type (void)
@@ -2044,30 +2053,61 @@ gst_ttml_render_get_alignment (GstSubtitleStyleSet * style_set)
}
+/*
+ * Overlays a set of rendered images to return a single image. Order is
+ * significant: later entries in @images are rendered on top of earlier
+ * entries.
+ */
static GstTtmlRenderRenderedImage *
-gst_ttml_render_stitch_blocks (GList * blocks)
+gst_ttml_render_overlay_images (GPtrArray * images)
{
- guint vert_offset = 0;
- GList *block_entry;
GstTtmlRenderRenderedImage *ret = NULL;
+ gint i;
- for (block_entry = g_list_first (blocks); block_entry;
- block_entry = block_entry->next) {
- GstTtmlRenderRenderedImage *block, *tmp;
- block = (GstTtmlRenderRenderedImage *) block_entry->data;
- tmp = ret;
-
- block->y += vert_offset;
- GST_CAT_LOG (ttmlrender_debug, "Rendering block at vertical offset %u",
- vert_offset);
- vert_offset = block->y + block->height;
- ret = gst_ttml_render_rendered_image_combine (ret, block);
- if (tmp)
- gst_ttml_render_rendered_image_free (tmp);
+ for (i = 0; i < images->len; ++i) {
+ GstTtmlRenderRenderedImage *tmp = ret;
+ ret = gst_ttml_render_rendered_image_combine (ret,
+ g_ptr_array_index (images, i));
+ gst_ttml_render_rendered_image_free (tmp);
+ }
+
+ return ret;
+}
+
+
+/*
+ * Takes a set of images and renders them as a single image, where all the
+ * images are arranged contiguously in the direction given by @direction. Note
+ * that the positions of the images in @images will be altered.
+ */
+static GstTtmlRenderRenderedImage *
+gst_ttml_render_stitch_images (GPtrArray * images, GstTtmlDirection direction)
+{
+ guint cur_offset = 0;
+ GstTtmlRenderRenderedImage *ret = NULL;
+ gint i;
+
+ for (i = 0; i < images->len; ++i) {
+ GstTtmlRenderRenderedImage *block;
+ block = g_ptr_array_index (images, i);
+
+ if (direction == GST_TTML_DIRECTION_BLOCK) {
+ block->y += cur_offset;
+ cur_offset = block->y + block->height;
+ } else {
+ block->x += cur_offset;
+ cur_offset = block->x + block->width;
+ }
}
+ ret = gst_ttml_render_overlay_images (images);
+
if (ret) {
- GST_CAT_LOG (ttmlrender_debug, "Height of stitched image: %u", ret->height);
+ if (direction == GST_TTML_DIRECTION_BLOCK)
+ GST_CAT_LOG (ttmlrender_debug, "Height of stitched image: %u",
+ ret->height);
+ else
+ GST_CAT_LOG (ttmlrender_debug, "Width of stitched image: %u", ret->width);
ret->image = gst_buffer_make_writable (ret->image);
}
return ret;
@@ -2194,10 +2234,12 @@ static GstVideoOverlayComposition *
gst_ttml_render_render_text_region (GstTtmlRender * render,
GstSubtitleRegion * region, GstBuffer * text_buf)
{
- GList *blocks = NULL;
guint region_x, region_y, region_width, region_height;
guint window_x, window_y, window_width, window_height;
guint padding_start, padding_end, padding_before, padding_after;
+ GPtrArray *rendered_blocks =
+ g_ptr_array_new_with_free_func (
+ (GDestroyNotify) gst_ttml_render_rendered_image_free);
GstTtmlRenderRenderedImage *region_image = NULL;
GstTtmlRenderRenderedImage *blocks_image;
GstVideoOverlayComposition *ret = NULL;
@@ -2249,15 +2291,14 @@ gst_ttml_render_render_text_region (GstTtmlRender * render,
rendered_block = gst_ttml_render_render_text_block (render, block, text_buf,
window_width, TRUE);
- blocks = g_list_append (blocks, rendered_block);
+ g_ptr_array_add (rendered_blocks, rendered_block);
}
- if (blocks) {
+ if (rendered_blocks->len > 0) {
GstTtmlRenderRenderedImage *tmp;
- blocks_image = gst_ttml_render_stitch_blocks (blocks);
- g_list_free_full (blocks,
- (GDestroyNotify) gst_ttml_render_rendered_image_free);
+ blocks_image = gst_ttml_render_stitch_images (rendered_blocks,
+ GST_TTML_DIRECTION_BLOCK);
blocks_image->x += window_x;
switch (region->style_set->display_align) {
@@ -2303,6 +2344,8 @@ gst_ttml_render_render_text_region (GstTtmlRender * render,
ret = gst_ttml_render_compose_overlay (region_image);
gst_ttml_render_rendered_image_free (region_image);
}
+
+ g_ptr_array_unref (rendered_blocks);
return ret;
}