diff --git a/sys/decklink/gstdecklinksink.cpp b/sys/decklink/gstdecklinksink.cpp
index 9fc39e4..55355d3 100644
--- a/sys/decklink/gstdecklinksink.cpp
+++ b/sys/decklink/gstdecklinksink.cpp
@@ -126,9 +126,11 @@ GST_STATIC_PAD_TEMPLATE ("videosink",
     GST_PAD_SINK,
     GST_PAD_ALWAYS,
     GST_STATIC_CAPS (
-      MODE(720,486,30000,1001,true)
+      MODE(1920,1080,30000,1001,true) ";"
+      //      MODE(720,486,30000,1001,true)";"
     ));
 #if 0
+      MODE(720,486,30000,1001,true)";"
       MODE(720,486,24000,1001,true) ";"
       MODE(720,576,25,1,true) ";"
       MODE(1920,1080,24000,1001,false) ";"
@@ -296,6 +298,7 @@ gst_decklink_sink_init (GstDecklinkSink * decklinksink,
 
   decklinksink->cond = g_cond_new();
   decklinksink->mutex = g_mutex_new();
+  decklinksink->audio_mutex = g_mutex_new();
 
   decklinksink->mode = 0;
 
@@ -306,6 +309,15 @@ gst_decklink_sink_init (GstDecklinkSink * decklinksink,
   decklinksink->interlaced = modes[decklinksink->mode].interlaced;
   decklinksink->bmd_mode = modes[decklinksink->mode].mode;
 
+
+  decklinksink->video_start_time = decklinksink->video_last_time = GST_CLOCK_TIME_NONE;
+  decklinksink->audio_start_time = decklinksink->audio_last_time = GST_CLOCK_TIME_NONE;
+  decklinksink->start_cond = g_cond_new();
+  decklinksink->start_mutex = g_mutex_new();
+  
+  decklinksink->audio_buffer = gst_buffer_new();
+  decklinksink->video_buffer = gst_buffer_new();
+
   decklinksink->callback = new Output;
   decklinksink->callback->decklinksink = decklinksink;
 }
@@ -366,6 +378,10 @@ gst_decklink_sink_finalize (GObject * object)
   /* clean up object here */
   g_cond_free (decklinksink->cond);
   g_mutex_free (decklinksink->mutex);
+  g_mutex_free (decklinksink->audio_mutex);
+
+  g_cond_free (decklinksink->start_cond);
+  g_mutex_free (decklinksink->start_mutex);
 
   delete decklinksink->callback;
 
@@ -381,6 +397,13 @@ gst_decklink_sink_start (GstDecklinkSink *decklinksink)
   IDeckLinkDisplayMode *mode;
   BMDTimeValue fps_n;
   BMDTimeScale fps_d;
+  char output_mode[64];
+  // choose your card number here
+  int card_number = 1;
+
+  // choose your output mode here
+  strcpy(output_mode, "HD 1080i 59.94");
+  // strcpy(output_mode, "NTSC");
 
   iterator = CreateDeckLinkIteratorInstance ();
   if (iterator == NULL) {
@@ -388,12 +411,16 @@ gst_decklink_sink_start (GstDecklinkSink *decklinksink)
     return FALSE;
   }
 
-  ret = iterator->Next (&decklinksink->decklink);
-  if (ret != S_OK) {
-    GST_ERROR("no card");
-    return FALSE;
+  for (int i = 0; i <= card_number; i++){ 
+    ret = iterator->Next (&decklinksink->decklink);
+    if (ret != S_OK) {
+      GST_ERROR("no card");
+      return FALSE;
+    }
   }
 
+  iterator->Release();
+
   ret = decklinksink->decklink->QueryInterface (IID_IDeckLinkOutput,
       (void **)&decklinksink->output);
   if (ret != S_OK) {
@@ -409,20 +436,27 @@ gst_decklink_sink_start (GstDecklinkSink *decklinksink)
     return FALSE;
   }
 
+  // Lets Pick the right mode...
+  const char *displayModeString = NULL;
   while (mode_iterator->Next (&mode) == S_OK) {
-    break;
+    mode->GetName (&displayModeString);
+    if (!strcmp(output_mode, displayModeString)){
+      GST_ERROR ("Mode: %s.\n", displayModeString);
+      break;
+    }
+    mode->Release ();
   }
   if (!mode) {
     GST_ERROR ("bad mode");
     return FALSE;
   }
-
+  
   decklinksink->width = mode->GetWidth ();
   decklinksink->height = mode->GetHeight ();
   mode->GetFrameRate (&fps_n, &fps_d);
   decklinksink->fps_n = fps_n;
   decklinksink->fps_d = fps_d;
-
+  
   decklinksink->display_mode = mode->GetDisplayMode ();
 
   ret = decklinksink->output->EnableVideoOutput (decklinksink->display_mode,
@@ -434,15 +468,13 @@ gst_decklink_sink_start (GstDecklinkSink *decklinksink)
   //decklinksink->video_enabled = TRUE;
 
   decklinksink->output->SetScheduledFrameCompletionCallback (decklinksink->callback);
-
-  if (0) {
-    ret = decklinksink->output->EnableAudioOutput (bmdAudioSampleRate48kHz,
-        16, 2, bmdAudioOutputStreamContinuous);
-    if (ret != S_OK) {
-      GST_ERROR ("failed to enable audio output");
-      return FALSE;
-    }
-  }
+    
+  ret = decklinksink->output->EnableAudioOutput (bmdAudioSampleRate48kHz,
+      16, 2, bmdAudioOutputStreamContinuous);
+  if (ret != S_OK) {
+    GST_ERROR ("failed to enable audio output");
+    return FALSE;
+   }
 
   decklinksink->num_frames = 0;
 
@@ -674,6 +706,20 @@ gst_decklink_sink_videosink_chain (GstPad * pad, GstBuffer * buffer)
   decklinksink = GST_DECKLINK_SINK (gst_pad_get_parent (pad));
 
   GST_DEBUG_OBJECT (decklinksink, "chain");
+  
+  if ( !GST_BUFFER_TIMESTAMP_IS_VALID (buffer) )
+  {
+      GST_DEBUG("Video Buffer Timestamp Invalid!");
+      ret = GST_FLOW_OK;
+      goto exit;
+  }
+
+  // lets use the video to drive our playback
+  if ( !GST_CLOCK_TIME_IS_VALID(decklinksink->video_start_time) )
+      decklinksink->video_start_time = GST_BUFFER_TIMESTAMP(buffer);
+  decklinksink->video_last_time = GST_BUFFER_TIMESTAMP(buffer);
+  
+  // GST_DEBUG("Video Buffer Timestamp: %llu", GST_BUFFER_TIMESTAMP(buffer));
 
 #if 0
   if (!decklinksink->video_enabled) {
@@ -688,15 +734,25 @@ gst_decklink_sink_videosink_chain (GstPad * pad, GstBuffer * buffer)
   }
 #endif
 
+  // wait until audio catches up with the video
+  /*
+  if (decklinksink->sched_started == FALSE)
+  {
+      g_mutex_lock (decklinksink->start_mutex);
+      g_cond_wait (decklinksink->start_cond, decklinksink->start_mutex);
+      g_mutex_unlock (decklinksink->start_mutex);
+  }
+  */
+
   decklinksink->output->CreateVideoFrame (decklinksink->width,
       decklinksink->height, decklinksink->width * 2, bmdFormat8BitYUV,
       bmdFrameFlagDefault, &frame);
 
   frame->GetBytes (&data);
   memcpy (data, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer));
-  gst_buffer_unref (buffer);
 
   g_mutex_lock (decklinksink->mutex);
+  // should we buffer more than 2 frames?
   while (decklinksink->queued_frames > 2 && !decklinksink->stop) {
     g_cond_wait (decklinksink->cond, decklinksink->mutex);
   }
@@ -706,13 +762,27 @@ gst_decklink_sink_videosink_chain (GstPad * pad, GstBuffer * buffer)
   g_mutex_unlock (decklinksink->mutex);
 
   if (!decklinksink->stop) {
+/*
+    decklinksink->output->ScheduleVideoFrame (frame, (uint64_t)
+        ((GST_BUFFER_TIMESTAMP(buffer) - decklinksink->playback_start_time) /
+	 (long double) 1000000000.0) * ((long double) decklinksink->fps_d / (long double) decklinksink->fps_n),
+        decklinksink->fps_n, decklinksink->fps_d);
+*/
+
     decklinksink->output->ScheduleVideoFrame (frame,
         decklinksink->num_frames * decklinksink->fps_n,
         decklinksink->fps_n, decklinksink->fps_d);
+
     decklinksink->num_frames++;
 
     if (!decklinksink->sched_started) {
-      decklinksink->output->StartScheduledPlayback (0, 100, 1.0);
+      
+      // wait for the signal to start the playback...
+      g_mutex_lock (decklinksink->start_mutex);
+      g_cond_wait (decklinksink->start_cond, decklinksink->start_mutex);
+      g_mutex_unlock (decklinksink->start_mutex);
+
+      decklinksink->output->StartScheduledPlayback (0, decklinksink->fps_d, 1.0);
       decklinksink->sched_started = TRUE;
     }
 
@@ -723,6 +793,8 @@ gst_decklink_sink_videosink_chain (GstPad * pad, GstBuffer * buffer)
 
   frame->Release ();
 
+exit:
+  gst_buffer_unref (buffer);
   gst_object_unref (decklinksink);
   return ret;
 }
@@ -928,14 +1000,63 @@ static GstFlowReturn
 gst_decklink_sink_audiosink_chain (GstPad * pad, GstBuffer * buffer)
 {
   GstDecklinkSink *decklinksink;
+  GstFlowReturn ret;
 
   decklinksink = GST_DECKLINK_SINK (gst_pad_get_parent (pad));
 
   GST_DEBUG_OBJECT (decklinksink, "chain");
 
+  if ( !GST_BUFFER_TIMESTAMP_IS_VALID (buffer) )
+  {
+      GST_DEBUG("Audio Buffer Timestamp Invalid!");
+      gst_object_unref (buffer);
+      ret = GST_FLOW_OK;
+      goto exit;
+  }
+
+  if ( !GST_CLOCK_TIME_IS_VALID (decklinksink->audio_start_time) )
+      decklinksink->audio_start_time = GST_BUFFER_TIMESTAMP(buffer);
+  decklinksink->audio_last_time = GST_BUFFER_TIMESTAMP(buffer);
+
+  if ( !GST_CLOCK_TIME_IS_VALID(decklinksink->video_start_time) )
+  {
+      GST_DEBUG("decklinksink->video_start_time not setted!");
+      gst_object_unref (buffer);
+      ret = GST_FLOW_OK;
+      goto exit;
+  }
+
+  // here is the trick
+  if (decklinksink->audio_last_time < (decklinksink->video_start_time))
+  {
+      GST_DEBUG("decklinksink->video_last_time < decklinksink->audio_start_time !");
+      gst_object_unref (buffer);
+      ret = GST_FLOW_OK;
+      goto exit;
+  }
+
+  // signalize audio is in sync with video
+  if (decklinksink->sched_started == FALSE)
+  {
+    g_mutex_lock (decklinksink->start_mutex);
+    g_cond_signal (decklinksink->start_cond);
+    g_mutex_unlock (decklinksink->start_mutex);
+  }
 
+  // GST_DEBUG("Audio Buffer Timestamp: %llu", GST_BUFFER_TIMESTAMP(buffer));
+  
+  // concatenate both buffers
+  g_mutex_lock (decklinksink->audio_mutex);
+  decklinksink->audio_buffer = 
+      gst_buffer_join(decklinksink->audio_buffer, buffer);
+  g_mutex_unlock (decklinksink->audio_mutex);
+
+  // GST_DEBUG("Audio Buffer Size: %d", GST_BUFFER_SIZE (decklinksink->audio_buffer));
+
+exit:
   gst_object_unref (decklinksink);
-  return GST_FLOW_OK;
+
+  return ret;
 }
 
 static GstFlowReturn
@@ -1052,8 +1173,40 @@ Output::ScheduledPlaybackHasStopped ()
 HRESULT
 Output::RenderAudioSamples (bool preroll)
 {
-  GST_ERROR("RenderAudioSamples");
-  
-  return S_OK;
+    guint samplesWritten;
+    GstBuffer *buffer;
+    static bool first_run = 1;
+    
+    if (first_run){
+      first_run = 0;
+      g_usleep(330000);
+    }
+        
+    if (GST_BUFFER_SIZE(decklinksink->audio_buffer) > 0){
+      g_mutex_lock (decklinksink->audio_mutex);
+      decklinksink->output->ScheduleAudioSamples(GST_BUFFER_DATA(decklinksink->audio_buffer)   ,
+						 GST_BUFFER_SIZE(decklinksink->audio_buffer) / 4, // 2 bytes per sample, stereo
+						 0, 0,
+						 &samplesWritten);
+      
+      buffer = gst_buffer_new_and_alloc (GST_BUFFER_SIZE(decklinksink->audio_buffer) - (samplesWritten * 4));
+      
+      memcpy(GST_BUFFER_DATA(buffer), GST_BUFFER_DATA(decklinksink->audio_buffer) + (samplesWritten * 4), GST_BUFFER_SIZE(decklinksink->audio_buffer) - (samplesWritten * 4));
+      
+      gst_buffer_unref(decklinksink->audio_buffer);
+      
+      decklinksink->audio_buffer = buffer;
+      
+      g_mutex_unlock (decklinksink->audio_mutex);
+      
+    }
+    else{
+      GST_DEBUG("Audio Buffer == 0!!");
+    }
+    
+    
+    GST_DEBUG("RenderAudioSamples");
+    
+    return S_OK;
 }
 
diff --git a/sys/decklink/gstdecklinksink.h b/sys/decklink/gstdecklinksink.h
index 2f0d1d7..f3f7af8 100644
--- a/sys/decklink/gstdecklinksink.h
+++ b/sys/decklink/gstdecklinksink.h
@@ -51,12 +51,15 @@ public IDeckLinkAudioOutputCallback
 struct _GstDecklinkSink
 {
   GstElement base_decklinksink;
+  GstBuffer *audio_buffer;
+  GstBuffer *video_buffer;
 
   GstPad *videosinkpad;
   GstPad *audiosinkpad;
 
   GMutex *mutex;
   GCond *cond;
+  GMutex *audio_mutex;
   int queued_frames;
   gboolean stop;
 
@@ -64,7 +67,7 @@ struct _GstDecklinkSink
   IDeckLinkOutput *output;
   Output *callback;
   BMDDisplayMode display_mode;
-  gboolean video_enabled;
+    // gboolean video_enabled;
   gboolean sched_started;
 
   int num_frames;
@@ -73,6 +76,13 @@ struct _GstDecklinkSink
   int width;
   int height;
   gboolean interlaced;
+    
+  GstClockTime video_start_time, video_last_time;
+  GstClockTime audio_start_time, audio_last_time;
+
+  GMutex *start_mutex;
+  GCond *start_cond;
+    
   BMDDisplayMode bmd_mode;
 
   /* properties */
