/*
 *  Copyright 2009 Nokia Corporation <multimedia@maemo.org>
 *            2006 Zeeshan Ali <zeeshan.ali@nokia.com>.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

/**
 * SECTION:element-fpsdisplaysink
 *
 * Can display the current and average framerate as a testoverlay or on stdout.
 *
 * <refsect2>
 * <title>Example launch lines</title>
 * |[
 * gst-launch-1.0 videotestsrc ! fpsdisplaysink
 * gst-launch-1.0 videotestsrc ! fpsdisplaysink text-overlay=false
 * gst-launch-1.0 filesrc location=video.avi ! decodebin name=d ! queue ! fpsdisplaysink d. ! queue ! fakesink sync=true
 * gst-launch-1.0 playbin uri=file:///path/to/video.avi video-sink="fpsdisplaysink" audio-sink=fakesink
 * ]|
 * </refsect2>
 */
/* FIXME:
 * - can we avoid plugging the textoverlay?
 * - gst-seek 15 "videotestsrc ! fpsdisplaysink" dies when closing gst-seek
 *
 * NOTE:
 * - if we make ourself RANK_PRIMARY+10 or something that autovideosink would
 *   select and fpsdisplaysink is set to use autovideosink as its internal sink
 *   it doesn't work. Reason: autovideosink creates a fpsdisplaysink, that
 *   creates an autovideosink, that...
 */

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

#include "debugutils-marshal.h"
#include "fpsdisplaysink.h"

#define DEFAULT_SIGNAL_FPS_MEASUREMENTS FALSE
#define DEFAULT_FPS_UPDATE_INTERVAL_MS 500      /* 500 ms */
#define DEFAULT_FONT "Sans 15"
#define DEFAULT_SILENT FALSE
#define DEFAULT_LAST_MESSAGE NULL

/* generic templates */
static GstStaticPadTemplate fps_display_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS_ANY);

GST_DEBUG_CATEGORY_STATIC (fps_display_sink_debug);
#define GST_CAT_DEFAULT fps_display_sink_debug

#define DEFAULT_SYNC TRUE

enum
{
  /* FILL ME */
  SIGNAL_FPS_MEASUREMENTS,
  LAST_SIGNAL
};

enum
{
  PROP_0,
  PROP_SYNC,
  PROP_TEXT_OVERLAY,
  PROP_VIDEO_SINK,
  PROP_FPS_UPDATE_INTERVAL,
  PROP_MAX_FPS,
  PROP_MIN_FPS,
  PROP_SIGNAL_FPS_MEASUREMENTS,
  PROP_FRAMES_DROPPED,
  PROP_FRAMES_RENDERED,
  PROP_SILENT,
  PROP_LAST_MESSAGE
      /* FILL ME */
};

static GstBinClass *parent_class = NULL;

static GstStateChangeReturn fps_display_sink_change_state (GstElement * element,
    GstStateChange transition);
static void fps_display_sink_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void fps_display_sink_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static void fps_display_sink_dispose (GObject * object);
static void fps_display_sink_handle_message (GstBin * bin,
    GstMessage * message);

static gboolean display_current_fps (gpointer data);

static guint fpsdisplaysink_signals[LAST_SIGNAL] = { 0 };

static GParamSpec *pspec_last_message = NULL;

static void
fps_display_sink_class_init (GstFPSDisplaySinkClass * klass)
{
  GObjectClass *gobject_klass = G_OBJECT_CLASS (klass);
  GstElementClass *gstelement_klass = GST_ELEMENT_CLASS (klass);
  GstBinClass *bin_class = GST_BIN_CLASS (klass);

  parent_class = g_type_class_peek_parent (klass);

  gobject_klass->set_property = fps_display_sink_set_property;
  gobject_klass->get_property = fps_display_sink_get_property;
  gobject_klass->dispose = fps_display_sink_dispose;

  bin_class->handle_message = fps_display_sink_handle_message;

  g_object_class_install_property (gobject_klass, PROP_SYNC,
      g_param_spec_boolean ("sync",
          "Sync", "Sync on the clock (if the internally used sink doesn't "
          "have this property it will be ignored", DEFAULT_SYNC,
          G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));

  g_object_class_install_property (gobject_klass, PROP_TEXT_OVERLAY,
      g_param_spec_boolean ("text-overlay",
          "text-overlay",
          "Whether to use text-overlay", TRUE,
          G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));

  g_object_class_install_property (gobject_klass, PROP_VIDEO_SINK,
      g_param_spec_object ("video-sink",
          "video-sink",
          "Video sink to use (Must only be called on NULL state)",
          GST_TYPE_ELEMENT, G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));

  g_object_class_install_property (gobject_klass, PROP_FPS_UPDATE_INTERVAL,
      g_param_spec_int ("fps-update-interval", "Fps update interval",
          "Time between consecutive frames per second measures and update "
          " (in ms). Should be set on NULL state", 1, G_MAXINT,
          DEFAULT_FPS_UPDATE_INTERVAL_MS,
          G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));

  g_object_class_install_property (gobject_klass, PROP_MAX_FPS,
      g_param_spec_double ("max-fps", "Max fps",
          "Maximum fps rate measured. Reset when going from NULL to READY."
          "-1 means no measurement has yet been done", -1, G_MAXDOUBLE, -1,
          G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));

  g_object_class_install_property (gobject_klass, PROP_MIN_FPS,
      g_param_spec_double ("min-fps", "Min fps",
          "Minimum fps rate measured. Reset when going from NULL to READY."
          "-1 means no measurement has yet been done", -1, G_MAXDOUBLE, -1,
          G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));

  g_object_class_install_property (gobject_klass, PROP_FRAMES_DROPPED,
      g_param_spec_uint ("frames-dropped", "dropped frames",
          "Number of frames dropped by the sink", 0, G_MAXUINT, 0,
          G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));

  g_object_class_install_property (gobject_klass, PROP_FRAMES_RENDERED,
      g_param_spec_uint ("frames-rendered", "rendered frames",
          "Number of frames rendered", 0, G_MAXUINT, 0,
          G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));

  g_object_class_install_property (gobject_klass, PROP_SILENT,
      g_param_spec_boolean ("silent", "enable stdout output",
          "Don't produce last_message events", DEFAULT_SILENT,
          G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));

  g_object_class_install_property (gobject_klass, PROP_SIGNAL_FPS_MEASUREMENTS,
      g_param_spec_boolean ("signal-fps-measurements",
          "Signal fps measurements",
          "If the fps-measurements signal should be emited.",
          DEFAULT_SIGNAL_FPS_MEASUREMENTS,
          G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));

  pspec_last_message = g_param_spec_string ("last-message", "Last Message",
      "The message describing current status", DEFAULT_LAST_MESSAGE,
      G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
  g_object_class_install_property (gobject_klass, PROP_LAST_MESSAGE,
      pspec_last_message);

  /**
   * GstFPSDisplaySink::fps-measurements:
   * @fpsdisplaysink: a #GstFPSDisplaySink
   * @fps: The current measured fps
   * @droprate: The rate at which buffers are being dropped
   * @avgfps: The average fps
   *
   * Signals the application about the measured fps
   *
   * Since: 0.10.20
   */
  fpsdisplaysink_signals[SIGNAL_FPS_MEASUREMENTS] =
      g_signal_new ("fps-measurements", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, 0, NULL, NULL,
      __gst_debugutils_marshal_VOID__DOUBLE_DOUBLE_DOUBLE,
      G_TYPE_NONE, 3, G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_DOUBLE);

  gstelement_klass->change_state = fps_display_sink_change_state;

  gst_element_class_add_pad_template (gstelement_klass,
      gst_static_pad_template_get (&fps_display_sink_template));

  gst_element_class_set_static_metadata (gstelement_klass,
      "Measure and show framerate on videosink", "Sink/Video",
      "Shows the current frame-rate and drop-rate of the videosink as overlay or text on stdout",
      "Zeeshan Ali <zeeshan.ali@nokia.com>, Stefan Kost <stefan.kost@nokia.com>");
}

static GstPadProbeReturn
on_video_sink_data_flow (GstPad * pad, GstPadProbeInfo * info,
    gpointer user_data)
{
  GstMiniObject *mini_obj = GST_PAD_PROBE_INFO_DATA (info);
  GstFPSDisplaySink *self = GST_FPS_DISPLAY_SINK (user_data);

  if (GST_IS_BUFFER (mini_obj)) {
    GstClockTime ts;

    /* assume the frame is going to be rendered. If it isnt', we'll get a qos
     * message and reset ->frames_rendered from there.
     */
    g_atomic_int_inc (&self->frames_rendered);

    ts = gst_util_get_timestamp ();
    if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (self->start_ts))) {
      self->interval_ts = self->last_ts = self->start_ts = ts;
    }
    if (GST_CLOCK_DIFF (self->interval_ts, ts) > self->fps_update_interval) {
      display_current_fps (self);
      self->interval_ts = ts;
    }
  }

  return GST_PAD_PROBE_OK;
}

static void
update_sub_sync (GstElement * sink, gpointer data)
{
  /* Some sinks (like autovideosink) don't have the sync property so
   * we check it exists before setting it to avoid a warning at
   * runtime. */
  if (g_object_class_find_property (G_OBJECT_GET_CLASS (sink), "sync"))
    g_object_set (sink, "sync", *((gboolean *) data), NULL);
  else
    GST_WARNING ("Internal sink doesn't have sync property");
}

static void
update_sub_sync_foreach (const GValue * item, gpointer data)
{
  GstElement *sink = g_value_get_object (item);

  update_sub_sync (sink, data);
}

static void
fps_display_sink_update_sink_sync (GstFPSDisplaySink * self)
{
  GstIterator *iterator;

  if (self->video_sink == NULL)
    return;

  if (GST_IS_BIN (self->video_sink)) {
    iterator = gst_bin_iterate_sinks (GST_BIN (self->video_sink));
    gst_iterator_foreach (iterator,
        (GstIteratorForeachFunction) update_sub_sync_foreach,
        (void *) &self->sync);
    gst_iterator_free (iterator);
  } else
    update_sub_sync (self->video_sink, (void *) &self->sync);

}

static void
update_video_sink (GstFPSDisplaySink * self, GstElement * video_sink)
{
  GstPad *sink_pad;

  if (self->video_sink) {

    /* remove pad probe */
    sink_pad = gst_element_get_static_pad (self->video_sink, "sink");
    gst_pad_remove_probe (sink_pad, self->data_probe_id);
    gst_object_unref (sink_pad);
    self->data_probe_id = -1;

    /* remove ghost pad target */
    gst_ghost_pad_set_target (GST_GHOST_PAD (self->ghost_pad), NULL);

    /* remove old sink */
    gst_bin_remove (GST_BIN (self), self->video_sink);
    gst_object_unref (self->video_sink);
  }

  /* create child elements */
  self->video_sink = video_sink;

  if (self->video_sink == NULL)
    return;

  fps_display_sink_update_sink_sync (self);

  /* take a ref before bin takes the ownership */
  gst_object_ref (self->video_sink);

  gst_bin_add (GST_BIN (self), self->video_sink);

  /* attach or pad probe */
  sink_pad = gst_element_get_static_pad (self->video_sink, "sink");
  self->data_probe_id = gst_pad_add_probe (sink_pad,
      GST_PAD_PROBE_TYPE_DATA_BOTH, on_video_sink_data_flow,
      (gpointer) self, NULL);
  gst_object_unref (sink_pad);
}

static void
fps_display_sink_init (GstFPSDisplaySink * self,
    GstFPSDisplaySinkClass * g_class)
{
  self->sync = DEFAULT_SYNC;
  self->signal_measurements = DEFAULT_SIGNAL_FPS_MEASUREMENTS;
  self->use_text_overlay = TRUE;
  self->fps_update_interval = GST_MSECOND * DEFAULT_FPS_UPDATE_INTERVAL_MS;
  self->video_sink = NULL;
  self->max_fps = -1;
  self->min_fps = -1;
  self->silent = DEFAULT_SILENT;
  self->last_message = g_strdup (DEFAULT_LAST_MESSAGE);

  self->ghost_pad = gst_ghost_pad_new_no_target ("sink", GST_PAD_SINK);
  gst_element_add_pad (GST_ELEMENT (self), self->ghost_pad);
}

static gboolean
display_current_fps (gpointer data)
{
  GstFPSDisplaySink *self = GST_FPS_DISPLAY_SINK (data);
  guint64 frames_rendered, frames_dropped;
  gdouble rr, dr, average_fps;
  gchar fps_message[256];
  gdouble time_diff, time_elapsed;
  GstClockTime current_ts = gst_util_get_timestamp ();

  frames_rendered = g_atomic_int_get (&self->frames_rendered);
  frames_dropped = g_atomic_int_get (&self->frames_dropped);

  if ((frames_rendered + frames_dropped) == 0) {
    /* in case timer fired and we didn't yet get any QOS events */
    return TRUE;
  }

  time_diff = (gdouble) (current_ts - self->last_ts) / GST_SECOND;
  time_elapsed = (gdouble) (current_ts - self->start_ts) / GST_SECOND;

  rr = (gdouble) (frames_rendered - self->last_frames_rendered) / time_diff;
  dr = (gdouble) (frames_dropped - self->last_frames_dropped) / time_diff;

  average_fps = (gdouble) frames_rendered / time_elapsed;

  if (self->max_fps == -1 || rr > self->max_fps) {
    self->max_fps = rr;
    GST_DEBUG_OBJECT (self, "Updated max-fps to %f", rr);
  }
  if (self->min_fps == -1 || rr < self->min_fps) {
    self->min_fps = rr;
    GST_DEBUG_OBJECT (self, "Updated min-fps to %f", rr);
  }

  if (self->signal_measurements) {
    GST_LOG_OBJECT (self, "Signaling measurements: fps:%f droprate:%f "
        "avg-fps:%f", rr, dr, average_fps);
    g_signal_emit (G_OBJECT (self),
        fpsdisplaysink_signals[SIGNAL_FPS_MEASUREMENTS], 0, rr, dr,
        average_fps);
  }

  /* Display on a single line to make it easier to read and import
   * into, for example, excel..  note: it would be nice to show
   * timestamp too.. need to check if there is a sane way to log
   * timestamp of last rendered buffer, so we could correlate dips
   * in framerate to certain positions in the stream.
   */
  if (dr == 0.0) {
    g_snprintf (fps_message, 255,
        "rendered: %" G_GUINT64_FORMAT ", dropped: %" G_GUINT64_FORMAT
        ", current: %.2f, average: %.2f", frames_rendered, frames_dropped, rr,
        average_fps);
  } else {
    g_snprintf (fps_message, 255,
        "rendered: %" G_GUINT64_FORMAT ", dropped: %" G_GUINT64_FORMAT
        ", fps: %.2f, drop rate: %.2f", frames_rendered, frames_dropped, rr,
        dr);
  }

  if (self->use_text_overlay) {
    g_object_set (self->text_overlay, "text", fps_message, NULL);
  }

  if (!self->silent) {
    GST_OBJECT_LOCK (self);
    g_free (self->last_message);
    self->last_message = g_strdup (fps_message);
    GST_OBJECT_UNLOCK (self);
    g_object_notify_by_pspec ((GObject *) self, pspec_last_message);
  }

  self->last_frames_rendered = frames_rendered;
  self->last_frames_dropped = frames_dropped;
  self->last_ts = current_ts;

  return TRUE;
}

static void
fps_display_sink_start (GstFPSDisplaySink * self)
{
  GstPad *target_pad = NULL;

  /* Init counters */
  self->frames_rendered = 0;
  self->frames_dropped = 0;
  self->last_frames_rendered = G_GUINT64_CONSTANT (0);
  self->last_frames_dropped = G_GUINT64_CONSTANT (0);
  self->max_fps = -1;
  self->min_fps = -1;

  /* init time stamps */
  self->last_ts = self->start_ts = self->interval_ts = GST_CLOCK_TIME_NONE;

  GST_DEBUG_OBJECT (self, "Use text-overlay? %d", self->use_text_overlay);

  if (self->use_text_overlay) {
    if (!self->text_overlay) {
      self->text_overlay =
          gst_element_factory_make ("textoverlay", "fps-display-text-overlay");
      if (!self->text_overlay) {
        GST_WARNING_OBJECT (self, "text-overlay element could not be created");
        self->use_text_overlay = FALSE;
        goto no_text_overlay;
      }
      gst_object_ref (self->text_overlay);
      g_object_set (self->text_overlay,
          "font-desc", DEFAULT_FONT, "silent", FALSE, NULL);
      gst_bin_add (GST_BIN (self), self->text_overlay);

      if (!gst_element_link (self->text_overlay, self->video_sink)) {
        GST_ERROR_OBJECT (self, "Could not link elements");
      }
    }
    target_pad = gst_element_get_static_pad (self->text_overlay, "video_sink");
  }
no_text_overlay:
  if (!self->use_text_overlay) {
    if (self->text_overlay) {
      gst_element_unlink (self->text_overlay, self->video_sink);
      gst_bin_remove (GST_BIN (self), self->text_overlay);
      self->text_overlay = NULL;
    }
    target_pad = gst_element_get_static_pad (self->video_sink, "sink");
  }
  gst_ghost_pad_set_target (GST_GHOST_PAD (self->ghost_pad), target_pad);
  gst_object_unref (target_pad);
}

static void
fps_display_sink_stop (GstFPSDisplaySink * self)
{
  if (self->text_overlay) {
    gst_element_unlink (self->text_overlay, self->video_sink);
    gst_bin_remove (GST_BIN (self), self->text_overlay);
    gst_object_unref (self->text_overlay);
    self->text_overlay = NULL;
  }

  if (!self->silent) {
    gchar *str;

    /* print the max and minimum fps values */
    str =
        g_strdup_printf ("Max-fps: %0.2f, Min-fps: %0.2f", self->max_fps,
        self->min_fps);
    GST_OBJECT_LOCK (self);
    g_free (self->last_message);
    self->last_message = str;
    GST_OBJECT_UNLOCK (self);
    g_object_notify_by_pspec ((GObject *) self, pspec_last_message);
  }

  GST_OBJECT_LOCK (self);
  g_free (self->last_message);
  self->last_message = NULL;
  GST_OBJECT_UNLOCK (self);
}

static void
fps_display_sink_dispose (GObject * object)
{
  GstFPSDisplaySink *self = GST_FPS_DISPLAY_SINK (object);

  if (self->video_sink) {
    gst_object_unref (self->video_sink);
    self->video_sink = NULL;
  }

  if (self->text_overlay) {
    gst_object_unref (self->text_overlay);
    self->text_overlay = NULL;
  }

  GST_OBJECT_LOCK (self);
  g_free (self->last_message);
  self->last_message = NULL;
  GST_OBJECT_UNLOCK (self);

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

static void
fps_display_sink_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstFPSDisplaySink *self = GST_FPS_DISPLAY_SINK (object);

  switch (prop_id) {
    case PROP_SYNC:
      self->sync = g_value_get_boolean (value);
      fps_display_sink_update_sink_sync (self);
      break;
    case PROP_TEXT_OVERLAY:
      self->use_text_overlay = g_value_get_boolean (value);

      if (self->text_overlay) {
        if (!self->use_text_overlay) {
          GST_DEBUG_OBJECT (self, "text-overlay set to false");
          g_object_set (self->text_overlay, "text", "", "silent", TRUE, NULL);
        } else {
          GST_DEBUG_OBJECT (self, "text-overlay set to true");
          g_object_set (self->text_overlay, "silent", FALSE, NULL);
        }
      }
      break;
    case PROP_VIDEO_SINK:
      /* FIXME should we add a state-lock or a lock around here?
       * need to check if it is possible that a state change NULL->READY can
       * happen while this code is executing on a different thread */
      if (GST_STATE (self) != GST_STATE_NULL) {
        g_warning ("Can't set video-sink property of fpsdisplaysink if not on "
            "NULL state");
        break;
      }
      update_video_sink (self, (GstElement *) g_value_get_object (value));
      break;
    case PROP_FPS_UPDATE_INTERVAL:
      self->fps_update_interval =
          GST_MSECOND * (GstClockTime) g_value_get_int (value);
      break;
    case PROP_SIGNAL_FPS_MEASUREMENTS:
      self->signal_measurements = g_value_get_boolean (value);
      break;
    case PROP_SILENT:
      self->silent = g_value_get_boolean (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
fps_display_sink_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstFPSDisplaySink *self = GST_FPS_DISPLAY_SINK (object);

  switch (prop_id) {
    case PROP_SYNC:
      g_value_set_boolean (value, self->sync);
      break;
    case PROP_TEXT_OVERLAY:
      g_value_set_boolean (value, self->use_text_overlay);
      break;
    case PROP_VIDEO_SINK:
      g_value_set_object (value, self->video_sink);
      break;
    case PROP_FPS_UPDATE_INTERVAL:
      g_value_set_int (value, (gint) (self->fps_update_interval / GST_MSECOND));
      break;
    case PROP_MAX_FPS:
      g_value_set_double (value, self->max_fps);
      break;
    case PROP_MIN_FPS:
      g_value_set_double (value, self->min_fps);
      break;
    case PROP_FRAMES_DROPPED:
      g_value_set_uint (value, g_atomic_int_get (&self->frames_dropped));
      break;
    case PROP_FRAMES_RENDERED:
      g_value_set_uint (value, g_atomic_int_get (&self->frames_rendered));
      break;
    case PROP_SIGNAL_FPS_MEASUREMENTS:
      g_value_set_boolean (value, self->signal_measurements);
      break;
    case PROP_SILENT:
      g_value_set_boolean (value, self->silent);
      break;
    case PROP_LAST_MESSAGE:
      GST_OBJECT_LOCK (self);
      g_value_set_string (value, self->last_message);
      GST_OBJECT_UNLOCK (self);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static GstStateChangeReturn
fps_display_sink_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
  GstFPSDisplaySink *self = GST_FPS_DISPLAY_SINK (element);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:

      if (self->video_sink == NULL) {
        GstElement *video_sink;

        GST_DEBUG_OBJECT (self, "No video sink set, creating autovideosink");
        video_sink = gst_element_factory_make ("autovideosink",
            "fps-display-video_sink");
        update_video_sink (self, video_sink);
      }

      if (self->video_sink != NULL) {
        fps_display_sink_start (self);
      } else {
        GST_ELEMENT_ERROR (self, LIBRARY, INIT,
            ("No video sink set and autovideosink is not available"), (NULL));
        ret = GST_STATE_CHANGE_FAILURE;
      }
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      /* reinforce our sync to children, as they might have changed
       * internally */
      fps_display_sink_update_sink_sync (self);
      break;
    default:
      break;
  }

  ret = GST_CALL_PARENT_WITH_DEFAULT (GST_ELEMENT_CLASS, change_state,
      (element, transition), GST_STATE_CHANGE_SUCCESS);

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_NULL:
      fps_display_sink_stop (self);
      break;
    default:
      break;
  }

  return ret;
}

static void
fps_display_sink_handle_message (GstBin * bin, GstMessage * message)
{
  GstFPSDisplaySink *self = (GstFPSDisplaySink *) bin;

  if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_QOS) {
    GstFormat format;
    guint64 rendered, dropped;

    gst_message_parse_qos_stats (message, &format, &rendered, &dropped);
    if (format != GST_FORMAT_UNDEFINED) {
      if (rendered != -1)
        g_atomic_int_set (&self->frames_rendered, rendered);

      if (dropped != -1)
        g_atomic_int_set (&self->frames_dropped, dropped);
    }
  }

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

GType
fps_display_sink_get_type (void)
{
  static GType fps_display_sink_type = 0;

  if (!fps_display_sink_type) {
    static const GTypeInfo fps_display_sink_info = {
      sizeof (GstFPSDisplaySinkClass),
      NULL,
      NULL,
      (GClassInitFunc) fps_display_sink_class_init,
      NULL,
      NULL,
      sizeof (GstFPSDisplaySink),
      0,
      (GInstanceInitFunc) fps_display_sink_init,
    };

    fps_display_sink_type = g_type_register_static (GST_TYPE_BIN,
        "GstFPSDisplaySink", &fps_display_sink_info, 0);

    GST_DEBUG_CATEGORY_INIT (fps_display_sink_debug, "fpsdisplaysink", 0,
        "FPS Display Sink");
  }

  return fps_display_sink_type;
}
