
#include <gst/gst.h>

static gboolean
bus_call (GstBus     *bus,
          GstMessage *msg,
          gpointer    data)
{
  GMainLoop *loop = (GMainLoop *) data;

  switch (GST_MESSAGE_TYPE (msg)) {

    case GST_MESSAGE_EOS:
      g_print ("End of stream\n");
      g_main_loop_quit (loop);
      break;

    case GST_MESSAGE_ERROR: {
      gchar  *debug;
      GError *error;

      gst_message_parse_error (msg, &error, &debug);
      g_free (debug);

      g_printerr ("Error: %s\n", error->message);
      g_error_free (error);

      g_main_loop_quit (loop);
      break;
    }
    default:
      break;
  }

  return TRUE;
}

static GstCaps *caps1;
static GstCaps *caps2;




static gboolean
reset_src_caps(gpointer data)
{
  GstBin *pipeline;
  GstElement *capsfilter;
  GstElement *src;
  GstStateChangeReturn ret;

  pipeline = GST_BIN (data);

  capsfilter = gst_bin_get_by_name (pipeline, "cf");
  src = gst_bin_get_by_name (pipeline, "src");

  gst_element_set_state (src, GST_STATE_READY);

  g_object_set (capsfilter, "caps", caps2, NULL);

  GST_ERROR ("### Setting to playing");
  ret = gst_element_set_state (src, GST_STATE_PLAYING);
  if (ret == 0) {
    GST_ERROR ("### FAILURE! %d", ret);
  } else {
    GST_ERROR ("### SUCCESS");
  }

  gst_object_unref (src);
  gst_object_unref (capsfilter);

  return FALSE;
}

int main() {
  GstElement *pipeline;
  GstElement *capsfilter;
  GMainLoop *loop;
  GstBus *bus;

  gst_init (NULL, NULL);

  loop = g_main_loop_new (NULL, FALSE);

  pipeline = GST_ELEMENT (gst_parse_launch ("v4l2src name=src ! capsfilter name=cf ! fakesink", NULL));
  capsfilter = gst_bin_get_by_name (GST_BIN (pipeline), "cf");

  caps1 = gst_caps_from_string ("video/x-raw-yuv, format=(fourcc)UYVY, width=(int)640, height=(int)480, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)30/1");
  caps2 = gst_caps_from_string ("video/x-raw-yuv, format=(fourcc)UYVY, width=(int)320, height=(int)240, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)30/1");

  g_object_set (capsfilter, "caps", caps1, NULL);

  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
  gst_bus_add_watch (bus, bus_call, loop);
  gst_object_unref (bus);

  gst_element_set_state (pipeline, GST_STATE_PLAYING);
  g_timeout_add (5000, reset_src_caps, pipeline);
  g_main_loop_run (loop);

  gst_element_set_state (pipeline, GST_STATE_NULL);

  gst_object_unref (capsfilter);
  gst_object_unref (pipeline);
  gst_caps_unref (caps1);
  gst_caps_unref (caps2);

  return 0;
}
