decklink2src: Add "skip-first-time" property

... so that the element can skip first N frames as requested.
This commit is contained in:
Seungha Yang 2023-06-13 22:52:30 +09:00
parent f45c572321
commit 96365cd8de
3 changed files with 50 additions and 8 deletions

View file

@ -384,6 +384,8 @@ struct _GstDeckLink2Input
gboolean discont;
gboolean audio_discont;
gboolean flushing;
GstClockTime skip_first_time;
GstClockTime start_time;
guint window_size;
guint window_fill;
@ -1498,12 +1500,30 @@ gst_decklink2_input_on_frame_arrived (GstDeckLink2Input * self,
if (!clock) {
GST_WARNING_OBJECT (self,
"Frame arrived but we dont have configured clock");
} else {
base_time = gst_element_get_base_time (GST_ELEMENT (self->client));
capture_time = gst_clock_get_time (clock);
gst_object_unref (clock);
if (capture_time >= base_time)
capture_time -= base_time;
return;
}
base_time = gst_element_get_base_time (GST_ELEMENT (self->client));
capture_time = gst_clock_get_time (clock);
gst_object_unref (clock);
if (capture_time >= base_time)
capture_time -= base_time;
if (!GST_CLOCK_TIME_IS_VALID (self->start_time))
self->start_time = capture_time;
if (GST_CLOCK_TIME_IS_VALID (self->skip_first_time)) {
GstClockTime diff = capture_time - self->start_time;
if (diff < self->skip_first_time) {
GST_DEBUG_OBJECT (self,
"Skipping frame as requested: %" GST_TIME_FORMAT " < %"
GST_TIME_FORMAT, GST_TIME_ARGS (capture_time),
GST_TIME_ARGS (self->skip_first_time + self->start_time));
return;
}
GST_DEBUG_OBJECT (self, "All frames were skipped as requested");
self->skip_first_time = GST_CLOCK_TIME_NONE;
}
if (frame) {
@ -1856,11 +1876,13 @@ gst_decklink2_input_stop_unlocked (GstDeckLink2Input * self)
gst_clear_caps (&self->selected_video_caps);
gst_clear_caps (&self->selected_audio_caps);
priv->signal = false;
self->skip_first_time = GST_CLOCK_TIME_NONE;
self->start_time = GST_CLOCK_TIME_NONE;
}
HRESULT
gst_decklink2_input_start (GstDeckLink2Input * input, GstElement * client,
BMDProfileID profile_id, guint buffer_size,
BMDProfileID profile_id, guint buffer_size, GstClockTime skip_first_time,
const GstDeckLink2InputVideoConfig * video_config,
const GstDeckLink2InputAudioConfig * audio_config)
{
@ -1872,6 +1894,9 @@ gst_decklink2_input_start (GstDeckLink2Input * input, GstElement * client,
gst_decklink2_input_stop_unlocked (input);
gst_decklink2_input_reset_time_mapping (input);
if (skip_first_time > 0 && GST_CLOCK_TIME_IS_VALID (skip_first_time))
input->skip_first_time = skip_first_time;
if (profile_id != bmdProfileDefault) {
GstDeckLink2Object *object;
gchar *profile_id_str = g_enum_to_string (GST_TYPE_DECKLINK2_PROFILE_ID,

View file

@ -61,6 +61,7 @@ HRESULT gst_decklink2_input_start (GstDeckLink2Input * input,
GstElement * client,
BMDProfileID profile_id,
guint buffer_size,
GstClockTime skip_first_time,
const GstDeckLink2InputVideoConfig * video_config,
const GstDeckLink2InputAudioConfig * audio_config);

View file

@ -48,6 +48,7 @@ enum
PROP_OUTPUT_AFD_BAR,
PROP_BUFFER_SIZE,
PROP_SIGNAL,
PROP_SKIP_FIRST_TIME,
};
#define DEFAULT_MODE bmdModeUnknown
@ -62,6 +63,7 @@ enum
#define DEFAULT_OUTPUT_AFD_BAR FALSE
#define DEFAULT_BUFFER_SIZE 5
#define DEFAULT_AUDIO_CHANNELS GST_DECKLINK2_AUDIO_CHANNELS_2
#define DEFAULT_SKIP_FIRST_TIME 0
struct GstDeckLink2SrcPrivate
{
@ -96,6 +98,7 @@ struct _GstDeckLink2Src
gboolean output_cc;
gboolean output_afd_bar;
guint buffer_size;
GstClockTime skip_first_time;
};
static void gst_decklink2_src_finalize (GObject * object);
@ -251,6 +254,9 @@ gst_decklink2_src_set_property (GObject * object, guint prop_id,
case PROP_BUFFER_SIZE:
self->buffer_size = g_value_get_uint (value);
break;
case PROP_SKIP_FIRST_TIME:
self->skip_first_time = g_value_get_uint64 (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -311,6 +317,9 @@ gst_decklink2_src_get_property (GObject * object, guint prop_id, GValue * value,
g_value_set_boolean (value, has_signal);
break;
}
case PROP_SKIP_FIRST_TIME:
g_value_set_uint64 (value, self->skip_first_time);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -529,7 +538,8 @@ gst_decklink2_src_run (GstDeckLink2Src * self)
audio_config.channels = self->audio_channels;
hr = gst_decklink2_input_start (self->input, GST_ELEMENT (self),
self->profile_id, self->buffer_size, &video_config, &audio_config);
self->profile_id, self->buffer_size, self->skip_first_time,
&video_config, &audio_config);
if (!gst_decklink2_result (hr)) {
GST_ERROR_OBJECT (self, "Couldn't start stream, hr: 0x%x", (guint) hr);
return FALSE;
@ -671,4 +681,10 @@ gst_decklink2_src_install_properties (GObjectClass * object_class)
g_param_spec_boolean ("signal", "Signal",
"True if there is a valid input signal available",
FALSE, (GParamFlags) (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)));
g_object_class_install_property (object_class, PROP_SKIP_FIRST_TIME,
g_param_spec_uint64 ("skip-first-time", "Skip First Time",
"Skip that much time of initial frames after starting", 0,
G_MAXUINT64, DEFAULT_SKIP_FIRST_TIME,
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
}