/*
 * GStreamer
 * Copyright (C) 2010 Texas Instruments, Inc
 * Copyright (C) 2011 Thiago Santos <thiago.sousa.santos@collabora.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.
 */


/**
 * SECTION:element-wrappercamerabinsrc
 *
 * A camera bin src element that wraps a default video source with a single
 * pad into the 3pad model that camerabin2 expects.
 */

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <gst/interfaces/photography.h>
#include <gst/gst-i18n-plugin.h>

#include "gstwrappercamerabinsrc.h"
#include "gstdigitalzoom.h"
#include "camerabingeneral.h"

enum
{
  PROP_0,
  PROP_VIDEO_SRC,
  PROP_VIDEO_SRC_FILTER
};

GST_DEBUG_CATEGORY (wrapper_camera_bin_src_debug);
#define GST_CAT_DEFAULT wrapper_camera_bin_src_debug

#define gst_wrapper_camera_bin_src_parent_class parent_class
G_DEFINE_TYPE (GstWrapperCameraBinSrc, gst_wrapper_camera_bin_src,
    GST_TYPE_BASE_CAMERA_SRC);

static GstStaticPadTemplate vfsrc_template =
GST_STATIC_PAD_TEMPLATE (GST_BASE_CAMERA_SRC_VIEWFINDER_PAD_NAME,
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS_ANY);

static GstStaticPadTemplate imgsrc_template =
GST_STATIC_PAD_TEMPLATE (GST_BASE_CAMERA_SRC_IMAGE_PAD_NAME,
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS_ANY);

static GstStaticPadTemplate vidsrc_template =
GST_STATIC_PAD_TEMPLATE (GST_BASE_CAMERA_SRC_VIDEO_PAD_NAME,
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS_ANY);

static void set_capsfilter_caps (GstWrapperCameraBinSrc * self,
    GstCaps * new_caps);

static void
gst_wrapper_camera_bin_src_dispose (GObject * object)
{
  GstWrapperCameraBinSrc *self = GST_WRAPPER_CAMERA_BIN_SRC (object);

  if (self->src_pad) {
    gst_object_unref (self->src_pad);
    self->src_pad = NULL;
  }
  if (self->video_tee_sink) {
    gst_object_unref (self->video_tee_sink);
    self->video_tee_sink = NULL;
  }
  if (self->video_tee_vf_pad) {
    gst_object_unref (self->video_tee_vf_pad);
    self->video_tee_vf_pad = NULL;
  }
  if (self->app_vid_src) {
    gst_object_unref (self->app_vid_src);
    self->app_vid_src = NULL;
  }
  if (self->app_vid_filter) {
    gst_object_unref (self->app_vid_filter);
    self->app_vid_filter = NULL;
  }
  if (self->srcfilter_pad) {
    gst_object_unref (self->srcfilter_pad);
    self->srcfilter_pad = NULL;
  }
  gst_caps_replace (&self->image_capture_caps, NULL);

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

static void
gst_wrapper_camera_bin_src_finalize (GstWrapperCameraBinSrc * self)
{
  G_OBJECT_CLASS (parent_class)->finalize ((GObject *) (self));
}

static void
gst_wrapper_camera_bin_src_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec)
{
  GstWrapperCameraBinSrc *self = GST_WRAPPER_CAMERA_BIN_SRC (object);

  switch (prop_id) {
    case PROP_VIDEO_SRC:
      if (GST_STATE (self) != GST_STATE_NULL) {
        GST_ELEMENT_ERROR (self, CORE, FAILED,
            ("camerasrc must be in NULL state when setting the video source element"),
            (NULL));
      } else {
        if (self->app_vid_src)
          gst_object_unref (self->app_vid_src);
        self->app_vid_src = g_value_get_object (value);
        if (self->app_vid_src)
          gst_object_ref (self->app_vid_src);
      }
      break;
    case PROP_VIDEO_SRC_FILTER:
      if (GST_STATE (self) != GST_STATE_NULL) {
        GST_ELEMENT_ERROR (self, CORE, FAILED,
            ("camerasrc must be in NULL state when setting the video source filter element"),
            (NULL));
      } else {
        if (self->app_vid_filter)
          gst_object_unref (self->app_vid_filter);
        self->app_vid_filter = g_value_get_object (value);
        if (self->app_vid_filter)
          gst_object_ref (self->app_vid_filter);
      }
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec);
      break;
  }
}

static void
gst_wrapper_camera_bin_src_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec)
{
  GstWrapperCameraBinSrc *self = GST_WRAPPER_CAMERA_BIN_SRC (object);

  switch (prop_id) {
    case PROP_VIDEO_SRC:
      if (self->src_vid_src)
        g_value_set_object (value, self->src_vid_src);
      else
        g_value_set_object (value, self->app_vid_src);
      break;
    case PROP_VIDEO_SRC_FILTER:
      if (self->video_filter)
        g_value_set_object (value, self->video_filter);
      else
        g_value_set_object (value, self->app_vid_filter);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec);
      break;
  }
}

static void
gst_wrapper_camera_bin_src_reset_src_zoom (GstWrapperCameraBinSrc * self)
{
  if (self->src_crop) {
    g_object_set (self->src_crop, "top", 0, "left", 0, "bottom", 0, "right", 0,
        NULL);
  }
}

static void
gst_wrapper_camera_bin_reset_video_src_caps (GstWrapperCameraBinSrc * self,
    GstCaps * new_filter_caps)
{
  GST_DEBUG_OBJECT (self, "Resetting src caps to %" GST_PTR_FORMAT,
      new_filter_caps);
  if (self->src_vid_src) {
    GstCaps *src_neg_caps;      /* negotiated caps on src_filter */
    gboolean ret = FALSE;

    /* After pipe was negotiated src_filter do not have any filter caps.
     * In this situation we should compare negotiated caps on capsfilter pad
     * with requested range of caps. If one of this caps intersect,
     * then we can avoid reseting.
     */
    src_neg_caps = gst_pad_get_current_caps (self->srcfilter_pad);
    if (src_neg_caps && new_filter_caps && gst_caps_is_fixed (new_filter_caps))
      ret = gst_caps_can_intersect (src_neg_caps, new_filter_caps);
    else if (new_filter_caps == NULL) {
      /* If new_filter_caps = NULL, then some body wont to empty
       * capsfilter (set to ANY). In this case we will need to reset pipe,
       * but if capsfilter is actually empthy, then we can avoid
       * one more reseting.
       */
      GstCaps *old_filter_caps; /* range of caps on capsfilter */

      g_object_get (G_OBJECT (self->src_filter),
          "caps", &old_filter_caps, NULL);
      ret = gst_caps_is_any (old_filter_caps);
      gst_caps_unref (old_filter_caps);
    }
    if (src_neg_caps)
      gst_caps_unref (src_neg_caps);

    if (ret) {
      GST_DEBUG_OBJECT (self, "Negotiated caps on srcfilter intersect "
          "with requested caps, do not reset it.");
      return;
    }

    set_capsfilter_caps (self, new_filter_caps);
  }
}

static void
gst_wrapper_camera_bin_src_set_output (GstWrapperCameraBinSrc * self,
    GstPad * old_pad, GstPad * output_pad)
{
  GstQuery *drain = gst_query_new_drain ();
  gst_pad_peer_query (self->src_pad, drain);
  gst_query_unref (drain);

  if (old_pad)
    gst_ghost_pad_set_target (GST_GHOST_PAD (old_pad), NULL);
  if (output_pad)
    gst_ghost_pad_set_target (GST_GHOST_PAD (output_pad), self->src_pad);
}

/**
 * gst_wrapper_camera_bin_src_imgsrc_probe:
 *
 * Buffer probe called before sending each buffer to image queue.
 */
static GstPadProbeReturn
gst_wrapper_camera_bin_src_imgsrc_probe (GstPad * pad, GstPadProbeInfo * info,
    gpointer data)
{
  GstWrapperCameraBinSrc *self = GST_WRAPPER_CAMERA_BIN_SRC (data);
  GstBaseCameraSrc *camerasrc = GST_BASE_CAMERA_SRC (data);
  GstBuffer *buffer = GST_BUFFER (info->data);
  GstPadProbeReturn ret = GST_PAD_PROBE_DROP;

  GST_LOG_OBJECT (self, "Image probe, mode %d, capture count %d bufsize: %"
      G_GSIZE_FORMAT, camerasrc->mode, self->image_capture_count,
      gst_buffer_get_size (buffer));

  g_mutex_lock (&camerasrc->capturing_mutex);
  if (self->image_capture_count > 0) {
    GstSample *sample;
    GstCaps *caps;
    ret = GST_PAD_PROBE_OK;
    self->image_capture_count--;

    /* post preview */
    /* TODO This can likely be optimized if the viewfinder caps is the same as
     * the preview caps, avoiding another scaling of the same buffer. */
    GST_DEBUG_OBJECT (self, "Posting preview for image");
    caps = gst_pad_get_current_caps (pad);
    sample = gst_sample_new (buffer, caps, NULL, NULL);
    gst_base_camera_src_post_preview (camerasrc, sample);
    gst_caps_unref (caps);
    gst_sample_unref (sample);

    if (self->image_capture_count == 0) {
      GstCaps *anycaps = gst_caps_new_any ();

      /* Get back to viewfinder */
      gst_wrapper_camera_bin_src_reset_src_zoom (self);
      gst_wrapper_camera_bin_reset_video_src_caps (self, anycaps);
      gst_wrapper_camera_bin_src_set_output (self, self->imgsrc, self->vfsrc);
      gst_base_camera_src_finish_capture (camerasrc);

      gst_caps_unref (anycaps);
    }
  }
  g_mutex_unlock (&camerasrc->capturing_mutex);
  return ret;
}

/**
 * gst_wrapper_camera_bin_src_vidsrc_probe:
 *
 * Buffer probe called before sending each buffer to video queue.
 */
static GstPadProbeReturn
gst_wrapper_camera_bin_src_vidsrc_probe (GstPad * pad, GstPadProbeInfo * info,
    gpointer data)
{
  GstWrapperCameraBinSrc *self = GST_WRAPPER_CAMERA_BIN_SRC (data);
  GstBaseCameraSrc *camerasrc = GST_BASE_CAMERA_SRC_CAST (self);
  GstPadProbeReturn ret = GST_PAD_PROBE_DROP;
  GstBuffer *buffer = GST_BUFFER (info->data);

  GST_LOG_OBJECT (self, "Video probe, mode %d, capture status %d",
      camerasrc->mode, self->video_rec_status);

  /* TODO do we want to lock for every buffer? */
  /*
   * Note that we can use gst_pad_push_event here because we are a buffer
   * probe.
   */
  /* TODO shouldn't access this directly */
  g_mutex_lock (&camerasrc->capturing_mutex);
  if (self->video_rec_status == GST_VIDEO_RECORDING_STATUS_DONE) {
    /* NOP */
  } else if (self->video_rec_status == GST_VIDEO_RECORDING_STATUS_STARTING) {
    GstClockTime ts;
    GstSegment segment;
    GstCaps *caps;
    GstSample *sample;

    GST_DEBUG_OBJECT (self, "Starting video recording");
    self->video_rec_status = GST_VIDEO_RECORDING_STATUS_RUNNING;

    ts = GST_BUFFER_TIMESTAMP (buffer);
    if (!GST_CLOCK_TIME_IS_VALID (ts))
      ts = 0;
    gst_segment_init (&segment, GST_FORMAT_TIME);
    segment.start = ts;
    gst_pad_push_event (self->vidsrc, gst_event_new_segment (&segment));

    /* post preview */
    GST_DEBUG_OBJECT (self, "Posting preview for video");
    caps = gst_pad_get_current_caps (pad);
    sample = gst_sample_new (buffer, caps, NULL, NULL);
    gst_base_camera_src_post_preview (camerasrc, sample);
    gst_caps_unref (caps);
    gst_sample_unref (sample);

    ret = GST_PAD_PROBE_OK;
  } else if (self->video_rec_status == GST_VIDEO_RECORDING_STATUS_FINISHING) {
    GstPad *peer;

    /* send eos */
    GST_DEBUG_OBJECT (self, "Finishing video recording, pushing eos");

    peer = gst_pad_get_peer (self->vidsrc);

    if (peer) {
      /* send to the peer as we don't want our pads with eos flag */
      gst_pad_send_event (peer, gst_event_new_eos ());
      gst_object_unref (peer);
    } else {
      GST_WARNING_OBJECT (camerasrc, "No peer pad for vidsrc");
    }
    self->video_rec_status = GST_VIDEO_RECORDING_STATUS_DONE;

    gst_pad_unlink (self->src_pad, self->video_tee_sink);
    gst_wrapper_camera_bin_src_set_output (self, self->vfsrc, self->vfsrc);
    gst_base_camera_src_finish_capture (camerasrc);
  } else {
    ret = GST_PAD_PROBE_OK;
  }
  g_mutex_unlock (&camerasrc->capturing_mutex);
  return ret;
}

static void
gst_wrapper_camera_bin_src_caps_cb (GstPad * pad, GParamSpec * pspec,
    gpointer user_data)
{
  GstBaseCameraSrc *bcamsrc = GST_BASE_CAMERA_SRC (user_data);
  GstWrapperCameraBinSrc *self = GST_WRAPPER_CAMERA_BIN_SRC (user_data);
  GstCaps *caps;
  GstStructure *in_st = NULL;

  caps = gst_pad_get_current_caps (pad);

  GST_DEBUG_OBJECT (self, "src-filter caps changed to %" GST_PTR_FORMAT, caps);

  if (caps && gst_caps_get_size (caps)) {
    in_st = gst_caps_get_structure (caps, 0);
    if (in_st) {
      gst_structure_get_int (in_st, "width", &bcamsrc->width);
      gst_structure_get_int (in_st, "height", &bcamsrc->height);

      GST_DEBUG_OBJECT (self, "Source dimensions now: %dx%d", bcamsrc->width,
          bcamsrc->height);
    }
  }

  /* Update zoom */
  gst_base_camera_src_setup_zoom (bcamsrc);

  if (caps)
    gst_caps_unref (caps);
};

static void
gst_wrapper_camera_bin_src_max_zoom_cb (GObject * self, GParamSpec * pspec,
    gpointer user_data)
{
  GstBaseCameraSrc *bcamsrc = (GstBaseCameraSrc *) user_data;

  g_object_get (self, "max-zoom", &bcamsrc->max_zoom, NULL);
  g_object_notify (G_OBJECT (bcamsrc), "max-zoom");
}

static gboolean
gst_wrapper_camera_bin_src_src_event (GstPad * pad, GstObject * parent,
    GstEvent * event)
{
  gboolean ret = TRUE;
  GstWrapperCameraBinSrc *self = GST_WRAPPER_CAMERA_BIN_SRC (parent);

  GST_DEBUG_OBJECT (self, "Handling event %p %" GST_PTR_FORMAT, event, event);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_RECONFIGURE:
      if (pad == self->imgsrc) {
        GST_DEBUG_OBJECT (self, "Image mode reconfigure event received");
        self->image_renegotiate = TRUE;
      } else if (pad == self->vidsrc) {
        GST_DEBUG_OBJECT (self, "Video mode reconfigure event received");
        self->video_renegotiate = TRUE;
      }
      if (pad == self->imgsrc || pad == self->vidsrc) {
        gst_event_unref (event);
        return ret;
      }
      break;
    default:
      ret = gst_pad_event_default (pad, parent, event);
      break;
  }

  return ret;
}

/**
 * check_and_replace_src
 * @self: #GstWrapperCamerabinSrcCameraSrc object
 *
 * Checks if the current videosrc needs to be replaced
 */
static gboolean
check_and_replace_src (GstWrapperCameraBinSrc * self)
{
  GstBin *cbin = GST_BIN_CAST (self);
  GstBaseCameraSrc *bcamsrc = GST_BASE_CAMERA_SRC_CAST (self);

  if (self->src_vid_src && self->src_vid_src == self->app_vid_src) {
    GST_DEBUG_OBJECT (self, "No need to change current videosrc");
    return TRUE;
  }

  if (self->src_vid_src) {
    GST_DEBUG_OBJECT (self, "Removing old video source");
    if (self->src_max_zoom_signal_id) {
      g_signal_handler_disconnect (self->src_vid_src,
          self->src_max_zoom_signal_id);
      self->src_max_zoom_signal_id = 0;
    }
    if (self->src_event_probe_id) {
      GstPad *pad;
      pad = gst_element_get_static_pad (self->src_vid_src, "src");
      gst_pad_remove_probe (pad, self->src_event_probe_id);
      gst_object_unref (pad);
      self->src_event_probe_id = 0;
    }
    gst_bin_remove (GST_BIN_CAST (self), self->src_vid_src);
    self->src_vid_src = NULL;
  }

  GST_DEBUG_OBJECT (self, "Adding new video source");

  /* Add application set or default video src element */
  if (!(self->src_vid_src = gst_camerabin_setup_default_element (cbin,
              self->app_vid_src, "autovideosrc", DEFAULT_VIDEOSRC,
              "camerasrc-real-src"))) {
    self->src_vid_src = NULL;
    goto fail;
  }

  if (!gst_bin_add (cbin, self->src_vid_src)) {
    goto fail;
  }

  /* check if we already have the next element to link to */
  if (self->src_crop) {
    if (!gst_element_link_pads (self->src_vid_src, "src", self->src_crop,
            "sink")) {
      goto fail;
    }
  }

  /* we listen for changes to max-zoom in the video src so that
   * we can proxy them to the basecamerasrc property */
  if (g_object_class_find_property (G_OBJECT_GET_CLASS (bcamsrc), "max-zoom")) {
    self->src_max_zoom_signal_id =
        g_signal_connect (G_OBJECT (self->src_vid_src), "notify::max-zoom",
        (GCallback) gst_wrapper_camera_bin_src_max_zoom_cb, bcamsrc);
  }

  return TRUE;

fail:
  if (self->src_vid_src)
    gst_element_set_state (self->src_vid_src, GST_STATE_NULL);
  return FALSE;
}

/**
 * gst_wrapper_camera_bin_src_construct_pipeline:
 * @bcamsrc: camerasrc object
 *
 * This function creates and links the elements of the camerasrc bin
 * videosrc ! cspconv ! srcfilter ! cspconv ! capsfilter ! crop ! scale ! \
 * capsfilter
 *
 * Returns: TRUE, if elements were successfully created, FALSE otherwise
 */
static gboolean
gst_wrapper_camera_bin_src_construct_pipeline (GstBaseCameraSrc * bcamsrc)
{
  GstWrapperCameraBinSrc *self = GST_WRAPPER_CAMERA_BIN_SRC (bcamsrc);
  GstBin *cbin = GST_BIN (bcamsrc);
  GstElement *filter_csp;
  GstElement *src_csp;
  GstElement *capsfilter;
  GstElement *video_recording_tee;
  gboolean ret = FALSE;
  GstPad *tee_pad;

  /* checks and adds a new video src if needed */
  if (!check_and_replace_src (self))
    goto done;

  if (!self->elements_created) {

    GST_DEBUG_OBJECT (self, "constructing pipeline");

    if (!(self->src_crop =
            gst_camerabin_create_and_add_element (cbin, "videocrop",
                "src-crop")))
      goto done;

    if (!gst_camerabin_create_and_add_element (cbin, "videoconvert",
            "src-videoconvert"))
      goto done;

    if (self->app_vid_filter) {
      self->video_filter = gst_object_ref (self->app_vid_filter);

      if (!gst_camerabin_add_element (cbin, self->video_filter))
        goto done;
      if (!gst_camerabin_create_and_add_element (cbin, "videoconvert",
              "filter-videoconvert"))
        goto done;
    }

    if (!(self->src_filter =
            gst_camerabin_create_and_add_element (cbin, "capsfilter",
                "src-capsfilter")))
      goto done;

    /* attach to notify::caps on the first capsfilter and use a callback
     * to recalculate the zoom properties when these caps change and to
     * propagate the caps to the second capsfilter */
    self->srcfilter_pad = gst_element_get_static_pad (self->src_filter, "src");
    g_signal_connect (self->srcfilter_pad, "notify::caps",
        G_CALLBACK (gst_wrapper_camera_bin_src_caps_cb), self);

    if (!(self->digitalzoom = g_object_new (GST_TYPE_DIGITAL_ZOOM, NULL))) {
      GST_ELEMENT_ERROR (self, CORE, MISSING_PLUGIN,
          (_("Digitalzoom element couldn't be created")), (NULL));

      goto done;
    }
    if (!gst_camerabin_add_element_full (GST_BIN_CAST (self), NULL,
            self->digitalzoom, "sink"))
      goto done;

    /* keep a 'tee' element that has 2 source pads, one is linked to the
     * vidsrc pad and the other is linked as needed to the viewfinder
     * when video recording is hapenning */
    video_recording_tee = gst_element_factory_make ("tee", "video_rec_tee");
    gst_bin_add (GST_BIN_CAST (self), video_recording_tee);     /* TODO check returns */
    self->video_tee_vf_pad =
        gst_element_get_request_pad (video_recording_tee, "src_%u");
    self->video_tee_sink =
        gst_element_get_static_pad (video_recording_tee, "sink");
    tee_pad = gst_element_get_request_pad (video_recording_tee, "src_%u");
    gst_ghost_pad_set_target (GST_GHOST_PAD (self->vidsrc), tee_pad);
    gst_object_unref (tee_pad);

    /* viewfinder pad */
    self->src_pad = gst_element_get_static_pad (self->digitalzoom, "src");
    gst_ghost_pad_set_target (GST_GHOST_PAD (self->vfsrc), self->src_pad);

    gst_pad_set_active (self->vfsrc, TRUE);
    gst_pad_set_active (self->imgsrc, TRUE);    /* XXX ??? */
    gst_pad_set_active (self->vidsrc, TRUE);    /* XXX ??? */

    gst_pad_add_probe (self->imgsrc, GST_PAD_PROBE_TYPE_BUFFER,
        gst_wrapper_camera_bin_src_imgsrc_probe, self, NULL);
    gst_pad_add_probe (self->video_tee_sink, GST_PAD_PROBE_TYPE_BUFFER,
        gst_wrapper_camera_bin_src_vidsrc_probe, self, NULL);
  }

  /* Do this even if pipeline is constructed */

  if (self->video_filter) {
    /* check if we need to replace the current one */
    if (self->video_filter != self->app_vid_filter) {
      gst_bin_remove (cbin, self->video_filter);
      gst_object_unref (self->video_filter);
      self->video_filter = NULL;
      filter_csp = gst_bin_get_by_name (cbin, "filter-videoconvert");
      gst_bin_remove (cbin, filter_csp);
      gst_object_unref (filter_csp);
      filter_csp = NULL;
    }
  }

  if (!self->video_filter) {
    if (self->app_vid_filter) {
      self->video_filter = gst_object_ref (self->app_vid_filter);
      filter_csp = gst_element_factory_make ("videoconvert",
          "filter-videoconvert");
      gst_bin_add_many (cbin, self->video_filter, filter_csp, NULL);
      src_csp = gst_bin_get_by_name (cbin, "src-videoconvert");
      capsfilter = gst_bin_get_by_name (cbin, "src-capsfilter");
      if (gst_pad_is_linked (gst_element_get_static_pad (src_csp, "src")))
        gst_element_unlink (src_csp, capsfilter);
      if (!gst_element_link_many (src_csp, self->video_filter, filter_csp,
              capsfilter, NULL)) {
        gst_object_unref (src_csp);
        gst_object_unref (capsfilter);
        goto done;
      }
      gst_object_unref (src_csp);
      gst_object_unref (capsfilter);
    }
  }
  ret = TRUE;
  self->elements_created = TRUE;
done:
  return ret;
}

/**
 * adapt_image_capture:
 * @self: camerasrc object
 * @in_caps: caps object that describes incoming image format
 *
 * Adjust capsfilters and crop according image capture caps if necessary.
 * The captured image format from video source might be different from
 * what application requested, so we can try to fix that in camerabin.
 *
 */
static void
adapt_image_capture (GstWrapperCameraBinSrc * self, GstCaps * in_caps)
{
  GstStructure *in_st, *req_st;
  gint in_width = 0, in_height = 0, req_width = 0, req_height = 0, crop = 0;
  gdouble ratio_w, ratio_h;

  GST_LOG_OBJECT (self, "in caps: %" GST_PTR_FORMAT, in_caps);
  GST_LOG_OBJECT (self, "requested caps: %" GST_PTR_FORMAT,
      self->image_capture_caps);

  in_st = gst_caps_get_structure (in_caps, 0);
  gst_structure_get_int (in_st, "width", &in_width);
  gst_structure_get_int (in_st, "height", &in_height);

  req_st = gst_caps_get_structure (self->image_capture_caps, 0);
  gst_structure_get_int (req_st, "width", &req_width);
  gst_structure_get_int (req_st, "height", &req_height);

  GST_INFO_OBJECT (self, "we requested %dx%d, and got %dx%d", req_width,
      req_height, in_width, in_height);

  /* Crop if requested aspect ratio differs from incoming frame aspect ratio */
  if (self->src_crop) {
    gint base_crop_top = 0, base_crop_bottom = 0;
    gint base_crop_left = 0, base_crop_right = 0;

    ratio_w = (gdouble) in_width / req_width;
    ratio_h = (gdouble) in_height / req_height;

    if (ratio_w < ratio_h) {
      crop = in_height - (req_height * ratio_w);
      base_crop_top = crop / 2;
      base_crop_bottom = crop / 2;
    } else {
      crop = in_width - (req_width * ratio_h);
      base_crop_left = crop / 2;
      base_crop_right += crop / 2;
    }

    GST_INFO_OBJECT (self,
        "setting base crop: left:%d, right:%d, top:%d, bottom:%d",
        base_crop_left, base_crop_right, base_crop_top, base_crop_bottom);
    g_object_set (G_OBJECT (self->src_crop),
        "top", base_crop_top, "bottom", base_crop_bottom,
        "left", base_crop_left, "right", base_crop_right, NULL);
  }

  /* Update capsfilters */
  set_capsfilter_caps (self, self->image_capture_caps);
}

/**
 * img_capture_prepared:
 * @data: camerasrc object
 * @caps: caps describing the prepared image format
 *
 * Callback which is called after image capture has been prepared.
 */
static void
img_capture_prepared (gpointer data, GstCaps * caps)
{
  GstWrapperCameraBinSrc *self = GST_WRAPPER_CAMERA_BIN_SRC (data);

  GST_INFO_OBJECT (self, "image capture prepared");

  /* It is possible we are about to get something else that we requested */
  if (!gst_caps_can_intersect (self->image_capture_caps, caps)) {
    adapt_image_capture (self, caps);
  } else {
    set_capsfilter_caps (self, self->image_capture_caps);
  }
}

static GstPadProbeReturn
start_image_capture (GstPad * pad, GstPadProbeInfo * info, gpointer udata)
{
  GstWrapperCameraBinSrc *self = udata;
  GstBaseCameraSrc *bcamsrc = GST_BASE_CAMERA_SRC (self);
  GstPhotography *photography =
      (GstPhotography *) gst_bin_get_by_interface (GST_BIN_CAST (bcamsrc),
      GST_TYPE_PHOTOGRAPHY);
  GstCaps *caps;

  GST_DEBUG_OBJECT (self, "Starting image capture");

  /* unlink from the viewfinder, link to the imagesrc pad to wait for
   * the buffer to pass */
  gst_wrapper_camera_bin_src_set_output (self, self->vfsrc, self->imgsrc);

  if (self->image_renegotiate) {
    self->image_renegotiate = FALSE;

    /* clean capsfilter caps so they don't interfere here */
    g_object_set (self->src_filter, "caps", NULL, NULL);

    caps = gst_pad_get_allowed_caps (self->imgsrc);
    gst_caps_replace (&self->image_capture_caps, caps);
    gst_caps_unref (caps);

    /* We caught this event in the src pad event handler and now we want to
     * actually push it upstream */
    gst_pad_mark_reconfigure (pad);
  }

  if (photography) {
    GST_DEBUG_OBJECT (self, "prepare image capture caps %" GST_PTR_FORMAT,
        self->image_capture_caps);
    if (!gst_photography_prepare_for_capture (photography,
            (GstPhotographyCapturePrepared) img_capture_prepared,
            self->image_capture_caps, self)) {
      GST_ELEMENT_ERROR (self, CORE, NEGOTIATION,
          ("Failed to prepare image capture"),
          ("Prepare capture call didn't succeed for the given caps"));
      self->image_capture_count = 0;
    }
    gst_object_unref (photography);
  } else {
    gst_wrapper_camera_bin_reset_video_src_caps (self,
        self->image_capture_caps);
  }

  self->image_capture_probe = 0;
  return GST_PAD_PROBE_REMOVE;
}

static GstPadProbeReturn
start_video_capture (GstPad * pad, GstPadProbeInfo * info, gpointer udata)
{
  GstWrapperCameraBinSrc *self = udata;
  GstCaps *caps;

  GST_DEBUG_OBJECT (self, "Starting video capture");

  if (self->video_renegotiate) {
    GstCaps *anycaps = gst_caps_new_any ();
    gst_wrapper_camera_bin_reset_video_src_caps (self, anycaps);
    gst_caps_unref (anycaps);

    /* clean capsfilter caps so they don't interfere here */
    g_object_set (self->src_filter, "caps", NULL, NULL);
  }

  /* unlink from the viewfinder, link to the imagesrc pad, wait for
   * the buffer to pass */
  gst_wrapper_camera_bin_src_set_output (self, self->vfsrc, NULL);
  gst_pad_link (self->src_pad, self->video_tee_sink);
  gst_ghost_pad_set_target (GST_GHOST_PAD (self->vfsrc),
      self->video_tee_vf_pad);

  if (self->video_renegotiate) {
    GST_DEBUG_OBJECT (self, "Getting allowed videosrc caps");
    caps = gst_pad_get_allowed_caps (self->vidsrc);
    GST_DEBUG_OBJECT (self, "Video src caps %" GST_PTR_FORMAT, caps);

    self->video_renegotiate = FALSE;
    gst_wrapper_camera_bin_reset_video_src_caps (self, caps);
    gst_caps_unref (caps);
  }
  self->video_capture_probe = 0;

  return GST_PAD_PROBE_REMOVE;
}

static gboolean
gst_wrapper_camera_bin_src_set_mode (GstBaseCameraSrc * bcamsrc,
    GstCameraBinMode mode)
{
  GstPhotography *photography =
      (GstPhotography *) gst_bin_get_by_interface (GST_BIN_CAST (bcamsrc),
      GST_TYPE_PHOTOGRAPHY);
  GstWrapperCameraBinSrc *self = GST_WRAPPER_CAMERA_BIN_SRC (bcamsrc);

  if (mode == MODE_IMAGE) {
    self->image_renegotiate = TRUE;
  } else {
    self->video_renegotiate = TRUE;
  }
  self->mode = mode;

  if (photography) {
    if (g_object_class_find_property (G_OBJECT_GET_CLASS (photography),
            "capture-mode")) {
      g_object_set (G_OBJECT (photography), "capture-mode", mode, NULL);
    }
    gst_object_unref (photography);
  } else {
    GstCaps *anycaps = gst_caps_new_any ();
    gst_wrapper_camera_bin_reset_video_src_caps (self, anycaps);
    gst_caps_unref (anycaps);
  }

  return TRUE;
}

static gboolean
set_videosrc_zoom (GstWrapperCameraBinSrc * self, gfloat zoom)
{
  gboolean ret = FALSE;

  if (g_object_class_find_property (G_OBJECT_GET_CLASS (self->src_vid_src),
          "zoom")) {
    g_object_set (G_OBJECT (self->src_vid_src), "zoom", zoom, NULL);
    ret = TRUE;
  }
  return ret;
}

static void
gst_wrapper_camera_bin_src_set_zoom (GstBaseCameraSrc * bcamsrc, gfloat zoom)
{
  GstWrapperCameraBinSrc *self = GST_WRAPPER_CAMERA_BIN_SRC (bcamsrc);

  GST_INFO_OBJECT (self, "setting zoom %f", zoom);

  if (set_videosrc_zoom (self, zoom)) {
    g_object_set (self->digitalzoom, "zoom", (gfloat) 1.0, NULL);
    GST_INFO_OBJECT (self, "zoom set using videosrc");
  } else {
    GST_INFO_OBJECT (self, "zoom set using digitalzoom");
    g_object_set (self->digitalzoom, "zoom", zoom, NULL);
  }
}

/**
 * update_aspect_filter:
 * @self: camerasrc object
 * @new_caps: new caps of next buffers arriving to view finder sink element
 *
 * Updates aspect ratio capsfilter to maintain aspect ratio, if we need to
 * scale frames for showing them in view finder.
 */
static void
update_aspect_filter (GstWrapperCameraBinSrc * self, GstCaps * new_caps)
{
  /* XXX why not instead add a preserve-aspect-ratio property to videoscale? */
#if 0
  if (camera->flags & GST_CAMERABIN_FLAG_VIEWFINDER_SCALE) {
    GstCaps *sink_caps, *ar_caps;
    GstStructure *st;
    gint in_w = 0, in_h = 0, sink_w = 0, sink_h = 0, target_w = 0, target_h = 0;
    gdouble ratio_w, ratio_h;
    GstPad *sink_pad;
    const GValue *range;

    sink_pad = gst_element_get_static_pad (camera->view_sink, "sink");

    if (sink_pad) {
      sink_caps = gst_pad_get_caps (sink_pad);
      gst_object_unref (sink_pad);
      if (sink_caps) {
        if (!gst_caps_is_any (sink_caps)) {
          GST_DEBUG_OBJECT (camera, "sink element caps %" GST_PTR_FORMAT,
              sink_caps);
          /* Get maximum resolution that view finder sink accepts */
          st = gst_caps_get_structure (sink_caps, 0);
          if (gst_structure_has_field_typed (st, "width", GST_TYPE_INT_RANGE)) {
            range = gst_structure_get_value (st, "width");
            sink_w = gst_value_get_int_range_max (range);
          }
          if (gst_structure_has_field_typed (st, "height", GST_TYPE_INT_RANGE)) {
            range = gst_structure_get_value (st, "height");
            sink_h = gst_value_get_int_range_max (range);
          }
          GST_DEBUG_OBJECT (camera, "sink element accepts max %dx%d", sink_w,
              sink_h);

          /* Get incoming frames' resolution */
          if (sink_h && sink_w) {
            st = gst_caps_get_structure (new_caps, 0);
            gst_structure_get_int (st, "width", &in_w);
            gst_structure_get_int (st, "height", &in_h);
            GST_DEBUG_OBJECT (camera, "new caps with %dx%d", in_w, in_h);
          }
        }
        gst_caps_unref (sink_caps);
      }
    }

    /* If we get bigger frames than view finder sink accepts, then we scale.
       If we scale we need to adjust aspect ratio capsfilter caps in order
       to maintain aspect ratio while scaling. */
    if (in_w && in_h && (in_w > sink_w || in_h > sink_h)) {
      ratio_w = (gdouble) sink_w / in_w;
      ratio_h = (gdouble) sink_h / in_h;

      if (ratio_w < ratio_h) {
        target_w = sink_w;
        target_h = (gint) (ratio_w * in_h);
      } else {
        target_w = (gint) (ratio_h * in_w);
        target_h = sink_h;
      }

      GST_DEBUG_OBJECT (camera, "setting %dx%d filter to maintain aspect ratio",
          target_w, target_h);
      ar_caps = gst_caps_copy (new_caps);
      gst_caps_set_simple (ar_caps, "width", G_TYPE_INT, target_w, "height",
          G_TYPE_INT, target_h, NULL);
    } else {
      GST_DEBUG_OBJECT (camera, "no scaling");
      ar_caps = new_caps;
    }

    GST_DEBUG_OBJECT (camera, "aspect ratio filter caps %" GST_PTR_FORMAT,
        ar_caps);
    g_object_set (G_OBJECT (camera->aspect_filter), "caps", ar_caps, NULL);
    if (ar_caps != new_caps)
      gst_caps_unref (ar_caps);
  }
#endif
}


/**
 * set_capsfilter_caps:
 * @self: camerasrc object
 * @new_caps: pointer to caps object to set
 *
 * Set given caps to camerabin capsfilters.
 */
static void
set_capsfilter_caps (GstWrapperCameraBinSrc * self, GstCaps * new_caps)
{
  GST_INFO_OBJECT (self, "new_caps:%" GST_PTR_FORMAT, new_caps);

  /* Update zoom */
  gst_base_camera_src_setup_zoom (GST_BASE_CAMERA_SRC (self));

  /* Update capsfilters */
  g_object_set (G_OBJECT (self->src_filter), "caps", new_caps, NULL);
  update_aspect_filter (self, new_caps);
  GST_INFO_OBJECT (self, "updated");
}

static gboolean
gst_wrapper_camera_bin_src_start_capture (GstBaseCameraSrc * camerasrc)
{
  GstWrapperCameraBinSrc *src = GST_WRAPPER_CAMERA_BIN_SRC (camerasrc);
  GstPad *pad;
  gboolean ret = TRUE;

  pad = gst_element_get_static_pad (src->src_vid_src, "src");

  /* TODO should we access this directly? Maybe a macro is better? */
  if (src->mode == MODE_IMAGE) {
    src->image_capture_count = 1;

    src->image_capture_probe =
        gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_IDLE, start_image_capture,
        src, NULL);
  } else if (src->mode == MODE_VIDEO) {
    if (src->video_rec_status == GST_VIDEO_RECORDING_STATUS_DONE) {
      src->video_rec_status = GST_VIDEO_RECORDING_STATUS_STARTING;
      src->video_capture_probe =
          gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_IDLE, start_video_capture,
          src, NULL);
    }
  } else {
    g_assert_not_reached ();
    ret = FALSE;
  }
  gst_object_unref (pad);
  return ret;
}

static void
gst_wrapper_camera_bin_src_stop_capture (GstBaseCameraSrc * camerasrc)
{
  GstWrapperCameraBinSrc *src = GST_WRAPPER_CAMERA_BIN_SRC (camerasrc);

  /* TODO shoud we access this directly? Maybe a macro is better? */
  if (src->mode == MODE_VIDEO) {
    if (src->video_rec_status == GST_VIDEO_RECORDING_STATUS_STARTING) {
      GST_DEBUG_OBJECT (src, "Aborting, had not started recording");
      src->video_rec_status = GST_VIDEO_RECORDING_STATUS_DONE;

    } else if (src->video_rec_status == GST_VIDEO_RECORDING_STATUS_RUNNING) {
      GST_DEBUG_OBJECT (src, "Marking video recording as finishing");
      src->video_rec_status = GST_VIDEO_RECORDING_STATUS_FINISHING;
    }
  } else {
    /* TODO check what happens when we try to stop a image capture */
  }
}

static GstStateChangeReturn
gst_wrapper_camera_bin_src_change_state (GstElement * element,
    GstStateChange trans)
{
  GstStateChangeReturn ret;
  GstWrapperCameraBinSrc *self = GST_WRAPPER_CAMERA_BIN_SRC (element);

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, trans);

  if (ret == GST_STATE_CHANGE_FAILURE)
    goto end;

  switch (trans) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      self->video_renegotiate = TRUE;
      self->image_renegotiate = TRUE;
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      break;
    case GST_STATE_CHANGE_NULL_TO_READY:
      break;
    default:
      break;
  }

end:
  return ret;
}

static void
gst_wrapper_camera_bin_src_class_init (GstWrapperCameraBinSrcClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
  GstBaseCameraSrcClass *gstbasecamerasrc_class;

  gobject_class = G_OBJECT_CLASS (klass);
  gstelement_class = GST_ELEMENT_CLASS (klass);
  gstbasecamerasrc_class = GST_BASE_CAMERA_SRC_CLASS (klass);

  gobject_class->dispose = gst_wrapper_camera_bin_src_dispose;
  gobject_class->finalize =
      (GObjectFinalizeFunc) gst_wrapper_camera_bin_src_finalize;
  gobject_class->set_property = gst_wrapper_camera_bin_src_set_property;
  gobject_class->get_property = gst_wrapper_camera_bin_src_get_property;

  /* g_object_class_install_property .... */
  g_object_class_install_property (gobject_class, PROP_VIDEO_SRC,
      g_param_spec_object ("video-source", "Video source",
          "The video source element to be used",
          GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_VIDEO_SRC_FILTER,
      g_param_spec_object ("video-source-filter", "Video source filter",
          "Optional video source filter element",
          GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  gstelement_class->change_state = gst_wrapper_camera_bin_src_change_state;

  gstbasecamerasrc_class->construct_pipeline =
      gst_wrapper_camera_bin_src_construct_pipeline;
  gstbasecamerasrc_class->set_zoom = gst_wrapper_camera_bin_src_set_zoom;
  gstbasecamerasrc_class->set_mode = gst_wrapper_camera_bin_src_set_mode;
  gstbasecamerasrc_class->start_capture =
      gst_wrapper_camera_bin_src_start_capture;
  gstbasecamerasrc_class->stop_capture =
      gst_wrapper_camera_bin_src_stop_capture;

  GST_DEBUG_CATEGORY_INIT (wrapper_camera_bin_src_debug, "wrappercamerabinsrc",
      0, "wrapper camera src");

  gst_element_class_add_static_pad_template (gstelement_class, &vfsrc_template);

  gst_element_class_add_static_pad_template (gstelement_class,
      &imgsrc_template);

  gst_element_class_add_static_pad_template (gstelement_class,
      &vidsrc_template);

  gst_element_class_set_static_metadata (gstelement_class,
      "Wrapper camera src element for camerabin2", "Source/Video",
      "Wrapper camera src element for camerabin2",
      "Thiago Santos <thiago.sousa.santos@collabora.com>");
}

static void
gst_wrapper_camera_bin_src_init (GstWrapperCameraBinSrc * self)
{
  self->vfsrc =
      gst_ghost_pad_new_no_target (GST_BASE_CAMERA_SRC_VIEWFINDER_PAD_NAME,
      GST_PAD_SRC);
  gst_element_add_pad (GST_ELEMENT (self), self->vfsrc);

  self->imgsrc =
      gst_ghost_pad_new_no_target (GST_BASE_CAMERA_SRC_IMAGE_PAD_NAME,
      GST_PAD_SRC);
  gst_element_add_pad (GST_ELEMENT (self), self->imgsrc);

  self->vidsrc =
      gst_ghost_pad_new_no_target (GST_BASE_CAMERA_SRC_VIDEO_PAD_NAME,
      GST_PAD_SRC);
  gst_element_add_pad (GST_ELEMENT (self), self->vidsrc);

  gst_pad_set_event_function (self->imgsrc,
      GST_DEBUG_FUNCPTR (gst_wrapper_camera_bin_src_src_event));
  gst_pad_set_event_function (self->vidsrc,
      GST_DEBUG_FUNCPTR (gst_wrapper_camera_bin_src_src_event));

  /* TODO where are variables reset? */
  self->image_capture_count = 0;
  self->video_rec_status = GST_VIDEO_RECORDING_STATUS_DONE;
  self->video_renegotiate = TRUE;
  self->image_renegotiate = TRUE;
  self->mode = GST_BASE_CAMERA_SRC_CAST (self)->mode;
  self->app_vid_filter = NULL;
}

gboolean
gst_wrapper_camera_bin_src_plugin_init (GstPlugin * plugin)
{
  return gst_element_register (plugin, "wrappercamerabinsrc", GST_RANK_NONE,
      gst_wrapper_camera_bin_src_get_type ());
}
