[longomatch] Simplify source element and make it more resilent to errors



commit 20a7d8334bfc143742dce7ba055e13b8f71215f3
Author: Andoni Morales Alastruey <ylatuya gmail com>
Date:   Sun Dec 14 03:05:18 2014 +0100

    Simplify source element and make it more resilent to errors

 libcesarplayer/gst-camera-capturer.c |  847 +++++++++++++++++-----------------
 libcesarplayer/test-capturer.c       |   11 +-
 2 files changed, 424 insertions(+), 434 deletions(-)
---
diff --git a/libcesarplayer/gst-camera-capturer.c b/libcesarplayer/gst-camera-capturer.c
index 79af44e..010d597 100644
--- a/libcesarplayer/gst-camera-capturer.c
+++ b/libcesarplayer/gst-camera-capturer.c
@@ -79,12 +79,11 @@ struct GstCameraCapturerPrivate
   /*GStreamer elements */
   GstElement *main_pipeline;
   GstElement *source_bin;
-  GstElement *source_decoder_bin;
-  GstElement *decoder_bin;
+  GstElement *video_converter_bin;
+  GstElement *splitter_bin;
   GstElement *preview_bin;
   GstElement *encoder_bin;
   GstElement *source;
-  GstElement *video_filter;
   GstElement *video_enc;
   GstElement *audio_enc;
   GstElement *muxer;
@@ -92,6 +91,9 @@ struct GstCameraCapturerPrivate
   GstElement *video_appsrc;
   GstElement *audio_appsrc;
 
+  gboolean has_video;
+  gboolean has_audio;
+
   /* Recording */
   gboolean is_recording;
   gboolean closing_recording;
@@ -296,74 +298,70 @@ gst_camera_capturer_update_device_id (GstCameraCapturer * gcc)
     g_object_set (gcc->priv->source, prop_name, gcc->priv->device_id, NULL);
 }
 
-static void
-cb_new_pad (GstElement * element, GstPad * pad, GstCameraCapturer * gcc)
+static gboolean
+gst_camera_capturer_create_converter_bin (GstCameraCapturer * gcc)
 {
+  GstElement *videoscale, *videorate, *filter, *bin;
+  GstPad *sink_pad, *src_pad;
   GstCaps *caps;
-  const gchar *mime;
-  GstElement *sink = NULL;
-  GstPad *epad;
-  GstBin *bin = GST_BIN (gcc->priv->source_decoder_bin);
 
-  caps = gst_pad_get_caps_reffed (pad);
-  mime = gst_structure_get_name (gst_caps_get_structure (caps, 0));
-  if (g_strrstr (mime, "video")) {
-    sink = gst_bin_get_by_name (bin, "video-pad");
+  gcc->priv->video_converter_bin = bin = gst_bin_new ("video-converter");
+
+  videorate = gst_element_factory_make ("videorate", NULL);
+  videoscale = gst_element_factory_make ("videoscale", NULL);
+  filter = gst_element_factory_make ("capsfilter", NULL);
+  /* Set caps for the encoding resolution */
+  caps = gst_caps_new_simple ("video/x-raw-yuv", "framerate",
+      GST_TYPE_FRACTION, 25, 1, NULL);
+  if (gcc->priv->output_width != 0) {
+    gst_caps_set_simple (caps, "width", G_TYPE_INT, gcc->priv->output_width,
+        NULL);
   }
-  if (g_strrstr (mime, "audio") && gcc->priv->audio_enabled) {
-    sink = gst_bin_get_by_name (bin, "audio-pad");
+  if (gcc->priv->output_height != 0) {
+    gst_caps_set_simple (caps, "height", G_TYPE_INT, gcc->priv->output_height,
+        NULL);
   }
+  g_object_set (filter, "caps", caps, NULL);
+  gst_bin_add_many (GST_BIN (bin), videorate, videoscale, filter, NULL);
 
-  if (sink != NULL) {
-    epad = gst_element_get_static_pad (sink, "sink");
-    gst_pad_link (pad, epad);
-    gst_object_unref (epad);
-    gst_object_unref (sink);
-  }
-  gst_caps_unref (caps);
+  gst_element_link_many (videorate, videoscale, filter, NULL);
+
+  /* Create ghost pads */
+  sink_pad = gst_element_get_static_pad (videorate, "sink");
+  gst_element_add_pad (bin, gst_ghost_pad_new ("sink",
+          sink_pad));
+  src_pad = gst_element_get_static_pad (filter, "src");
+  gst_element_add_pad (bin, gst_ghost_pad_new ("src",
+          src_pad));
+  gst_object_unref (sink_pad);
+  gst_object_unref (src_pad);
+
+  return TRUE;
 }
 
 static void
 gst_camera_capturer_create_encoder_bin (GstCameraCapturer * gcc)
 {
-  GstElement *colorspace, *videoscale, *videorate;
-  GstCaps *caps;
+  GstElement *colorspace;
   GstPad *v_sink_pad;
 
   GST_INFO_OBJECT (gcc, "Creating encoder bin");
   gcc->priv->encoder_bin = gst_bin_new ("encoder_bin");
 
   colorspace = gst_element_factory_make ("ffmpegcolorspace", NULL);
-  videoscale = gst_element_factory_make ("videoscale", NULL);
-  videorate = gst_element_factory_make ("videorate", NULL);
-  gcc->priv->video_filter = gst_element_factory_make ("capsfilter", NULL);
   gcc->priv->filesink = gst_element_factory_make ("filesink", NULL);
 
-  /* Set caps for the encoding resolution */
-  caps = gst_caps_new_simple ("video/x-raw-yuv", "framerate",
-      GST_TYPE_FRACTION, 25, 1, NULL);
-  if (gcc->priv->output_width != 0) {
-    gst_caps_set_simple (caps, "width", G_TYPE_INT, gcc->priv->output_width,
-        NULL);
-  }
-  if (gcc->priv->output_height != 0) {
-    gst_caps_set_simple (caps, "height", G_TYPE_INT, gcc->priv->output_height,
-        NULL);
-  }
-  g_object_set (gcc->priv->video_filter, "caps", caps, NULL);
-
-  gst_bin_add_many (GST_BIN (gcc->priv->encoder_bin), videorate, videoscale,
-      colorspace, gcc->priv->video_filter, gcc->priv->video_enc,
+  gst_bin_add_many (GST_BIN (gcc->priv->encoder_bin),
+      colorspace, gcc->priv->video_enc,
       gcc->priv->muxer, gcc->priv->filesink, NULL);
 
-  gst_element_link_many (videoscale, colorspace, videorate,
-      gcc->priv->video_filter, gcc->priv->video_enc, gcc->priv->muxer, NULL);
-  gst_element_link (gcc->priv->muxer, gcc->priv->filesink);
+  gst_element_link_many (colorspace, gcc->priv->video_enc,
+      gcc->priv->muxer, gcc->priv->filesink, NULL);
 
   g_object_set (gcc->priv->filesink, "location", gcc->priv->output_file, NULL);
 
   /* Create ghost pads */
-  v_sink_pad = gst_element_get_static_pad (videoscale, "sink");
+  v_sink_pad = gst_element_get_static_pad (colorspace, "sink");
   gst_element_add_pad (gcc->priv->encoder_bin, gst_ghost_pad_new ("video",
           v_sink_pad));
   gst_object_unref (GST_OBJECT (v_sink_pad));
@@ -376,7 +374,7 @@ gst_camera_capturer_create_encoder_bin (GstCameraCapturer * gcc)
     audioresample = gst_element_factory_make ("audioresample", NULL);
 
     gst_bin_add_many (GST_BIN (gcc->priv->encoder_bin), audioconvert,
-        audioresample, audioresample, gcc->priv->audio_enc, NULL);
+        audioresample, gcc->priv->audio_enc, NULL);
 
     gst_element_link_many (audioconvert, audioresample, gcc->priv->audio_enc,
         gcc->priv->muxer, NULL);
@@ -423,183 +421,6 @@ gst_camera_capturer_create_remuxer_bin (GstCameraCapturer * gcc)
   }
 }
 
-static GstElement *
-gst_camera_capturer_prepare_raw_source (GstCameraCapturer * gcc)
-{
-  GstElement *bin, *v_identity;
-  GstPad *video_pad, *src_pad;
-
-  GST_INFO_OBJECT (gcc, "Creating raw source");
-
-  gcc->priv->video_needs_keyframe_sync = FALSE;
-
-  gcc->priv->source_decoder_bin = gst_bin_new ("decoder");
-  bin = gcc->priv->source_decoder_bin;
-  v_identity = gst_element_factory_make ("identity", NULL);
-
-  gst_bin_add_many (GST_BIN (bin), v_identity, NULL);
-
-  /* add ghostpad */
-  video_pad = gst_element_get_static_pad (v_identity, "src");
-  gst_element_add_pad (bin, gst_ghost_pad_new ("video", video_pad));
-  gst_object_unref (GST_OBJECT (video_pad));
-  src_pad = gst_element_get_static_pad (v_identity, "sink");
-  gst_element_add_pad (bin, gst_ghost_pad_new ("sink", src_pad));
-  gst_object_unref (GST_OBJECT (src_pad));
-
-  gst_camera_capturer_create_encoder_bin (gcc);
-
-  return bin;
-}
-
-static GstElement *
-gst_camera_capturer_prepare_uri_source (GstCameraCapturer * gcc)
-{
-  GstElement *bin, *decodebin, *identity;
-  GstPad *video_pad;
-
-  GST_INFO_OBJECT (gcc, "Creating URI source");
-
-  gcc->priv->video_needs_keyframe_sync = FALSE;
-
-  gcc->priv->source_decoder_bin = gst_bin_new ("decoder");
-  bin = gcc->priv->source_decoder_bin;
-  decodebin = gst_element_factory_make ("uridecodebin", NULL);
-  g_object_set (decodebin, "uri", gcc->priv->device_id, NULL);
-  g_signal_connect (decodebin, "autoplug-select",
-      G_CALLBACK (lgm_filter_video_decoders), gcc);
-  identity = gst_element_factory_make ("identity", "video-pad");
-
-  gst_bin_add_many (GST_BIN (bin), decodebin, identity, NULL);
-
-  /* add ghostpad */
-  video_pad = gst_element_get_static_pad (identity, "src");
-  gst_element_add_pad (bin, gst_ghost_pad_new ("video", video_pad));
-  gst_object_unref (GST_OBJECT (video_pad));
-
-  if (gcc->priv->audio_enabled) {
-    GstElement *audio;
-    GstPad *audio_pad;
-
-    audio = gst_element_factory_make ("identity", "audio-pad");
-    gst_bin_add_many (GST_BIN (bin), audio, NULL);
-
-    /* add ghostpad */
-    audio_pad = gst_element_get_static_pad (audio, "src");
-    gst_element_add_pad (bin, gst_ghost_pad_new ("audio", audio_pad));
-    gst_object_unref (GST_OBJECT (audio_pad));
-  }
-
-  g_signal_connect (decodebin, "pad-added", G_CALLBACK (cb_new_pad), gcc);
-
-  gst_camera_capturer_create_encoder_bin (gcc);
-
-  return bin;
-}
-
-static GstElement *
-gst_camera_capturer_prepare_dv_source (GstCameraCapturer * gcc)
-{
-  GstElement *bin, *decodebin, *colorspace, *deinterlacer;
-  GstPad *video_pad, *src_pad;
-
-  GST_INFO_OBJECT (gcc, "Creating dv source");
-
-  gcc->priv->video_needs_keyframe_sync = FALSE;
-
-  gcc->priv->source_decoder_bin = gst_bin_new ("decoder");
-  bin = gcc->priv->source_decoder_bin;
-  decodebin = gst_element_factory_make ("decodebin2", NULL);
-  colorspace = gst_element_factory_make ("ffmpegcolorspace", "video-pad");
-  deinterlacer = gst_element_factory_make ("ffdeinterlace", NULL);
-  if (deinterlacer == NULL)
-    deinterlacer = gst_element_factory_make ("identity", NULL);
-
-  gst_bin_add_many (GST_BIN (bin), decodebin, colorspace, deinterlacer, NULL);
-  gst_element_link (colorspace, deinterlacer);
-
-  /* add ghostpad */
-  video_pad = gst_element_get_static_pad (deinterlacer, "src");
-  gst_element_add_pad (bin, gst_ghost_pad_new ("video", video_pad));
-  gst_object_unref (GST_OBJECT (video_pad));
-  src_pad = gst_element_get_static_pad (decodebin, "sink");
-  gst_element_add_pad (bin, gst_ghost_pad_new ("sink", src_pad));
-  gst_object_unref (GST_OBJECT (src_pad));
-
-  if (gcc->priv->audio_enabled) {
-    GstElement *audio;
-    GstPad *audio_pad;
-
-    audio = gst_element_factory_make ("identity", "audio-pad");
-
-    gst_bin_add_many (GST_BIN (bin), audio, NULL);
-
-    /* add ghostpad */
-    audio_pad = gst_element_get_static_pad (audio, "src");
-    gst_element_add_pad (bin, gst_ghost_pad_new ("audio", audio_pad));
-    gst_object_unref (GST_OBJECT (audio_pad));
-  }
-
-  g_signal_connect (decodebin, "pad-added", G_CALLBACK (cb_new_pad), gcc);
-
-  gst_camera_capturer_create_encoder_bin (gcc);
-
-  return bin;
-}
-
-static GstElement *
-gst_camera_capturer_prepare_mpegts_source (GstCameraCapturer * gcc)
-{
-  GstElement *bin, *demuxer, *video, *video_parser;
-  GstPad *video_pad, *src_pad;
-
-  GST_INFO_OBJECT (gcc, "Creating mpegts source");
-
-  gcc->priv->video_needs_keyframe_sync = TRUE;
-  gcc->priv->video_synced = FALSE;
-
-  /* We don't want to reencode, only remux */
-  gcc->priv->source_decoder_bin = gst_bin_new ("decoder");
-  bin = gcc->priv->source_decoder_bin;
-  demuxer = gst_element_factory_make ("mpegtsdemux", NULL);
-  video_parser = gst_element_factory_make ("h264parse", "video-pad");
-  video = gst_element_factory_make ("capsfilter", NULL);
-  g_object_set (video, "caps",
-      gst_caps_from_string ("video/x-h264, stream-format=avc, alignment=au"),
-      NULL);
-
-  gst_bin_add_many (GST_BIN (bin), demuxer, video_parser, video, NULL);
-  gst_element_link (video_parser, video);
-
-  /* add ghostpad */
-  video_pad = gst_element_get_static_pad (video, "src");
-  gst_element_add_pad (bin, gst_ghost_pad_new ("video", video_pad));
-  gst_object_unref (GST_OBJECT (video_pad));
-  src_pad = gst_element_get_static_pad (demuxer, "sink");
-  gst_element_add_pad (bin, gst_ghost_pad_new ("sink", src_pad));
-  gst_object_unref (GST_OBJECT (src_pad));
-
-  if (gcc->priv->audio_enabled) {
-    GstElement *audio;
-    GstPad *audio_pad;
-
-    audio = gst_element_factory_make ("identity", "audio-pad");
-
-    gst_bin_add_many (GST_BIN (bin), audio, NULL);
-
-    /* add ghostpad */
-    audio_pad = gst_element_get_static_pad (audio, "src");
-    gst_element_add_pad (bin, gst_ghost_pad_new ("audio", audio_pad));
-    gst_object_unref (GST_OBJECT (audio_pad));
-  }
-
-  g_signal_connect (demuxer, "pad-added", G_CALLBACK (cb_new_pad), gcc);
-
-  gst_camera_capturer_create_remuxer_bin (gcc);
-
-  return bin;
-}
-
 static gboolean
 gst_camera_capturer_encoding_retimestamper (GstCameraCapturer * gcc,
     GstBuffer * prev_buf, gboolean is_video)
@@ -677,10 +498,9 @@ gst_camera_capturer_encoding_retimestamper (GstCameraCapturer * gcc,
 
   GST_BUFFER_TIMESTAMP (enc_buf) = new_buf_ts;
 
-  GST_LOG_OBJECT (gcc,
-      "Pushing %s frame to the encoder in ts:% " GST_TIME_FORMAT " out ts: %"
-      GST_TIME_FORMAT, is_video ? "video" : "audio", GST_TIME_ARGS (buf_ts),
-      GST_TIME_ARGS (new_buf_ts));
+  GST_LOG_OBJECT (gcc, "Pushing %s frame to the encoder in ts:% "
+      GST_TIME_FORMAT " out ts: %" GST_TIME_FORMAT, is_video ? "video" :
+      "audio", GST_TIME_ARGS (buf_ts), GST_TIME_ARGS (new_buf_ts));
 
   if (is_video)
     gst_app_src_push_buffer (GST_APP_SRC (gcc->priv->video_appsrc), enc_buf);
@@ -709,110 +529,111 @@ gst_camera_capturer_video_encoding_probe (GstPad * pad, GstBuffer * buf,
 }
 
 static void
-gst_camera_capturer_create_decoder_bin (GstCameraCapturer * gcc)
+gst_camera_capturer_create_splitter_bin (GstCameraCapturer * gcc)
 {
-  /*    decoder --> video_preview_queue
-   *            |
-   *            --> audio_preview_queue
+  /*   "videosink" --> video_converter --> video_preview_queue --> "video_preview"
+   *              |
+   *   "audiosink" --> audio_preview_queue --> "audiosrc" --> "audio_preview"
    *
-   *            video_appsrc   --> video_queue
-   *            audio_appsrc   --> audio_queue
+   *            video_appsrc  --> video_queue --> "videosrc"
+   *            audio_appsrc  --> audio_queue --> "audosrc"
    */
 
-  GstElement *v_queue, *v_prev_queue, *decoder_bin;
-  GstPad *v_dec_pad, *v_queue_pad, *v_prev_queue_pad;
-  GstPad *dec_sink_pad;
+  GstElement *v_queue, *v_prev_queue;
+  GstPad *v_queue_pad, *v_prev_queue_pad, *v_sink_pad;
+
 
-  GST_INFO_OBJECT (gcc, "Creating decoder bin");
-  decoder_bin = gcc->priv->source_decoder_bin;
+  GST_INFO_OBJECT (gcc, "Creating splitter bin");
   /* Create elements */
-  gcc->priv->decoder_bin = gst_bin_new ("decoder_bin");
-  v_queue = gst_element_factory_make ("queue2", "video-queue");
-  gcc->priv->video_appsrc = gst_element_factory_make ("appsrc", "video-appsrc");
+  gcc->priv->splitter_bin = gst_bin_new ("splitter");
   v_prev_queue = gst_element_factory_make ("queue2", "video-preview-queue");
+  gcc->priv->video_appsrc = gst_element_factory_make ("appsrc", "video-appsrc");
+  v_queue = gst_element_factory_make ("queue2", "video-queue");
 
   g_object_set (gcc->priv->video_appsrc, "block", TRUE, "max-bytes",
-      40 * 1024 * 1024, NULL);
+      20 * 1024 * 1024, NULL);
   g_object_set (v_queue, "max-size-time", 1 * GST_SECOND, NULL);
   g_object_set (v_prev_queue, "max-size-bytes", 0, NULL);
 
-  gst_bin_add_many (GST_BIN (gcc->priv->decoder_bin), decoder_bin, v_queue,
-      gcc->priv->video_appsrc, v_prev_queue, NULL);
+  gst_camera_capturer_create_converter_bin (gcc);
+  gst_bin_add_many (GST_BIN (gcc->priv->splitter_bin),
+      gcc->priv->video_converter_bin, v_prev_queue,
+      gcc->priv->video_appsrc, v_queue, NULL);
 
-  /* link decoder to the preview-queue */
-  v_dec_pad = gst_element_get_static_pad (decoder_bin, "video");
-  v_prev_queue_pad = gst_element_get_static_pad (v_prev_queue, "sink");
-  gst_pad_link (v_dec_pad, v_prev_queue_pad);
-  gst_object_unref (v_dec_pad);
-  gst_object_unref (v_prev_queue_pad);
+  /* link converter to the preview-queue */
+  gst_element_link (gcc->priv->video_converter_bin, v_prev_queue);
 
-  /* Link appsrc */
+  /* Link video appsrc to the queue */
   gst_element_link (gcc->priv->video_appsrc, v_queue);
 
-  /* Create ghost pads */
+  /* Create source ghost pads */
   v_queue_pad = gst_element_get_static_pad (v_queue, "src");
   v_prev_queue_pad = gst_element_get_static_pad (v_prev_queue, "src");
-  gst_element_add_pad (gcc->priv->decoder_bin, gst_ghost_pad_new ("video",
+  gst_element_add_pad (gcc->priv->splitter_bin, gst_ghost_pad_new ("videosrc",
           v_queue_pad));
-  gst_element_add_pad (gcc->priv->decoder_bin,
+  gst_element_add_pad (gcc->priv->splitter_bin,
       gst_ghost_pad_new ("video_preview", v_prev_queue_pad));
   gst_object_unref (v_queue_pad);
   gst_object_unref (v_prev_queue_pad);
 
-  /* Create the sink ghost pad, not needed for URI's */
-  dec_sink_pad = gst_element_get_static_pad (decoder_bin, "sink");
-  if (dec_sink_pad) {
-    gst_element_add_pad (gcc->priv->decoder_bin, gst_ghost_pad_new ("sink",
-            dec_sink_pad));
-    gst_object_unref (dec_sink_pad);
-  }
+  /* Create sink ghost pads */
+  v_sink_pad = gst_element_get_static_pad (gcc->priv->video_converter_bin, "sink");
+  gst_element_add_pad (gcc->priv->splitter_bin, gst_ghost_pad_new ("videosink",
+            v_sink_pad));
+  gst_object_unref (v_sink_pad);
 
   /* Add pad probes for the encoding branch */
   v_prev_queue_pad = gst_element_get_static_pad (v_prev_queue, "src");
   gst_pad_add_buffer_probe (v_prev_queue_pad,
       (GCallback) gst_camera_capturer_video_encoding_probe, gcc);
   gst_object_unref (v_prev_queue_pad);
-  if (gcc->priv->audio_enabled) {
-    GstElement *a_queue, *a_prev_queue;
-    GstPad *a_dec_pad, *a_queue_pad, *a_prev_queue_pad;
 
-    /* Create elements */
-    gcc->priv->audio_appsrc =
-        gst_element_factory_make ("appsrc", "video-appsrc");
-    a_queue = gst_element_factory_make ("queue2", "audio-queue");
-    a_prev_queue = gst_element_factory_make ("queue2", "audio-preview-queue");
-
-    g_object_set (a_queue, "max-size-time", 1 * GST_SECOND, NULL);
-
-    gst_bin_add_many (GST_BIN (gcc->priv->decoder_bin), gcc->priv->audio_appsrc,
-        a_queue, a_prev_queue, NULL);
+}
 
-    /* Link appsrc to the queue */
-    gst_element_link (gcc->priv->audio_appsrc, a_queue);
+static void
+gst_camera_capturer_fill_audio_splitter_bin (GstCameraCapturer * gcc)
+{
+  GstElement *a_queue, *a_prev_queue;
+  GstPad *a_queue_pad, *a_prev_queue_pad, *a_sink_pad, *ghost_pad;
 
-    /* link decoder to the queue */
-    a_dec_pad = gst_element_get_static_pad (decoder_bin, "audio");
-    a_prev_queue_pad = gst_element_get_static_pad (a_prev_queue, "sink");
-    gst_pad_link (a_dec_pad, a_prev_queue_pad);
-    gst_object_unref (a_dec_pad);
-    gst_object_unref (a_prev_queue_pad);
+  /* Create elements */
+  gcc->priv->audio_appsrc =
+      gst_element_factory_make ("appsrc", "audio-appsrc");
+  a_queue = gst_element_factory_make ("queue2", "audio-queue");
+  a_prev_queue = gst_element_factory_make ("queue2", "audio-preview-queue");
+
+  g_object_set (a_queue, "max-size-time", 1 * GST_SECOND, NULL);
+
+  gst_bin_add_many (GST_BIN (gcc->priv->splitter_bin), gcc->priv->audio_appsrc,
+      a_queue, a_prev_queue, NULL);
+
+  /* Link appsrc to the queue */
+  gst_element_link (gcc->priv->audio_appsrc, a_queue);
+
+  /* Create src ghost pads */
+  a_queue_pad = gst_element_get_static_pad (a_queue, "src");
+  a_prev_queue_pad = gst_element_get_static_pad (a_prev_queue, "src");
+  ghost_pad = gst_ghost_pad_new ("audiosrc", a_queue_pad);
+  gst_pad_set_active (ghost_pad, TRUE);
+  gst_element_add_pad (gcc->priv->splitter_bin, ghost_pad);
+  ghost_pad = gst_ghost_pad_new ("audio_preview", a_prev_queue_pad);
+  gst_pad_set_active (ghost_pad, TRUE);
+  gst_element_add_pad (gcc->priv->splitter_bin, ghost_pad);
+  gst_object_unref (a_queue_pad);
+  gst_object_unref (a_prev_queue_pad);
+
+  /* Create sink ghost pads */
+  a_sink_pad = gst_element_get_static_pad (a_prev_queue, "sink");
+  ghost_pad =gst_ghost_pad_new ("audiosink", a_sink_pad);
+  gst_pad_set_active (ghost_pad, TRUE);
+  gst_element_add_pad (gcc->priv->splitter_bin, ghost_pad);
+  gst_object_unref (a_sink_pad);
 
-    /* Create ghost pads */
-    a_queue_pad = gst_element_get_static_pad (a_queue, "src");
-    a_prev_queue_pad = gst_element_get_static_pad (a_prev_queue, "src");
-    gst_element_add_pad (gcc->priv->decoder_bin, gst_ghost_pad_new ("audio",
-            a_queue_pad));
-    gst_element_add_pad (gcc->priv->decoder_bin,
-        gst_ghost_pad_new ("audio_preview", a_prev_queue_pad));
-    gst_object_unref (a_queue_pad);
-    gst_object_unref (a_prev_queue_pad);
-
-    /* Add pad probes for the encoding branch */
-    a_prev_queue_pad = gst_element_get_static_pad (a_prev_queue, "src");
-    gst_pad_add_buffer_probe (a_prev_queue_pad,
-        (GCallback) gst_camera_capturer_audio_encoding_probe, gcc);
-    gst_object_unref (a_prev_queue_pad);
-  }
+  /* Add pad probes for the encoding branch */
+  a_prev_queue_pad = gst_element_get_static_pad (a_prev_queue, "src");
+  gst_pad_add_buffer_probe (a_prev_queue_pad,
+      (GCallback) gst_camera_capturer_audio_encoding_probe, gcc);
+  gst_object_unref (a_prev_queue_pad);
 }
 
 static void
@@ -824,7 +645,7 @@ gst_camera_capturer_link_encoder_bin (GstCameraCapturer * gcc)
 
   gst_bin_add (GST_BIN (gcc->priv->main_pipeline), gcc->priv->encoder_bin);
 
-  v_dec_pad = gst_element_get_static_pad (gcc->priv->decoder_bin, "video");
+  v_dec_pad = gst_element_get_static_pad (gcc->priv->splitter_bin, "videosrc");
   v_enc_pad = gst_element_get_static_pad (gcc->priv->encoder_bin, "video");
   gst_pad_link (v_dec_pad, v_enc_pad);
   gst_object_unref (v_dec_pad);
@@ -833,7 +654,7 @@ gst_camera_capturer_link_encoder_bin (GstCameraCapturer * gcc)
   if (gcc->priv->audio_enabled) {
     GstPad *a_dec_pad, *a_enc_pad;
 
-    a_dec_pad = gst_element_get_static_pad (gcc->priv->decoder_bin, "audio");
+    a_dec_pad = gst_element_get_static_pad (gcc->priv->splitter_bin, "audiosrc");
     a_enc_pad = gst_element_get_static_pad (gcc->priv->encoder_bin, "audio");
     gst_pad_link (a_dec_pad, a_enc_pad);
     gst_object_unref (a_dec_pad);
@@ -846,37 +667,48 @@ gst_camera_capturer_link_encoder_bin (GstCameraCapturer * gcc)
 static void
 gst_camera_capturer_link_preview (GstCameraCapturer * gcc)
 {
-  GstPad *v_dec_prev_pad, *v_prev_pad;
+  GstPad *v_dec_prev_pad, *v_prev_pad, *v_src_pad, *v_split_pad;
 
   GST_INFO_OBJECT (gcc, "Linking preview bin");
 
-  gst_bin_add (GST_BIN (gcc->priv->main_pipeline), gcc->priv->decoder_bin);
-
-  if (gcc->priv->source_bin != NULL)
-    gst_element_link (gcc->priv->source_bin, gcc->priv->decoder_bin);
+  /* Link source to splitter */
+  gst_bin_add (GST_BIN (gcc->priv->main_pipeline), gcc->priv->splitter_bin);
+  v_src_pad =
+      gst_element_get_static_pad (gcc->priv->source_bin, "video");
+  v_split_pad = gst_element_get_static_pad (gcc->priv->splitter_bin, "videosink");
+  gst_pad_link (v_src_pad, v_split_pad);
+  gst_object_unref (v_src_pad);
+  gst_object_unref (v_split_pad);
 
+  /* Link splitter to preview */
   v_dec_prev_pad =
-      gst_element_get_static_pad (gcc->priv->decoder_bin, "video_preview");
+      gst_element_get_static_pad (gcc->priv->splitter_bin, "video_preview");
   v_prev_pad = gst_element_get_static_pad (gcc->priv->preview_bin, "video");
-
   gst_pad_link (v_dec_prev_pad, v_prev_pad);
-
   gst_object_unref (v_dec_prev_pad);
   gst_object_unref (v_prev_pad);
+}
 
-  if (gcc->priv->audio_enabled) {
-    GstPad *a_dec_prev_pad, *a_prev_pad;
-
-    a_dec_prev_pad =
-        gst_element_get_static_pad (gcc->priv->decoder_bin, "audio_preview");
-    a_prev_pad = gst_element_get_static_pad (gcc->priv->preview_bin, "audio");
-
-    gst_pad_link (a_dec_prev_pad, a_prev_pad);
-
-    gst_object_unref (a_dec_prev_pad);
-    gst_object_unref (a_prev_pad);
-  }
-  gst_element_set_state (gcc->priv->decoder_bin, GST_STATE_PLAYING);
+static void
+gst_camera_capturer_link_audio_preview (GstCameraCapturer * gcc)
+{
+  GstPad *a_dec_prev_pad, *a_prev_pad, *a_src_pad, *a_split_pad;
+
+  /* Link audio source to splitter */
+  a_src_pad =
+      gst_element_get_static_pad (gcc->priv->source_bin, "audio");
+  a_split_pad = gst_element_get_static_pad (gcc->priv->splitter_bin, "audiosink");
+  gst_pad_link (a_src_pad, a_split_pad);
+  gst_object_unref (a_src_pad);
+  gst_object_unref (a_split_pad);
+
+  /* Link audio splitter to preview */
+  a_dec_prev_pad =
+      gst_element_get_static_pad (gcc->priv->splitter_bin, "audio_preview");
+  a_prev_pad = gst_element_get_static_pad (gcc->priv->preview_bin, "audio");
+  gst_pad_link (a_dec_prev_pad, a_prev_pad);
+  gst_object_unref (a_dec_prev_pad);
+  gst_object_unref (a_prev_pad);
 }
 
 static gboolean
@@ -907,6 +739,7 @@ gst_camera_capturer_create_preview (GstCameraCapturer * gcc)
   GstElement *v_decoder, *video_bin;
   GstPad *video_pad;
 
+  GST_INFO_OBJECT (gcc, "Create preview bin");
   v_decoder = gst_element_factory_make ("decodebin2", "preview-decoder");
 
   video_bin =
@@ -932,82 +765,52 @@ gst_camera_capturer_create_preview (GstCameraCapturer * gcc)
           video_pad));
   gst_object_unref (GST_OBJECT (video_pad));
 
-  if (gcc->priv->audio_enabled) {
-    GstElement *a_decoder, *audio_bin;
-    GstPad *audio_pad;
-
-    a_decoder = gst_element_factory_make ("decodebin2", NULL);
-
-    audio_bin =
-        gst_parse_bin_from_description
-        ("audioconvert ! audioresample ! autoaudiosink name=audiosink", TRUE,
-        NULL);
-
-    gst_bin_add_many (GST_BIN (gcc->priv->preview_bin), a_decoder, audio_bin,
-        NULL);
-
-    g_signal_connect (a_decoder, "pad-added", G_CALLBACK (cb_new_prev_pad),
-        audio_bin);
-
-    /* Create ghost pads */
-    audio_pad = gst_element_get_static_pad (a_decoder, "sink");
-    gst_element_add_pad (gcc->priv->preview_bin, gst_ghost_pad_new ("audio",
-            audio_pad));
-    gst_object_unref (GST_OBJECT (audio_pad));
-  }
-
   gst_bin_add (GST_BIN (gcc->priv->main_pipeline), gcc->priv->preview_bin);
   gst_element_set_state (gcc->priv->preview_bin, GST_STATE_PLAYING);
 }
 
 static void
-gst_camera_capturer_create_remainig (GstCameraCapturer * gcc)
+gst_camera_capturer_fill_audio_preview (GstCameraCapturer * gcc)
 {
-  gst_camera_capturer_create_decoder_bin (gcc);
-  gst_camera_capturer_create_preview (gcc);
+  GstElement *a_decoder, *audio_bin;
+  GstPad *audio_pad, *ghost_pad;
 
-  gst_camera_capturer_link_preview (gcc);
-  gst_element_set_state (gcc->priv->main_pipeline, GST_STATE_PLAYING);
-}
+  a_decoder = gst_element_factory_make ("decodebin2", NULL);
 
-static gboolean
-gst_camera_capturer_have_type_cb (GstElement * typefind, guint prob,
-    GstCaps * caps, GstCameraCapturer * gcc)
-{
-  GstCaps *media_caps;
-  GstElement *decoder_bin = NULL;
+  audio_bin =
+      gst_parse_bin_from_description
+      ("audioconvert ! audioresample ! autoaudiosink name=audiosink", TRUE,
+      NULL);
 
-  GST_INFO_OBJECT (gcc, "Found type with caps %s", gst_caps_to_string (caps));
+  gst_bin_add_many (GST_BIN (gcc->priv->preview_bin), a_decoder, audio_bin,
+      NULL);
 
-  /* Check for DV streams */
-  media_caps = gst_caps_from_string ("video/x-dv, systemstream=true");
+  g_signal_connect (a_decoder, "pad-added", G_CALLBACK (cb_new_prev_pad),
+      audio_bin);
 
-  if (gst_caps_can_intersect (caps, media_caps)) {
-    decoder_bin = gst_camera_capturer_prepare_dv_source (gcc);
-    gst_caps_unref (media_caps);
-  }
+  /* Create ghost pads */
+  audio_pad = gst_element_get_static_pad (a_decoder, "sink");
+  ghost_pad = gst_ghost_pad_new ("audio", audio_pad);
+  gst_pad_set_active (ghost_pad, TRUE);
+  gst_element_add_pad (gcc->priv->preview_bin, ghost_pad);
+  gst_object_unref (GST_OBJECT (audio_pad));
+}
 
-  /* Check for MPEG-TS streams */
-  media_caps = gst_caps_from_string ("video/mpegts");
-  if (gst_caps_can_intersect (caps, media_caps)) {
-    decoder_bin = gst_camera_capturer_prepare_mpegts_source (gcc);
-    gst_caps_unref (media_caps);
-  }
+static void
+gst_camera_capturer_fill_audio_source_bin (GstCameraCapturer * gcc)
+{
+  GstPad *audio_pad, *ghost_pad;
+  GstElement *identity;
 
-  /* Check for Raw streams */
-  media_caps = gst_caps_from_string ("video/x-raw-rgb; video/x-raw-yuv");
-  if (gst_caps_can_intersect (caps, media_caps)) {
-    gcc->priv->audio_enabled = FALSE;
-    decoder_bin = gst_camera_capturer_prepare_raw_source (gcc);
-    gst_caps_unref (media_caps);
-  }
+  identity = gst_element_factory_make ("identity", "audio-pad");
+  gst_bin_add (GST_BIN (gcc->priv->source_bin), identity);
 
-  if (decoder_bin != NULL) {
-    gst_camera_capturer_create_remainig (gcc);
-  } else {
-    /* FIXME: post error */
-  }
-  return TRUE;
+  /* add ghostpad */
+  audio_pad = gst_element_get_static_pad (identity, "src");
+  ghost_pad = gst_ghost_pad_new ("audio", audio_pad);
+  gst_pad_set_active (ghost_pad, TRUE);
+  gst_element_add_pad (gcc->priv->source_bin, ghost_pad);
+  gst_object_unref (audio_pad);
 }
 
 static GstCaps *
@@ -1018,6 +821,9 @@ gst_camera_capturer_find_highest_res (GstCameraCapturer *gcc, GstCaps *caps)
   gchar *caps_str;
   GstCaps *rcaps;
 
+  if (gst_caps_get_size (caps) == 0) {
+    return NULL;
+  }
   for (i=0; i < gst_caps_get_size (caps); i++) {
     GstStructure *s = gst_caps_get_structure (caps, i);
     if (gst_structure_get_int (s, "width", &width) &&
@@ -1042,42 +848,182 @@ gst_camera_capturer_find_highest_res (GstCameraCapturer *gcc, GstCaps *caps)
   return rcaps;
 }
 
-static gboolean
-gst_camera_capturer_create_video_source (GstCameraCapturer * gcc,
-    CaptureSourceType type, GError ** err)
+static void
+gst_camera_capturer_create_remainig (GstCameraCapturer * gcc)
 {
-  GstElement *bin;
-  GstElement *typefind, *source;
-  GstCaps *source_caps, *link_caps;
-  GstPad *source_pad;
-  gchar *source_str;
-  gchar *filter = "";
+  gst_camera_capturer_create_splitter_bin (gcc);
+  gst_camera_capturer_create_preview (gcc);
 
-  g_return_val_if_fail (gcc != NULL, FALSE);
-  g_return_val_if_fail (GST_IS_CAMERA_CAPTURER (gcc), FALSE);
+  gst_camera_capturer_link_preview (gcc);
+  gst_element_set_state (gcc->priv->main_pipeline, GST_STATE_PLAYING);
+}
 
-  switch (type) {
-    case CAPTURE_SOURCE_TYPE_DV:
-      GST_INFO_OBJECT (gcc, "Creating dv video source");
-      break;
-    case CAPTURE_SOURCE_TYPE_SYSTEM:
-      GST_INFO_OBJECT (gcc, "Creating system video source");
-      break;
-    case CAPTURE_SOURCE_TYPE_URI:
-      /* We don't use any source element for URI's, just a uridecodebin element
-       * which goes in the decoder bin */
-      GST_INFO_OBJECT (gcc, "Skippinig creation of video source for URI");
-      gcc->priv->source_bin = NULL;
-      gst_camera_capturer_prepare_uri_source (gcc);
-      gst_camera_capturer_create_remainig (gcc);
-      return TRUE;
-    case CAPTURE_SOURCE_TYPE_FILE:
-      GST_INFO_OBJECT (gcc, "Creating file video source");
-      gcc->priv->source_element_name = g_strdup ("filesrc");
-      break;
-    default:
-      g_assert_not_reached ();
+static void
+cb_no_more_pads (GstElement * element, GstCameraCapturer * gcc)
+{
+  if (!gcc->priv->has_video) {
+    g_signal_emit (gcc, gcc_signals[SIGNAL_ERROR], 0,
+        "The stream does not contains a video track");
+  }
+  if (!gcc->priv->has_audio) {
+    GST_INFO_OBJECT (gcc, "Source does not have audio: disabling audio encoding");
+    gcc->priv->audio_enabled = FALSE;
+  }
+}
+
+static void
+cb_new_pad (GstElement * element, GstPad * pad, GstCameraCapturer * gcc)
+{
+  GstCaps *caps;
+  const gchar *mime;
+  GstElement *sink = NULL;
+  GstPad *epad;
+  GstBin *bin = GST_BIN (gcc->priv->source_bin);
+
+  caps = gst_pad_get_caps_reffed (pad);
+  mime = gst_structure_get_name (gst_caps_get_structure (caps, 0));
+  if (!gcc->priv->has_video && g_strrstr (mime, "video")) {
+    GST_INFO_OBJECT (gcc, "Found video stream");
+    sink = gst_bin_get_by_name (bin, "video-pad");
+    gcc->priv->has_video = TRUE;
+  } else if (!gcc->priv->has_audio && g_strrstr (mime, "audio") &&
+      gcc->priv->audio_enabled) {
+    GST_INFO_OBJECT (gcc, "Found audio stream: enable audio branch");
+    gcc->priv->has_audio = TRUE;
+    gst_camera_capturer_fill_audio_source_bin (gcc);
+    gst_camera_capturer_fill_audio_splitter_bin (gcc);
+    gst_camera_capturer_fill_audio_preview (gcc);
+    gst_camera_capturer_link_audio_preview (gcc);
+    gst_element_set_state (gcc->priv->main_pipeline, GST_STATE_PLAYING);
+    sink = gst_bin_get_by_name (bin, "audio-pad");
+  }
+
+  if (sink != NULL) {
+    epad = gst_element_get_static_pad (sink, "sink");
+    gst_pad_link (pad, epad);
+    gst_object_unref (epad);
+    gst_object_unref (sink);
   }
+    GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(gcc->priv->main_pipeline), GST_DEBUG_GRAPH_SHOW_ALL,
+        "longomatch-capture-link");
+  gst_caps_unref (caps);
+}
+
+static gboolean
+gst_camera_capturer_fill_decodebin_source (GstCameraCapturer * gcc)
+{
+  GstElement *bin, *decodebin, *colorspace, *deinterlacer;
+  GstPad *video_pad, *src_pad;
+
+  GST_INFO_OBJECT (gcc, "Creating dv source");
+
+  gcc->priv->video_needs_keyframe_sync = FALSE;
+
+  bin = gcc->priv->source_bin;
+  decodebin = gst_element_factory_make ("decodebin2", NULL);
+  g_signal_connect (decodebin, "autoplug-select",
+      G_CALLBACK (lgm_filter_video_decoders), gcc);
+  colorspace = gst_element_factory_make ("ffmpegcolorspace", "video-pad");
+  deinterlacer = gst_element_factory_make ("ffdeinterlace", NULL);
+  if (deinterlacer == NULL)
+    deinterlacer = gst_element_factory_make ("identity", NULL);
+
+  gst_bin_add_many (GST_BIN (bin), decodebin, colorspace, deinterlacer, NULL);
+  gst_element_link (gcc->priv->source, decodebin);
+  gst_element_link (colorspace, deinterlacer);
+
+  /* add ghostpad */
+  video_pad = gst_element_get_static_pad (deinterlacer, "src");
+  gst_element_add_pad (bin, gst_ghost_pad_new ("video", video_pad));
+  gst_object_unref (GST_OBJECT (video_pad));
+
+  g_signal_connect (decodebin, "pad-added", G_CALLBACK (cb_new_pad), gcc);
+  g_signal_connect (decodebin, "no-more-pads", G_CALLBACK (cb_no_more_pads), gcc);
+  gst_bin_add (GST_BIN (gcc->priv->main_pipeline), bin);
+  gst_camera_capturer_create_remainig (gcc);
+
+  return TRUE;
+}
+
+static GstElement *
+gst_camera_capturer_prepare_mpegts_source (GstCameraCapturer * gcc)
+{
+  GstElement *bin, *demuxer, *video, *video_parser;
+  GstPad *video_pad, *src_pad;
+
+  GST_INFO_OBJECT (gcc, "Creating mpegts source");
+
+  gcc->priv->video_needs_keyframe_sync = TRUE;
+  gcc->priv->video_synced = FALSE;
+
+  /* We don't want to reencode, only remux */
+  bin = gcc->priv->source_bin;
+  demuxer = gst_element_factory_make ("mpegtsdemux", NULL);
+  video_parser = gst_element_factory_make ("h264parse", "video-pad");
+  video = gst_element_factory_make ("capsfilter", NULL);
+  g_object_set (video, "caps",
+      gst_caps_from_string ("video/x-h264, stream-format=avc, alignment=au"),
+      NULL);
+
+  gst_bin_add_many (GST_BIN (bin), demuxer, video_parser, video, NULL);
+  gst_element_link (gcc->priv->source, demuxer);
+  gst_element_link (video_parser, video);
+
+  /* add ghostpad */
+  video_pad = gst_element_get_static_pad (video, "src");
+  gst_element_add_pad (bin, gst_ghost_pad_new ("video", video_pad));
+  gst_object_unref (GST_OBJECT (video_pad));
+  src_pad = gst_element_get_static_pad (demuxer, "sink");
+  gst_element_add_pad (bin, gst_ghost_pad_new ("sink", src_pad));
+  gst_object_unref (GST_OBJECT (src_pad));
+
+  g_signal_connect (demuxer, "pad-added", G_CALLBACK (cb_new_pad), gcc);
+  g_signal_connect (demuxer, "no-more-pads", G_CALLBACK (cb_no_more_pads), gcc);
+  gst_camera_capturer_create_remuxer_bin (gcc);
+
+  return bin;
+}
+
+static gboolean
+gst_camera_capturer_create_uri_source (GstCameraCapturer * gcc, GError ** err)
+{
+  GstElement *bin, *decodebin, *identity;
+  GstPad *video_pad;
+
+  GST_INFO_OBJECT (gcc, "Creating URI source %s\n", gcc->priv->device_id);
+
+  gcc->priv->video_needs_keyframe_sync = FALSE;
+
+  gcc->priv->source_bin = bin = gst_bin_new ("source");
+  decodebin = gst_element_factory_make ("uridecodebin", NULL);
+  g_object_set (decodebin, "uri", gcc->priv->device_id, NULL);
+  g_signal_connect (decodebin, "autoplug-select",
+      G_CALLBACK (lgm_filter_video_decoders), gcc);
+  identity = gst_element_factory_make ("identity", "video-pad");
+
+  gst_bin_add_many (GST_BIN (bin), decodebin, identity, NULL);
+
+  /* add ghostpad */
+  video_pad = gst_element_get_static_pad (identity, "src");
+  gst_element_add_pad (bin, gst_ghost_pad_new ("video", video_pad));
+  gst_object_unref (GST_OBJECT (video_pad));
+
+  g_signal_connect (decodebin, "pad-added", G_CALLBACK (cb_new_pad), gcc);
+  g_signal_connect (decodebin, "no-more-pads", G_CALLBACK (cb_no_more_pads), gcc);
+  gst_bin_add (GST_BIN (gcc->priv->main_pipeline), bin);
+  gst_camera_capturer_create_remainig (gcc);
+  return TRUE;
+}
+
+static gboolean
+gst_camera_capturer_create_source (GstCameraCapturer *gcc,
+    GError ** err)
+{
+  GstElement *bin;
+  GstElement *source;
+  GstCaps *source_caps;
+  GstStructure *s = NULL;
+  GstPad *source_pad;
 
   gcc->priv->source_bin = bin = gst_bin_new ("source");
   gcc->priv->source = source = gst_element_factory_make (gcc->priv->source_element_name, "video-source");
@@ -1090,11 +1036,7 @@ gst_camera_capturer_create_video_source (GstCameraCapturer * gcc,
         gcc->priv->source_element_name);
     return FALSE;
   }
-  typefind = gst_element_factory_make ("typefind", "video-source-typefind");
-  gst_bin_add_many (GST_BIN(bin), source, typefind, NULL);
-  source_pad = gst_element_get_static_pad (typefind, "src");
-  gst_element_add_pad (bin, gst_ghost_pad_new ("src", source_pad));
-  gst_object_unref (source_pad);
+  gst_bin_add (GST_BIN(bin), source);
 
   /* dshowvideosrc's device must be set before linking the element
    * since the device is set in getcaps and can't be changed later */
@@ -1104,14 +1046,37 @@ gst_camera_capturer_create_video_source (GstCameraCapturer * gcc,
    * Choose the highest resolution and downscale later if needed */
   source_pad = gst_element_get_static_pad (source, "src");
   source_caps = gst_pad_get_caps_reffed (source_pad);
-  link_caps = gst_camera_capturer_find_highest_res (gcc, source_caps);
+
+  if (gst_caps_get_size (source_caps) != 0) {
+    s = gst_caps_get_structure (source_caps, 0);
+  }
+  if (s == NULL) { 
+    gst_camera_capturer_fill_decodebin_source (gcc);
+  } else if (gst_structure_has_name (s, "video/x-raw-yuv") ||
+      gst_structure_has_name (s, "video/x-raw-rgb")) {
+    GstPad *filter_pad;
+    GstElement *filter;
+    GstCaps *link_caps;
+
+    filter = gst_element_factory_make ("capsfilter", NULL);
+    gst_bin_add (GST_BIN (bin), filter);
+    gst_element_link (source, filter);
+    link_caps = gst_camera_capturer_find_highest_res (gcc, source_caps);
+    if (link_caps) {
+      g_object_set (filter, "caps", link_caps, NULL);
+      gst_caps_unref (link_caps);
+    }
+    filter_pad = gst_element_get_static_pad (filter, "src");
+    gst_element_add_pad (bin, gst_ghost_pad_new ("video", filter_pad));
+    gst_bin_add (GST_BIN (gcc->priv->main_pipeline), gcc->priv->source_bin);
+    gst_camera_capturer_create_remainig (gcc);
+    gcc->priv->audio_enabled = FALSE;
+  } else if (gst_structure_has_name (s, "video/x-dv")) {
+    gst_camera_capturer_fill_decodebin_source (gcc);
+  }
   gst_object_unref (source_pad);
   gst_caps_unref (source_caps);
 
-  gst_element_link_filtered (source, typefind, link_caps);
-  g_signal_connect (typefind, "have-type",
-      G_CALLBACK (gst_camera_capturer_have_type_cb), gcc);
-
   GST_INFO_OBJECT (gcc, "Created video source %s",
       gcc->priv->source_element_name);
 
@@ -1119,6 +1084,32 @@ gst_camera_capturer_create_video_source (GstCameraCapturer * gcc,
 }
 
 static gboolean
+gst_camera_capturer_create_video_source (GstCameraCapturer * gcc,
+    CaptureSourceType type, GError ** err)
+{
+  gboolean ret;
+
+  g_return_val_if_fail (gcc != NULL, FALSE);
+  g_return_val_if_fail (GST_IS_CAMERA_CAPTURER (gcc), FALSE);
+
+  switch (type) {
+    case CAPTURE_SOURCE_TYPE_FILE:
+      gcc->priv->source_element_name = g_strdup ("filesrc");
+    case CAPTURE_SOURCE_TYPE_DV:
+    case CAPTURE_SOURCE_TYPE_SYSTEM:
+      ret = gst_camera_capturer_create_source (gcc, err);
+      break;
+    case CAPTURE_SOURCE_TYPE_URI:
+      ret = gst_camera_capturer_create_uri_source (gcc, err);
+      break;
+    default:
+      g_assert_not_reached ();
+  }
+  return ret;
+
+}
+
+static gboolean
 gst_camera_capturer_create_video_encoder (GstCameraCapturer * gcc,
     VideoEncoderType type, GError ** err)
 {
@@ -1197,9 +1188,6 @@ gst_camera_capturer_initialize (GstCameraCapturer * gcc)
           gcc->priv->source_type, &err))
     goto missing_plugin;
 
-  /* add the source element */
-  if (gcc->priv->source_bin)
-    gst_bin_add (GST_BIN (gcc->priv->main_pipeline), gcc->priv->source_bin);
   return;
 
 missing_plugin:
@@ -1506,6 +1494,7 @@ gst_camera_capturer_start (GstCameraCapturer * gcc)
       && gcc->priv->accum_recorded_ts == GST_CLOCK_TIME_NONE) {
     gcc->priv->accum_recorded_ts = 0;
     gcc->priv->is_recording = TRUE;
+    gst_camera_capturer_create_encoder_bin (gcc);
     gst_camera_capturer_link_encoder_bin (gcc);
   }
   g_mutex_unlock (&gcc->priv->recording_lock);
diff --git a/libcesarplayer/test-capturer.c b/libcesarplayer/test-capturer.c
index e26974c..6e7e3df 100644
--- a/libcesarplayer/test-capturer.c
+++ b/libcesarplayer/test-capturer.c
@@ -56,9 +56,10 @@ on_realized_cb (GtkWidget * video)
   window = lgm_get_window_handle (gtk_widget_get_window (video));
 
   gvc = gst_camera_capturer_new (&error);
-  gst_camera_capturer_configure (gvc, sargv[1], CAPTURE_SOURCE_TYPE_SYSTEM,
-      sargv[2], sargv[3], VIDEO_ENCODER_H264, AUDIO_ENCODER_AAC,
-      VIDEO_MUXER_MP4, 1000, 100, FALSE, 320, 240, window);
+  gst_camera_capturer_configure (gvc, sargv[1],
+      (CaptureSourceType) atoi(sargv[4]), sargv[2], sargv[3],
+      VIDEO_ENCODER_H264, AUDIO_ENCODER_AAC,
+      VIDEO_MUXER_MP4, 1000, 100, TRUE, 320, 240, window);
   gst_camera_capturer_run (gvc);
   g_signal_connect (G_OBJECT (recbutton), "clicked",
       G_CALLBACK (rec_clicked_cb), gvc);
@@ -95,8 +96,8 @@ create_window (void)
 int
 main (int argc, char **argv)
 {
-  if (argc != 4) {
-    g_print ("Usage: test-encoder output_file device_type device-id\n");
+  if (argc != 5) {
+    g_print ("Usage: test-capturer output_file device_name device_id device_type \n");
     return 1;
   }
   gtk_init (&argc, &argv);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]