/* GStreamer
 * Copyright 2010 ST-Ericsson SA 
 *  @author: Benjamin Gaignard <benjamin.gaignard@stericsson.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.
 */
/*
 * test autovideoconvert:
 * if rgb2bayer is present
 * gst-launch-1.0 videotestsrc num-buffers=2 ! "video/x-raw,width=100,height=100,framerate=10/1" ! autovideoconvert ! "video/x-bayer,width=100,height=100,format=bggr,framerate=10/1" ! fakesink -v
 * if bayer2rgb is present
 * gst-launch-1.0 videotestsrc num-buffers=2 ! "video/x-bayer,width=100,height=100,format=bggr,framerate=10/1" ! autovideoconvert ! "video/x-raw,width=100,height=100,framerate=10/1" ! fakesink -v
 * test with videoconvert
 * gst-launch-1.0 videotestsrc num-buffers=2 ! "video/x-raw,format=RGBx,width=100,height=100,framerate=10/1" ! autovideoconvert ! "video/x-raw,format=RGB16,width=100,height=100,framerate=10/1" ! fakesink -v
 */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <string.h>

#include "gstautovideoconvert.h"

GST_DEBUG_CATEGORY (autovideoconvert_debug);
#define GST_CAT_DEFAULT (autovideoconvert_debug)

static GMutex factories_mutex;
static guint32 factories_cookie = 0;    /* Cookie from last time when factories was updated */
static GList *factories = NULL; /* factories we can use for selecting elements */

/* element factory information */
static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS_ANY);

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


static GstStateChangeReturn gst_auto_video_convert_change_state (GstElement *
    element, GstStateChange transition);

void gst_auto_video_convert_update_factory_list (GstAutoVideoConvert *
    autovideoconvert);

static gboolean
gst_auto_video_convert_element_filter (GstPluginFeature * feature,
    GstAutoVideoConvert * autovideoconvert)
{
  const gchar *klass;

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

  klass = gst_element_factory_get_metadata (GST_ELEMENT_FACTORY_CAST (feature),
      GST_ELEMENT_METADATA_KLASS);
  /* only select color space converter */
  if (strstr (klass, "Filter") &&
      strstr (klass, "Converter") && strstr (klass, "Video")) {
    GST_DEBUG_OBJECT (autovideoconvert,
        "gst_auto_video_convert_element_filter found %s\n",
        gst_plugin_feature_get_name (GST_PLUGIN_FEATURE_CAST (feature)));
    return TRUE;
  }
  return FALSE;
}


static GList *
gst_auto_video_convert_create_factory_list (GstAutoVideoConvert *
    autovideoconvert)
{
  GList *result = NULL;

  /* get the feature list using the filter */
  result = gst_registry_feature_filter (gst_registry_get (),
      (GstPluginFeatureFilter) gst_auto_video_convert_element_filter,
      FALSE, autovideoconvert);

  /* sort on rank and name */
  result = g_list_sort (result, gst_plugin_feature_rank_compare_func);

  return result;
}

void
gst_auto_video_convert_update_factory_list (GstAutoVideoConvert *
    autovideoconvert)
{
  /* use a static mutex to protect factories list and factories cookie */
  g_mutex_lock (&factories_mutex);

  /* test if a factories list already exist or not */
  if (!factories) {
    /* no factories list create it */
    factories_cookie =
        gst_registry_get_feature_list_cookie (gst_registry_get ());
    factories = gst_auto_video_convert_create_factory_list (autovideoconvert);
  } else {
    /* a factories list exist but is it up to date? */
    if (factories_cookie !=
        gst_registry_get_feature_list_cookie (gst_registry_get ())) {
      /* we need to update the factories list */
      /* first free the old one */
      gst_plugin_feature_list_free (factories);
      /* then create an updated one */
      factories_cookie =
          gst_registry_get_feature_list_cookie (gst_registry_get ());
      factories = gst_auto_video_convert_create_factory_list (autovideoconvert);
    }
  }

  g_mutex_unlock (&factories_mutex);
}

G_DEFINE_TYPE (GstAutoVideoConvert, gst_auto_video_convert, GST_TYPE_BIN);

static void
gst_auto_video_convert_class_init (GstAutoVideoConvertClass * klass)
{
  GstElementClass *gstelement_class = (GstElementClass *) klass;

  GST_DEBUG_CATEGORY_INIT (autovideoconvert_debug, "autovideoconvert", 0,
      "Auto color space converter");

  gst_element_class_add_static_pad_template (gstelement_class, &srctemplate);
  gst_element_class_add_static_pad_template (gstelement_class, &sinktemplate);

  gst_element_class_set_static_metadata (gstelement_class,
      "Select color space convertor based on caps", "Generic/Bin",
      "Selects the right color space convertor based on the caps",
      "Benjamin Gaignard <benjamin.gaignard@stericsson.com>");

  gstelement_class->change_state =
      GST_DEBUG_FUNCPTR (gst_auto_video_convert_change_state);

}

static gboolean
gst_auto_video_convert_add_autoconvert (GstAutoVideoConvert * autovideoconvert)
{
  GstPad *pad;

  if (autovideoconvert->autoconvert)
    return TRUE;

  autovideoconvert->autoconvert =
      gst_element_factory_make ("autoconvert", "autoconvertchild");
  if (!autovideoconvert->autoconvert) {
    GST_ERROR_OBJECT (autovideoconvert,
        "Could not create autoconvert instance");
    return FALSE;
  }

  /* first add autoconvert in bin */
  gst_bin_add (GST_BIN (autovideoconvert),
      gst_object_ref (autovideoconvert->autoconvert));

  /* get sinkpad and link it to ghost sink pad */
  pad = gst_element_get_static_pad (autovideoconvert->autoconvert, "sink");
  gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (autovideoconvert->sinkpad),
      pad);
  gst_object_unref (pad);

  /* get srcpad and link it to ghost src pad */
  pad = gst_element_get_static_pad (autovideoconvert->autoconvert, "src");
  gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (autovideoconvert->srcpad), pad);
  gst_object_unref (pad);

  return TRUE;
}

static void
gst_auto_video_convert_remove_autoconvert (GstAutoVideoConvert *
    autovideoconvert)
{
  if (!autovideoconvert->autoconvert)
    return;

  gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (autovideoconvert->srcpad),
      NULL);
  gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (autovideoconvert->sinkpad),
      NULL);

  gst_bin_remove (GST_BIN (autovideoconvert), autovideoconvert->autoconvert);
  gst_object_unref (autovideoconvert->autoconvert);
  autovideoconvert->autoconvert = NULL;
}

static void
gst_auto_video_convert_init (GstAutoVideoConvert * autovideoconvert)
{
  GstPadTemplate *pad_tmpl;

  /* get sink pad template */
  pad_tmpl = gst_static_pad_template_get (&sinktemplate);
  autovideoconvert->sinkpad =
      gst_ghost_pad_new_no_target_from_template ("sink", pad_tmpl);
  /* add sink ghost pad */
  gst_element_add_pad (GST_ELEMENT (autovideoconvert),
      autovideoconvert->sinkpad);
  gst_object_unref (pad_tmpl);

  /* get src pad template */
  pad_tmpl = gst_static_pad_template_get (&srctemplate);
  autovideoconvert->srcpad =
      gst_ghost_pad_new_no_target_from_template ("src", pad_tmpl);
  /* add src ghost pad */
  gst_element_add_pad (GST_ELEMENT (autovideoconvert),
      autovideoconvert->srcpad);
  gst_object_unref (pad_tmpl);

  return;
}

static GstStateChangeReturn
gst_auto_video_convert_change_state (GstElement * element,
    GstStateChange transition)
{
  GstAutoVideoConvert *autovideoconvert = GST_AUTO_VIDEO_CONVERT (element);
  GstStateChangeReturn ret;

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
    {
      /* create and add autoconvert in bin */
      if (!gst_auto_video_convert_add_autoconvert (autovideoconvert)) {
        ret = GST_STATE_CHANGE_FAILURE;
        return ret;
      }
      /* get an updated list of factories */
      gst_auto_video_convert_update_factory_list (autovideoconvert);
      GST_DEBUG_OBJECT (autovideoconvert, "set factories list");
      /* give factory list to autoconvert */
      g_object_set (GST_ELEMENT (autovideoconvert->autoconvert), "factories",
          factories, NULL);
      break;
    }
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (gst_auto_video_convert_parent_class)->change_state
      (element, transition);
  if (ret == GST_STATE_CHANGE_FAILURE)
    return ret;

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_NULL:
    {
      gst_auto_video_convert_remove_autoconvert (autovideoconvert);
      break;
    }
    default:
      break;
  }

  return ret;
}
