/* GStreamer Smart Video Encoder element
 * Copyright (C) <2010> Edward Hervey <bilboed@gmail.com>
 *
 * 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.
 */

/* TODO:
 * * Implement get_caps/set_caps (store/forward caps)
 * * Adjust template caps to the formats we can support
 **/

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

#include <string.h>
#include "gstsmartencoder.h"

GST_DEBUG_CATEGORY_STATIC (smart_encoder_debug);
#define GST_CAT_DEFAULT smart_encoder_debug

/* FIXME : Update this with new caps */
/* WARNING : We can only allow formats with closed-GOP */
#define ALLOWED_CAPS "video/x-h263;video/x-intel-h263;"\
  "video/mpeg,mpegversion=(int)1,systemstream=(boolean)false;"\
  "video/mpeg,mpegversion=(int)2,systemstream=(boolean)false;"

static GstStaticPadTemplate src_template =
GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (ALLOWED_CAPS)
    );

static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (ALLOWED_CAPS)
    );

static GQuark INTERNAL_ELEMENT;

/* GstSmartEncoder signals and args */
enum
{
  /* FILL ME */
  LAST_SIGNAL
};

enum
{
  PROP_0
      /* FILL ME */
};

static void
_do_init (void)
{
  INTERNAL_ELEMENT = g_quark_from_static_string ("internal-element");
};

G_DEFINE_TYPE_EXTENDED (GstSmartEncoder, gst_smart_encoder, GST_TYPE_ELEMENT, 0,
    _do_init ());

static void gst_smart_encoder_dispose (GObject * object);

static gboolean setup_recoder_pipeline (GstSmartEncoder * smart_encoder);

static GstFlowReturn gst_smart_encoder_chain (GstPad * pad, GstObject * parent,
    GstBuffer * buf);
static gboolean smart_encoder_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event);
static gboolean smart_encoder_sink_query (GstPad * pad, GstObject * parent,
    GstQuery * query);
static GstCaps *smart_encoder_sink_getcaps (GstPad * pad, GstCaps * filter);
static GstStateChangeReturn
gst_smart_encoder_change_state (GstElement * element,
    GstStateChange transition);

static void
gst_smart_encoder_class_init (GstSmartEncoderClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *element_class;

  element_class = (GstElementClass *) klass;
  gobject_class = G_OBJECT_CLASS (klass);

  gst_smart_encoder_parent_class = g_type_class_peek_parent (klass);

  gst_element_class_add_static_pad_template (element_class, &src_template);
  gst_element_class_add_static_pad_template (element_class, &sink_template);

  gst_element_class_set_static_metadata (element_class, "Smart Video Encoder",
      "Codec/Recoder/Video",
      "Re-encodes portions of Video that lay on segment boundaries",
      "Edward Hervey <bilboed@gmail.com>");

  gobject_class->dispose = (GObjectFinalizeFunc) (gst_smart_encoder_dispose);
  element_class->change_state = gst_smart_encoder_change_state;

  GST_DEBUG_CATEGORY_INIT (smart_encoder_debug, "smartencoder", 0,
      "Smart Encoder");
}

static void
smart_encoder_reset (GstSmartEncoder * smart_encoder)
{
  gst_segment_init (smart_encoder->segment, GST_FORMAT_UNDEFINED);

  if (smart_encoder->encoder) {
    /* Clean up/remove elements */
    gst_element_set_state (smart_encoder->encoder, GST_STATE_NULL);
    gst_element_set_state (smart_encoder->decoder, GST_STATE_NULL);
    gst_element_set_bus (smart_encoder->encoder, NULL);
    gst_element_set_bus (smart_encoder->decoder, NULL);
    gst_pad_set_active (smart_encoder->internal_srcpad, FALSE);
    gst_pad_set_active (smart_encoder->internal_sinkpad, FALSE);
    gst_object_unref (smart_encoder->encoder);
    gst_object_unref (smart_encoder->decoder);
    gst_object_unref (smart_encoder->internal_srcpad);
    gst_object_unref (smart_encoder->internal_sinkpad);

    smart_encoder->encoder = NULL;
    smart_encoder->decoder = NULL;
    smart_encoder->internal_sinkpad = NULL;
    smart_encoder->internal_srcpad = NULL;
  }

  if (smart_encoder->newsegment) {
    gst_event_unref (smart_encoder->newsegment);
    smart_encoder->newsegment = NULL;
  }
}


static void
gst_smart_encoder_init (GstSmartEncoder * smart_encoder)
{
  smart_encoder->sinkpad =
      gst_pad_new_from_static_template (&sink_template, "sink");
  gst_pad_set_chain_function (smart_encoder->sinkpad, gst_smart_encoder_chain);
  gst_pad_set_event_function (smart_encoder->sinkpad, smart_encoder_sink_event);
  gst_pad_set_query_function (smart_encoder->sinkpad, smart_encoder_sink_query);
  gst_element_add_pad (GST_ELEMENT (smart_encoder), smart_encoder->sinkpad);

  smart_encoder->srcpad =
      gst_pad_new_from_static_template (&src_template, "src");
  gst_pad_use_fixed_caps (smart_encoder->srcpad);
  gst_element_add_pad (GST_ELEMENT (smart_encoder), smart_encoder->srcpad);

  smart_encoder->segment = gst_segment_new ();

  smart_encoder_reset (smart_encoder);
}

void
gst_smart_encoder_dispose (GObject * object)
{
  GstSmartEncoder *smart_encoder = (GstSmartEncoder *) object;

  if (smart_encoder->segment)
    gst_segment_free (smart_encoder->segment);
  smart_encoder->segment = NULL;
  if (smart_encoder->available_caps)
    gst_caps_unref (smart_encoder->available_caps);
  smart_encoder->available_caps = NULL;
  G_OBJECT_CLASS (gst_smart_encoder_parent_class)->dispose (object);
}

static GstFlowReturn
gst_smart_encoder_reencode_gop (GstSmartEncoder * smart_encoder)
{
  GstFlowReturn res = GST_FLOW_OK;
  GList *tmp;

  if (smart_encoder->encoder == NULL) {
    if (!setup_recoder_pipeline (smart_encoder))
      return GST_FLOW_ERROR;
  }

  /* Activate elements */
  /* Set elements to PAUSED */
  gst_element_set_state (smart_encoder->encoder, GST_STATE_PAUSED);
  gst_element_set_state (smart_encoder->decoder, GST_STATE_PAUSED);

  GST_INFO ("Pushing Flush start/stop to clean decoder/encoder");
  gst_pad_push_event (smart_encoder->internal_srcpad,
      gst_event_new_flush_start ());
  gst_pad_push_event (smart_encoder->internal_srcpad,
      gst_event_new_flush_stop (TRUE));

  /* push newsegment */
  GST_INFO ("Pushing newsegment %" GST_PTR_FORMAT, smart_encoder->newsegment);
  gst_pad_push_event (smart_encoder->internal_srcpad,
      gst_event_ref (smart_encoder->newsegment));

  /* Push buffers through our pads */
  GST_DEBUG ("Pushing pending buffers");

  for (tmp = smart_encoder->pending_gop; tmp; tmp = tmp->next) {
    GstBuffer *buf = (GstBuffer *) tmp->data;

    res = gst_pad_push (smart_encoder->internal_srcpad, buf);
    if (G_UNLIKELY (res != GST_FLOW_OK))
      break;
  }

  if (G_UNLIKELY (res != GST_FLOW_OK)) {
    GST_WARNING ("Error pushing pending buffers : %s", gst_flow_get_name (res));
    /* Remove pending bfufers */
    for (tmp = smart_encoder->pending_gop; tmp; tmp = tmp->next) {
      gst_buffer_unref ((GstBuffer *) tmp->data);
    }
  } else {
    GST_INFO ("Pushing out EOS to flush out decoder/encoder");
    gst_pad_push_event (smart_encoder->internal_srcpad, gst_event_new_eos ());
  }

  /* Activate elements */
  /* Set elements to PAUSED */
  gst_element_set_state (smart_encoder->encoder, GST_STATE_NULL);
  gst_element_set_state (smart_encoder->decoder, GST_STATE_NULL);

  g_list_free (smart_encoder->pending_gop);
  smart_encoder->pending_gop = NULL;

  return res;
}

static GstFlowReturn
gst_smart_encoder_push_pending_gop (GstSmartEncoder * smart_encoder)
{
  guint64 cstart, cstop;
  GList *tmp;
  GstFlowReturn res = GST_FLOW_OK;

  GST_DEBUG ("Pushing pending GOP (%" GST_TIME_FORMAT " -- %" GST_TIME_FORMAT
      ")", GST_TIME_ARGS (smart_encoder->gop_start),
      GST_TIME_ARGS (smart_encoder->gop_stop));

  /* If GOP is entirely within segment, just push downstream */
  if (gst_segment_clip (smart_encoder->segment, GST_FORMAT_TIME,
          smart_encoder->gop_start, smart_encoder->gop_stop, &cstart, &cstop)) {
    if ((cstart != smart_encoder->gop_start)
        || (cstop != smart_encoder->gop_stop)) {
      GST_DEBUG ("GOP needs to be re-encoded from %" GST_TIME_FORMAT " to %"
          GST_TIME_FORMAT, GST_TIME_ARGS (cstart), GST_TIME_ARGS (cstop));
      res = gst_smart_encoder_reencode_gop (smart_encoder);
    } else {
      /* The whole GOP is within the segment, push all pending buffers downstream */
      GST_DEBUG ("GOP doesn't need to be modified, pushing downstream");
      for (tmp = smart_encoder->pending_gop; tmp; tmp = tmp->next) {
        GstBuffer *buf = (GstBuffer *) tmp->data;
        res = gst_pad_push (smart_encoder->srcpad, buf);
        if (G_UNLIKELY (res != GST_FLOW_OK))
          break;
      }
    }
  } else {
    /* The whole GOP is outside the segment, there's most likely
     * a bug somewhere. */
    GST_WARNING
        ("GOP is entirely outside of the segment, upstream gave us too much data");
    for (tmp = smart_encoder->pending_gop; tmp; tmp = tmp->next) {
      gst_buffer_unref ((GstBuffer *) tmp->data);
    }
  }

  if (smart_encoder->pending_gop) {
    g_list_free (smart_encoder->pending_gop);
    smart_encoder->pending_gop = NULL;
  }
  smart_encoder->gop_start = GST_CLOCK_TIME_NONE;
  smart_encoder->gop_stop = GST_CLOCK_TIME_NONE;

  return res;
}

static GstFlowReturn
gst_smart_encoder_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
  GstSmartEncoder *smart_encoder;
  GstFlowReturn res = GST_FLOW_OK;
  gboolean discont, keyframe;

  smart_encoder = GST_SMART_ENCODER (parent);

  discont = GST_BUFFER_IS_DISCONT (buf);
  keyframe = !GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);

  GST_DEBUG ("New buffer %s %s %" GST_TIME_FORMAT,
      discont ? "discont" : "",
      keyframe ? "keyframe" : "", GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));

  if (keyframe) {
    GST_DEBUG ("Got a keyframe");

    /* If there's a pending GOP, flush it out */
    if (smart_encoder->pending_gop) {
      /* Mark gop_stop */
      smart_encoder->gop_stop = GST_BUFFER_TIMESTAMP (buf);

      /* flush pending */
      res = gst_smart_encoder_push_pending_gop (smart_encoder);
      if (G_UNLIKELY (res != GST_FLOW_OK))
        goto beach;
    }

    /* Mark gop_start for new gop */
    smart_encoder->gop_start = GST_BUFFER_TIMESTAMP (buf);
  }

  /* Store buffer */
  smart_encoder->pending_gop = g_list_append (smart_encoder->pending_gop, buf);
  /* Update GOP stop position */
  if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
    smart_encoder->gop_stop = GST_BUFFER_TIMESTAMP (buf);
    if (GST_BUFFER_DURATION_IS_VALID (buf))
      smart_encoder->gop_stop += GST_BUFFER_DURATION (buf);
  }

  GST_DEBUG ("Buffer stored , Current GOP : %" GST_TIME_FORMAT " -- %"
      GST_TIME_FORMAT, GST_TIME_ARGS (smart_encoder->gop_start),
      GST_TIME_ARGS (smart_encoder->gop_stop));

beach:
  return res;
}

static gboolean
smart_encoder_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  gboolean res = TRUE;
  GstSmartEncoder *smart_encoder = GST_SMART_ENCODER (parent);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_STOP:
      smart_encoder_reset (smart_encoder);
      break;
    case GST_EVENT_SEGMENT:
    {
      gst_event_copy_segment (event, smart_encoder->segment);

      GST_DEBUG_OBJECT (smart_encoder, "segment: %" GST_SEGMENT_FORMAT,
          smart_encoder->segment);
      if (smart_encoder->segment->format != GST_FORMAT_TIME) {
        GST_ERROR
            ("smart_encoder can not handle streams not specified in GST_FORMAT_TIME");
        gst_event_unref (event);
        return FALSE;
      }

      /* And keep a copy for further usage */
      if (smart_encoder->newsegment)
        gst_event_unref (smart_encoder->newsegment);
      smart_encoder->newsegment = gst_event_ref (event);
    }
      break;
    case GST_EVENT_EOS:
      GST_DEBUG ("Eos, flushing remaining data");
      if (smart_encoder->segment->format == GST_FORMAT_TIME)
        gst_smart_encoder_push_pending_gop (smart_encoder);
      break;
    default:
      break;
  }

  res = gst_pad_push_event (smart_encoder->srcpad, event);

  return res;
}

static GstCaps *
smart_encoder_sink_getcaps (GstPad * pad, GstCaps * filter)
{
  GstCaps *peer, *tmpl, *res;
  GstSmartEncoder *smart_encoder = GST_SMART_ENCODER (gst_pad_get_parent (pad));

  /* Use computed caps */
  if (smart_encoder->available_caps)
    tmpl = gst_caps_ref (smart_encoder->available_caps);
  else
    tmpl = gst_static_pad_template_get_caps (&src_template);

  /* Try getting it from downstream */
  peer = gst_pad_peer_query_caps (smart_encoder->srcpad, tmpl);

  if (peer == NULL) {
    res = tmpl;
  } else {
    res = peer;
    gst_caps_unref (tmpl);
  }

  gst_object_unref (smart_encoder);
  return res;
}

static gboolean
smart_encoder_sink_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
  gboolean res;

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

      gst_query_parse_caps (query, &filter);
      caps = smart_encoder_sink_getcaps (pad, filter);
      gst_query_set_caps_result (query, caps);
      gst_caps_unref (caps);
      res = TRUE;
      break;
    }
    default:
      res = gst_pad_query_default (pad, parent, query);
      break;
  }
  return res;
}

/*****************************************
 *    Internal encoder/decoder pipeline  *
 ******************************************/

static GstElementFactory *
get_decoder_factory (GstCaps * caps)
{
  GstElementFactory *fact = NULL;
  GList *decoders, *tmp;

  tmp =
      gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_DECODER,
      GST_RANK_MARGINAL);
  decoders = gst_element_factory_list_filter (tmp, caps, GST_PAD_SINK, FALSE);
  gst_plugin_feature_list_free (tmp);

  for (tmp = decoders; tmp; tmp = tmp->next) {
    /* We just pick the first one */
    fact = (GstElementFactory *) tmp->data;
    gst_object_ref (fact);
    break;
  }

  gst_plugin_feature_list_free (decoders);

  return fact;
}

static GstElementFactory *
get_encoder_factory (GstCaps * caps)
{
  GstElementFactory *fact = NULL;
  GList *encoders, *tmp;

  tmp =
      gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_ENCODER,
      GST_RANK_MARGINAL);
  encoders = gst_element_factory_list_filter (tmp, caps, GST_PAD_SRC, FALSE);
  gst_plugin_feature_list_free (tmp);

  for (tmp = encoders; tmp; tmp = tmp->next) {
    /* We just pick the first one */
    fact = (GstElementFactory *) tmp->data;
    gst_object_ref (fact);
    break;
  }

  gst_plugin_feature_list_free (encoders);

  return fact;
}

static GstElement *
get_decoder (GstCaps * caps)
{
  GstElementFactory *fact = get_decoder_factory (caps);
  GstElement *res = NULL;

  if (fact) {
    res = gst_element_factory_create (fact, "internal-decoder");
    gst_object_unref (fact);
  }
  return res;
}

static GstElement *
get_encoder (GstCaps * caps)
{
  GstElementFactory *fact = get_encoder_factory (caps);
  GstElement *res = NULL;

  if (fact) {
    res = gst_element_factory_create (fact, "internal-encoder");
    gst_object_unref (fact);
  }
  return res;
}

static GstFlowReturn
internal_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
  GstSmartEncoder *smart_encoder =
      g_object_get_qdata ((GObject *) pad, INTERNAL_ELEMENT);

  return gst_pad_push (smart_encoder->srcpad, buf);
}

static gboolean
setup_recoder_pipeline (GstSmartEncoder * smart_encoder)
{
  GstPad *tmppad;
  GstCaps *caps;

  /* Fast path */
  if (G_UNLIKELY (smart_encoder->encoder))
    return TRUE;

  GST_DEBUG ("Creating internal decoder and encoder");

  /* Create decoder/encoder */
  caps = gst_pad_get_current_caps (smart_encoder->sinkpad);
  smart_encoder->decoder = get_decoder (caps);
  if (G_UNLIKELY (smart_encoder->decoder == NULL))
    goto no_decoder;
  gst_caps_unref (caps);
  gst_element_set_bus (smart_encoder->decoder, GST_ELEMENT_BUS (smart_encoder));

  caps = gst_pad_get_current_caps (smart_encoder->sinkpad);
  smart_encoder->encoder = get_encoder (caps);
  if (G_UNLIKELY (smart_encoder->encoder == NULL))
    goto no_encoder;
  gst_caps_unref (caps);
  gst_element_set_bus (smart_encoder->encoder, GST_ELEMENT_BUS (smart_encoder));

  GST_DEBUG ("Creating internal pads");

  /* Create internal pads */

  /* Source pad which we'll use to feed data to decoders */
  smart_encoder->internal_srcpad = gst_pad_new ("internal_src", GST_PAD_SRC);
  g_object_set_qdata ((GObject *) smart_encoder->internal_srcpad,
      INTERNAL_ELEMENT, smart_encoder);
  gst_pad_set_active (smart_encoder->internal_srcpad, TRUE);

  /* Sink pad which will get the buffers from the encoder.
   * Note: We don't need an event function since we'll be discarding all
   * of them. */
  smart_encoder->internal_sinkpad = gst_pad_new ("internal_sink", GST_PAD_SINK);
  g_object_set_qdata ((GObject *) smart_encoder->internal_sinkpad,
      INTERNAL_ELEMENT, smart_encoder);
  gst_pad_set_chain_function (smart_encoder->internal_sinkpad, internal_chain);
  gst_pad_set_active (smart_encoder->internal_sinkpad, TRUE);

  GST_DEBUG ("Linking pads to elements");

  /* Link everything */
  tmppad = gst_element_get_static_pad (smart_encoder->encoder, "src");
  if (GST_PAD_LINK_FAILED (gst_pad_link (tmppad,
              smart_encoder->internal_sinkpad)))
    goto sinkpad_link_fail;
  gst_object_unref (tmppad);

  if (!gst_element_link (smart_encoder->decoder, smart_encoder->encoder))
    goto encoder_decoder_link_fail;

  tmppad = gst_element_get_static_pad (smart_encoder->decoder, "sink");
  if (GST_PAD_LINK_FAILED (gst_pad_link (smart_encoder->internal_srcpad,
              tmppad)))
    goto srcpad_link_fail;
  gst_object_unref (tmppad);

  GST_DEBUG ("Done creating internal elements/pads");

  return TRUE;

no_decoder:
  {
    GST_WARNING ("Couldn't find a decoder for %" GST_PTR_FORMAT, caps);
    gst_caps_unref (caps);
    return FALSE;
  }

no_encoder:
  {
    GST_WARNING ("Couldn't find an encoder for %" GST_PTR_FORMAT, caps);
    gst_caps_unref (caps);
    return FALSE;
  }

srcpad_link_fail:
  {
    gst_object_unref (tmppad);
    GST_WARNING ("Couldn't link internal srcpad to decoder");
    return FALSE;
  }

sinkpad_link_fail:
  {
    gst_object_unref (tmppad);
    GST_WARNING ("Couldn't link encoder to internal sinkpad");
    return FALSE;
  }

encoder_decoder_link_fail:
  {
    GST_WARNING ("Couldn't link decoder to encoder");
    return FALSE;
  }
}

static GstStateChangeReturn
gst_smart_encoder_find_elements (GstSmartEncoder * smart_encoder)
{
  guint i, n;
  GstCaps *tmpl, *st, *res;
  GstElementFactory *dec, *enc;
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;

  if (G_UNLIKELY (smart_encoder->available_caps))
    goto beach;

  /* Iterate over all pad template caps and see if we have both an
   * encoder and a decoder for those media types */
  tmpl = gst_static_pad_template_get_caps (&src_template);
  res = gst_caps_new_empty ();
  n = gst_caps_get_size (tmpl);

  for (i = 0; i < n; i++) {
    st = gst_caps_copy_nth (tmpl, i);
    GST_DEBUG_OBJECT (smart_encoder,
        "Checking for available decoder and encoder for %" GST_PTR_FORMAT, st);
    if (!(dec = get_decoder_factory (st))) {
      gst_caps_unref (st);
      continue;
    }
    gst_object_unref (dec);
    if (!(enc = get_encoder_factory (st))) {
      gst_caps_unref (st);
      continue;
    }
    gst_object_unref (enc);
    GST_DEBUG_OBJECT (smart_encoder, "OK");
    gst_caps_append (res, st);
  }

  gst_caps_unref (tmpl);

  if (gst_caps_is_empty (res)) {
    gst_caps_unref (res);
    ret = GST_STATE_CHANGE_FAILURE;
  } else
    smart_encoder->available_caps = res;

  GST_DEBUG_OBJECT (smart_encoder, "Done, available_caps:%" GST_PTR_FORMAT,
      smart_encoder->available_caps);

beach:
  return ret;
}

/******************************************
 *    GstElement vmethod implementations  *
 ******************************************/

static GstStateChangeReturn
gst_smart_encoder_change_state (GstElement * element, GstStateChange transition)
{
  GstSmartEncoder *smart_encoder;
  GstStateChangeReturn ret;

  g_return_val_if_fail (GST_IS_SMART_ENCODER (element),
      GST_STATE_CHANGE_FAILURE);

  smart_encoder = GST_SMART_ENCODER (element);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      /* Figure out which elements are available  */
      if ((ret =
              gst_smart_encoder_find_elements (smart_encoder)) ==
          GST_STATE_CHANGE_FAILURE)
        goto beach;
      break;
    default:
      break;
  }

  ret =
      GST_ELEMENT_CLASS (gst_smart_encoder_parent_class)->change_state (element,
      transition);

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      smart_encoder_reset (smart_encoder);
      break;
    default:
      break;
  }

beach:
  return ret;
}
