#include <gst/gst.h>

static GstElement *crop;
static GstElement *cf;

gboolean changed = FALSE;

static GstPadProbeReturn
crop_caps_probe (GstPad * pad, GstPadProbeInfo * info, gpointer udata)
{
  GstEvent *event = info->data;
  if (changed)
    return GST_PAD_PROBE_OK;

  if (GST_EVENT_TYPE (event) == GST_EVENT_CAPS) {
    GstCaps *caps;

    changed = TRUE;
    gst_event_parse_caps (event, &caps);
    g_object_set (cf, "caps", caps, NULL);
    g_object_set (crop, "left", 100, "top", 50, NULL);
  }

  return GST_PAD_PROBE_OK;
}

static void
add_pad_probe (GstElement * el)
{
  GstPad *src;

  src = gst_element_get_static_pad (el, "src");
  gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, crop_caps_probe,
      cf, NULL);

  gst_object_unref (src);
}

int main(void)
{
  GstElement *pipeline;

  gst_init (NULL, NULL);

  pipeline = gst_parse_launch ("videotestsrc name=src ! videocrop name=crop "
      "! videoscale ! capsfilter name=cf ! autovideosink", NULL);

  if (!pipeline) {
    g_print ("Failed to create pipeline\n");
    return -1;
  }
  crop = gst_bin_get_by_name (GST_BIN (pipeline), "crop");
  cf = gst_bin_get_by_name (GST_BIN (pipeline), "cf");

  add_pad_probe (crop);

  gst_element_set_state (pipeline, GST_STATE_PLAYING);

  g_usleep (5 * G_USEC_PER_SEC);

  gst_element_set_state (pipeline, GST_STATE_NULL);
  gst_object_unref (crop);
  gst_object_unref (cf);
  gst_object_unref (pipeline);
}
