/*
 * 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
 *
 * #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.
 *
 * <refsect2>
 * <title>Examples</title>
 * |[
 * 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.
 * </refsect2>
 */

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