/*
 * Copyright (C) 2009 Sebastian Dröge <sebastian.droege@collabora.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-subtitleoverlay
 * @title: subtitleoverlay
 *
 * #GstBin that auto-magically overlays a video stream with subtitles by
 * autoplugging the required elements.
 *
 * It supports raw, timestamped text, different textual subtitle formats and
 * DVD subpicture subtitles.
 *
 * ## Examples
 * |[
 * gst-launch-1.0 -v filesrc location=test.mkv ! matroskademux name=demux ! video/x-h264 ! queue ! decodebin ! subtitleoverlay name=overlay ! videoconvert ! autovideosink  demux. ! subpicture/x-dvd ! queue ! overlay.
 * ]|
 *  This will play back the given Matroska file with h264 video and dvd subpicture style subtitles.
 *
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "gstsubtitleoverlay.h"

#include <gst/pbutils/missing-plugins.h>
#include <gst/video/video.h>
#include <string.h>

GST_DEBUG_CATEGORY_STATIC (subtitle_overlay_debug);
#define GST_CAT_DEFAULT subtitle_overlay_debug

#define IS_SUBTITLE_CHAIN_IGNORE_ERROR(flow) \
  G_UNLIKELY (flow == GST_FLOW_ERROR || flow == GST_FLOW_NOT_NEGOTIATED)

#define IS_VIDEO_CHAIN_IGNORE_ERROR(flow) \
  G_UNLIKELY (flow == GST_FLOW_ERROR)

static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS_ANY);

static GstStaticPadTemplate video_sinktemplate =
GST_STATIC_PAD_TEMPLATE ("video_sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS_ANY);

static GstStaticPadTemplate subtitle_sinktemplate =
GST_STATIC_PAD_TEMPLATE ("subtitle_sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS_ANY);

enum
{
  PROP_0,
  PROP_SILENT,
  PROP_FONT_DESC,
  PROP_SUBTITLE_ENCODING
};

#define gst_subtitle_overlay_parent_class parent_class
G_DEFINE_TYPE (GstSubtitleOverlay, gst_subtitle_overlay, GST_TYPE_BIN);

static GQuark _subtitle_overlay_event_marker_id = 0;

static void
do_async_start (GstSubtitleOverlay * self)
{
  if (!self->do_async) {
    GstMessage *msg = gst_message_new_async_start (GST_OBJECT_CAST (self));

    GST_DEBUG_OBJECT (self, "Posting async-start");
    GST_BIN_CLASS (parent_class)->handle_message (GST_BIN_CAST (self), msg);
    self->do_async = TRUE;
  }
}

static void
do_async_done (GstSubtitleOverlay * self)
{
  if (self->do_async) {
    GstMessage *msg = gst_message_new_async_done (GST_OBJECT_CAST (self),
        GST_CLOCK_TIME_NONE);

    GST_DEBUG_OBJECT (self, "Posting async-done");
    GST_BIN_CLASS (parent_class)->handle_message (GST_BIN_CAST (self), msg);
    self->do_async = FALSE;
  }
}

static GstPadProbeReturn
_pad_blocked_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data);

static void
block_video (GstSubtitleOverlay * self)
{
  if (self->video_block_id != 0)
    return;

  if (self->video_block_pad) {
    self->video_block_id =
        gst_pad_add_probe (self->video_block_pad,
        GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM, _pad_blocked_cb, self, NULL);
  }
}

static void
unblock_video (GstSubtitleOverlay * self)
{
  if (self->video_block_id) {
    gst_pad_remove_probe (self->video_block_pad, self->video_block_id);
    self->video_sink_blocked = FALSE;
    self->video_block_id = 0;
  }
}

static void
block_subtitle (GstSubtitleOverlay * self)
{
  if (self->subtitle_block_id != 0)
    return;

  if (self->subtitle_block_pad) {
    self->subtitle_block_id =
        gst_pad_add_probe (self->subtitle_block_pad,
        GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM, _pad_blocked_cb, self, NULL);
  }
}

static void
unblock_subtitle (GstSubtitleOverlay * self)
{
  if (self->subtitle_block_id) {
    gst_pad_remove_probe (self->subtitle_block_pad, self->subtitle_block_id);
    self->subtitle_sink_blocked = FALSE;
    self->subtitle_block_id = 0;
  }
}

static gboolean
pad_supports_caps (GstPad * pad, GstCaps * caps)
{
  GstCaps *pad_caps;
  gboolean ret = FALSE;

  pad_caps = gst_pad_query_caps (pad, NULL);
  if (gst_caps_is_subset (caps, pad_caps))
    ret = TRUE;
  gst_caps_unref (pad_caps);

  return ret;
}

static void
gst_subtitle_overlay_finalize (GObject * object)
{
  GstSubtitleOverlay *self = GST_SUBTITLE_OVERLAY (object);

  g_mutex_clear (&self->lock);
  g_mutex_clear (&self->factories_lock);

  if (self->factories)
    gst_plugin_feature_list_free (self->factories);
  self->factories = NULL;
  gst_caps_replace (&self->factory_caps, NULL);

  if (self->font_desc) {
    g_free (self->font_desc);
    self->font_desc = NULL;
  }

  if (self->encoding) {
    g_free (self->encoding);
    self->encoding = NULL;
  }

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

static gboolean
_is_renderer (GstElementFactory * factory)
{
  const gchar *klass, *name;

  klass =
      gst_element_factory_get_metadata (factory, GST_ELEMENT_METADATA_KLASS);
  name = gst_plugin_feature_get_name (GST_PLUGIN_FEATURE_CAST (factory));

  if (klass != NULL) {
    if (strstr (klass, "Overlay/Subtitle") != NULL ||
        strstr (klass, "Overlay/SubPicture") != NULL)
      return TRUE;
    if (strcmp (name, "textoverlay") == 0)
      return TRUE;
  }
  return FALSE;
}

static gboolean
_is_parser (GstElementFactory * factory)
{
  const gchar *klass;

  klass =
      gst_element_factory_get_metadata (factory, GST_ELEMENT_METADATA_KLASS);

  if (klass != NULL && strstr (klass, "Parser/Subtitle") != NULL)
    return TRUE;
  return FALSE;
}

static const gchar *const _sub_pad_names[] = { "subpicture", "subpicture_sink",
  "text", "text_sink",
  "subtitle_sink", "subtitle"
};

static gboolean
_is_video_pad (GstPad * pad, gboolean * hw_accelerated)
{
  GstPad *peer = gst_pad_get_peer (pad);
  GstCaps *caps;
  gboolean ret = FALSE;
  const gchar *name;
  guint i;

  if (peer) {
    caps = gst_pad_get_current_caps (peer);
    if (!caps) {
      caps = gst_pad_query_caps (peer, NULL);
    }
    gst_object_unref (peer);
  } else {
    caps = gst_pad_query_caps (pad, NULL);
  }

  for (i = 0; i < gst_caps_get_size (caps) && !ret; i++) {
    name = gst_structure_get_name (gst_caps_get_structure (caps, i));
    if (g_str_equal (name, "video/x-raw")) {
      ret = TRUE;
      if (hw_accelerated)
        *hw_accelerated = FALSE;

    } else if (g_str_has_prefix (name, "video/x-surface")) {
      ret = TRUE;
      if (hw_accelerated)
        *hw_accelerated = TRUE;
    } else {

      ret = FALSE;
      if (hw_accelerated)
        *hw_accelerated = FALSE;
    }
  }

  gst_caps_unref (caps);

  return ret;
}

static GstCaps *
_get_sub_caps (GstElementFactory * factory)
{
  const GList *templates;
  GList *walk;
  gboolean is_parser = _is_parser (factory);

  templates = gst_element_factory_get_static_pad_templates (factory);
  for (walk = (GList *) templates; walk; walk = g_list_next (walk)) {
    GstStaticPadTemplate *templ = walk->data;

    if (templ->direction == GST_PAD_SINK && templ->presence == GST_PAD_ALWAYS) {
      gboolean found = FALSE;

      if (is_parser) {
        found = TRUE;
      } else {
        guint i;

        for (i = 0; i < G_N_ELEMENTS (_sub_pad_names); i++) {
          if (strcmp (templ->name_template, _sub_pad_names[i]) == 0) {
            found = TRUE;
            break;
          }
        }
      }
      if (found)
        return gst_static_caps_get (&templ->static_caps);
    }
  }
  return NULL;
}

static gboolean
_factory_filter (GstPluginFeature * feature, GstCaps ** subcaps)
{
  GstElementFactory *factory;
  guint rank;
  const gchar *name;
  const GList *templates;
  GList *walk;
  gboolean is_renderer;
  GstCaps *templ_caps = NULL;
  gboolean have_video_sink = FALSE;

  /* we only care about element factories */
  if (!GST_IS_ELEMENT_FACTORY (feature))
    return FALSE;

  factory = GST_ELEMENT_FACTORY_CAST (feature);

  /* only select elements with autoplugging rank or textoverlay */
  name = gst_plugin_feature_get_name (feature);
  rank = gst_plugin_feature_get_rank (feature);
  if (strcmp ("textoverlay", name) != 0 && rank < GST_RANK_MARGINAL)
    return FALSE;

  /* Check if it's a renderer or a parser */
  if (_is_renderer (factory)) {
    is_renderer = TRUE;
  } else if (_is_parser (factory)) {
    is_renderer = FALSE;
  } else {
    return FALSE;
  }

  /* Check if there's a video sink in case of a renderer */
  if (is_renderer) {
    templates = gst_element_factory_get_static_pad_templates (factory);
    for (walk = (GList *) templates; walk; walk = g_list_next (walk)) {
      GstStaticPadTemplate *templ = walk->data;

      /* we only care about the always-sink templates */
      if (templ->direction == GST_PAD_SINK && templ->presence == GST_PAD_ALWAYS) {
        if (strcmp (templ->name_template, "video") == 0 ||
            strcmp (templ->name_template, "video_sink") == 0) {
          have_video_sink = TRUE;
        }
      }
    }
  }
  templ_caps = _get_sub_caps (factory);

  if (is_renderer && have_video_sink && templ_caps) {
    GST_DEBUG ("Found renderer element %s (%s) with caps %" GST_PTR_FORMAT,
        gst_element_factory_get_metadata (factory,
            GST_ELEMENT_METADATA_LONGNAME),
        gst_plugin_feature_get_name (feature), templ_caps);
    *subcaps = gst_caps_merge (*subcaps, templ_caps);
    return TRUE;
  } else if (!is_renderer && !have_video_sink && templ_caps) {
    GST_DEBUG ("Found parser element %s (%s) with caps %" GST_PTR_FORMAT,
        gst_element_factory_get_metadata (factory,
            GST_ELEMENT_METADATA_LONGNAME),
        gst_plugin_feature_get_name (feature), templ_caps);
    *subcaps = gst_caps_merge (*subcaps, templ_caps);
    return TRUE;
  } else {
    if (templ_caps)
      gst_caps_unref (templ_caps);
    return FALSE;
  }
}

/* Call with factories_lock! */
static gboolean
gst_subtitle_overlay_update_factory_list (GstSubtitleOverlay * self)
{
  GstRegistry *registry;
  guint cookie;

  registry = gst_registry_get ();
  cookie = gst_registry_get_feature_list_cookie (registry);
  if (!self->factories || self->factories_cookie != cookie) {
    GstCaps *subcaps;
    GList *factories;

    subcaps = gst_caps_new_empty ();

    factories = gst_registry_feature_filter (registry,
        (GstPluginFeatureFilter) _factory_filter, FALSE, &subcaps);
    GST_DEBUG_OBJECT (self, "Created factory caps: %" GST_PTR_FORMAT, subcaps);
    gst_caps_replace (&self->factory_caps, subcaps);
    gst_caps_unref (subcaps);
    if (self->factories)
      gst_plugin_feature_list_free (self->factories);
    self->factories = factories;
    self->factories_cookie = cookie;
  }

  return (self->factories != NULL);
}

G_LOCK_DEFINE_STATIC (_factory_caps);
static GstCaps *_factory_caps = NULL;
static guint32 _factory_caps_cookie = 0;

GstCaps *
gst_subtitle_overlay_create_factory_caps (void)
{
  GstRegistry *registry;
  GList *factories;
  GstCaps *subcaps = NULL;
  guint cookie;

  registry = gst_registry_get ();
  cookie = gst_registry_get_feature_list_cookie (registry);
  G_LOCK (_factory_caps);
  if (!_factory_caps || _factory_caps_cookie != cookie) {
    if (_factory_caps)
      gst_caps_unref (_factory_caps);
    _factory_caps = gst_caps_new_empty ();

    /* The caps is cached */
    GST_MINI_OBJECT_FLAG_SET (_factory_caps,
        GST_MINI_OBJECT_FLAG_MAY_BE_LEAKED);

    factories = gst_registry_feature_filter (registry,
        (GstPluginFeatureFilter) _factory_filter, FALSE, &_factory_caps);
    GST_DEBUG ("Created factory caps: %" GST_PTR_FORMAT, _factory_caps);
    gst_plugin_feature_list_free (factories);
    _factory_caps_cookie = cookie;
  }
  subcaps = gst_caps_ref (_factory_caps);
  G_UNLOCK (_factory_caps);

  return subcaps;
}

static gboolean
check_factory_for_caps (GstElementFactory * factory, const GstCaps * caps)
{
  GstCaps *fcaps = _get_sub_caps (factory);
  gboolean ret = (fcaps) ? gst_caps_is_subset (caps, fcaps) : FALSE;

  if (fcaps)
    gst_caps_unref (fcaps);

  if (ret)
    gst_object_ref (factory);
  return ret;
}

static GList *
gst_subtitle_overlay_get_factories_for_caps (const GList * list,
    const GstCaps * caps)
{
  const GList *walk = list;
  GList *result = NULL;

  while (walk) {
    GstElementFactory *factory = walk->data;

    walk = g_list_next (walk);

    if (check_factory_for_caps (factory, caps)) {
      result = g_list_prepend (result, factory);
    }
  }

  return result;
}

static gint
_sort_by_ranks (GstPluginFeature * f1, GstPluginFeature * f2)
{
  gint diff;
  const gchar *rname1, *rname2;

  diff = gst_plugin_feature_get_rank (f2) - gst_plugin_feature_get_rank (f1);
  if (diff != 0)
    return diff;

  /* If the ranks are the same sort by name to get deterministic results */
  rname1 = gst_plugin_feature_get_name (f1);
  rname2 = gst_plugin_feature_get_name (f2);

  diff = strcmp (rname1, rname2);

  return diff;
}

static GstPad *
_get_sub_pad (GstElement * element)
{
  GstPad *pad;
  guint i;

  for (i = 0; i < G_N_ELEMENTS (_sub_pad_names); i++) {
    pad = gst_element_get_static_pad (element, _sub_pad_names[i]);
    if (pad)
      return pad;
  }
  return NULL;
}

static GstPad *
_get_video_pad (GstElement * element)
{
  static const gchar *const pad_names[] = { "video", "video_sink" };
  GstPad *pad;
  guint i;

  for (i = 0; i < G_N_ELEMENTS (pad_names); i++) {
    pad = gst_element_get_static_pad (element, pad_names[i]);
    if (pad)
      return pad;
  }
  return NULL;
}

static gboolean
_create_element (GstSubtitleOverlay * self, GstElement ** element,
    const gchar * factory_name, GstElementFactory * factory,
    const gchar * element_name, gboolean mandatory)
{
  GstElement *elt;

  g_assert (!factory || !factory_name);

  if (factory_name) {
    elt = gst_element_factory_make (factory_name, element_name);
  } else {
    factory_name =
        gst_plugin_feature_get_name (GST_PLUGIN_FEATURE_CAST (factory));
    elt = gst_element_factory_create (factory, element_name);
  }

  if (G_UNLIKELY (!elt)) {
    if (!factory) {
      GstMessage *msg;

      msg =
          gst_missing_element_message_new (GST_ELEMENT_CAST (self),
          factory_name);
      gst_element_post_message (GST_ELEMENT_CAST (self), msg);

      if (mandatory)
        GST_ELEMENT_ERROR (self, CORE, MISSING_PLUGIN, (NULL),
            ("no '%s' plugin found", factory_name));
      else
        GST_ELEMENT_WARNING (self, CORE, MISSING_PLUGIN, (NULL),
            ("no '%s' plugin found", factory_name));
    } else {
      if (mandatory) {
        GST_ELEMENT_ERROR (self, CORE, FAILED, (NULL),
            ("can't instantiate '%s'", factory_name));
      } else {
        GST_ELEMENT_WARNING (self, CORE, FAILED, (NULL),
            ("can't instantiate '%s'", factory_name));
      }
    }

    return FALSE;
  }

  if (G_UNLIKELY (gst_element_set_state (elt,
              GST_STATE_READY) != GST_STATE_CHANGE_SUCCESS)) {
    gst_object_unref (elt);
    if (mandatory) {
      GST_ELEMENT_ERROR (self, CORE, STATE_CHANGE, (NULL),
          ("failed to set '%s' to READY", factory_name));
    } else {
      GST_WARNING_OBJECT (self, "Failed to set '%s' to READY", factory_name);
    }
    return FALSE;
  }

  if (G_UNLIKELY (!gst_bin_add (GST_BIN_CAST (self), gst_object_ref (elt)))) {
    gst_element_set_state (elt, GST_STATE_NULL);
    gst_object_unref (elt);
    if (mandatory) {
      GST_ELEMENT_ERROR (self, CORE, FAILED, (NULL),
          ("failed to add '%s' to subtitleoverlay", factory_name));
    } else {
      GST_WARNING_OBJECT (self, "Failed to add '%s' to subtitleoverlay",
          factory_name);
    }
    return FALSE;
  }

  gst_element_sync_state_with_parent (elt);
  *element = elt;
  return TRUE;
}

static void
_remove_element (GstSubtitleOverlay * self, GstElement ** element)
{
  if (*element) {
    gst_bin_remove (GST_BIN_CAST (self), *element);
    gst_element_set_state (*element, GST_STATE_NULL);
    gst_object_unref (*element);
    *element = NULL;
  }
}

static gboolean
_setup_passthrough (GstSubtitleOverlay * self)
{
  GstPad *src, *sink;
  GstElement *identity;

  GST_DEBUG_OBJECT (self, "Doing video passthrough");

  if (self->passthrough_identity) {
    GST_DEBUG_OBJECT (self, "Already in passthrough mode");
    goto out;
  }

  /* Unlink & destroy everything */
  gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->srcpad), NULL);
  gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->video_sinkpad), NULL);
  gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->subtitle_sinkpad), NULL);
  self->silent_property = NULL;
  _remove_element (self, &self->post_colorspace);
  _remove_element (self, &self->overlay);
  _remove_element (self, &self->parser);
  _remove_element (self, &self->renderer);
  _remove_element (self, &self->pre_colorspace);
  _remove_element (self, &self->passthrough_identity);

  if (G_UNLIKELY (!_create_element (self, &self->passthrough_identity,
              "identity", NULL, "passthrough-identity", TRUE))) {
    return FALSE;
  }

  identity = self->passthrough_identity;
  g_object_set (G_OBJECT (identity), "silent", TRUE, "signal-handoffs", FALSE,
      NULL);

  /* Set src ghostpad target */
  src = gst_element_get_static_pad (self->passthrough_identity, "src");
  if (G_UNLIKELY (!src)) {
    GST_ELEMENT_ERROR (self, CORE, PAD, (NULL),
        ("Failed to get srcpad from identity"));
    return FALSE;
  }

  if (G_UNLIKELY (!gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->srcpad),
              src))) {
    GST_ELEMENT_ERROR (self, CORE, PAD, (NULL),
        ("Failed to set srcpad target"));
    gst_object_unref (src);
    return FALSE;
  }
  gst_object_unref (src);

  sink = gst_element_get_static_pad (self->passthrough_identity, "sink");
  if (G_UNLIKELY (!sink)) {
    GST_ELEMENT_ERROR (self, CORE, PAD, (NULL),
        ("Failed to get sinkpad from identity"));
    return FALSE;
  }

  /* Link sink ghostpads to identity */
  if (G_UNLIKELY (!gst_ghost_pad_set_target (GST_GHOST_PAD_CAST
              (self->video_sinkpad), sink))) {
    GST_ELEMENT_ERROR (self, CORE, PAD, (NULL),
        ("Failed to set video sinkpad target"));
    gst_object_unref (sink);
    return FALSE;
  }
  gst_object_unref (sink);

  GST_DEBUG_OBJECT (self, "Video passthrough setup successfully");

out:
  /* Unblock pads */
  unblock_video (self);
  unblock_subtitle (self);

  return TRUE;
}

/* Must be called with subtitleoverlay lock! */
static gboolean
_has_property_with_type (GObject * object, const gchar * property, GType type)
{
  GObjectClass *gobject_class;
  GParamSpec *pspec;

  gobject_class = G_OBJECT_GET_CLASS (object);
  pspec = g_object_class_find_property (gobject_class, property);
  return (pspec && pspec->value_type == type);
}

static void
gst_subtitle_overlay_set_fps (GstSubtitleOverlay * self)
{
  if (!self->parser || self->fps_d == 0)
    return;

  if (!_has_property_with_type (G_OBJECT (self->parser), "video-fps",
          GST_TYPE_FRACTION))
    return;

  GST_DEBUG_OBJECT (self, "Updating video-fps property in parser");
  g_object_set (self->parser, "video-fps", self->fps_n, self->fps_d, NULL);
}

static const gchar *
_get_silent_property (GstElement * element, gboolean * invert)
{
  static const struct
  {
    const gchar *name;
    gboolean invert;
  } properties[] = { {
  "silent", FALSE}, {
  "enable", TRUE}};
  guint i;

  for (i = 0; i < G_N_ELEMENTS (properties); i++) {
    if (_has_property_with_type (G_OBJECT (element), properties[i].name,
            G_TYPE_BOOLEAN)) {
      *invert = properties[i].invert;
      return properties[i].name;
    }
  }
  return NULL;
}

static gboolean
_setup_parser (GstSubtitleOverlay * self)
{
  GstPad *video_peer;

  /* Try to get the latest video framerate */
  video_peer = gst_pad_get_peer (self->video_sinkpad);
  if (video_peer) {
    GstCaps *video_caps;
    gint fps_n, fps_d;

    video_caps = gst_pad_get_current_caps (video_peer);
    if (!video_caps) {
      video_caps = gst_pad_query_caps (video_peer, NULL);
      if (!gst_caps_is_fixed (video_caps)) {
        gst_caps_unref (video_caps);
        video_caps = NULL;
      }
    }

    if (video_caps) {
      GstStructure *st = gst_caps_get_structure (video_caps, 0);
      if (gst_structure_get_fraction (st, "framerate", &fps_n, &fps_d)) {
        GST_DEBUG_OBJECT (self, "New video fps: %d/%d", fps_n, fps_d);
        self->fps_n = fps_n;
        self->fps_d = fps_d;
      }
    }

    if (video_caps)
      gst_caps_unref (video_caps);
    gst_object_unref (video_peer);
  }

  if (_has_property_with_type (G_OBJECT (self->parser), "subtitle-encoding",
          G_TYPE_STRING))
    g_object_set (self->parser, "subtitle-encoding", self->encoding, NULL);

  /* Try to set video fps on the parser */
  gst_subtitle_overlay_set_fps (self);


  return TRUE;
}

static gboolean
_setup_renderer (GstSubtitleOverlay * self, GstElement * renderer)
{
  GstElementFactory *factory = gst_element_get_factory (renderer);
  const gchar *name =
      gst_plugin_feature_get_name (GST_PLUGIN_FEATURE_CAST (factory));

  if (strcmp (name, "textoverlay") == 0) {
    /* Set some textoverlay specific properties */
    gst_util_set_object_arg (G_OBJECT (renderer), "halignment", "center");
    gst_util_set_object_arg (G_OBJECT (renderer), "valignment", "bottom");
    g_object_set (G_OBJECT (renderer), "wait-text", FALSE, NULL);
    if (self->font_desc)
      g_object_set (G_OBJECT (renderer), "font-desc", self->font_desc, NULL);
    self->silent_property = "silent";
    self->silent_property_invert = FALSE;
  } else {
    self->silent_property =
        _get_silent_property (renderer, &self->silent_property_invert);
    if (_has_property_with_type (G_OBJECT (renderer), "subtitle-encoding",
            G_TYPE_STRING))
      g_object_set (renderer, "subtitle-encoding", self->encoding, NULL);
    if (_has_property_with_type (G_OBJECT (renderer), "font-desc",
            G_TYPE_STRING))
      g_object_set (renderer, "font-desc", self->font_desc, NULL);
  }

  return TRUE;
}

/* subtitle_src==NULL means: use subtitle_sink ghostpad */
static gboolean
_link_renderer (GstSubtitleOverlay * self, GstElement * renderer,
    GstPad * subtitle_src)
{
  GstPad *sink, *src;
  gboolean is_video, is_hw;

  is_video = _is_video_pad (self->video_sinkpad, &is_hw);

  if (is_video) {
    gboolean render_is_hw;

    /* First check that renderer also supports the video format */
    sink = _get_video_pad (renderer);
    if (G_UNLIKELY (!sink)) {
      GST_WARNING_OBJECT (self, "Can't get video sink from renderer");
      return FALSE;
    }

    if (is_video != _is_video_pad (sink, &render_is_hw) ||
        is_hw != render_is_hw) {
      GST_DEBUG_OBJECT (self, "Renderer doesn't support %s video",
          is_hw ? "surface" : "raw");
      gst_object_unref (sink);
      return FALSE;
    }
    gst_object_unref (sink);

    if (!is_hw) {
      /* First link everything internally */
      if (G_UNLIKELY (!_create_element (self, &self->post_colorspace,
                  COLORSPACE, NULL, "post-colorspace", FALSE))) {
        return FALSE;
      }
      src = gst_element_get_static_pad (renderer, "src");
      if (G_UNLIKELY (!src)) {
        GST_WARNING_OBJECT (self, "Can't get src pad from renderer");
        return FALSE;
      }

      sink = gst_element_get_static_pad (self->post_colorspace, "sink");
      if (G_UNLIKELY (!sink)) {
        GST_WARNING_OBJECT (self, "Can't get sink pad from " COLORSPACE);
        gst_object_unref (src);
        return FALSE;
      }

      if (G_UNLIKELY (gst_pad_link (src, sink) != GST_PAD_LINK_OK)) {
        GST_WARNING_OBJECT (self, "Can't link renderer with " COLORSPACE);
        gst_object_unref (src);
        gst_object_unref (sink);
        return FALSE;
      }
      gst_object_unref (src);
      gst_object_unref (sink);

      if (G_UNLIKELY (!_create_element (self, &self->pre_colorspace,
                  COLORSPACE, NULL, "pre-colorspace", FALSE))) {
        return FALSE;
      }

      sink = _get_video_pad (renderer);
      if (G_UNLIKELY (!sink)) {
        GST_WARNING_OBJECT (self, "Can't get video sink from renderer");
        return FALSE;
      }

      src = gst_element_get_static_pad (self->pre_colorspace, "src");
      if (G_UNLIKELY (!src)) {
        GST_WARNING_OBJECT (self, "Can't get srcpad from " COLORSPACE);
        gst_object_unref (sink);
        return FALSE;
      }

      if (G_UNLIKELY (gst_pad_link (src, sink) != GST_PAD_LINK_OK)) {
        GST_WARNING_OBJECT (self, "Can't link " COLORSPACE " to renderer");
        gst_object_unref (src);
        gst_object_unref (sink);
        return FALSE;
      }
      gst_object_unref (src);
      gst_object_unref (sink);

      /* Set src ghostpad target */
      src = gst_element_get_static_pad (self->post_colorspace, "src");
      if (G_UNLIKELY (!src)) {
        GST_WARNING_OBJECT (self, "Can't get src pad from " COLORSPACE);
        return FALSE;
      }
    } else {
      /* Set src ghostpad target in the harware accelerated case */

      src = gst_element_get_static_pad (renderer, "src");
      if (G_UNLIKELY (!src)) {
        GST_WARNING_OBJECT (self, "Can't get src pad from renderer");
        return FALSE;
      }
    }
  } else {                      /* No video pad */
    GstCaps *allowed_caps, *video_caps = NULL;
    GstPad *video_peer;
    gboolean is_subset = FALSE;

    video_peer = gst_pad_get_peer (self->video_sinkpad);
    if (video_peer) {
      video_caps = gst_pad_get_current_caps (video_peer);
      if (!video_caps) {
        video_caps = gst_pad_query_caps (video_peer, NULL);
      }
      gst_object_unref (video_peer);
    }

    sink = _get_video_pad (renderer);
    if (G_UNLIKELY (!sink)) {
      GST_WARNING_OBJECT (self, "Can't get video sink from renderer");
      if (video_caps)
        gst_caps_unref (video_caps);
      return FALSE;
    }
    allowed_caps = gst_pad_query_caps (sink, NULL);
    gst_object_unref (sink);

    if (allowed_caps && video_caps)
      is_subset = gst_caps_is_subset (video_caps, allowed_caps);

    if (allowed_caps)
      gst_caps_unref (allowed_caps);

    if (video_caps)
      gst_caps_unref (video_caps);

    if (G_UNLIKELY (!is_subset)) {
      GST_WARNING_OBJECT (self, "Renderer with custom caps is not "
          "compatible with video stream");
      return FALSE;
    }

    src = gst_element_get_static_pad (renderer, "src");
    if (G_UNLIKELY (!src)) {
      GST_WARNING_OBJECT (self, "Can't get src pad from renderer");
      return FALSE;
    }
  }

  if (G_UNLIKELY (!gst_ghost_pad_set_target (GST_GHOST_PAD_CAST
              (self->srcpad), src))) {
    GST_WARNING_OBJECT (self, "Can't set srcpad target");
    gst_object_unref (src);
    return FALSE;
  }
  gst_object_unref (src);

  /* Set the sink ghostpad targets */
  if (self->pre_colorspace) {
    sink = gst_element_get_static_pad (self->pre_colorspace, "sink");
    if (G_UNLIKELY (!sink)) {
      GST_WARNING_OBJECT (self, "Can't get sink pad from " COLORSPACE);
      return FALSE;
    }
  } else {
    sink = _get_video_pad (renderer);
    if (G_UNLIKELY (!sink)) {
      GST_WARNING_OBJECT (self, "Can't get sink pad from %" GST_PTR_FORMAT,
          renderer);
      return FALSE;
    }
  }

  if (G_UNLIKELY (!gst_ghost_pad_set_target (GST_GHOST_PAD_CAST
              (self->video_sinkpad), sink))) {
    GST_WARNING_OBJECT (self, "Can't set video sinkpad target");
    gst_object_unref (sink);
    return FALSE;
  }
  gst_object_unref (sink);

  sink = _get_sub_pad (renderer);
  if (G_UNLIKELY (!sink)) {
    GST_WARNING_OBJECT (self, "Failed to get subpad");
    return FALSE;
  }

  if (subtitle_src) {
    if (G_UNLIKELY (gst_pad_link (subtitle_src, sink) != GST_PAD_LINK_OK)) {
      GST_WARNING_OBJECT (self, "Failed to link subtitle srcpad with renderer");
      gst_object_unref (sink);
      return FALSE;
    }
  } else {
    if (G_UNLIKELY (!gst_ghost_pad_set_target (GST_GHOST_PAD_CAST
                (self->subtitle_sinkpad), sink))) {
      GST_WARNING_OBJECT (self, "Failed to set subtitle sink target");
      gst_object_unref (sink);
      return FALSE;
    }
  }
  gst_object_unref (sink);

  return TRUE;
}

static GstPadProbeReturn
_pad_blocked_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
{
  GstSubtitleOverlay *self = GST_SUBTITLE_OVERLAY_CAST (user_data);
  GstCaps *subcaps;
  GList *l, *factories = NULL;

  if (GST_IS_EVENT (info->data)) {
    if (!GST_EVENT_IS_SERIALIZED (info->data)) {
      GST_DEBUG_OBJECT (pad, "Letting non-serialized event %s pass",
          GST_EVENT_TYPE_NAME (info->data));
      return GST_PAD_PROBE_PASS;
    }
    if (GST_EVENT_TYPE (info->data) == GST_EVENT_STREAM_START) {
      GST_DEBUG_OBJECT (pad, "Letting event %s pass",
          GST_EVENT_TYPE_NAME (info->data));
      return GST_PAD_PROBE_PASS;
    }
  }

  GST_DEBUG_OBJECT (pad, "Pad blocked");

  GST_SUBTITLE_OVERLAY_LOCK (self);
  if (pad == self->video_block_pad)
    self->video_sink_blocked = TRUE;
  else if (pad == self->subtitle_block_pad)
    self->subtitle_sink_blocked = TRUE;

  /* Now either both or the video sink are blocked */

  /* Get current subtitle caps */
  subcaps = self->subcaps;
  if (!subcaps) {
    GstPad *peer;

    peer = gst_pad_get_peer (self->subtitle_sinkpad);
    if (peer) {
      subcaps = gst_pad_get_current_caps (peer);
      if (!subcaps) {
        subcaps = gst_pad_query_caps (peer, NULL);
        if (!gst_caps_is_fixed (subcaps)) {
          gst_caps_unref (subcaps);
          subcaps = NULL;
        }
      }
      gst_object_unref (peer);
    }
    gst_caps_replace (&self->subcaps, subcaps);
    if (subcaps)
      gst_caps_unref (subcaps);
  }
  GST_DEBUG_OBJECT (self, "Current subtitle caps: %" GST_PTR_FORMAT, subcaps);

  /* If there are no subcaps but the subtitle sink is blocked upstream
   * must behave wrong as there are no fixed caps set for the first
   * buffer or in-order event after stream-start */
  if (G_UNLIKELY (!subcaps && self->subtitle_sink_blocked)) {
    GST_ELEMENT_WARNING (self, CORE, NEGOTIATION, (NULL),
        ("Subtitle sink is blocked but we have no subtitle caps"));
    subcaps = NULL;
  }

  if (self->subtitle_error || (self->silent && !self->silent_property)) {
    _setup_passthrough (self);
    do_async_done (self);
    goto out;
  }

  /* Now do something with the caps */
  if (subcaps && !self->subtitle_flush) {
    GstPad *target =
        gst_ghost_pad_get_target (GST_GHOST_PAD_CAST (self->subtitle_sinkpad));

    if (target && pad_supports_caps (target, subcaps)) {
      GST_DEBUG_OBJECT (pad, "Target accepts caps");

      gst_object_unref (target);

      /* Unblock pads */
      unblock_video (self);
      unblock_subtitle (self);
      goto out;
    } else if (target) {
      gst_object_unref (target);
    }
  }

  if (self->subtitle_sink_blocked && !self->video_sink_blocked) {
    GST_DEBUG_OBJECT (self, "Subtitle sink blocked but video not blocked");
    block_video (self);
    goto out;
  }

  self->subtitle_flush = FALSE;

  /* Find our factories */
  g_mutex_lock (&self->factories_lock);
  gst_subtitle_overlay_update_factory_list (self);
  if (subcaps) {
    factories =
        gst_subtitle_overlay_get_factories_for_caps (self->factories, subcaps);
    if (!factories) {
      GstMessage *msg;

      msg = gst_missing_decoder_message_new (GST_ELEMENT_CAST (self), subcaps);
      gst_element_post_message (GST_ELEMENT_CAST (self), msg);
      GST_ELEMENT_WARNING (self, CORE, MISSING_PLUGIN, (NULL),
          ("no suitable subtitle plugin found"));
      subcaps = NULL;
      self->subtitle_error = TRUE;
    }
  }
  g_mutex_unlock (&self->factories_lock);

  if (!subcaps) {
    _setup_passthrough (self);
    do_async_done (self);
    goto out;
  }

  /* Now the interesting parts are done: subtitle overlaying! */

  /* Sort the factories by rank */
  factories = g_list_sort (factories, (GCompareFunc) _sort_by_ranks);

  for (l = factories; l; l = l->next) {
    GstElementFactory *factory = l->data;
    gboolean is_renderer = _is_renderer (factory);
    GstPad *sink, *src;

    /* Unlink & destroy everything */

    gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->srcpad), NULL);
    gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->video_sinkpad), NULL);
    gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->subtitle_sinkpad),
        NULL);
    self->silent_property = NULL;
    _remove_element (self, &self->post_colorspace);
    _remove_element (self, &self->overlay);
    _remove_element (self, &self->parser);
    _remove_element (self, &self->renderer);
    _remove_element (self, &self->pre_colorspace);
    _remove_element (self, &self->passthrough_identity);

    GST_DEBUG_OBJECT (self, "Trying factory '%s'",
        GST_STR_NULL (gst_plugin_feature_get_name (GST_PLUGIN_FEATURE_CAST
                (factory))));

    if (G_UNLIKELY ((is_renderer
                && !_create_element (self, &self->renderer, NULL, factory,
                    "renderer", FALSE)) || (!is_renderer
                && !_create_element (self, &self->parser, NULL, factory,
                    "parser", FALSE))))
      continue;

    if (!is_renderer) {
      GstCaps *parser_caps;
      GList *overlay_factories, *k;

      if (!_setup_parser (self))
        continue;

      /* Find our factories */
      src = gst_element_get_static_pad (self->parser, "src");
      parser_caps = gst_pad_query_caps (src, NULL);
      gst_object_unref (src);

      g_assert (parser_caps != NULL);

      g_mutex_lock (&self->factories_lock);
      gst_subtitle_overlay_update_factory_list (self);
      GST_DEBUG_OBJECT (self,
          "Searching overlay factories for caps %" GST_PTR_FORMAT, parser_caps);
      overlay_factories =
          gst_subtitle_overlay_get_factories_for_caps (self->factories,
          parser_caps);
      g_mutex_unlock (&self->factories_lock);

      if (!overlay_factories) {
        GST_WARNING_OBJECT (self,
            "Found no suitable overlay factories for caps %" GST_PTR_FORMAT,
            parser_caps);
        gst_caps_unref (parser_caps);
        continue;
      }
      gst_caps_unref (parser_caps);

      /* Sort the factories by rank */
      overlay_factories =
          g_list_sort (overlay_factories, (GCompareFunc) _sort_by_ranks);

      for (k = overlay_factories; k; k = k->next) {
        GstElementFactory *overlay_factory = k->data;

        GST_DEBUG_OBJECT (self, "Trying overlay factory '%s'",
            GST_STR_NULL (gst_plugin_feature_get_name (GST_PLUGIN_FEATURE_CAST
                    (overlay_factory))));

        /* Try this factory and link it, otherwise unlink everything
         * again and remove the overlay. Up to this point only the
         * parser was instantiated and setup, nothing was linked
         */

        gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->srcpad), NULL);
        gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->video_sinkpad),
            NULL);
        gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->subtitle_sinkpad),
            NULL);
        self->silent_property = NULL;
        _remove_element (self, &self->post_colorspace);
        _remove_element (self, &self->overlay);
        _remove_element (self, &self->pre_colorspace);

        if (!_create_element (self, &self->overlay, NULL, overlay_factory,
                "overlay", FALSE)) {
          GST_DEBUG_OBJECT (self, "Could not create element");
          continue;
        }

        if (!_setup_renderer (self, self->overlay)) {
          GST_DEBUG_OBJECT (self, "Could not setup element");
          continue;
        }

        src = gst_element_get_static_pad (self->parser, "src");
        if (!_link_renderer (self, self->overlay, src)) {
          GST_DEBUG_OBJECT (self, "Could not link element");
          gst_object_unref (src);
          continue;
        }
        gst_object_unref (src);

        /* Everything done here, go out of loop */
        GST_DEBUG_OBJECT (self, "%s is a suitable element",
            GST_STR_NULL (gst_plugin_feature_get_name (GST_PLUGIN_FEATURE_CAST
                    (overlay_factory))));
        break;
      }

      if (overlay_factories)
        gst_plugin_feature_list_free (overlay_factories);

      if (G_UNLIKELY (k == NULL)) {
        GST_WARNING_OBJECT (self, "Failed to find usable overlay factory");
        continue;
      }

      /* Now link subtitle sinkpad of the bin and the parser */
      sink = gst_element_get_static_pad (self->parser, "sink");
      if (!gst_ghost_pad_set_target (GST_GHOST_PAD_CAST
              (self->subtitle_sinkpad), sink)) {
        gst_object_unref (sink);
        continue;
      }
      gst_object_unref (sink);

      /* Everything done here, go out of loop */
      break;
    } else {
      /* Is renderer factory */

      if (!_setup_renderer (self, self->renderer))
        continue;

      /* subtitle_src==NULL means: use subtitle_sink ghostpad */
      if (!_link_renderer (self, self->renderer, NULL))
        continue;

      /* Everything done here, go out of loop */
      break;
    }
  }

  if (G_UNLIKELY (l == NULL)) {
    GST_ELEMENT_WARNING (self, CORE, FAILED, (NULL),
        ("Failed to find any usable factories"));
    self->subtitle_error = TRUE;
    _setup_passthrough (self);
    do_async_done (self);
    goto out;
  }

  GST_DEBUG_OBJECT (self, "Everything worked, unblocking pads");
  unblock_video (self);
  unblock_subtitle (self);
  do_async_done (self);

out:
  if (factories)
    gst_plugin_feature_list_free (factories);
  GST_SUBTITLE_OVERLAY_UNLOCK (self);

  return GST_PAD_PROBE_OK;
}

static GstStateChangeReturn
gst_subtitle_overlay_change_state (GstElement * element,
    GstStateChange transition)
{
  GstSubtitleOverlay *self = GST_SUBTITLE_OVERLAY (element);
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      GST_DEBUG_OBJECT (self, "State change NULL->READY");
      g_mutex_lock (&self->factories_lock);
      if (G_UNLIKELY (!gst_subtitle_overlay_update_factory_list (self))) {
        g_mutex_unlock (&self->factories_lock);
        return GST_STATE_CHANGE_FAILURE;
      }
      g_mutex_unlock (&self->factories_lock);

      GST_SUBTITLE_OVERLAY_LOCK (self);
      /* Set the internal pads to blocking */
      block_video (self);
      block_subtitle (self);
      GST_SUBTITLE_OVERLAY_UNLOCK (self);
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      GST_DEBUG_OBJECT (self, "State change READY->PAUSED");

      self->fps_n = self->fps_d = 0;

      self->subtitle_flush = FALSE;
      self->subtitle_error = FALSE;

      self->downstream_chain_error = FALSE;

      do_async_start (self);
      ret = GST_STATE_CHANGE_ASYNC;

      break;
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      GST_DEBUG_OBJECT (self, "State change PAUSED->PLAYING");
    default:
      break;
  }

  {
    GstStateChangeReturn bret;

    bret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
    GST_DEBUG_OBJECT (self, "Base class state changed returned: %d", bret);
    if (G_UNLIKELY (bret == GST_STATE_CHANGE_FAILURE)) {
      do_async_done (self);
      return ret;
    }

    else if (bret == GST_STATE_CHANGE_ASYNC)
      ret = bret;
    else if (G_UNLIKELY (bret == GST_STATE_CHANGE_NO_PREROLL)) {
      do_async_done (self);
      ret = bret;
    }
  }

  switch (transition) {
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      GST_DEBUG_OBJECT (self, "State change PLAYING->PAUSED");
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      GST_DEBUG_OBJECT (self, "State change PAUSED->READY");

      /* Set the pads back to blocking state */
      GST_SUBTITLE_OVERLAY_LOCK (self);
      block_video (self);
      block_subtitle (self);
      GST_SUBTITLE_OVERLAY_UNLOCK (self);

      do_async_done (self);

      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      GST_DEBUG_OBJECT (self, "State change READY->NULL");

      GST_SUBTITLE_OVERLAY_LOCK (self);
      gst_caps_replace (&self->subcaps, NULL);

      /* Unlink ghost pads */
      gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->srcpad), NULL);
      gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->video_sinkpad), NULL);
      gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->subtitle_sinkpad),
          NULL);

      /* Unblock pads */
      unblock_video (self);
      unblock_subtitle (self);

      /* Remove elements */
      self->silent_property = NULL;
      _remove_element (self, &self->post_colorspace);
      _remove_element (self, &self->overlay);
      _remove_element (self, &self->parser);
      _remove_element (self, &self->renderer);
      _remove_element (self, &self->pre_colorspace);
      _remove_element (self, &self->passthrough_identity);
      GST_SUBTITLE_OVERLAY_UNLOCK (self);

      break;
    default:
      break;
  }

  return ret;
}

static void
gst_subtitle_overlay_handle_message (GstBin * bin, GstMessage * message)
{
  GstSubtitleOverlay *self = GST_SUBTITLE_OVERLAY_CAST (bin);

  if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ERROR) {
    GstObject *src = GST_MESSAGE_SRC (message);

    /* Convert error messages from the subtitle pipeline to
     * warnings and switch to passthrough mode */
    if (src && (
            (self->overlay
                && gst_object_has_as_ancestor (src,
                    GST_OBJECT_CAST (self->overlay))) || (self->parser
                && gst_object_has_as_ancestor (src,
                    GST_OBJECT_CAST (self->parser))) || (self->renderer
                && gst_object_has_as_ancestor (src,
                    GST_OBJECT_CAST (self->renderer))))) {
      GError *err = NULL;
      gchar *debug = NULL;
      GstMessage *wmsg;

      gst_message_parse_error (message, &err, &debug);
      GST_DEBUG_OBJECT (self,
          "Got error message from subtitle element %s: %s (%s)",
          GST_MESSAGE_SRC_NAME (message), GST_STR_NULL (err->message),
          GST_STR_NULL (debug));

      wmsg = gst_message_new_warning (src, err, debug);
      gst_message_unref (message);
      g_error_free (err);
      g_free (debug);
      message = wmsg;

      GST_SUBTITLE_OVERLAY_LOCK (self);
      self->subtitle_error = TRUE;

      block_subtitle (self);
      block_video (self);
      GST_SUBTITLE_OVERLAY_UNLOCK (self);
    }
  }

  GST_BIN_CLASS (parent_class)->handle_message (bin, message);
}

static void
gst_subtitle_overlay_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstSubtitleOverlay *self = GST_SUBTITLE_OVERLAY_CAST (object);

  switch (prop_id) {
    case PROP_SILENT:
      g_value_set_boolean (value, self->silent);
      break;
    case PROP_FONT_DESC:
      GST_SUBTITLE_OVERLAY_LOCK (self);
      g_value_set_string (value, self->font_desc);
      GST_SUBTITLE_OVERLAY_UNLOCK (self);
      break;
    case PROP_SUBTITLE_ENCODING:
      GST_SUBTITLE_OVERLAY_LOCK (self);
      g_value_set_string (value, self->encoding);
      GST_SUBTITLE_OVERLAY_UNLOCK (self);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_subtitle_overlay_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstSubtitleOverlay *self = GST_SUBTITLE_OVERLAY_CAST (object);

  switch (prop_id) {
    case PROP_SILENT:
      GST_SUBTITLE_OVERLAY_LOCK (self);
      self->silent = g_value_get_boolean (value);
      if (self->silent_property) {
        gboolean silent = self->silent;

        if (self->silent_property_invert)
          silent = !silent;

        if (self->overlay)
          g_object_set (self->overlay, self->silent_property, silent, NULL);
        else if (self->renderer)
          g_object_set (self->renderer, self->silent_property, silent, NULL);
      } else {
        block_subtitle (self);
        block_video (self);
      }
      GST_SUBTITLE_OVERLAY_UNLOCK (self);
      break;
    case PROP_FONT_DESC:
      GST_SUBTITLE_OVERLAY_LOCK (self);
      g_free (self->font_desc);
      self->font_desc = g_value_dup_string (value);
      if (self->overlay
          && _has_property_with_type (G_OBJECT (self->overlay), "font-desc",
              G_TYPE_STRING))
        g_object_set (self->overlay, "font-desc", self->font_desc, NULL);
      else if (self->renderer
          && _has_property_with_type (G_OBJECT (self->renderer), "font-desc",
              G_TYPE_STRING))
        g_object_set (self->renderer, "font-desc", self->font_desc, NULL);
      GST_SUBTITLE_OVERLAY_UNLOCK (self);
      break;
    case PROP_SUBTITLE_ENCODING:
      GST_SUBTITLE_OVERLAY_LOCK (self);
      g_free (self->encoding);
      self->encoding = g_value_dup_string (value);
      if (self->renderer
          && _has_property_with_type (G_OBJECT (self->renderer),
              "subtitle-encoding", G_TYPE_STRING))
        g_object_set (self->renderer, "subtitle-encoding", self->encoding,
            NULL);
      if (self->parser
          && _has_property_with_type (G_OBJECT (self->parser),
              "subtitle-encoding", G_TYPE_STRING))
        g_object_set (self->parser, "subtitle-encoding", self->encoding, NULL);
      GST_SUBTITLE_OVERLAY_UNLOCK (self);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_subtitle_overlay_class_init (GstSubtitleOverlayClass * klass)
{
  GObjectClass *gobject_class = (GObjectClass *) klass;
  GstElementClass *element_class = (GstElementClass *) klass;
  GstBinClass *bin_class = (GstBinClass *) klass;

  gobject_class->finalize = gst_subtitle_overlay_finalize;
  gobject_class->set_property = gst_subtitle_overlay_set_property;
  gobject_class->get_property = gst_subtitle_overlay_get_property;

  g_object_class_install_property (gobject_class, PROP_SILENT,
      g_param_spec_boolean ("silent",
          "Silent",
          "Whether to show subtitles", FALSE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_FONT_DESC,
      g_param_spec_string ("font-desc",
          "Subtitle font description",
          "Pango font description of font "
          "to be used for subtitle rendering", NULL,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_SUBTITLE_ENCODING,
      g_param_spec_string ("subtitle-encoding", "subtitle encoding",
          "Encoding to assume if input subtitles are not in UTF-8 encoding. "
          "If not set, the GST_SUBTITLE_ENCODING environment variable will "
          "be checked for an encoding to use. If that is not set either, "
          "ISO-8859-15 will be assumed.", NULL,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  gst_element_class_add_static_pad_template (element_class, &srctemplate);

  gst_element_class_add_static_pad_template (element_class,
      &video_sinktemplate);
  gst_element_class_add_static_pad_template (element_class,
      &subtitle_sinktemplate);

  gst_element_class_set_static_metadata (element_class, "Subtitle Overlay",
      "Video/Overlay/Subtitle",
      "Overlays a video stream with subtitles",
      "Sebastian Dröge <sebastian.droege@collabora.co.uk>");

  element_class->change_state =
      GST_DEBUG_FUNCPTR (gst_subtitle_overlay_change_state);

  bin_class->handle_message =
      GST_DEBUG_FUNCPTR (gst_subtitle_overlay_handle_message);
}

static GstFlowReturn
gst_subtitle_overlay_src_proxy_chain (GstPad * proxypad, GstObject * parent,
    GstBuffer * buffer)
{
  GstPad *ghostpad;
  GstSubtitleOverlay *self;
  GstFlowReturn ret;

  ghostpad = GST_PAD_CAST (parent);
  if (G_UNLIKELY (!ghostpad)) {
    gst_buffer_unref (buffer);
    return GST_FLOW_ERROR;
  }
  self = GST_SUBTITLE_OVERLAY_CAST (gst_pad_get_parent (ghostpad));
  if (G_UNLIKELY (!self || self->srcpad != ghostpad)) {
    gst_buffer_unref (buffer);
    gst_object_unref (ghostpad);
    return GST_FLOW_ERROR;
  }

  ret = gst_proxy_pad_chain_default (proxypad, parent, buffer);

  if (IS_VIDEO_CHAIN_IGNORE_ERROR (ret)) {
    GST_ERROR_OBJECT (self, "Downstream chain error: %s",
        gst_flow_get_name (ret));
    self->downstream_chain_error = TRUE;
  }

  gst_object_unref (self);

  return ret;
}

static gboolean
gst_subtitle_overlay_src_proxy_event (GstPad * proxypad, GstObject * parent,
    GstEvent * event)
{
  GstPad *ghostpad = NULL;
  GstSubtitleOverlay *self = NULL;
  gboolean ret = FALSE;
  const GstStructure *s;

  ghostpad = GST_PAD_CAST (parent);
  if (G_UNLIKELY (!ghostpad))
    goto out;
  self = GST_SUBTITLE_OVERLAY_CAST (gst_pad_get_parent (ghostpad));
  if (G_UNLIKELY (!self || self->srcpad != ghostpad))
    goto out;

  s = gst_event_get_structure (event);
  if (s && gst_structure_id_has_field (s, _subtitle_overlay_event_marker_id)) {
    GST_DEBUG_OBJECT (ghostpad,
        "Dropping event with marker: %" GST_PTR_FORMAT,
        gst_event_get_structure (event));
    gst_event_unref (event);
    event = NULL;
    ret = TRUE;
  } else {
    ret = gst_pad_event_default (proxypad, parent, event);
    event = NULL;
  }

out:
  if (event)
    gst_event_unref (event);
  if (self)
    gst_object_unref (self);

  return ret;
}

static gboolean
gst_subtitle_overlay_video_sink_setcaps (GstSubtitleOverlay * self,
    GstCaps * caps)
{
  GstPad *target;
  gboolean ret = TRUE;
  GstVideoInfo info;

  GST_DEBUG_OBJECT (self, "Setting caps: %" GST_PTR_FORMAT, caps);

  if (!gst_video_info_from_caps (&info, caps)) {
    GST_ERROR_OBJECT (self, "Failed to parse caps");
    ret = FALSE;
    GST_SUBTITLE_OVERLAY_UNLOCK (self);
    goto out;
  }

  target = gst_ghost_pad_get_target (GST_GHOST_PAD_CAST (self->video_sinkpad));

  GST_SUBTITLE_OVERLAY_LOCK (self);

  if (!target || !pad_supports_caps (target, caps)) {
    GST_DEBUG_OBJECT (target, "Target did not accept caps -- reconfiguring");

    block_subtitle (self);
    block_video (self);
  }

  if (self->fps_n != info.fps_n || self->fps_d != info.fps_d) {
    GST_DEBUG_OBJECT (self, "New video fps: %d/%d", info.fps_n, info.fps_d);
    self->fps_n = info.fps_n;
    self->fps_d = info.fps_d;
    gst_subtitle_overlay_set_fps (self);
  }
  GST_SUBTITLE_OVERLAY_UNLOCK (self);

  if (target)
    gst_object_unref (target);

out:

  return ret;
}

static gboolean
gst_subtitle_overlay_video_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event)
{
  GstSubtitleOverlay *self = GST_SUBTITLE_OVERLAY (parent);
  gboolean ret;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CAPS:
    {
      GstCaps *caps;

      gst_event_parse_caps (event, &caps);
      ret = gst_subtitle_overlay_video_sink_setcaps (self, caps);
      if (!ret)
        goto done;
      break;
    }
    default:
      break;
  }

  ret = gst_pad_event_default (pad, parent, gst_event_ref (event));

done:
  gst_event_unref (event);

  return ret;
}

static GstFlowReturn
gst_subtitle_overlay_video_sink_chain (GstPad * pad, GstObject * parent,
    GstBuffer * buffer)
{
  GstSubtitleOverlay *self = GST_SUBTITLE_OVERLAY (parent);
  GstFlowReturn ret = gst_proxy_pad_chain_default (pad, parent, buffer);

  if (G_UNLIKELY (self->downstream_chain_error) || self->passthrough_identity) {
    return ret;
  } else if (IS_VIDEO_CHAIN_IGNORE_ERROR (ret)) {
    GST_DEBUG_OBJECT (self, "Subtitle renderer produced chain error: %s",
        gst_flow_get_name (ret));
    GST_SUBTITLE_OVERLAY_LOCK (self);
    self->subtitle_error = TRUE;
    block_subtitle (self);
    block_video (self);
    GST_SUBTITLE_OVERLAY_UNLOCK (self);

    return GST_FLOW_OK;
  }

  return ret;
}

static GstFlowReturn
gst_subtitle_overlay_subtitle_sink_chain (GstPad * pad, GstObject * parent,
    GstBuffer * buffer)
{
  GstSubtitleOverlay *self = GST_SUBTITLE_OVERLAY (parent);

  if (self->subtitle_error) {
    gst_buffer_unref (buffer);
    return GST_FLOW_OK;
  } else {
    GstFlowReturn ret = gst_proxy_pad_chain_default (pad, parent, buffer);

    if (IS_SUBTITLE_CHAIN_IGNORE_ERROR (ret)) {
      GST_DEBUG_OBJECT (self, "Subtitle chain error: %s",
          gst_flow_get_name (ret));
      GST_SUBTITLE_OVERLAY_LOCK (self);
      self->subtitle_error = TRUE;
      block_subtitle (self);
      block_video (self);
      GST_SUBTITLE_OVERLAY_UNLOCK (self);

      return GST_FLOW_OK;
    }

    return ret;
  }
}

static GstCaps *
gst_subtitle_overlay_subtitle_sink_getcaps (GstPad * pad, GstCaps * filter)
{
  GstCaps *ret, *subcaps;

  subcaps = gst_subtitle_overlay_create_factory_caps ();
  if (filter) {
    ret = gst_caps_intersect_full (filter, subcaps, GST_CAPS_INTERSECT_FIRST);
    gst_caps_unref (subcaps);
  } else {
    ret = subcaps;
  }

  return ret;
}

static gboolean
gst_subtitle_overlay_subtitle_sink_setcaps (GstSubtitleOverlay * self,
    GstCaps * caps)
{
  gboolean ret = TRUE;
  GstPad *target = NULL;

  GST_DEBUG_OBJECT (self, "Setting caps: %" GST_PTR_FORMAT, caps);

  target =
      gst_ghost_pad_get_target (GST_GHOST_PAD_CAST (self->subtitle_sinkpad));

  GST_SUBTITLE_OVERLAY_LOCK (self);
  gst_caps_replace (&self->subcaps, caps);

  if (target && pad_supports_caps (target, caps)) {
    GST_DEBUG_OBJECT (self, "Target accepts caps");
    GST_SUBTITLE_OVERLAY_UNLOCK (self);
    goto out;
  }

  GST_DEBUG_OBJECT (self, "Target did not accept caps");

  self->subtitle_error = FALSE;
  block_subtitle (self);
  block_video (self);
  GST_SUBTITLE_OVERLAY_UNLOCK (self);

out:
  if (target)
    gst_object_unref (target);

  return ret;
}

static GstPadLinkReturn
gst_subtitle_overlay_subtitle_sink_link (GstPad * pad, GstObject * parent,
    GstPad * peer)
{
  GstSubtitleOverlay *self = GST_SUBTITLE_OVERLAY (parent);
  GstCaps *caps;

  GST_DEBUG_OBJECT (pad, "Linking pad to peer %" GST_PTR_FORMAT, peer);

  caps = gst_pad_get_current_caps (peer);
  if (!caps) {
    caps = gst_pad_query_caps (peer, NULL);
    if (!gst_caps_is_fixed (caps)) {
      gst_caps_unref (caps);
      caps = NULL;
    }
  }

  if (caps) {
    GST_SUBTITLE_OVERLAY_LOCK (self);
    GST_DEBUG_OBJECT (pad, "Have fixed peer caps: %" GST_PTR_FORMAT, caps);
    gst_caps_replace (&self->subcaps, caps);

    self->subtitle_error = FALSE;

    block_subtitle (self);
    block_video (self);
    GST_SUBTITLE_OVERLAY_UNLOCK (self);
    gst_caps_unref (caps);
  }

  return GST_PAD_LINK_OK;
}

static void
gst_subtitle_overlay_subtitle_sink_unlink (GstPad * pad, GstObject * parent)
{
  GstSubtitleOverlay *self = GST_SUBTITLE_OVERLAY (parent);

  /* FIXME: Can't use gst_pad_get_parent() here because this is called with
   * the object lock from state changes
   */

  GST_DEBUG_OBJECT (pad, "Pad unlinking");
  gst_caps_replace (&self->subcaps, NULL);

  GST_SUBTITLE_OVERLAY_LOCK (self);
  self->subtitle_error = FALSE;

  block_subtitle (self);
  block_video (self);
  GST_SUBTITLE_OVERLAY_UNLOCK (self);
}

static gboolean
gst_subtitle_overlay_subtitle_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event)
{
  GstSubtitleOverlay *self = GST_SUBTITLE_OVERLAY (parent);
  gboolean ret;

  GST_DEBUG_OBJECT (pad, "Got event %" GST_PTR_FORMAT, event);

  if (GST_EVENT_TYPE (event) == GST_EVENT_CUSTOM_DOWNSTREAM_OOB &&
      gst_event_has_name (event, "playsink-custom-subtitle-flush")) {
    GST_DEBUG_OBJECT (pad, "Custom subtitle flush event");
    GST_SUBTITLE_OVERLAY_LOCK (self);
    self->subtitle_flush = TRUE;
    self->subtitle_error = FALSE;
    block_subtitle (self);
    block_video (self);
    GST_SUBTITLE_OVERLAY_UNLOCK (self);

    gst_event_unref (event);
    event = NULL;
    ret = TRUE;
    goto out;
  }

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CAPS:
    {
      GstCaps *caps;

      gst_event_parse_caps (event, &caps);
      ret = gst_subtitle_overlay_subtitle_sink_setcaps (self, caps);
      if (!ret)
        goto out;
      break;
    }
    case GST_EVENT_FLUSH_STOP:
    case GST_EVENT_FLUSH_START:
    case GST_EVENT_SEGMENT:
    case GST_EVENT_EOS:
    {
      GstStructure *structure;

      /* Add our event marker to make sure no events from here go ever outside
       * the element, they're only interesting for our internal elements */
      event = GST_EVENT_CAST (gst_event_make_writable (event));
      structure = gst_event_writable_structure (event);

      gst_structure_id_set (structure, _subtitle_overlay_event_marker_id,
          G_TYPE_BOOLEAN, TRUE, NULL);
      break;
    }
    default:
      break;
  }

  ret = gst_pad_event_default (pad, parent, gst_event_ref (event));

  gst_event_unref (event);

out:
  return ret;
}

static gboolean
gst_subtitle_overlay_subtitle_sink_query (GstPad * pad, GstObject * parent,
    GstQuery * query)
{
  gboolean ret;

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_ACCEPT_CAPS:
    {
      gst_query_set_accept_caps_result (query, TRUE);
      ret = TRUE;
      break;
    }
    case GST_QUERY_CAPS:
    {
      GstCaps *filter, *caps;

      gst_query_parse_caps (query, &filter);
      caps = gst_subtitle_overlay_subtitle_sink_getcaps (pad, 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 void
gst_subtitle_overlay_init (GstSubtitleOverlay * self)
{
  GstPadTemplate *templ;
  GstPad *proxypad = NULL;

  g_mutex_init (&self->lock);
  g_mutex_init (&self->factories_lock);

  templ = gst_static_pad_template_get (&srctemplate);
  self->srcpad = gst_ghost_pad_new_no_target_from_template ("src", templ);
  gst_object_unref (templ);

  proxypad =
      GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD (self->srcpad)));
  gst_pad_set_event_function (proxypad,
      GST_DEBUG_FUNCPTR (gst_subtitle_overlay_src_proxy_event));
  gst_pad_set_chain_function (proxypad,
      GST_DEBUG_FUNCPTR (gst_subtitle_overlay_src_proxy_chain));
  gst_object_unref (proxypad);

  gst_element_add_pad (GST_ELEMENT_CAST (self), self->srcpad);

  templ = gst_static_pad_template_get (&video_sinktemplate);
  self->video_sinkpad =
      gst_ghost_pad_new_no_target_from_template ("video_sink", templ);
  gst_object_unref (templ);
  gst_pad_set_event_function (self->video_sinkpad,
      GST_DEBUG_FUNCPTR (gst_subtitle_overlay_video_sink_event));
  gst_pad_set_chain_function (self->video_sinkpad,
      GST_DEBUG_FUNCPTR (gst_subtitle_overlay_video_sink_chain));

  proxypad =
      GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD
          (self->video_sinkpad)));
  self->video_block_pad = proxypad;
  gst_object_unref (proxypad);
  gst_element_add_pad (GST_ELEMENT_CAST (self), self->video_sinkpad);

  templ = gst_static_pad_template_get (&subtitle_sinktemplate);
  self->subtitle_sinkpad =
      gst_ghost_pad_new_no_target_from_template ("subtitle_sink", templ);
  gst_object_unref (templ);
  gst_pad_set_link_function (self->subtitle_sinkpad,
      GST_DEBUG_FUNCPTR (gst_subtitle_overlay_subtitle_sink_link));
  gst_pad_set_unlink_function (self->subtitle_sinkpad,
      GST_DEBUG_FUNCPTR (gst_subtitle_overlay_subtitle_sink_unlink));
  gst_pad_set_event_function (self->subtitle_sinkpad,
      GST_DEBUG_FUNCPTR (gst_subtitle_overlay_subtitle_sink_event));
  gst_pad_set_query_function (self->subtitle_sinkpad,
      GST_DEBUG_FUNCPTR (gst_subtitle_overlay_subtitle_sink_query));
  gst_pad_set_chain_function (self->subtitle_sinkpad,
      GST_DEBUG_FUNCPTR (gst_subtitle_overlay_subtitle_sink_chain));

  proxypad =
      GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD
          (self->subtitle_sinkpad)));
  self->subtitle_block_pad = proxypad;
  gst_object_unref (proxypad);

  gst_element_add_pad (GST_ELEMENT_CAST (self), self->subtitle_sinkpad);

  self->fps_n = 0;
  self->fps_d = 0;
}

gboolean
gst_subtitle_overlay_plugin_init (GstPlugin * plugin)
{
  GST_DEBUG_CATEGORY_INIT (subtitle_overlay_debug, "subtitleoverlay", 0,
      "Subtitle Overlay");

  _subtitle_overlay_event_marker_id =
      g_quark_from_static_string ("gst-subtitle-overlay-event-marker");

  return gst_element_register (plugin, "subtitleoverlay", GST_RANK_NONE,
      GST_TYPE_SUBTITLE_OVERLAY);
}
