/* 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_pad_template (element_class,
      gst_static_pad_template_get (&src_template));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&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;
}
