diff --git a/sys/decklink/capture.cpp b/sys/decklink/capture.cpp index 8804eebaf1..c2a0bcb3d7 100644 --- a/sys/decklink/capture.cpp +++ b/sys/decklink/capture.cpp @@ -84,59 +84,80 @@ HRESULT videoFrame, IDeckLinkAudioInputPacket * audioFrame) { GstDecklinkSrc *decklinksrc; + const char *timecodeString = NULL; g_return_val_if_fail (priv != NULL, S_OK); g_return_val_if_fail (GST_IS_DECKLINK_SRC (priv), S_OK); decklinksrc = GST_DECKLINK_SRC (priv); - // Handle Video Frame - if (videoFrame) { - if (videoFrame->GetFlags () & bmdFrameHasNoInputSource) { - GST_DEBUG ("Frame received - No input signal detected"); - } else { - const char *timecodeString = NULL; - if (g_timecodeFormat != 0) { - IDeckLinkTimecode *timecode; - if (videoFrame->GetTimecode (g_timecodeFormat, &timecode) == S_OK) { - timecode->GetString (&timecodeString); - CONVERT_COM_STRING (timecodeString); - } - } + if (videoFrame == NULL) { + GST_WARNING_OBJECT (decklinksrc, "video frame is NULL"); + return S_OK; + } - GST_DEBUG ("Frame received [%s] - %s - Size: %li bytes", - timecodeString != NULL ? timecodeString : "No timecode", - "Valid Frame", videoFrame->GetRowBytes () * videoFrame->GetHeight ()); + if (audioFrame == NULL) { + GST_WARNING_OBJECT (decklinksrc, "audio frame is NULL"); + return S_OK; + } - if (timecodeString) - FREE_COM_STRING (timecodeString); + if (videoFrame->GetFlags () & bmdFrameHasNoInputSource) { + GST_DEBUG_OBJECT (decklinksrc, "Frame received - No input signal detected"); + return S_OK; + } - g_mutex_lock (decklinksrc->mutex); - if (decklinksrc->video_frame != NULL) { - decklinksrc->dropped_frames++; - } else { - videoFrame->AddRef (); - decklinksrc->video_frame = videoFrame; - if (audioFrame) { - audioFrame->AddRef (); - decklinksrc->audio_frame = audioFrame; - } - } - - /* increment regardless whether frame was dropped or not */ - decklinksrc->frame_num++; - - g_cond_signal (decklinksrc->cond); - g_mutex_unlock (decklinksrc->mutex); + if (g_timecodeFormat != 0) { + IDeckLinkTimecode *timecode; + if (videoFrame->GetTimecode (g_timecodeFormat, &timecode) == S_OK) { + timecode->GetString (&timecodeString); + CONVERT_COM_STRING (timecodeString); } } + + GST_DEBUG_OBJECT (decklinksrc, "Frame received [%s] - %s - Size: %li bytes", + timecodeString != NULL ? timecodeString : "No timecode", + "Valid Frame", videoFrame->GetRowBytes () * videoFrame->GetHeight ()); + + if (timecodeString) + FREE_COM_STRING (timecodeString); + + g_mutex_lock (decklinksrc->mutex); + if (decklinksrc->video_frame != NULL) { + decklinksrc->dropped_frames++; + decklinksrc->video_frame->Release(); + if (decklinksrc->audio_frame) { + decklinksrc->audio_frame->Release(); + } + } + videoFrame->AddRef (); + decklinksrc->video_frame = videoFrame; + if (audioFrame) { + audioFrame->AddRef (); + decklinksrc->audio_frame = audioFrame; + } + + /* increment regardless whether frame was dropped or not */ + decklinksrc->frame_num++; + + g_cond_signal (decklinksrc->cond); + g_mutex_unlock (decklinksrc->mutex); + return S_OK; } HRESULT - DeckLinkCaptureDelegate::VideoInputFormatChanged - (BMDVideoInputFormatChangedEvents events, IDeckLinkDisplayMode * mode, - BMDDetectedVideoInputFormatFlags) { - GST_ERROR ("moo"); +DeckLinkCaptureDelegate::VideoInputFormatChanged ( + BMDVideoInputFormatChangedEvents events, IDeckLinkDisplayMode * mode, + BMDDetectedVideoInputFormatFlags) +{ + GstDecklinkSrc *decklinksrc; + + g_return_val_if_fail (priv != NULL, S_OK); + g_return_val_if_fail (GST_IS_DECKLINK_SRC (priv), S_OK); + + decklinksrc = GST_DECKLINK_SRC (priv); + + GST_ERROR_OBJECT (decklinksrc, "unimplemented: video input format changed"); + return S_OK; } diff --git a/sys/decklink/gstdecklink.cpp b/sys/decklink/gstdecklink.cpp index 88e3559be5..4a0c09f08b 100644 --- a/sys/decklink/gstdecklink.cpp +++ b/sys/decklink/gstdecklink.cpp @@ -190,34 +190,96 @@ gst_decklink_mode_get_template_caps (void) return caps; } -IDeckLink * -gst_decklink_get_nth_device (int n) +typedef struct _Device Device; +struct _Device { + IDeckLink *decklink; + IDeckLinkInput *input; + IDeckLinkOutput *output; + IDeckLinkConfiguration *config; +}; + +static int n_devices; +static Device devices[10]; + +static void +init_devices (void) { IDeckLinkIterator *iterator; IDeckLink *decklink = NULL; HRESULT ret; int i; + static gboolean inited = FALSE; + + if (inited) return; + inited = TRUE; iterator = CreateDeckLinkIteratorInstance (); if (iterator == NULL) { GST_ERROR ("no driver"); - return NULL; + return; } + i = 0; ret = iterator->Next (&decklink); - if (ret != S_OK) { - GST_ERROR ("no card"); - return NULL; - } - for (i = 0; i < n; i++) { - ret = iterator->Next (&decklink); + while (ret == S_OK) { + devices[i].decklink = decklink; + + ret = decklink->QueryInterface (IID_IDeckLinkInput, + (void **) &devices[i].input); if (ret != S_OK) { - GST_ERROR ("no card"); - return NULL; + GST_WARNING ("selected device does not have input interface"); + return; } + + ret = decklink->QueryInterface (IID_IDeckLinkOutput, + (void **) &devices[i].output); + if (ret != S_OK) { + GST_WARNING ("selected device does not have output interface"); + return; + } + + ret = decklink->QueryInterface (IID_IDeckLinkConfiguration, + (void **) &devices[i].config); + if (ret != S_OK) { + GST_WARNING ("selected device does not have config interface"); + return; + } + + ret = iterator->Next (&decklink); + i++; } - return decklink; + n_devices = i; + + iterator->Release(); +} + +IDeckLink * +gst_decklink_get_nth_device (int n) +{ + init_devices (); + return devices[n].decklink; +} + +IDeckLinkInput * +gst_decklink_get_nth_input (int n) +{ + init_devices (); + return devices[n].input; +} + +IDeckLinkOutput * +gst_decklink_get_nth_output (int n) +{ + init_devices (); + return devices[n].output; +} + +IDeckLinkConfiguration * +gst_decklink_get_nth_config (int n) +{ + init_devices (); + return devices[n].config; } static gboolean diff --git a/sys/decklink/gstdecklink.h b/sys/decklink/gstdecklink.h index 77c5cc43a8..3b62b4f9bc 100644 --- a/sys/decklink/gstdecklink.h +++ b/sys/decklink/gstdecklink.h @@ -108,6 +108,8 @@ GstCaps * gst_decklink_mode_get_caps (GstDecklinkModeEnum e); GstCaps * gst_decklink_mode_get_template_caps (void); IDeckLink * gst_decklink_get_nth_device (int n); - +IDeckLinkInput * gst_decklink_get_nth_input (int n); +IDeckLinkOutput * gst_decklink_get_nth_output (int n); +IDeckLinkConfiguration * gst_decklink_get_nth_config (int n); #endif diff --git a/sys/decklink/gstdecklinksink.cpp b/sys/decklink/gstdecklinksink.cpp index dd28a60c62..eeb1c95c85 100644 --- a/sys/decklink/gstdecklinksink.cpp +++ b/sys/decklink/gstdecklinksink.cpp @@ -469,12 +469,7 @@ gst_decklink_sink_start (GstDecklinkSink * decklinksink) return FALSE; } - ret = decklinksink->decklink->QueryInterface (IID_IDeckLinkOutput, - (void **) &decklinksink->output); - if (ret != S_OK) { - GST_WARNING ("selected device does not have output interface"); - return FALSE; - } + decklinksink->output = gst_decklink_get_nth_output (decklinksink->device); decklinksink->output->SetAudioCallback (decklinksink->callback); @@ -527,11 +522,6 @@ gst_decklink_sink_stop (GstDecklinkSink * decklinksink) decklinksink->output->DisableAudioOutput (); decklinksink->output->DisableVideoOutput (); - decklinksink->output->Release (); - decklinksink->output = NULL; - decklinksink->decklink->Release (); - decklinksink->decklink = NULL; - return TRUE; } diff --git a/sys/decklink/gstdecklinksrc.cpp b/sys/decklink/gstdecklinksrc.cpp index 4c0c9b4723..ee1c464578 100644 --- a/sys/decklink/gstdecklinksrc.cpp +++ b/sys/decklink/gstdecklinksrc.cpp @@ -515,8 +515,6 @@ gst_decklink_src_start (GstElement * element) { GstDecklinkSrc *decklinksrc = GST_DECKLINK_SRC (element); DeckLinkCaptureDelegate *delegate; - //IDeckLinkDisplayModeIterator *mode_iterator; - //IDeckLinkDisplayMode *mode; BMDAudioSampleType sample_depth; int channels; HRESULT ret; @@ -532,24 +530,19 @@ gst_decklink_src_start (GstElement * element) return FALSE; } - ret = decklinksrc->decklink->QueryInterface (IID_IDeckLinkInput, - (void **) &decklinksrc->input); - if (ret != S_OK) { - GST_ERROR ("selected device does not have input interface"); - return FALSE; - } + decklinksrc->input = gst_decklink_get_nth_input (decklinksrc->device); delegate = new DeckLinkCaptureDelegate (); delegate->priv = decklinksrc; - decklinksrc->input->SetCallback (delegate); - - ret = decklinksrc->decklink->QueryInterface (IID_IDeckLinkConfiguration, - (void **) &config); + ret = decklinksrc->input->SetCallback (delegate); if (ret != S_OK) { - GST_ERROR ("query interface failed"); + GST_ERROR ("set callback failed (input source)"); return FALSE; } + decklinksrc->config = gst_decklink_get_nth_config (decklinksrc->device); + config = decklinksrc->config; + switch (decklinksrc->connection) { default: case GST_DECKLINK_CONNECTION_SDI: @@ -613,25 +606,6 @@ gst_decklink_src_start (GstElement * element) GST_ERROR ("set configuration (audio input connection)"); return FALSE; } -#if 0 - ret = decklinksrc->input->GetDisplayModeIterator (&mode_iterator); - if (ret != S_OK) { - GST_ERROR ("failed to get display mode iterator"); - return FALSE; - } - - i = 0; - while (mode_iterator->Next (&mode) == S_OK) { - const char *mode_name; - - mode->GetName (&mode_name); - - GST_DEBUG ("%d: mode name: %s", i, mode_name); - - mode->Release (); - i++; - } -#endif mode = gst_decklink_get_mode (decklinksrc->mode); @@ -667,6 +641,7 @@ static gboolean gst_decklink_src_stop (GstElement * element) { GstDecklinkSrc *decklinksrc = GST_DECKLINK_SRC (element); + //int refcount; gst_task_stop (decklinksrc->task); @@ -681,12 +656,6 @@ gst_decklink_src_stop (GstElement * element) decklinksrc->input->DisableVideoInput (); decklinksrc->input->DisableAudioInput (); - decklinksrc->input->Release (); - decklinksrc->input = NULL; - - decklinksrc->decklink->Release (); - decklinksrc->decklink = NULL; - return TRUE; } @@ -1456,6 +1425,7 @@ gst_decklinksrc_class_probe_devices (GstElementClass * klass) n_devices++; } } + iterator->Release(); probed = TRUE; } diff --git a/sys/decklink/gstdecklinksrc.h b/sys/decklink/gstdecklinksrc.h index 38d00d7116..f64a4e6452 100644 --- a/sys/decklink/gstdecklinksrc.h +++ b/sys/decklink/gstdecklinksrc.h @@ -45,6 +45,7 @@ struct _GstDecklinkSrc IDeckLink *decklink; IDeckLinkInput *input; + IDeckLinkConfiguration *config; GMutex *mutex; GCond *cond;