mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 05:28:32 +00:00
ttmlrender: add facility to stitch images in both directions
https://bugzilla.gnome.org/show_bug.cgi?id=780402
This commit is contained in:
parent
ce532ddcfd
commit
2a4a18b2ab
1 changed files with 66 additions and 23 deletions
|
@ -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)))
|
#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
|
typedef struct
|
||||||
{
|
{
|
||||||
guint height;
|
guint height;
|
||||||
|
@ -149,6 +156,8 @@ static GstTtmlRenderRenderedImage *gst_ttml_render_rendered_image_copy
|
||||||
(GstTtmlRenderRenderedImage * image);
|
(GstTtmlRenderRenderedImage * image);
|
||||||
static void gst_ttml_render_rendered_image_free
|
static void gst_ttml_render_rendered_image_free
|
||||||
(GstTtmlRenderRenderedImage * image);
|
(GstTtmlRenderRenderedImage * image);
|
||||||
|
static GstTtmlRenderRenderedImage *gst_ttml_render_stitch_images (GPtrArray *
|
||||||
|
images, GstTtmlDirection direction);
|
||||||
|
|
||||||
GType
|
GType
|
||||||
gst_ttml_render_get_type (void)
|
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 *
|
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;
|
GstTtmlRenderRenderedImage *ret = NULL;
|
||||||
|
gint i;
|
||||||
|
|
||||||
for (block_entry = g_list_first (blocks); block_entry;
|
for (i = 0; i < images->len; ++i) {
|
||||||
block_entry = block_entry->next) {
|
GstTtmlRenderRenderedImage *tmp = ret;
|
||||||
GstTtmlRenderRenderedImage *block, *tmp;
|
ret = gst_ttml_render_rendered_image_combine (ret,
|
||||||
block = (GstTtmlRenderRenderedImage *) block_entry->data;
|
g_ptr_array_index (images, i));
|
||||||
tmp = ret;
|
gst_ttml_render_rendered_image_free (tmp);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
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);
|
ret->image = gst_buffer_make_writable (ret->image);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -2194,10 +2234,12 @@ static GstVideoOverlayComposition *
|
||||||
gst_ttml_render_render_text_region (GstTtmlRender * render,
|
gst_ttml_render_render_text_region (GstTtmlRender * render,
|
||||||
GstSubtitleRegion * region, GstBuffer * text_buf)
|
GstSubtitleRegion * region, GstBuffer * text_buf)
|
||||||
{
|
{
|
||||||
GList *blocks = NULL;
|
|
||||||
guint region_x, region_y, region_width, region_height;
|
guint region_x, region_y, region_width, region_height;
|
||||||
guint window_x, window_y, window_width, window_height;
|
guint window_x, window_y, window_width, window_height;
|
||||||
guint padding_start, padding_end, padding_before, padding_after;
|
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 *region_image = NULL;
|
||||||
GstTtmlRenderRenderedImage *blocks_image;
|
GstTtmlRenderRenderedImage *blocks_image;
|
||||||
GstVideoOverlayComposition *ret = NULL;
|
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,
|
rendered_block = gst_ttml_render_render_text_block (render, block, text_buf,
|
||||||
window_width, TRUE);
|
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;
|
GstTtmlRenderRenderedImage *tmp;
|
||||||
|
|
||||||
blocks_image = gst_ttml_render_stitch_blocks (blocks);
|
blocks_image = gst_ttml_render_stitch_images (rendered_blocks,
|
||||||
g_list_free_full (blocks,
|
GST_TTML_DIRECTION_BLOCK);
|
||||||
(GDestroyNotify) gst_ttml_render_rendered_image_free);
|
|
||||||
blocks_image->x += window_x;
|
blocks_image->x += window_x;
|
||||||
|
|
||||||
switch (region->style_set->display_align) {
|
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);
|
ret = gst_ttml_render_compose_overlay (region_image);
|
||||||
gst_ttml_render_rendered_image_free (region_image);
|
gst_ttml_render_rendered_image_free (region_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_ptr_array_unref (rendered_blocks);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue