/* 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.
 */

/**
 * SECTION:element-ttmlrender
 * @title: ttmlrender
 *
 * Renders timed text on top of a video stream. It receives text in buffers
 * from a ttmlparse element; each text string is in its own #GstMemory within
 * the GstBuffer, and the styling and layout associated with each text string
 * is in metadata attached to the #GstBuffer.
 *
 * ## Example launch lines
 * |[
 * gst-launch-1.0 filesrc location=<media file location> ! video/quicktime ! qtdemux name=q ttmlrender name=r q. ! queue ! h264parse ! avdec_h264 ! autovideoconvert ! r.video_sink filesrc location=<subtitle file location> blocksize=16777216 ! queue ! ttmlparse ! r.text_sink r. ! ximagesink q. ! queue ! aacparse ! avdec_aac ! audioconvert ! alsasink
 * ]| Parse and render TTML subtitles contained in a single XML file over an
 * MP4 stream containing H.264 video and AAC audio:
 *
 */

#include <gst/video/video.h>
#include <gst/video/gstvideometa.h>
#include <gst/video/video-overlay-composition.h>
#include <pango/pangocairo.h>

#include <string.h>
#include <math.h>

#include "gstttmlrender.h"
#include "subtitle.h"
#include "subtitlemeta.h"

#define VIDEO_FORMATS GST_VIDEO_OVERLAY_COMPOSITION_BLEND_FORMATS

#define TTML_RENDER_CAPS GST_VIDEO_CAPS_MAKE (VIDEO_FORMATS)

#define TTML_RENDER_ALL_CAPS TTML_RENDER_CAPS ";" \
    GST_VIDEO_CAPS_MAKE_WITH_FEATURES ("ANY", GST_VIDEO_FORMATS_ALL)

GST_DEBUG_CATEGORY_EXTERN (ttmlrender_debug);
#define GST_CAT_DEFAULT ttmlrender_debug

static GstStaticCaps sw_template_caps = GST_STATIC_CAPS (TTML_RENDER_CAPS);

static GstStaticPadTemplate src_template_factory =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (TTML_RENDER_ALL_CAPS)
    );

static GstStaticPadTemplate video_sink_template_factory =
GST_STATIC_PAD_TEMPLATE ("video_sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (TTML_RENDER_ALL_CAPS)
    );

static GstStaticPadTemplate text_sink_template_factory =
GST_STATIC_PAD_TEMPLATE ("text_sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("text/x-raw(meta:GstSubtitleMeta)")
    );

#define GST_TTML_RENDER_GET_LOCK(ov) (&GST_TTML_RENDER (ov)->lock)
#define GST_TTML_RENDER_GET_COND(ov) (&GST_TTML_RENDER (ov)->cond)
#define GST_TTML_RENDER_LOCK(ov)     (g_mutex_lock (GST_TTML_RENDER_GET_LOCK (ov)))
#define GST_TTML_RENDER_UNLOCK(ov)   (g_mutex_unlock (GST_TTML_RENDER_GET_LOCK (ov)))
#define GST_TTML_RENDER_WAIT(ov)     (g_cond_wait (GST_TTML_RENDER_GET_COND (ov), GST_TTML_RENDER_GET_LOCK (ov)))
#define GST_TTML_RENDER_SIGNAL(ov)   (g_cond_signal (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
{
  guint line_height;
  guint baseline_offset;
} BlockMetrics;


typedef struct
{
  guint height;
  guint baseline;
} FontMetrics;


typedef struct
{
  guint first_index;
  guint last_index;
} CharRange;


/* @pango_font_size is the font size you would need to tell pango in order that
 * the actual rendered height of @text matches the text height in @element's
 * style set. */
typedef struct
{
  GstSubtitleElement *element;
  guint pango_font_size;
  FontMetrics pango_font_metrics;
  gchar *text;
} UnifiedElement;


typedef struct
{
  GPtrArray *unified_elements;
  GstSubtitleStyleSet *style_set;
  gchar *joined_text;
} UnifiedBlock;


static GstElementClass *parent_class = NULL;
static void gst_ttml_render_base_init (gpointer g_class);
static void gst_ttml_render_class_init (GstTtmlRenderClass * klass);
static void gst_ttml_render_init (GstTtmlRender * render,
    GstTtmlRenderClass * klass);

static GstStateChangeReturn gst_ttml_render_change_state (GstElement *
    element, GstStateChange transition);

static GstCaps *gst_ttml_render_get_videosink_caps (GstPad * pad,
    GstTtmlRender * render, GstCaps * filter);
static GstCaps *gst_ttml_render_get_src_caps (GstPad * pad,
    GstTtmlRender * render, GstCaps * filter);
static gboolean gst_ttml_render_setcaps (GstTtmlRender * render,
    GstCaps * caps);
static gboolean gst_ttml_render_src_event (GstPad * pad,
    GstObject * parent, GstEvent * event);
static gboolean gst_ttml_render_src_query (GstPad * pad,
    GstObject * parent, GstQuery * query);

static gboolean gst_ttml_render_video_event (GstPad * pad,
    GstObject * parent, GstEvent * event);
static gboolean gst_ttml_render_video_query (GstPad * pad,
    GstObject * parent, GstQuery * query);
static GstFlowReturn gst_ttml_render_video_chain (GstPad * pad,
    GstObject * parent, GstBuffer * buffer);

static gboolean gst_ttml_render_text_event (GstPad * pad,
    GstObject * parent, GstEvent * event);
static GstFlowReturn gst_ttml_render_text_chain (GstPad * pad,
    GstObject * parent, GstBuffer * buffer);
static GstPadLinkReturn gst_ttml_render_text_pad_link (GstPad * pad,
    GstObject * parent, GstPad * peer);
static void gst_ttml_render_text_pad_unlink (GstPad * pad, GstObject * parent);
static void gst_ttml_render_pop_text (GstTtmlRender * render);

static void gst_ttml_render_finalize (GObject * object);

static gboolean gst_ttml_render_can_handle_caps (GstCaps * incaps);

static GstTtmlRenderRenderedImage *gst_ttml_render_rendered_image_new
    (GstBuffer * image, gint x, gint y, guint width, guint height);
static GstTtmlRenderRenderedImage *gst_ttml_render_rendered_image_new_empty
    (void);
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_rendered_image_combine
    (GstTtmlRenderRenderedImage * image1, GstTtmlRenderRenderedImage * image2);
static GstTtmlRenderRenderedImage *gst_ttml_render_stitch_images (GPtrArray *
    images, GstTtmlDirection direction);

static gboolean gst_ttml_render_color_is_transparent (GstSubtitleColor * color);

GType
gst_ttml_render_get_type (void)
{
  static GType type = 0;

  if (g_once_init_enter ((gsize *) & type)) {
    static const GTypeInfo info = {
      sizeof (GstTtmlRenderClass),
      (GBaseInitFunc) gst_ttml_render_base_init,
      NULL,
      (GClassInitFunc) gst_ttml_render_class_init,
      NULL,
      NULL,
      sizeof (GstTtmlRender),
      0,
      (GInstanceInitFunc) gst_ttml_render_init,
    };

    g_once_init_leave ((gsize *) & type,
        g_type_register_static (GST_TYPE_ELEMENT, "GstTtmlRender", &info, 0));
  }

  return type;
}

static void
gst_ttml_render_base_init (gpointer g_class)
{
  GstTtmlRenderClass *klass = GST_TTML_RENDER_CLASS (g_class);
  PangoFontMap *fontmap;

  /* Only lock for the subclasses here, the base class
   * doesn't have this mutex yet and it's not necessary
   * here */
  if (klass->pango_lock)
    g_mutex_lock (klass->pango_lock);
  fontmap = pango_cairo_font_map_get_default ();
  klass->pango_context =
      pango_font_map_create_context (PANGO_FONT_MAP (fontmap));
  if (klass->pango_lock)
    g_mutex_unlock (klass->pango_lock);
}

static void
gst_ttml_render_class_init (GstTtmlRenderClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;

  gobject_class = (GObjectClass *) klass;
  gstelement_class = (GstElementClass *) klass;

  parent_class = g_type_class_peek_parent (klass);

  gobject_class->finalize = gst_ttml_render_finalize;

  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&src_template_factory));
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&video_sink_template_factory));
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&text_sink_template_factory));

  gst_element_class_set_static_metadata (gstelement_class,
      "TTML subtitle renderer", "Overlay/Subtitle",
      "Renders timed-text subtitles on top of video buffers",
      "David Schleef <ds@schleef.org>, Zeeshan Ali <zeeshan.ali@nokia.com>, "
      "Chris Bass <dash@rd.bbc.co.uk>");

  gstelement_class->change_state =
      GST_DEBUG_FUNCPTR (gst_ttml_render_change_state);

  klass->pango_lock = g_slice_new (GMutex);
  g_mutex_init (klass->pango_lock);
}

static void
gst_ttml_render_finalize (GObject * object)
{
  GstTtmlRender *render = GST_TTML_RENDER (object);

  if (render->compositions) {
    g_list_free_full (render->compositions,
        (GDestroyNotify) gst_video_overlay_composition_unref);
    render->compositions = NULL;
  }

  if (render->text_buffer) {
    gst_buffer_unref (render->text_buffer);
    render->text_buffer = NULL;
  }

  if (render->layout) {
    g_object_unref (render->layout);
    render->layout = NULL;
  }

  g_mutex_clear (&render->lock);
  g_cond_clear (&render->cond);

  G_OBJECT_CLASS (parent_class)->finalize (object);
}

static void
gst_ttml_render_init (GstTtmlRender * render, GstTtmlRenderClass * klass)
{
  GstPadTemplate *template;

  /* video sink */
  template = gst_static_pad_template_get (&video_sink_template_factory);
  render->video_sinkpad = gst_pad_new_from_template (template, "video_sink");
  gst_object_unref (template);
  gst_pad_set_event_function (render->video_sinkpad,
      GST_DEBUG_FUNCPTR (gst_ttml_render_video_event));
  gst_pad_set_chain_function (render->video_sinkpad,
      GST_DEBUG_FUNCPTR (gst_ttml_render_video_chain));
  gst_pad_set_query_function (render->video_sinkpad,
      GST_DEBUG_FUNCPTR (gst_ttml_render_video_query));
  GST_PAD_SET_PROXY_ALLOCATION (render->video_sinkpad);
  gst_element_add_pad (GST_ELEMENT (render), render->video_sinkpad);

  template =
      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass),
      "text_sink");
  if (template) {
    /* text sink */
    render->text_sinkpad = gst_pad_new_from_template (template, "text_sink");

    gst_pad_set_event_function (render->text_sinkpad,
        GST_DEBUG_FUNCPTR (gst_ttml_render_text_event));
    gst_pad_set_chain_function (render->text_sinkpad,
        GST_DEBUG_FUNCPTR (gst_ttml_render_text_chain));
    gst_pad_set_link_function (render->text_sinkpad,
        GST_DEBUG_FUNCPTR (gst_ttml_render_text_pad_link));
    gst_pad_set_unlink_function (render->text_sinkpad,
        GST_DEBUG_FUNCPTR (gst_ttml_render_text_pad_unlink));
    gst_element_add_pad (GST_ELEMENT (render), render->text_sinkpad);
  }

  /* (video) source */
  template = gst_static_pad_template_get (&src_template_factory);
  render->srcpad = gst_pad_new_from_template (template, "src");
  gst_object_unref (template);
  gst_pad_set_event_function (render->srcpad,
      GST_DEBUG_FUNCPTR (gst_ttml_render_src_event));
  gst_pad_set_query_function (render->srcpad,
      GST_DEBUG_FUNCPTR (gst_ttml_render_src_query));
  gst_element_add_pad (GST_ELEMENT (render), render->srcpad);

  g_mutex_lock (GST_TTML_RENDER_GET_CLASS (render)->pango_lock);

  render->wait_text = TRUE;
  render->need_render = TRUE;
  render->text_buffer = NULL;
  render->text_linked = FALSE;

  render->compositions = NULL;
  render->layout =
      pango_layout_new (GST_TTML_RENDER_GET_CLASS (render)->pango_context);

  g_mutex_init (&render->lock);
  g_cond_init (&render->cond);
  gst_segment_init (&render->segment, GST_FORMAT_TIME);
  g_mutex_unlock (GST_TTML_RENDER_GET_CLASS (render)->pango_lock);
}


/* only negotiate/query video render composition support for now */
static gboolean
gst_ttml_render_negotiate (GstTtmlRender * render, GstCaps * caps)
{
  GstQuery *query;
  gboolean attach = FALSE;
  gboolean caps_has_meta = TRUE;
  gboolean ret;
  GstCapsFeatures *f;
  GstCaps *original_caps;
  gboolean original_has_meta = FALSE;
  gboolean allocation_ret = TRUE;

  GST_DEBUG_OBJECT (render, "performing negotiation");

  gst_pad_check_reconfigure (render->srcpad);

  if (!caps)
    caps = gst_pad_get_current_caps (render->video_sinkpad);
  else
    gst_caps_ref (caps);

  if (!caps || gst_caps_is_empty (caps))
    goto no_format;

  original_caps = caps;

  /* Try to use the render meta if possible */
  f = gst_caps_get_features (caps, 0);

  /* if the caps doesn't have the render meta, we query if downstream
   * accepts it before trying the version without the meta
   * If upstream already is using the meta then we can only use it */
  if (!f
      || !gst_caps_features_contains (f,
          GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION)) {
    GstCaps *overlay_caps;

    /* In this case we added the meta, but we can work without it
     * so preserve the original caps so we can use it as a fallback */
    overlay_caps = gst_caps_copy (caps);

    f = gst_caps_get_features (overlay_caps, 0);
    gst_caps_features_add (f,
        GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION);

    ret = gst_pad_peer_query_accept_caps (render->srcpad, overlay_caps);
    GST_DEBUG_OBJECT (render, "Downstream accepts the render meta: %d", ret);
    if (ret) {
      gst_caps_unref (caps);
      caps = overlay_caps;

    } else {
      /* fallback to the original */
      gst_caps_unref (overlay_caps);
      caps_has_meta = FALSE;
    }
  } else {
    original_has_meta = TRUE;
  }
  GST_DEBUG_OBJECT (render, "Using caps %" GST_PTR_FORMAT, caps);
  ret = gst_pad_set_caps (render->srcpad, caps);

  if (ret) {
    /* find supported meta */
    query = gst_query_new_allocation (caps, FALSE);

    if (!gst_pad_peer_query (render->srcpad, query)) {
      /* no problem, we use the query defaults */
      GST_DEBUG_OBJECT (render, "ALLOCATION query failed");
      allocation_ret = FALSE;
    }

    if (caps_has_meta && gst_query_find_allocation_meta (query,
            GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE, NULL))
      attach = TRUE;

    gst_query_unref (query);
  }

  if (!allocation_ret && render->video_flushing) {
    ret = FALSE;
  } else if (original_caps && !original_has_meta && !attach) {
    if (caps_has_meta) {
      /* Some elements (fakesink) claim to accept the meta on caps but won't
         put it in the allocation query result, this leads below
         check to fail. Prevent this by removing the meta from caps */
      gst_caps_unref (caps);
      caps = gst_caps_ref (original_caps);
      ret = gst_pad_set_caps (render->srcpad, caps);
      if (ret && !gst_ttml_render_can_handle_caps (caps))
        ret = FALSE;
    }
  }

  if (!ret) {
    GST_DEBUG_OBJECT (render, "negotiation failed, schedule reconfigure");
    gst_pad_mark_reconfigure (render->srcpad);
  }

  gst_caps_unref (caps);

  if (!ret)
    gst_pad_mark_reconfigure (render->srcpad);

  return ret;

no_format:
  {
    if (caps)
      gst_caps_unref (caps);
    gst_pad_mark_reconfigure (render->srcpad);
    return FALSE;
  }
}

static gboolean
gst_ttml_render_can_handle_caps (GstCaps * incaps)
{
  gboolean ret;
  GstCaps *caps;
  static GstStaticCaps static_caps = GST_STATIC_CAPS (TTML_RENDER_CAPS);

  caps = gst_static_caps_get (&static_caps);
  ret = gst_caps_is_subset (incaps, caps);
  gst_caps_unref (caps);

  return ret;
}

static gboolean
gst_ttml_render_setcaps (GstTtmlRender * render, GstCaps * caps)
{
  GstVideoInfo info;
  gboolean ret = FALSE;

  if (!gst_video_info_from_caps (&info, caps))
    goto invalid_caps;

  render->info = info;
  render->format = GST_VIDEO_INFO_FORMAT (&info);
  render->width = GST_VIDEO_INFO_WIDTH (&info);
  render->height = GST_VIDEO_INFO_HEIGHT (&info);

  ret = gst_ttml_render_negotiate (render, caps);

  GST_TTML_RENDER_LOCK (render);
  g_mutex_lock (GST_TTML_RENDER_GET_CLASS (render)->pango_lock);
  if (!gst_ttml_render_can_handle_caps (caps)) {
    GST_DEBUG_OBJECT (render, "unsupported caps %" GST_PTR_FORMAT, caps);
    ret = FALSE;
  }

  g_mutex_unlock (GST_TTML_RENDER_GET_CLASS (render)->pango_lock);
  GST_TTML_RENDER_UNLOCK (render);

  return ret;

  /* ERRORS */
invalid_caps:
  {
    GST_DEBUG_OBJECT (render, "could not parse caps");
    return FALSE;
  }
}


static gboolean
gst_ttml_render_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
  gboolean ret = FALSE;
  GstTtmlRender *render;

  render = GST_TTML_RENDER (parent);

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_CAPS:
    {
      GstCaps *filter, *caps;

      gst_query_parse_caps (query, &filter);
      caps = gst_ttml_render_get_src_caps (pad, render, filter);
      gst_query_set_caps_result (query, caps);
      gst_caps_unref (caps);
      ret = TRUE;
      break;
    }
    default:
      ret = gst_pad_query_default (pad, parent, query);
      break;
  }

  return ret;
}

static gboolean
gst_ttml_render_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstTtmlRender *render;
  gboolean ret;

  render = GST_TTML_RENDER (parent);

  if (render->text_linked) {
    gst_event_ref (event);
    ret = gst_pad_push_event (render->video_sinkpad, event);
    gst_pad_push_event (render->text_sinkpad, event);
  } else {
    ret = gst_pad_push_event (render->video_sinkpad, event);
  }

  return ret;
}

/**
 * gst_ttml_render_add_feature_and_intersect:
 *
 * Creates a new #GstCaps containing the (given caps +
 * given caps feature) + (given caps intersected by the
 * given filter).
 *
 * Returns: the new #GstCaps
 */
static GstCaps *
gst_ttml_render_add_feature_and_intersect (GstCaps * caps,
    const gchar * feature, GstCaps * filter)
{
  int i, caps_size;
  GstCaps *new_caps;

  new_caps = gst_caps_copy (caps);

  caps_size = gst_caps_get_size (new_caps);
  for (i = 0; i < caps_size; i++) {
    GstCapsFeatures *features = gst_caps_get_features (new_caps, i);

    if (!gst_caps_features_is_any (features)) {
      gst_caps_features_add (features, feature);
    }
  }

  gst_caps_append (new_caps, gst_caps_intersect_full (caps,
          filter, GST_CAPS_INTERSECT_FIRST));

  return new_caps;
}

/**
 * gst_ttml_render_intersect_by_feature:
 *
 * Creates a new #GstCaps based on the following filtering rule.
 *
 * For each individual caps contained in given caps, if the
 * caps uses the given caps feature, keep a version of the caps
 * with the feature and an another one without. Otherwise, intersect
 * the caps with the given filter.
 *
 * Returns: the new #GstCaps
 */
static GstCaps *
gst_ttml_render_intersect_by_feature (GstCaps * caps,
    const gchar * feature, GstCaps * filter)
{
  int i, caps_size;
  GstCaps *new_caps;

  new_caps = gst_caps_new_empty ();

  caps_size = gst_caps_get_size (caps);
  for (i = 0; i < caps_size; i++) {
    GstStructure *caps_structure = gst_caps_get_structure (caps, i);
    GstCapsFeatures *caps_features =
        gst_caps_features_copy (gst_caps_get_features (caps, i));
    GstCaps *filtered_caps;
    GstCaps *simple_caps =
        gst_caps_new_full (gst_structure_copy (caps_structure), NULL);
    gst_caps_set_features (simple_caps, 0, caps_features);

    if (gst_caps_features_contains (caps_features, feature)) {
      gst_caps_append (new_caps, gst_caps_copy (simple_caps));

      gst_caps_features_remove (caps_features, feature);
      filtered_caps = gst_caps_ref (simple_caps);
    } else {
      filtered_caps = gst_caps_intersect_full (simple_caps, filter,
          GST_CAPS_INTERSECT_FIRST);
    }

    gst_caps_unref (simple_caps);
    gst_caps_append (new_caps, filtered_caps);
  }

  return new_caps;
}

static GstCaps *
gst_ttml_render_get_videosink_caps (GstPad * pad,
    GstTtmlRender * render, GstCaps * filter)
{
  GstPad *srcpad = render->srcpad;
  GstCaps *peer_caps = NULL, *caps = NULL, *overlay_filter = NULL;

  if (G_UNLIKELY (!render))
    return gst_pad_get_pad_template_caps (pad);

  if (filter) {
    /* filter caps + composition feature + filter caps
     * filtered by the software caps. */
    GstCaps *sw_caps = gst_static_caps_get (&sw_template_caps);
    overlay_filter = gst_ttml_render_add_feature_and_intersect (filter,
        GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, sw_caps);
    gst_caps_unref (sw_caps);

    GST_DEBUG_OBJECT (render, "render filter %" GST_PTR_FORMAT, overlay_filter);
  }

  peer_caps = gst_pad_peer_query_caps (srcpad, overlay_filter);

  if (overlay_filter)
    gst_caps_unref (overlay_filter);

  if (peer_caps) {

    GST_DEBUG_OBJECT (pad, "peer caps  %" GST_PTR_FORMAT, peer_caps);

    if (gst_caps_is_any (peer_caps)) {
      /* if peer returns ANY caps, return filtered src pad template caps */
      caps = gst_caps_copy (gst_pad_get_pad_template_caps (srcpad));
    } else {

      /* duplicate caps which contains the composition into one version with
       * the meta and one without. Filter the other caps by the software caps */
      GstCaps *sw_caps = gst_static_caps_get (&sw_template_caps);
      caps = gst_ttml_render_intersect_by_feature (peer_caps,
          GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, sw_caps);
      gst_caps_unref (sw_caps);
    }

    gst_caps_unref (peer_caps);

  } else {
    /* no peer, our padtemplate is enough then */
    caps = gst_pad_get_pad_template_caps (pad);
  }

  if (filter) {
    GstCaps *intersection = gst_caps_intersect_full (filter, caps,
        GST_CAPS_INTERSECT_FIRST);
    gst_caps_unref (caps);
    caps = intersection;
  }

  GST_DEBUG_OBJECT (render, "returning  %" GST_PTR_FORMAT, caps);

  return caps;
}

static GstCaps *
gst_ttml_render_get_src_caps (GstPad * pad, GstTtmlRender * render,
    GstCaps * filter)
{
  GstPad *sinkpad = render->video_sinkpad;
  GstCaps *peer_caps = NULL, *caps = NULL, *overlay_filter = NULL;

  if (G_UNLIKELY (!render))
    return gst_pad_get_pad_template_caps (pad);

  if (filter) {
    /* duplicate filter caps which contains the composition into one version
     * with the meta and one without. Filter the other caps by the software
     * caps */
    GstCaps *sw_caps = gst_static_caps_get (&sw_template_caps);
    overlay_filter =
        gst_ttml_render_intersect_by_feature (filter,
        GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, sw_caps);
    gst_caps_unref (sw_caps);
  }

  peer_caps = gst_pad_peer_query_caps (sinkpad, overlay_filter);

  if (overlay_filter)
    gst_caps_unref (overlay_filter);

  if (peer_caps) {

    GST_DEBUG_OBJECT (pad, "peer caps  %" GST_PTR_FORMAT, peer_caps);

    if (gst_caps_is_any (peer_caps)) {

      /* if peer returns ANY caps, return filtered sink pad template caps */
      caps = gst_caps_copy (gst_pad_get_pad_template_caps (sinkpad));

    } else {

      /* return upstream caps + composition feature + upstream caps
       * filtered by the software caps. */
      GstCaps *sw_caps = gst_static_caps_get (&sw_template_caps);
      caps = gst_ttml_render_add_feature_and_intersect (peer_caps,
          GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, sw_caps);
      gst_caps_unref (sw_caps);
    }

    gst_caps_unref (peer_caps);

  } else {
    /* no peer, our padtemplate is enough then */
    caps = gst_pad_get_pad_template_caps (pad);
  }

  if (filter) {
    GstCaps *intersection;

    intersection =
        gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
    gst_caps_unref (caps);
    caps = intersection;
  }
  GST_DEBUG_OBJECT (render, "returning  %" GST_PTR_FORMAT, caps);

  return caps;
}


static GstFlowReturn
gst_ttml_render_push_frame (GstTtmlRender * render, GstBuffer * video_frame)
{
  GstVideoFrame frame;
  GList *compositions = render->compositions;

  if (compositions == NULL) {
    GST_CAT_DEBUG (ttmlrender_debug, "No compositions.");
    goto done;
  }

  if (gst_pad_check_reconfigure (render->srcpad)) {
    if (!gst_ttml_render_negotiate (render, NULL)) {
      gst_pad_mark_reconfigure (render->srcpad);
      gst_buffer_unref (video_frame);
      if (GST_PAD_IS_FLUSHING (render->srcpad))
        return GST_FLOW_FLUSHING;
      else
        return GST_FLOW_NOT_NEGOTIATED;
    }
  }

  video_frame = gst_buffer_make_writable (video_frame);

  if (!gst_video_frame_map (&frame, &render->info, video_frame,
          GST_MAP_READWRITE))
    goto invalid_frame;

  while (compositions) {
    GstVideoOverlayComposition *composition = compositions->data;
    gst_video_overlay_composition_blend (composition, &frame);
    compositions = compositions->next;
  }

  gst_video_frame_unmap (&frame);

done:

  return gst_pad_push (render->srcpad, video_frame);

  /* ERRORS */
invalid_frame:
  {
    gst_buffer_unref (video_frame);
    GST_DEBUG_OBJECT (render, "received invalid buffer");
    return GST_FLOW_OK;
  }
}

static GstPadLinkReturn
gst_ttml_render_text_pad_link (GstPad * pad, GstObject * parent, GstPad * peer)
{
  GstTtmlRender *render;

  render = GST_TTML_RENDER (parent);
  if (G_UNLIKELY (!render))
    return GST_PAD_LINK_REFUSED;

  GST_DEBUG_OBJECT (render, "Text pad linked");

  render->text_linked = TRUE;

  return GST_PAD_LINK_OK;
}

static void
gst_ttml_render_text_pad_unlink (GstPad * pad, GstObject * parent)
{
  GstTtmlRender *render;

  /* don't use gst_pad_get_parent() here, will deadlock */
  render = GST_TTML_RENDER (parent);

  GST_DEBUG_OBJECT (render, "Text pad unlinked");

  render->text_linked = FALSE;

  gst_segment_init (&render->text_segment, GST_FORMAT_UNDEFINED);
}

static gboolean
gst_ttml_render_text_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  gboolean ret = FALSE;
  GstTtmlRender *render = NULL;

  render = GST_TTML_RENDER (parent);

  GST_LOG_OBJECT (pad, "received event %s", GST_EVENT_TYPE_NAME (event));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEGMENT:
    {
      const GstSegment *segment;

      render->text_eos = FALSE;

      gst_event_parse_segment (event, &segment);

      if (segment->format == GST_FORMAT_TIME) {
        GST_TTML_RENDER_LOCK (render);
        gst_segment_copy_into (segment, &render->text_segment);
        GST_DEBUG_OBJECT (render, "TEXT SEGMENT now: %" GST_SEGMENT_FORMAT,
            &render->text_segment);
        GST_TTML_RENDER_UNLOCK (render);
      } else {
        GST_ELEMENT_WARNING (render, STREAM, MUX, (NULL),
            ("received non-TIME newsegment event on text input"));
      }

      gst_event_unref (event);
      ret = TRUE;

      /* wake up the video chain, it might be waiting for a text buffer or
       * a text segment update */
      GST_TTML_RENDER_LOCK (render);
      GST_TTML_RENDER_BROADCAST (render);
      GST_TTML_RENDER_UNLOCK (render);
      break;
    }
    case GST_EVENT_GAP:
    {
      GstClockTime start, duration;

      gst_event_parse_gap (event, &start, &duration);
      if (GST_CLOCK_TIME_IS_VALID (duration))
        start += duration;
      /* we do not expect another buffer until after gap,
       * so that is our position now */
      render->text_segment.position = start;

      /* wake up the video chain, it might be waiting for a text buffer or
       * a text segment update */
      GST_TTML_RENDER_LOCK (render);
      GST_TTML_RENDER_BROADCAST (render);
      GST_TTML_RENDER_UNLOCK (render);

      gst_event_unref (event);
      ret = TRUE;
      break;
    }
    case GST_EVENT_FLUSH_STOP:
      GST_TTML_RENDER_LOCK (render);
      GST_INFO_OBJECT (render, "text flush stop");
      render->text_flushing = FALSE;
      render->text_eos = FALSE;
      gst_ttml_render_pop_text (render);
      gst_segment_init (&render->text_segment, GST_FORMAT_TIME);
      GST_TTML_RENDER_UNLOCK (render);
      gst_event_unref (event);
      ret = TRUE;
      break;
    case GST_EVENT_FLUSH_START:
      GST_TTML_RENDER_LOCK (render);
      GST_INFO_OBJECT (render, "text flush start");
      render->text_flushing = TRUE;
      GST_TTML_RENDER_BROADCAST (render);
      GST_TTML_RENDER_UNLOCK (render);
      gst_event_unref (event);
      ret = TRUE;
      break;
    case GST_EVENT_EOS:
      GST_TTML_RENDER_LOCK (render);
      render->text_eos = TRUE;
      GST_INFO_OBJECT (render, "text EOS");
      /* wake up the video chain, it might be waiting for a text buffer or
       * a text segment update */
      GST_TTML_RENDER_BROADCAST (render);
      GST_TTML_RENDER_UNLOCK (render);
      gst_event_unref (event);
      ret = TRUE;
      break;
    default:
      ret = gst_pad_event_default (pad, parent, event);
      break;
  }

  return ret;
}

static gboolean
gst_ttml_render_video_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  gboolean ret = FALSE;
  GstTtmlRender *render = NULL;

  render = GST_TTML_RENDER (parent);

  GST_DEBUG_OBJECT (pad, "received event %s", GST_EVENT_TYPE_NAME (event));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CAPS:
    {
      GstCaps *caps;
      gint prev_width = render->width;
      gint prev_height = render->height;

      gst_event_parse_caps (event, &caps);
      ret = gst_ttml_render_setcaps (render, caps);
      if (render->width != prev_width || render->height != prev_height)
        render->need_render = TRUE;
      gst_event_unref (event);
      break;
    }
    case GST_EVENT_SEGMENT:
    {
      const GstSegment *segment;

      GST_DEBUG_OBJECT (render, "received new segment");

      gst_event_parse_segment (event, &segment);

      if (segment->format == GST_FORMAT_TIME) {
        GST_DEBUG_OBJECT (render, "VIDEO SEGMENT now: %" GST_SEGMENT_FORMAT,
            &render->segment);

        gst_segment_copy_into (segment, &render->segment);
      } else {
        GST_ELEMENT_WARNING (render, STREAM, MUX, (NULL),
            ("received non-TIME newsegment event on video input"));
      }

      ret = gst_pad_event_default (pad, parent, event);
      break;
    }
    case GST_EVENT_EOS:
      GST_TTML_RENDER_LOCK (render);
      GST_INFO_OBJECT (render, "video EOS");
      render->video_eos = TRUE;
      GST_TTML_RENDER_UNLOCK (render);
      ret = gst_pad_event_default (pad, parent, event);
      break;
    case GST_EVENT_FLUSH_START:
      GST_TTML_RENDER_LOCK (render);
      GST_INFO_OBJECT (render, "video flush start");
      render->video_flushing = TRUE;
      GST_TTML_RENDER_BROADCAST (render);
      GST_TTML_RENDER_UNLOCK (render);
      ret = gst_pad_event_default (pad, parent, event);
      break;
    case GST_EVENT_FLUSH_STOP:
      GST_TTML_RENDER_LOCK (render);
      GST_INFO_OBJECT (render, "video flush stop");
      render->video_flushing = FALSE;
      render->video_eos = FALSE;
      gst_segment_init (&render->segment, GST_FORMAT_TIME);
      GST_TTML_RENDER_UNLOCK (render);
      ret = gst_pad_event_default (pad, parent, event);
      break;
    default:
      ret = gst_pad_event_default (pad, parent, event);
      break;
  }

  return ret;
}

static gboolean
gst_ttml_render_video_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
  gboolean ret = FALSE;
  GstTtmlRender *render;

  render = GST_TTML_RENDER (parent);

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_CAPS:
    {
      GstCaps *filter, *caps;

      gst_query_parse_caps (query, &filter);
      caps = gst_ttml_render_get_videosink_caps (pad, render, filter);
      gst_query_set_caps_result (query, caps);
      gst_caps_unref (caps);
      ret = TRUE;
      break;
    }
    default:
      ret = gst_pad_query_default (pad, parent, query);
      break;
  }

  return ret;
}

/* Called with lock held */
static void
gst_ttml_render_pop_text (GstTtmlRender * render)
{
  g_return_if_fail (GST_IS_TTML_RENDER (render));

  if (render->text_buffer) {
    GST_DEBUG_OBJECT (render, "releasing text buffer %p", render->text_buffer);
    gst_buffer_unref (render->text_buffer);
    render->text_buffer = NULL;
  }

  /* Let the text task know we used that buffer */
  GST_TTML_RENDER_BROADCAST (render);
}

/* We receive text buffers here. If they are out of segment we just ignore them.
   If the buffer is in our segment we keep it internally except if another one
   is already waiting here, in that case we wait that it gets kicked out */
static GstFlowReturn
gst_ttml_render_text_chain (GstPad * pad, GstObject * parent,
    GstBuffer * buffer)
{
  GstFlowReturn ret = GST_FLOW_OK;
  GstTtmlRender *render = NULL;
  gboolean in_seg = FALSE;
  guint64 clip_start = 0, clip_stop = 0;

  render = GST_TTML_RENDER (parent);

  GST_TTML_RENDER_LOCK (render);

  if (render->text_flushing) {
    GST_TTML_RENDER_UNLOCK (render);
    ret = GST_FLOW_FLUSHING;
    GST_LOG_OBJECT (render, "text flushing");
    goto beach;
  }

  if (render->text_eos) {
    GST_TTML_RENDER_UNLOCK (render);
    ret = GST_FLOW_EOS;
    GST_LOG_OBJECT (render, "text EOS");
    goto beach;
  }

  GST_LOG_OBJECT (render, "%" GST_SEGMENT_FORMAT "  BUFFER: ts=%"
      GST_TIME_FORMAT ", end=%" GST_TIME_FORMAT, &render->segment,
      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)),
      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer) +
          GST_BUFFER_DURATION (buffer)));

  if (G_LIKELY (GST_BUFFER_TIMESTAMP_IS_VALID (buffer))) {
    GstClockTime stop;

    if (G_LIKELY (GST_BUFFER_DURATION_IS_VALID (buffer)))
      stop = GST_BUFFER_TIMESTAMP (buffer) + GST_BUFFER_DURATION (buffer);
    else
      stop = GST_CLOCK_TIME_NONE;

    in_seg = gst_segment_clip (&render->text_segment, GST_FORMAT_TIME,
        GST_BUFFER_TIMESTAMP (buffer), stop, &clip_start, &clip_stop);
  } else {
    in_seg = TRUE;
  }

  if (in_seg) {
    if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer))
      GST_BUFFER_TIMESTAMP (buffer) = clip_start;
    else if (GST_BUFFER_DURATION_IS_VALID (buffer))
      GST_BUFFER_DURATION (buffer) = clip_stop - clip_start;

    /* Wait for the previous buffer to go away */
    while (render->text_buffer != NULL) {
      GST_DEBUG ("Pad %s:%s has a buffer queued, waiting",
          GST_DEBUG_PAD_NAME (pad));
      GST_TTML_RENDER_WAIT (render);
      GST_DEBUG ("Pad %s:%s resuming", GST_DEBUG_PAD_NAME (pad));
      if (render->text_flushing) {
        GST_TTML_RENDER_UNLOCK (render);
        ret = GST_FLOW_FLUSHING;
        goto beach;
      }
    }

    if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer))
      render->text_segment.position = clip_start;

    render->text_buffer = buffer;
    /* That's a new text buffer we need to render */
    render->need_render = TRUE;

    /* in case the video chain is waiting for a text buffer, wake it up */
    GST_TTML_RENDER_BROADCAST (render);
  }

  GST_TTML_RENDER_UNLOCK (render);

beach:

  return ret;
}


/* Caller needs to free returned string after use. */
static gchar *
gst_ttml_render_color_to_string (GstSubtitleColor color)
{
#if PANGO_VERSION_CHECK (1,38,0)
  return g_strdup_printf ("#%02x%02x%02x%02x",
      color.r, color.g, color.b, color.a);
#else
  return g_strdup_printf ("#%02x%02x%02x", color.r, color.g, color.b);
#endif
}


static GstBuffer *
gst_ttml_render_draw_rectangle (guint width, guint height,
    GstSubtitleColor color)
{
  GstMapInfo map;
  cairo_surface_t *surface;
  cairo_t *cairo_state;
  GstBuffer *buffer = gst_buffer_new_allocate (NULL, 4 * width * height, NULL);

  gst_buffer_map (buffer, &map, GST_MAP_READWRITE);
  surface = cairo_image_surface_create_for_data (map.data,
      CAIRO_FORMAT_ARGB32, width, height, width * 4);
  cairo_state = cairo_create (surface);

  /* clear surface */
  cairo_set_operator (cairo_state, CAIRO_OPERATOR_CLEAR);
  cairo_paint (cairo_state);
  cairo_set_operator (cairo_state, CAIRO_OPERATOR_OVER);

  cairo_save (cairo_state);
  cairo_set_source_rgba (cairo_state, color.r / 255.0, color.g / 255.0,
      color.b / 255.0, color.a / 255.0);
  cairo_paint (cairo_state);
  cairo_restore (cairo_state);
  cairo_destroy (cairo_state);
  cairo_surface_destroy (surface);
  gst_buffer_unmap (buffer, &map);

  return buffer;
}


static void
gst_ttml_render_char_range_free (CharRange * range)
{
  g_slice_free (CharRange, range);
}


/* Choose fonts for generic fontnames based upon IMSC1 and HbbTV specs. */
static gchar *
gst_ttml_render_resolve_generic_fontname (const gchar * name)
{
  if ((g_strcmp0 (name, "default") == 0)) {
    return
        g_strdup ("TiresiasScreenfont,Liberation Mono,Courier New,monospace");
  } else if ((g_strcmp0 (name, "monospace") == 0)) {
    return g_strdup ("Letter Gothic,Liberation Mono,Courier New,monospace");
  } else if ((g_strcmp0 (name, "sansSerif") == 0)) {
    return g_strdup ("TiresiasScreenfont,sans");
  } else if ((g_strcmp0 (name, "serif") == 0)) {
    return g_strdup ("serif");
  } else if ((g_strcmp0 (name, "monospaceSansSerif") == 0)) {
    return g_strdup ("Letter Gothic,monospace");
  } else if ((g_strcmp0 (name, "monospaceSerif") == 0)) {
    return g_strdup ("Courier New,Liberation Mono,monospace");
  } else if ((g_strcmp0 (name, "proportionalSansSerif") == 0)) {
    return g_strdup ("TiresiasScreenfont,Arial,Helvetica,Liberation Sans,sans");
  } else if ((g_strcmp0 (name, "proportionalSerif") == 0)) {
    return g_strdup ("serif");
  } else {
    return NULL;
  }
}


static gchar *
gst_ttml_render_get_text_from_buffer (GstBuffer * buf, guint index)
{
  GstMapInfo map;
  GstMemory *mem;
  gchar *buf_text = NULL;

  mem = gst_buffer_get_memory (buf, index);
  if (!mem) {
    GST_CAT_ERROR (ttmlrender_debug, "Failed to access memory at index %u.",
        index);
    return NULL;
  }

  if (!gst_memory_map (mem, &map, GST_MAP_READ)) {
    GST_CAT_ERROR (ttmlrender_debug, "Failed to map memory at index %u.",
        index);
    goto map_fail;
  }

  buf_text = g_strndup ((const gchar *) map.data, map.size);
  if (!g_utf8_validate (buf_text, -1, NULL)) {
    GST_CAT_ERROR (ttmlrender_debug, "Text in buffer us not valid UTF-8");
    g_free (buf_text);
    buf_text = NULL;
  }

  gst_memory_unmap (mem, &map);
map_fail:
  gst_memory_unref (mem);
  return buf_text;
}


static void
gst_ttml_render_unified_element_free (UnifiedElement * unified_element)
{
  if (!unified_element)
    return;

  gst_subtitle_element_unref (unified_element->element);
  g_free (unified_element->text);
  g_slice_free (UnifiedElement, unified_element);
}


static UnifiedElement *
gst_ttml_render_unified_element_copy (const UnifiedElement * unified_element)
{
  UnifiedElement *ret;

  if (!unified_element)
    return NULL;

  ret = g_slice_new0 (UnifiedElement);
  ret->element = gst_subtitle_element_ref (unified_element->element);
  ret->pango_font_size = unified_element->pango_font_size;
  ret->pango_font_metrics.height = unified_element->pango_font_metrics.height;
  ret->pango_font_metrics.baseline =
      unified_element->pango_font_metrics.baseline;
  ret->text = g_strdup (unified_element->text);

  return ret;
}


static void
gst_ttml_render_unified_block_free (UnifiedBlock * unified_block)
{
  if (!unified_block)
    return;

  gst_subtitle_style_set_unref (unified_block->style_set);
  g_ptr_array_unref (unified_block->unified_elements);
  g_free (unified_block->joined_text);
  g_slice_free (UnifiedBlock, unified_block);
}


static UnifiedElement *
gst_ttml_render_unified_block_get_element (const UnifiedBlock * block,
    guint index)
{
  if (index >= block->unified_elements->len)
    return NULL;
  else
    return g_ptr_array_index (block->unified_elements, index);
}


static UnifiedBlock *
gst_ttml_render_unified_block_copy (const UnifiedBlock * block)
{
  UnifiedBlock *ret;
  gint i;

  if (!block)
    return NULL;

  ret = g_slice_new0 (UnifiedBlock);
  ret->joined_text = g_strdup (block->joined_text);
  ret->style_set = gst_subtitle_style_set_ref (block->style_set);
  ret->unified_elements = g_ptr_array_new_with_free_func ((GDestroyNotify)
      gst_ttml_render_unified_element_free);

  for (i = 0; i < block->unified_elements->len; ++i) {
    UnifiedElement *ue = gst_ttml_render_unified_block_get_element (block, i);
    UnifiedElement *ue_copy = gst_ttml_render_unified_element_copy (ue);
    g_ptr_array_add (ret->unified_elements, ue_copy);
  }

  return ret;
}


static guint
gst_ttml_render_unified_block_element_count (const UnifiedBlock * block)
{
  return block->unified_elements->len;
}


/*
 * Generates pango-markup'd version of @text that would make pango render it
 * with the styling specified by @style_set.
 */
static gchar *
gst_ttml_render_generate_pango_markup (GstSubtitleStyleSet * style_set,
    guint font_height, const gchar * text)
{
  gchar *ret, *font_family, *font_size, *fgcolor;
  const gchar *font_style, *font_weight, *underline;
  gchar *escaped_text = g_markup_escape_text (text, -1);

  fgcolor = gst_ttml_render_color_to_string (style_set->color);
  font_size = g_strdup_printf ("%u", font_height);
  font_family =
      gst_ttml_render_resolve_generic_fontname (style_set->font_family);
  if (!font_family)
    font_family = g_strdup (style_set->font_family);
  font_style = (style_set->font_style ==
      GST_SUBTITLE_FONT_STYLE_NORMAL) ? "normal" : "italic";
  font_weight = (style_set->font_weight ==
      GST_SUBTITLE_FONT_WEIGHT_NORMAL) ? "normal" : "bold";
  underline = (style_set->text_decoration ==
      GST_SUBTITLE_TEXT_DECORATION_UNDERLINE) ? "single" : "none";

  ret = g_strconcat ("<span "
      "fgcolor=\"", fgcolor, "\" ",
      "font=\"", font_size, "px\" ",
      "font_family=\"", font_family, "\" ",
      "font_style=\"", font_style, "\" ",
      "font_weight=\"", font_weight, "\" ",
      "underline=\"", underline, "\" ", ">", escaped_text, "</span>", NULL);

  g_free (fgcolor);
  g_free (font_family);
  g_free (font_size);
  g_free (escaped_text);
  return ret;
}


/*
 * Unfortunately, pango does not expose accurate metrics about fonts (their
 * maximum height and baseline position), so we need to calculate this
 * information ourselves by examining the ink rectangle of a string containing
 * characters that extend to the maximum height/depth of the font.
 */
static FontMetrics
gst_ttml_render_get_pango_font_metrics (GstTtmlRender * render,
    GstSubtitleStyleSet * style_set, guint font_size)
{
  PangoRectangle ink_rect;
  gchar *string;
  FontMetrics ret;

  string = gst_ttml_render_generate_pango_markup (style_set, font_size,
      "Áĺľď¿gqy");
  pango_layout_set_markup (render->layout, string, strlen (string));
  pango_layout_get_pixel_extents (render->layout, &ink_rect, NULL);
  g_free (string);

  ret.height = ink_rect.height;
  ret.baseline = PANGO_PIXELS (pango_layout_get_baseline (render->layout))
      - ink_rect.y;
  return ret;
}


/*
 * Return the font size that you would need to pass to pango in order that the
 * font applied to @element would be rendered at the text height applied to
 * @element.
 */
static guint
gst_ttml_render_get_pango_font_size (GstTtmlRender * render,
    const GstSubtitleElement * element)
{
  guint desired_font_size =
      (guint) ceil (element->style_set->font_size * render->height);
  guint font_size = desired_font_size;
  guint rendered_height = G_MAXUINT;
  FontMetrics metrics;

  while (rendered_height > desired_font_size) {
    metrics =
        gst_ttml_render_get_pango_font_metrics (render, element->style_set,
        font_size);
    rendered_height = metrics.height;
    --font_size;
  }

  return font_size + 1;
}


/*
 * Reunites each element in @block with its text, as extracted from @buf. Also
 * stores the concatenated text from all contained elements to facilitate
 * future processing.
 */
static UnifiedBlock *
gst_ttml_render_unify_block (GstTtmlRender * render,
    const GstSubtitleBlock * block, GstBuffer * buf)
{
  UnifiedBlock *ret = g_slice_new0 (UnifiedBlock);
  guint i;

  ret->unified_elements = g_ptr_array_new_with_free_func ((GDestroyNotify)
      gst_ttml_render_unified_element_free);
  ret->style_set = gst_subtitle_style_set_ref (block->style_set);
  ret->joined_text = g_strdup ("");

  for (i = 0; i < gst_subtitle_block_get_element_count (block); ++i) {
    gchar *text;
    UnifiedElement *ue = g_slice_new0 (UnifiedElement);
    ue->element =
        gst_subtitle_element_ref (gst_subtitle_block_get_element (block, i));
    ue->pango_font_size =
        gst_ttml_render_get_pango_font_size (render, ue->element);
    ue->pango_font_metrics =
        gst_ttml_render_get_pango_font_metrics (render, ue->element->style_set,
        ue->pango_font_size);
    ue->text =
        gst_ttml_render_get_text_from_buffer (buf, ue->element->text_index);
    g_ptr_array_add (ret->unified_elements, ue);

    text = g_strjoin (NULL, ret->joined_text, ue->text, NULL);
    g_free (ret->joined_text);
    ret->joined_text = text;
  }

  return ret;
}


/*
 * Returns index of nearest breakpoint before @index in @block's text. If no
 * breakpoints are found, returns -1.
 */
static gint
gst_ttml_render_get_nearest_breakpoint (const UnifiedBlock * block, guint index)
{
  const gchar *end = block->joined_text + index - 1;

  while ((end = g_utf8_find_prev_char (block->joined_text, end))) {
    gchar buf[6] = { 0 };
    gunichar u = g_utf8_get_char (end);
    gint nbytes = g_unichar_to_utf8 (u, buf);

    if (nbytes == 1 && (buf[0] == 0x20 || buf[0] == 0x9 || buf[0] == 0xD))
      return end - block->joined_text;
  }

  return -1;
}


/* Return the pango markup representation of all the elements in @block. */
static gchar *
gst_ttml_render_generate_block_markup (const UnifiedBlock * block)
{
  gchar *joined_text, *old_text;
  guint element_count = gst_ttml_render_unified_block_element_count (block);
  guint i;

  joined_text = g_strdup ("");

  for (i = 0; i < element_count; ++i) {
    UnifiedElement *ue = gst_ttml_render_unified_block_get_element (block, i);
    gchar *element_markup =
        gst_ttml_render_generate_pango_markup (ue->element->style_set,
        ue->pango_font_size, ue->text);

    old_text = joined_text;
    joined_text = g_strconcat (joined_text, element_markup, NULL);
    GST_CAT_DEBUG (ttmlrender_debug, "Joined text is now: %s", joined_text);

    g_free (element_markup);
    g_free (old_text);
  }

  return joined_text;
}


/*
 * Returns a set of character ranges, which correspond to the ranges of
 * characters from @block that should be rendered on each generated line area.
 * Essentially, this function determines line breaking and wrapping.
 */
static GPtrArray *
gst_ttml_render_get_line_char_ranges (GstTtmlRender * render,
    const UnifiedBlock * block, guint width, gboolean wrap)
{
  gint start_index = 0;
  GPtrArray *line_ranges = g_ptr_array_new_with_free_func ((GDestroyNotify)
      gst_ttml_render_char_range_free);
  PangoRectangle ink_rect;
  gchar *markup;
  gint i;

  /* Handle hard breaks in block text. */
  while (start_index < strlen (block->joined_text)) {
    CharRange *range = g_slice_new0 (CharRange);
    gchar *c = block->joined_text + start_index;
    while (*c != '\0' && *c != '\n')
      ++c;
    range->first_index = start_index;
    range->last_index = (c - block->joined_text) - 1;
    g_ptr_array_add (line_ranges, range);
    start_index = range->last_index + 2;
  }

  if (!wrap)
    return line_ranges;

  GST_CAT_LOG (ttmlrender_debug,
      "After handling breaks, we have the following ranges:");
  for (i = 0; i < line_ranges->len; ++i) {
    CharRange *range = g_ptr_array_index (line_ranges, i);
    GST_CAT_LOG (ttmlrender_debug, "ranges[%d] first:%u  last:%u", i,
        range->first_index, range->last_index);
  }

  markup = gst_ttml_render_generate_block_markup (block);
  pango_layout_set_markup (render->layout, markup, strlen (markup));
  pango_layout_set_width (render->layout, -1);

  pango_layout_get_pixel_extents (render->layout, &ink_rect, NULL);
  GST_CAT_LOG (ttmlrender_debug, "Layout extents - x:%d  y:%d  w:%d  h:%d",
      ink_rect.x, ink_rect.y, ink_rect.width, ink_rect.height);

  /* For each range, wrap if it extends beyond allowed width. */
  for (i = 0; i < line_ranges->len; ++i) {
    CharRange *range, *new_range;
    gint max_line_extent;
    gint end_index = 0;
    gint trailing;
    PangoRectangle rect;
    gboolean within_line;

    do {
      range = g_ptr_array_index (line_ranges, i);
      GST_CAT_LOG (ttmlrender_debug,
          "Seeing if we need to wrap range[%d] - start:%u  end:%u", i,
          range->first_index, range->last_index);

      pango_layout_index_to_pos (render->layout, range->first_index, &rect);
      GST_CAT_LOG (ttmlrender_debug, "First char at x:%d  y:%d", rect.x,
          rect.y);

      max_line_extent = rect.x + (PANGO_SCALE * width);
      GST_CAT_LOG (ttmlrender_debug, "max_line_extent: %d",
          PANGO_PIXELS (max_line_extent));

      within_line =
          pango_layout_xy_to_index (render->layout, max_line_extent, rect.y,
          &end_index, &trailing);

      GST_CAT_LOG (ttmlrender_debug, "Index nearest to breakpoint: %d",
          end_index);

      if (within_line) {
        end_index = gst_ttml_render_get_nearest_breakpoint (block, end_index);

        if (end_index > range->first_index) {
          new_range = g_slice_new0 (CharRange);
          new_range->first_index = end_index + 1;
          new_range->last_index = range->last_index;
          GST_CAT_LOG (ttmlrender_debug,
              "Wrapping line %d; added new range - start:%u  end:%u", i,
              new_range->first_index, new_range->last_index);

          range->last_index = end_index;
          GST_CAT_LOG (ttmlrender_debug,
              "Modified last_index of existing range; range is now start:%u  "
              "end:%u", range->first_index, range->last_index);

          g_ptr_array_insert (line_ranges, ++i, new_range);
        } else {
          GST_CAT_DEBUG (ttmlrender_debug,
              "Couldn't find a suitable breakpoint");
          within_line = FALSE;
        }
      }
    } while (within_line);
  }

  g_free (markup);
  return line_ranges;
}


/*
 * Returns the index of the element in @block containing the character at index
 * @char_index in @block's text. If @offset is not NULL, sets it to the
 * character offset of @char_index within the element where it is found.
 */
static gint
gst_ttml_render_get_element_index (const UnifiedBlock * block,
    const gint char_index, gint * offset)
{
  gint count = 0;
  gint i;

  if ((char_index < 0) || (char_index >= strlen (block->joined_text)))
    return -1;

  for (i = 0; i < gst_ttml_render_unified_block_element_count (block); ++i) {
    UnifiedElement *ue = gst_ttml_render_unified_block_get_element (block, i);
    if ((char_index >= count) && (char_index < (count + strlen (ue->text)))) {
      if (offset)
        *offset = char_index - count;
      break;
    }
    count += strlen (ue->text);
  }

  return i;
}


static guint
gst_ttml_render_strip_leading_spaces (gchar ** string)
{
  gchar *c = *string;

  while (c) {
    gchar buf[6] = { 0 };
    gunichar u = g_utf8_get_char (c);
    gint nbytes = g_unichar_to_utf8 (u, buf);

    if ((nbytes == 1) && (buf[0] == 0x20))
      c = g_utf8_find_next_char (c, c + strlen (*string));
    else
      break;
  }

  if (!c) {
    GST_CAT_DEBUG (ttmlrender_debug,
        "All characters would be removed from string.");
    return 0;
  } else if (c > *string) {
    gchar *tmp = *string;
    *string = g_strdup (c);
    GST_CAT_DEBUG (ttmlrender_debug, "Replacing text \"%s\" with \"%s\"", tmp,
        *string);
    g_free (tmp);
  }

  return strlen (*string);
}


static guint
gst_ttml_render_strip_trailing_spaces (gchar ** string)
{
  gchar *c = *string + strlen (*string) - 1;
  gint nbytes;

  while (c) {
    gchar buf[6] = { 0 };
    gunichar u = g_utf8_get_char (c);
    nbytes = g_unichar_to_utf8 (u, buf);

    if ((nbytes == 1) && (buf[0] == 0x20))
      c = g_utf8_find_prev_char (*string, c);
    else
      break;
  }

  if (!c) {
    GST_CAT_DEBUG (ttmlrender_debug,
        "All characters would be removed from string.");
    return 0;
  } else {
    gchar *tmp = *string;
    *string = g_strndup (*string, (c - *string) + nbytes);
    GST_CAT_DEBUG (ttmlrender_debug, "Replacing text \"%s\" with \"%s\"", tmp,
        *string);
    g_free (tmp);
  }

  return strlen (*string);
}


/*
 * Treating each block in @blocks as a separate line area, conditionally strips
 * space characters from the beginning and end of each line. This function
 * implements the suppress-at-line-break="auto" and
 * white-space-treatment="ignore-if-surrounding-linefeed" behaviours (specified
 * by TTML section 7.2.3) for elements at the start and end of lines that have
 * xml:space="default" applied to them. If stripping whitespace from a block
 * removes all elements of that block, the block will be removed from @blocks.
 * Returns the number of remaining blocks.
 */
static guint
gst_ttml_render_handle_whitespace (GPtrArray * blocks)
{
  gint i;

  for (i = 0; i < blocks->len; ++i) {
    UnifiedBlock *ub = g_ptr_array_index (blocks, i);
    UnifiedElement *ue;
    guint remaining_chars = 0;

    /* Remove leading spaces from line area. */
    while ((gst_ttml_render_unified_block_element_count (ub) > 0)
        && (remaining_chars == 0)) {
      ue = gst_ttml_render_unified_block_get_element (ub, 0);
      if (!ue->element->suppress_whitespace)
        break;
      remaining_chars = gst_ttml_render_strip_leading_spaces (&ue->text);

      if (remaining_chars == 0) {
        g_ptr_array_remove_index (ub->unified_elements, 0);
        GST_CAT_DEBUG (ttmlrender_debug, "Removed first element from block");
      }
    }

    remaining_chars = 0;

    /* Remove trailing spaces from line area. */
    while ((gst_ttml_render_unified_block_element_count (ub) > 0)
        && (remaining_chars == 0)) {
      ue = gst_ttml_render_unified_block_get_element (ub,
          gst_ttml_render_unified_block_element_count (ub) - 1);
      if (!ue->element->suppress_whitespace)
        break;
      remaining_chars = gst_ttml_render_strip_trailing_spaces (&ue->text);

      if (remaining_chars == 0) {
        g_ptr_array_remove_index (ub->unified_elements,
            gst_ttml_render_unified_block_element_count (ub) - 1);
        GST_CAT_DEBUG (ttmlrender_debug, "Removed last element from block");
      }
    }

    if (gst_ttml_render_unified_block_element_count (ub) == 0)
      g_ptr_array_remove_index (blocks, i--);
  }

  return blocks->len;
}


/*
 * Splits a single UnifiedBlock, @block, into an array of separate
 * UnifiedBlocks, according to the character ranges given in @char_ranges.
 * Each resulting UnifiedBlock will contain only the elements to which belong
 * the characters in its corresponding character range; the text of the first
 * and last element in the block will be clipped of any characters before and
 * after, respectively, the first and last characters in the corresponding
 * range.
 */
static GPtrArray *
gst_ttml_render_split_block (UnifiedBlock * block, GPtrArray * char_ranges)
{
  GPtrArray *ret = g_ptr_array_new_with_free_func ((GDestroyNotify)
      gst_ttml_render_unified_block_free);
  gint i;

  for (i = 0; i < char_ranges->len; ++i) {
    gint index;
    gint first_offset = 0;
    gint last_offset = 0;
    CharRange *range = g_ptr_array_index (char_ranges, i);
    UnifiedBlock *clone = gst_ttml_render_unified_block_copy (block);
    UnifiedElement *ue;
    gchar *tmp;

    GST_CAT_LOG (ttmlrender_debug, "range start:%u  end:%u", range->first_index,
        range->last_index);
    index =
        gst_ttml_render_get_element_index (clone, range->last_index,
        &last_offset);
    GST_CAT_LOG (ttmlrender_debug, "Last char in range is in element %d",
        index);

    if (index < 0) {
      GST_CAT_WARNING (ttmlrender_debug, "Range end not found in block text.");
      gst_ttml_render_unified_block_free (clone);
      continue;
    }

    /* Remove elements that are after the one that contains the range end. */
    GST_CAT_LOG (ttmlrender_debug, "There are %d elements in cloned block.",
        gst_ttml_render_unified_block_element_count (clone));
    while (gst_ttml_render_unified_block_element_count (clone) > (index + 1)) {
      GST_CAT_LOG (ttmlrender_debug, "Removing last element in cloned block.");
      g_ptr_array_remove_index (clone->unified_elements, index + 1);
    }

    index =
        gst_ttml_render_get_element_index (clone, range->first_index,
        &first_offset);
    GST_CAT_LOG (ttmlrender_debug, "First char in range is in element %d",
        index);

    if (index < 0) {
      GST_CAT_WARNING (ttmlrender_debug,
          "Range start not found in block text.");
      gst_ttml_render_unified_block_free (clone);
      continue;
    }

    /* Remove elements that are before the one that contains the range start. */
    while (index > 0) {
      GST_CAT_LOG (ttmlrender_debug, "Removing first element in cloned block");
      g_ptr_array_remove_index (clone->unified_elements, 0);
      --index;
    }

    /* Remove characters from first element that are before the range start. */
    ue = gst_ttml_render_unified_block_get_element (clone, 0);
    if (first_offset > 0) {
      tmp = ue->text;
      ue->text = g_strdup (ue->text + first_offset);
      GST_CAT_DEBUG (ttmlrender_debug,
          "First element text has been clipped to \"%s\"", ue->text);
      g_free (tmp);

      if (gst_ttml_render_unified_block_element_count (clone) == 1)
        last_offset -= first_offset;
    }

    /* Remove characters from last element that are after the range end. */
    ue = gst_ttml_render_unified_block_get_element (clone,
        gst_ttml_render_unified_block_element_count (clone) - 1);
    if (last_offset < (strlen (ue->text) - 1)) {
      tmp = ue->text;
      ue->text = g_strndup (ue->text, last_offset + 1);
      GST_CAT_DEBUG (ttmlrender_debug,
          "Last element text has been clipped to \"%s\"", ue->text);
      g_free (tmp);
    }

    if (gst_ttml_render_unified_block_element_count (clone) > 0)
      g_ptr_array_add (ret, clone);
    else
      gst_ttml_render_unified_block_free (clone);
  }

  if (ret->len == 0) {
    GST_CAT_DEBUG (ttmlrender_debug, "No elements remain in clone.");
    g_ptr_array_unref (ret);
    ret = NULL;
  }
  return ret;
}


/* Render the text in a pango-markup string. */
static GstTtmlRenderRenderedImage *
gst_ttml_render_draw_text (GstTtmlRender * render, const gchar * text,
    guint line_height, guint baseline_offset)
{
  GstTtmlRenderRenderedImage *ret;
  cairo_surface_t *surface, *cropped_surface;
  cairo_t *cairo_state, *cropped_state;
  GstMapInfo map;
  PangoRectangle logical_rect, ink_rect;
  guint buf_width, buf_height;
  gint stride;
  gint bounding_box_x1, bounding_box_x2, bounding_box_y1, bounding_box_y2;
  gint baseline;

  ret = gst_ttml_render_rendered_image_new_empty ();

  pango_layout_set_markup (render->layout, text, strlen (text));
  GST_CAT_DEBUG (ttmlrender_debug, "Layout text: \"%s\"",
      pango_layout_get_text (render->layout));
  pango_layout_set_width (render->layout, -1);

  pango_layout_get_pixel_extents (render->layout, &ink_rect, &logical_rect);

  baseline = PANGO_PIXELS (pango_layout_get_baseline (render->layout));

  bounding_box_x1 = MIN (logical_rect.x, ink_rect.x);
  bounding_box_x2 = MAX (logical_rect.x + logical_rect.width,
      ink_rect.x + ink_rect.width);
  bounding_box_y1 = MIN (logical_rect.y, ink_rect.y);
  bounding_box_y2 = MAX (logical_rect.y + logical_rect.height,
      ink_rect.y + ink_rect.height);

  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
      (bounding_box_x2 - bounding_box_x1), (bounding_box_y2 - bounding_box_y1));
  cairo_state = cairo_create (surface);
  cairo_set_operator (cairo_state, CAIRO_OPERATOR_CLEAR);
  cairo_paint (cairo_state);
  cairo_set_operator (cairo_state, CAIRO_OPERATOR_OVER);

  cairo_save (cairo_state);
  pango_cairo_show_layout (cairo_state, render->layout);
  cairo_restore (cairo_state);

  buf_width = bounding_box_x2 - bounding_box_x1;
  buf_height = ink_rect.height;
  GST_CAT_DEBUG (ttmlrender_debug, "Output buffer width: %u  height: %u",
      buf_width, buf_height);

  ret->image = gst_buffer_new_allocate (NULL, 4 * buf_width * buf_height, NULL);
  gst_buffer_memset (ret->image, 0, 0U, 4 * buf_width * buf_height);
  gst_buffer_map (ret->image, &map, GST_MAP_READWRITE);

  stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, buf_width);
  cropped_surface =
      cairo_image_surface_create_for_data (map.data, CAIRO_FORMAT_ARGB32,
      (bounding_box_x2 - bounding_box_x1), ink_rect.height, stride);
  cropped_state = cairo_create (cropped_surface);
  cairo_set_source_surface (cropped_state, surface, -bounding_box_x1,
      -ink_rect.y);
  cairo_rectangle (cropped_state, 0, 0, buf_width, buf_height);
  cairo_fill (cropped_state);

  cairo_destroy (cairo_state);
  cairo_surface_destroy (surface);
  cairo_destroy (cropped_state);
  cairo_surface_destroy (cropped_surface);
  gst_buffer_unmap (ret->image, &map);

  ret->width = buf_width;
  ret->height = buf_height;
  ret->x = 0;
  ret->y = MAX (0, (gint) baseline_offset - (baseline - ink_rect.y));
  return ret;
}


static GstTtmlRenderRenderedImage *
gst_ttml_render_render_block_elements (GstTtmlRender * render,
    UnifiedBlock * block, BlockMetrics block_metrics)
{
  GPtrArray *inline_images = g_ptr_array_new_with_free_func (
      (GDestroyNotify) gst_ttml_render_rendered_image_free);
  GstTtmlRenderRenderedImage *ret = NULL;
  guint line_padding =
      (guint) ceil (block->style_set->line_padding * render->width);
  gint i;

  for (i = 0; i < gst_ttml_render_unified_block_element_count (block); ++i) {
    UnifiedElement *ue = gst_ttml_render_unified_block_get_element (block, i);
    gchar *markup;
    GstTtmlRenderRenderedImage *text_image, *bg_image, *combined_image;
    guint bg_offset, bg_width, bg_height;
    GstBuffer *background;

    markup = gst_ttml_render_generate_pango_markup (ue->element->style_set,
        ue->pango_font_size, ue->text);
    text_image = gst_ttml_render_draw_text (render, markup,
        block_metrics.line_height, block_metrics.baseline_offset);
    g_free (markup);

    if (!block->style_set->fill_line_gap) {
      bg_offset =
          block_metrics.baseline_offset - ue->pango_font_metrics.baseline;
      bg_height = ue->pango_font_metrics.height;
    } else {
      bg_offset = 0;
      bg_height = block_metrics.line_height;
    }
    bg_width = text_image->width;

    if (line_padding > 0) {
      if (i == 0) {
        text_image->x += line_padding;
        bg_width += line_padding;
      }
      if (i == (gst_ttml_render_unified_block_element_count (block) - 1))
        bg_width += line_padding;
    }

    background = gst_ttml_render_draw_rectangle (bg_width, bg_height,
        ue->element->style_set->background_color);
    bg_image = gst_ttml_render_rendered_image_new (background, 0,
        bg_offset, bg_width, bg_height);
    combined_image = gst_ttml_render_rendered_image_combine (bg_image,
        text_image);
    gst_ttml_render_rendered_image_free (bg_image);
    gst_ttml_render_rendered_image_free (text_image);
    g_ptr_array_add (inline_images, combined_image);
  }

  ret = gst_ttml_render_stitch_images (inline_images,
      GST_TTML_DIRECTION_INLINE);
  GST_CAT_DEBUG (ttmlrender_debug,
      "Stitched line image - x:%d  y:%d  w:%u  h:%u",
      ret->x, ret->y, ret->width, ret->height);
  g_ptr_array_unref (inline_images);
  return ret;
}


/*
 * Align the images in @lines according to the multi_row_align and text_align
 * settings in @style_set.
 */
static void
gst_ttml_render_align_line_areas (GPtrArray * lines,
    const GstSubtitleStyleSet * style_set)
{
  guint longest_line_width = 0;
  gint i;

  for (i = 0; i < lines->len; ++i) {
    GstTtmlRenderRenderedImage *line = g_ptr_array_index (lines, i);
    if (line->width > longest_line_width)
      longest_line_width = line->width;
  }

  for (i = 0; i < lines->len; ++i) {
    GstTtmlRenderRenderedImage *line = g_ptr_array_index (lines, i);

    switch (style_set->multi_row_align) {
      case GST_SUBTITLE_MULTI_ROW_ALIGN_CENTER:
        line->x += (gint) round ((longest_line_width - line->width) / 2.0);
        break;
      case GST_SUBTITLE_MULTI_ROW_ALIGN_END:
        line->x += (longest_line_width - line->width);
        break;
      case GST_SUBTITLE_MULTI_ROW_ALIGN_AUTO:
        switch (style_set->text_align) {
          case GST_SUBTITLE_TEXT_ALIGN_CENTER:
            line->x += (gint) round ((longest_line_width - line->width) / 2.0);
            break;
          case GST_SUBTITLE_TEXT_ALIGN_END:
          case GST_SUBTITLE_TEXT_ALIGN_RIGHT:
            line->x += (longest_line_width - line->width);
            break;
          default:
            break;
        }
        break;
      default:
        break;
    }
  }
}


/*
 * Renders each UnifiedBlock in @blocks, and sets the positions of the
 * resulting images according to the line height in @metrics and the alignment
 * settings in @style_set.
 */
static GPtrArray *
gst_ttml_render_layout_blocks (GstTtmlRender * render, GPtrArray * blocks,
    BlockMetrics metrics, const GstSubtitleStyleSet * style_set)
{
  GPtrArray *ret = g_ptr_array_new_with_free_func ((GDestroyNotify)
      gst_ttml_render_rendered_image_free);
  gint i;

  for (i = 0; i < blocks->len; ++i) {
    UnifiedBlock *block = g_ptr_array_index (blocks, i);

    GstTtmlRenderRenderedImage *line =
        gst_ttml_render_render_block_elements (render, block,
        metrics);
    line->y += (i * metrics.line_height);
    g_ptr_array_add (ret, line);
  }

  gst_ttml_render_align_line_areas (ret, style_set);
  return ret;
}


/* If any of an array of elements has line wrapping enabled, returns TRUE. */
static gboolean
gst_ttml_render_elements_are_wrapped (GPtrArray * elements)
{
  GstSubtitleElement *element;
  guint i;

  for (i = 0; i < elements->len; ++i) {
    element = g_ptr_array_index (elements, i);
    if (element->style_set->wrap_option == GST_SUBTITLE_WRAPPING_ON)
      return TRUE;
  }

  return FALSE;
}


/*
 * Return the descender (in pixels) shared by the greatest number of glyphs in
 * @block.
 */
static guint
gst_ttml_render_get_most_frequent_descender (GstTtmlRender * render,
    UnifiedBlock * block)
{
  GHashTable *count_table = g_hash_table_new (g_direct_hash, g_direct_equal);
  GHashTableIter iter;
  gpointer key, value;
  guint max_count = 0;
  guint ret = 0;
  gint i;

  for (i = 0; i < gst_ttml_render_unified_block_element_count (block); ++i) {
    UnifiedElement *ue = gst_ttml_render_unified_block_get_element (block, i);
    guint descender =
        ue->pango_font_metrics.height - ue->pango_font_metrics.baseline;
    guint count;

    if (g_hash_table_contains (count_table, GUINT_TO_POINTER (descender))) {
      count = GPOINTER_TO_UINT (g_hash_table_lookup (count_table,
              GUINT_TO_POINTER (descender)));
      GST_CAT_LOG (ttmlrender_debug,
          "Table already contains %u glyphs with descender %u; increasing "
          "that count to %ld", count, descender,
          count + g_utf8_strlen (ue->text, -1));
      count += g_utf8_strlen (ue->text, -1);
    } else {
      count = g_utf8_strlen (ue->text, -1);
      GST_CAT_LOG (ttmlrender_debug,
          "No glyphs with descender %u; adding entry to table with count of %u",
          descender, count);
    }

    g_hash_table_insert (count_table,
        GUINT_TO_POINTER (descender), GUINT_TO_POINTER (count));
  }

  g_hash_table_iter_init (&iter, count_table);
  while (g_hash_table_iter_next (&iter, &key, &value)) {
    guint descender = GPOINTER_TO_UINT (key);
    guint count = GPOINTER_TO_UINT (value);

    if (count > max_count) {
      max_count = count;
      ret = descender;
    }
  }

  g_hash_table_unref (count_table);
  return ret;
}


static BlockMetrics
gst_ttml_render_get_block_metrics (GstTtmlRender * render, UnifiedBlock * block)
{
  BlockMetrics ret;

  /*
   * The specified behaviour in TTML when lineHeight is "normal" is different
   * from the behaviour when a percentage is given. In the former case, the
   * line height is a percentage (the TTML spec recommends 125%) of the largest
   * font size that is applied to the spans within the block; in the latter
   * case, the line height is the given percentage of the font size that is
   * applied to the block itself.
   */
  if (block->style_set->line_height < 0) {      /* lineHeight="normal" case */
    guint max_text_height = 0;
    guint descender = 0;
    guint i;

    for (i = 0; i < gst_ttml_render_unified_block_element_count (block); ++i) {
      UnifiedElement *ue = gst_ttml_render_unified_block_get_element (block, i);

      if (ue->pango_font_metrics.height > max_text_height) {
        max_text_height = ue->pango_font_metrics.height;
        descender =
            ue->pango_font_metrics.height - ue->pango_font_metrics.baseline;
      }
    }

    GST_CAT_LOG (ttmlrender_debug, "Max descender: %u   Max text height: %u",
        descender, max_text_height);
    ret.line_height = (guint) ceil (max_text_height * 1.25);
    ret.baseline_offset = (guint) ((max_text_height + ret.line_height) / 2.0)
        - descender;
  } else {
    guint descender;
    guint font_size;

    descender = gst_ttml_render_get_most_frequent_descender (render, block);
    GST_CAT_LOG (ttmlrender_debug,
        "Got most frequent descender value of %u pixels.", descender);
    font_size = (guint) ceil (block->style_set->font_size * render->height);
    ret.line_height = (guint) ceil (font_size * block->style_set->line_height);
    ret.baseline_offset = (guint) ((font_size + ret.line_height) / 2.0)
        - descender;
  }

  return ret;
}


static GstTtmlRenderRenderedImage *
gst_ttml_render_rendered_image_new (GstBuffer * image, gint x, gint y,
    guint width, guint height)
{
  GstTtmlRenderRenderedImage *ret;

  ret = g_slice_new0 (GstTtmlRenderRenderedImage);

  ret->image = image;
  ret->x = x;
  ret->y = y;
  ret->width = width;
  ret->height = height;

  return ret;
}


static GstTtmlRenderRenderedImage *
gst_ttml_render_rendered_image_new_empty (void)
{
  return gst_ttml_render_rendered_image_new (NULL, 0, 0, 0, 0);
}


static inline GstTtmlRenderRenderedImage *
gst_ttml_render_rendered_image_copy (GstTtmlRenderRenderedImage * image)
{
  GstTtmlRenderRenderedImage *ret = g_slice_new0 (GstTtmlRenderRenderedImage);

  ret->image = gst_buffer_ref (image->image);
  ret->x = image->x;
  ret->y = image->y;
  ret->width = image->width;
  ret->height = image->height;

  return ret;
}


static void
gst_ttml_render_rendered_image_free (GstTtmlRenderRenderedImage * image)
{
  if (!image)
    return;
  gst_buffer_unref (image->image);
  g_slice_free (GstTtmlRenderRenderedImage, image);
}


/*
 * Combines two rendered image into a single image. The order of arguments is
 * significant: @image2 will be rendered on top of @image1.
 */
static GstTtmlRenderRenderedImage *
gst_ttml_render_rendered_image_combine (GstTtmlRenderRenderedImage * image1,
    GstTtmlRenderRenderedImage * image2)
{
  GstTtmlRenderRenderedImage *ret;
  GstMapInfo map1, map2, map_dest;
  cairo_surface_t *sfc1, *sfc2, *sfc_dest;
  cairo_t *state_dest;

  if (!image1 && !image2)
    return NULL;
  if (image1 && !image2)
    return gst_ttml_render_rendered_image_copy (image1);
  if (image2 && !image1)
    return gst_ttml_render_rendered_image_copy (image2);

  ret = g_slice_new0 (GstTtmlRenderRenderedImage);

  /* Work out dimensions of combined image. */
  ret->x = MIN (image1->x, image2->x);
  ret->y = MIN (image1->y, image2->y);
  ret->width = MAX (image1->x + image1->width, image2->x + image2->width)
      - ret->x;
  ret->height = MAX (image1->y + image1->height, image2->y + image2->height)
      - ret->y;

  GST_CAT_LOG (ttmlrender_debug, "Dimensions of combined image:  x:%u  y:%u  "
      "width:%u  height:%u", ret->x, ret->y, ret->width, ret->height);

  /* Create cairo_surface from src images. */
  gst_buffer_map (image1->image, &map1, GST_MAP_READ);
  sfc1 =
      cairo_image_surface_create_for_data (map1.data, CAIRO_FORMAT_ARGB32,
      image1->width, image1->height,
      cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, image1->width));

  gst_buffer_map (image2->image, &map2, GST_MAP_READ);
  sfc2 =
      cairo_image_surface_create_for_data (map2.data, CAIRO_FORMAT_ARGB32,
      image2->width, image2->height,
      cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, image2->width));

  /* Create cairo_surface for resultant image. */
  ret->image = gst_buffer_new_allocate (NULL, 4 * ret->width * ret->height,
      NULL);
  gst_buffer_memset (ret->image, 0, 0U, 4 * ret->width * ret->height);
  gst_buffer_map (ret->image, &map_dest, GST_MAP_READWRITE);
  sfc_dest =
      cairo_image_surface_create_for_data (map_dest.data, CAIRO_FORMAT_ARGB32,
      ret->width, ret->height,
      cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, ret->width));
  state_dest = cairo_create (sfc_dest);

  /* Blend image1 into destination surface. */
  cairo_set_source_surface (state_dest, sfc1, image1->x - ret->x,
      image1->y - ret->y);
  cairo_rectangle (state_dest, image1->x - ret->x, image1->y - ret->y,
      image1->width, image1->height);
  cairo_fill (state_dest);

  /* Blend image2 into destination surface. */
  cairo_set_source_surface (state_dest, sfc2, image2->x - ret->x,
      image2->y - ret->y);
  cairo_rectangle (state_dest, image2->x - ret->x, image2->y - ret->y,
      image2->width, image2->height);
  cairo_fill (state_dest);

  /* Return destination image. */
  cairo_destroy (state_dest);
  cairo_surface_destroy (sfc1);
  cairo_surface_destroy (sfc2);
  cairo_surface_destroy (sfc_dest);
  gst_buffer_unmap (image1->image, &map1);
  gst_buffer_unmap (image2->image, &map2);
  gst_buffer_unmap (ret->image, &map_dest);

  return ret;
}


static GstTtmlRenderRenderedImage *
gst_ttml_render_rendered_image_crop (GstTtmlRenderRenderedImage * image,
    gint x, gint y, guint width, guint height)
{
  GstTtmlRenderRenderedImage *ret;
  GstMapInfo map_src, map_dest;
  cairo_surface_t *sfc_src, *sfc_dest;
  cairo_t *state_dest;

  if ((x <= image->x) && (y <= image->y) && (width >= image->width)
      && (height >= image->height))
    return gst_ttml_render_rendered_image_copy (image);

  if (image->x >= (x + (gint) width)
      || (image->x + (gint) image->width) <= x
      || image->y >= (y + (gint) height)
      || (image->y + (gint) image->height) <= y) {
    GST_CAT_WARNING (ttmlrender_debug,
        "Crop rectangle doesn't intersect image.");
    return NULL;
  }

  ret = g_slice_new0 (GstTtmlRenderRenderedImage);

  ret->x = MAX (image->x, x);
  ret->y = MAX (image->y, y);
  ret->width = MIN ((image->x + image->width) - ret->x, (x + width) - ret->x);
  ret->height = MIN ((image->y + image->height) - ret->y,
      (y + height) - ret->y);

  GST_CAT_LOG (ttmlrender_debug, "Dimensions of cropped image:  x:%u  y:%u  "
      "width:%u  height:%u", ret->x, ret->y, ret->width, ret->height);

  /* Create cairo_surface from src image. */
  gst_buffer_map (image->image, &map_src, GST_MAP_READ);
  sfc_src =
      cairo_image_surface_create_for_data (map_src.data, CAIRO_FORMAT_ARGB32,
      image->width, image->height,
      cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, image->width));

  /* Create cairo_surface for cropped image. */
  ret->image = gst_buffer_new_allocate (NULL, 4 * ret->width * ret->height,
      NULL);
  gst_buffer_memset (ret->image, 0, 0U, 4 * ret->width * ret->height);
  gst_buffer_map (ret->image, &map_dest, GST_MAP_READWRITE);
  sfc_dest =
      cairo_image_surface_create_for_data (map_dest.data, CAIRO_FORMAT_ARGB32,
      ret->width, ret->height,
      cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, ret->width));
  state_dest = cairo_create (sfc_dest);

  /* Copy section of image1 into destination surface. */
  cairo_set_source_surface (state_dest, sfc_src, (image->x - ret->x),
      (image->y - ret->y));
  cairo_rectangle (state_dest, 0, 0, ret->width, ret->height);
  cairo_fill (state_dest);

  cairo_destroy (state_dest);
  cairo_surface_destroy (sfc_src);
  cairo_surface_destroy (sfc_dest);
  gst_buffer_unmap (image->image, &map_src);
  gst_buffer_unmap (ret->image, &map_dest);

  return ret;
}


static gboolean
gst_ttml_render_color_is_transparent (GstSubtitleColor * color)
{
  return (color->a == 0);
}


/*
 * 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_overlay_images (GPtrArray * images)
{
  GstTtmlRenderRenderedImage *ret = NULL;
  gint i;

  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) {
    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;
}


static GstTtmlRenderRenderedImage *
gst_ttml_render_render_text_block (GstTtmlRender * render,
    const GstSubtitleBlock * block, GstBuffer * text_buf, guint width,
    gboolean overflow)
{
  UnifiedBlock *unified_block;
  BlockMetrics metrics;
  gboolean wrap;
  guint line_padding;
  GPtrArray *ranges;
  GPtrArray *split_blocks;
  GPtrArray *images;
  GstTtmlRenderRenderedImage *rendered_block = NULL;
  gint i;

  unified_block = gst_ttml_render_unify_block (render, block, text_buf);
  metrics = gst_ttml_render_get_block_metrics (render, unified_block);
  wrap = gst_ttml_render_elements_are_wrapped (block->elements);

  line_padding = (guint) ceil (block->style_set->line_padding * render->width);
  ranges = gst_ttml_render_get_line_char_ranges (render, unified_block, width -
      (2 * line_padding), wrap);

  for (i = 0; i < ranges->len; ++i) {
    CharRange *range = g_ptr_array_index (ranges, i);
    GST_CAT_LOG (ttmlrender_debug, "ranges[%d] first:%u  last:%u", i,
        range->first_index, range->last_index);
  }

  split_blocks = gst_ttml_render_split_block (unified_block, ranges);
  if (split_blocks) {
    guint blocks_remining = gst_ttml_render_handle_whitespace (split_blocks);
    GST_CAT_DEBUG (ttmlrender_debug,
        "There are %u blocks remaining after whitespace handling.",
        blocks_remining);

    if (blocks_remining > 0) {
      images = gst_ttml_render_layout_blocks (render, split_blocks, metrics,
          unified_block->style_set);
      rendered_block = gst_ttml_render_overlay_images (images);
      g_ptr_array_unref (images);
    }
    g_ptr_array_unref (split_blocks);
  }

  g_ptr_array_unref (ranges);
  gst_ttml_render_unified_block_free (unified_block);
  return rendered_block;
}


static GstVideoOverlayComposition *
gst_ttml_render_compose_overlay (GstTtmlRenderRenderedImage * image)
{
  GstVideoOverlayRectangle *rectangle;
  GstVideoOverlayComposition *ret = NULL;

  gst_buffer_add_video_meta (image->image, GST_VIDEO_FRAME_FLAG_NONE,
      GST_VIDEO_OVERLAY_COMPOSITION_FORMAT_RGB, image->width, image->height);

  rectangle = gst_video_overlay_rectangle_new_raw (image->image, image->x,
      image->y, image->width, image->height,
      GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA);

  ret = gst_video_overlay_composition_new (rectangle);
  gst_video_overlay_rectangle_unref (rectangle);
  return ret;
}


static GstVideoOverlayComposition *
gst_ttml_render_render_text_region (GstTtmlRender * render,
    GstSubtitleRegion * region, GstBuffer * text_buf)
{
  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;
  GstVideoOverlayComposition *ret = NULL;
  guint i;

  region_width = (guint) (round (region->style_set->extent_w * render->width));
  region_height =
      (guint) (round (region->style_set->extent_h * render->height));
  region_x = (guint) (round (region->style_set->origin_x * render->width));
  region_y = (guint) (round (region->style_set->origin_y * render->height));

  padding_start =
      (guint) (round (region->style_set->padding_start * render->width));
  padding_end =
      (guint) (round (region->style_set->padding_end * render->width));
  padding_before =
      (guint) (round (region->style_set->padding_before * render->height));
  padding_after =
      (guint) (round (region->style_set->padding_after * render->height));

  /* "window" here refers to the section of the region that we're allowed to
   * render into, i.e., the region minus padding. */
  window_x = region_x + padding_start;
  window_y = region_y + padding_before;
  window_width = region_width - (padding_start + padding_end);
  window_height = region_height - (padding_before + padding_after);

  GST_CAT_DEBUG (ttmlrender_debug,
      "Padding: start: %u  end: %u  before: %u  after: %u",
      padding_start, padding_end, padding_before, padding_after);

  /* Render region background, if non-transparent. */
  if (!gst_ttml_render_color_is_transparent (&region->style_set->
          background_color)) {
    GstBuffer *bg_rect;

    bg_rect = gst_ttml_render_draw_rectangle (region_width, region_height,
        region->style_set->background_color);
    region_image = gst_ttml_render_rendered_image_new (bg_rect, region_x,
        region_y, region_width, region_height);
  }

  /* Render each block and append to list. */
  for (i = 0; i < gst_subtitle_region_get_block_count (region); ++i) {
    const GstSubtitleBlock *block;
    GstTtmlRenderRenderedImage *rendered_block, *block_bg_image, *tmp;
    GstBuffer *block_bg_buf;
    gint block_height;

    block = gst_subtitle_region_get_block (region, i);
    rendered_block = gst_ttml_render_render_text_block (render, block, text_buf,
        window_width, TRUE);

    if (!rendered_block)
      continue;

    GST_CAT_LOG (ttmlrender_debug, "rendered_block - x:%d  y:%d  w:%u  h:%u",
        rendered_block->x, rendered_block->y, rendered_block->width,
        rendered_block->height);

    switch (block->style_set->text_align) {
      case GST_SUBTITLE_TEXT_ALIGN_CENTER:
        rendered_block->x
            += (gint) round ((window_width - rendered_block->width) / 2.0);
        break;

      case GST_SUBTITLE_TEXT_ALIGN_RIGHT:
      case GST_SUBTITLE_TEXT_ALIGN_END:
        rendered_block->x += (window_width - rendered_block->width);
        break;

      default:
        break;
    }

    tmp = rendered_block;

    block_height = rendered_block->height + (2 * rendered_block->y);
    block_bg_buf = gst_ttml_render_draw_rectangle (window_width,
        block_height, block->style_set->background_color);
    block_bg_image = gst_ttml_render_rendered_image_new (block_bg_buf, 0, 0,
        window_width, block_height);
    rendered_block = gst_ttml_render_rendered_image_combine (block_bg_image,
        rendered_block);
    gst_ttml_render_rendered_image_free (tmp);
    gst_ttml_render_rendered_image_free (block_bg_image);

    rendered_block->y = 0;
    g_ptr_array_add (rendered_blocks, rendered_block);
  }

  if (rendered_blocks->len > 0) {
    GstTtmlRenderRenderedImage *blocks_image, *tmp;

    blocks_image = gst_ttml_render_stitch_images (rendered_blocks,
        GST_TTML_DIRECTION_BLOCK);
    blocks_image->x += window_x;

    switch (region->style_set->display_align) {
      case GST_SUBTITLE_DISPLAY_ALIGN_BEFORE:
        blocks_image->y = window_y;
        break;
      case GST_SUBTITLE_DISPLAY_ALIGN_CENTER:
        blocks_image->y = region_y + ((gint) ((region_height + padding_before)
                - (padding_after + blocks_image->height))) / 2;
        break;
      case GST_SUBTITLE_DISPLAY_ALIGN_AFTER:
        blocks_image->y = (region_y + region_height)
            - (padding_after + blocks_image->height);
        break;
    }

    if ((region->style_set->overflow == GST_SUBTITLE_OVERFLOW_MODE_HIDDEN)
        && ((blocks_image->height > window_height)
            || (blocks_image->width > window_width))) {
      GstTtmlRenderRenderedImage *tmp = blocks_image;
      blocks_image = gst_ttml_render_rendered_image_crop (blocks_image,
          window_x, window_y, window_width, window_height);
      gst_ttml_render_rendered_image_free (tmp);
    }

    tmp = region_image;
    region_image =
        gst_ttml_render_rendered_image_combine (region_image, blocks_image);
    gst_ttml_render_rendered_image_free (tmp);
    gst_ttml_render_rendered_image_free (blocks_image);
  }

  if (region_image) {
    ret = gst_ttml_render_compose_overlay (region_image);
    gst_ttml_render_rendered_image_free (region_image);
  }

  g_ptr_array_unref (rendered_blocks);
  return ret;
}


static GstFlowReturn
gst_ttml_render_video_chain (GstPad * pad, GstObject * parent,
    GstBuffer * buffer)
{
  GstTtmlRender *render;
  GstFlowReturn ret = GST_FLOW_OK;
  gboolean in_seg = FALSE;
  guint64 start, stop, clip_start = 0, clip_stop = 0;
  gchar *text = NULL;

  render = GST_TTML_RENDER (parent);

  if (!GST_BUFFER_TIMESTAMP_IS_VALID (buffer))
    goto missing_timestamp;

  /* ignore buffers that are outside of the current segment */
  start = GST_BUFFER_TIMESTAMP (buffer);

  if (!GST_BUFFER_DURATION_IS_VALID (buffer)) {
    stop = GST_CLOCK_TIME_NONE;
  } else {
    stop = start + GST_BUFFER_DURATION (buffer);
  }

  GST_LOG_OBJECT (render, "%" GST_SEGMENT_FORMAT "  BUFFER: ts=%"
      GST_TIME_FORMAT ", end=%" GST_TIME_FORMAT, &render->segment,
      GST_TIME_ARGS (start), GST_TIME_ARGS (stop));

  /* segment_clip() will adjust start unconditionally to segment_start if
   * no stop time is provided, so handle this ourselves */
  if (stop == GST_CLOCK_TIME_NONE && start < render->segment.start)
    goto out_of_segment;

  in_seg = gst_segment_clip (&render->segment, GST_FORMAT_TIME, start, stop,
      &clip_start, &clip_stop);

  if (!in_seg)
    goto out_of_segment;

  /* if the buffer is only partially in the segment, fix up stamps */
  if (clip_start != start || (stop != -1 && clip_stop != stop)) {
    GST_DEBUG_OBJECT (render, "clipping buffer timestamp/duration to segment");
    buffer = gst_buffer_make_writable (buffer);
    GST_BUFFER_TIMESTAMP (buffer) = clip_start;
    if (stop != -1)
      GST_BUFFER_DURATION (buffer) = clip_stop - clip_start;
  }

  /* now, after we've done the clipping, fix up end time if there's no
   * duration (we only use those estimated values internally though, we
   * don't want to set bogus values on the buffer itself) */
  if (stop == -1) {
    if (render->info.fps_n && render->info.fps_d) {
      GST_DEBUG_OBJECT (render, "estimating duration based on framerate");
      stop = start + gst_util_uint64_scale_int (GST_SECOND,
          render->info.fps_d, render->info.fps_n);
    } else {
      GST_LOG_OBJECT (render, "no duration, assuming minimal duration");
      stop = start + 1;         /* we need to assume some interval */
    }
  }

  gst_object_sync_values (GST_OBJECT (render), GST_BUFFER_TIMESTAMP (buffer));

wait_for_text_buf:

  GST_TTML_RENDER_LOCK (render);

  if (render->video_flushing)
    goto flushing;

  if (render->video_eos)
    goto have_eos;

  /* Text pad not linked; push input video frame */
  if (!render->text_linked) {
    GST_LOG_OBJECT (render, "Text pad not linked");
    GST_TTML_RENDER_UNLOCK (render);
    ret = gst_pad_push (render->srcpad, buffer);
    goto not_linked;
  }

  /* Text pad linked, check if we have a text buffer queued */
  if (render->text_buffer) {
    gboolean pop_text = FALSE, valid_text_time = TRUE;
    GstClockTime text_start = GST_CLOCK_TIME_NONE;
    GstClockTime text_end = GST_CLOCK_TIME_NONE;
    GstClockTime text_running_time = GST_CLOCK_TIME_NONE;
    GstClockTime text_running_time_end = GST_CLOCK_TIME_NONE;
    GstClockTime vid_running_time, vid_running_time_end;

    /* if the text buffer isn't stamped right, pop it off the
     * queue and display it for the current video frame only */
    if (!GST_BUFFER_TIMESTAMP_IS_VALID (render->text_buffer) ||
        !GST_BUFFER_DURATION_IS_VALID (render->text_buffer)) {
      GST_WARNING_OBJECT (render,
          "Got text buffer with invalid timestamp or duration");
      pop_text = TRUE;
      valid_text_time = FALSE;
    } else {
      text_start = GST_BUFFER_TIMESTAMP (render->text_buffer);
      text_end = text_start + GST_BUFFER_DURATION (render->text_buffer);
    }

    vid_running_time =
        gst_segment_to_running_time (&render->segment, GST_FORMAT_TIME, start);
    vid_running_time_end =
        gst_segment_to_running_time (&render->segment, GST_FORMAT_TIME, stop);

    /* If timestamp and duration are valid */
    if (valid_text_time) {
      text_running_time =
          gst_segment_to_running_time (&render->text_segment,
          GST_FORMAT_TIME, text_start);
      text_running_time_end =
          gst_segment_to_running_time (&render->text_segment,
          GST_FORMAT_TIME, text_end);
    }

    GST_LOG_OBJECT (render, "T: %" GST_TIME_FORMAT " - %" GST_TIME_FORMAT,
        GST_TIME_ARGS (text_running_time),
        GST_TIME_ARGS (text_running_time_end));
    GST_LOG_OBJECT (render, "V: %" GST_TIME_FORMAT " - %" GST_TIME_FORMAT,
        GST_TIME_ARGS (vid_running_time), GST_TIME_ARGS (vid_running_time_end));

    /* Text too old or in the future */
    if (valid_text_time && text_running_time_end <= vid_running_time) {
      /* text buffer too old, get rid of it and do nothing  */
      GST_LOG_OBJECT (render, "text buffer too old, popping");
      pop_text = FALSE;
      gst_ttml_render_pop_text (render);
      GST_TTML_RENDER_UNLOCK (render);
      goto wait_for_text_buf;
    } else if (valid_text_time && vid_running_time_end <= text_running_time) {
      GST_LOG_OBJECT (render, "text in future, pushing video buf");
      GST_TTML_RENDER_UNLOCK (render);
      /* Push the video frame */
      ret = gst_pad_push (render->srcpad, buffer);
    } else {
      if (render->need_render) {
        GstSubtitleRegion *region = NULL;
        GstSubtitleMeta *subtitle_meta = NULL;
        guint i;

        if (render->compositions) {
          g_list_free_full (render->compositions,
              (GDestroyNotify) gst_video_overlay_composition_unref);
          render->compositions = NULL;
        }

        subtitle_meta = gst_buffer_get_subtitle_meta (render->text_buffer);
        if (!subtitle_meta) {
          GST_CAT_WARNING (ttmlrender_debug, "Failed to get subtitle meta.");
        } else {
          for (i = 0; i < subtitle_meta->regions->len; ++i) {
            GstVideoOverlayComposition *composition;
            region = g_ptr_array_index (subtitle_meta->regions, i);
            composition = gst_ttml_render_render_text_region (render, region,
                render->text_buffer);
            if (composition) {
              render->compositions = g_list_append (render->compositions,
                  composition);
            }
          }
        }
        render->need_render = FALSE;
      }

      GST_TTML_RENDER_UNLOCK (render);
      ret = gst_ttml_render_push_frame (render, buffer);

      if (valid_text_time && text_running_time_end <= vid_running_time_end) {
        GST_LOG_OBJECT (render, "text buffer not needed any longer");
        pop_text = TRUE;
      }
    }
    if (pop_text) {
      GST_TTML_RENDER_LOCK (render);
      gst_ttml_render_pop_text (render);
      GST_TTML_RENDER_UNLOCK (render);
    }
  } else {
    gboolean wait_for_text_buf = TRUE;

    if (render->text_eos)
      wait_for_text_buf = FALSE;

    if (!render->wait_text)
      wait_for_text_buf = FALSE;

    /* Text pad linked, but no text buffer available - what now? */
    if (render->text_segment.format == GST_FORMAT_TIME) {
      GstClockTime text_start_running_time, text_position_running_time;
      GstClockTime vid_running_time;

      vid_running_time =
          gst_segment_to_running_time (&render->segment, GST_FORMAT_TIME,
          GST_BUFFER_TIMESTAMP (buffer));
      text_start_running_time =
          gst_segment_to_running_time (&render->text_segment,
          GST_FORMAT_TIME, render->text_segment.start);
      text_position_running_time =
          gst_segment_to_running_time (&render->text_segment,
          GST_FORMAT_TIME, render->text_segment.position);

      if ((GST_CLOCK_TIME_IS_VALID (text_start_running_time) &&
              vid_running_time < text_start_running_time) ||
          (GST_CLOCK_TIME_IS_VALID (text_position_running_time) &&
              vid_running_time < text_position_running_time)) {
        wait_for_text_buf = FALSE;
      }
    }

    if (wait_for_text_buf) {
      GST_DEBUG_OBJECT (render, "no text buffer, need to wait for one");
      GST_TTML_RENDER_WAIT (render);
      GST_DEBUG_OBJECT (render, "resuming");
      GST_TTML_RENDER_UNLOCK (render);
      goto wait_for_text_buf;
    } else {
      GST_TTML_RENDER_UNLOCK (render);
      GST_LOG_OBJECT (render, "no need to wait for a text buffer");
      ret = gst_pad_push (render->srcpad, buffer);
    }
  }

not_linked:
  g_free (text);

  /* Update position */
  render->segment.position = clip_start;

  return ret;

missing_timestamp:
  {
    GST_WARNING_OBJECT (render, "buffer without timestamp, discarding");
    gst_buffer_unref (buffer);
    return GST_FLOW_OK;
  }

flushing:
  {
    GST_TTML_RENDER_UNLOCK (render);
    GST_DEBUG_OBJECT (render, "flushing, discarding buffer");
    gst_buffer_unref (buffer);
    return GST_FLOW_FLUSHING;
  }
have_eos:
  {
    GST_TTML_RENDER_UNLOCK (render);
    GST_DEBUG_OBJECT (render, "eos, discarding buffer");
    gst_buffer_unref (buffer);
    return GST_FLOW_EOS;
  }
out_of_segment:
  {
    GST_DEBUG_OBJECT (render, "buffer out of segment, discarding");
    gst_buffer_unref (buffer);
    return GST_FLOW_OK;
  }
}

static GstStateChangeReturn
gst_ttml_render_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
  GstTtmlRender *render = GST_TTML_RENDER (element);

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      GST_TTML_RENDER_LOCK (render);
      render->text_flushing = TRUE;
      render->video_flushing = TRUE;
      /* pop_text will broadcast on the GCond and thus also make the video
       * chain exit if it's waiting for a text buffer */
      gst_ttml_render_pop_text (render);
      GST_TTML_RENDER_UNLOCK (render);
      break;
    default:
      break;
  }

  ret = parent_class->change_state (element, transition);
  if (ret == GST_STATE_CHANGE_FAILURE)
    return ret;

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      GST_TTML_RENDER_LOCK (render);
      render->text_flushing = FALSE;
      render->video_flushing = FALSE;
      render->video_eos = FALSE;
      render->text_eos = FALSE;
      gst_segment_init (&render->segment, GST_FORMAT_TIME);
      gst_segment_init (&render->text_segment, GST_FORMAT_TIME);
      GST_TTML_RENDER_UNLOCK (render);
      break;
    default:
      break;
  }

  return ret;
}
