decklinksrc: Add property to skip the first N seconds of capture

On some hardware the first few frames are bogus and not very useful.
Their timestamps are off, they have no timecodes, or there are spurious
black frames / no-signal frames. After a few frames this stabilizes
though.

https://bugzilla.gnome.org/show_bug.cgi?id=774850
This commit is contained in:
Sebastian Dröge 2016-11-25 14:57:15 +02:00
parent cf224a9990
commit 331b2af050
3 changed files with 45 additions and 1 deletions

View file

@ -436,6 +436,19 @@ gst_decklink_audio_src_got_packet (GstElement * element,
GstDecklinkVideoSrc *videosrc =
GST_DECKLINK_VIDEO_SRC_CAST (gst_object_ref (self->input->videosrc));
if (videosrc->first_time == GST_CLOCK_TIME_NONE)
videosrc->first_time = packet_time;
if (videosrc->skip_first_time > 0
&& packet_time - videosrc->first_time < videosrc->skip_first_time) {
GST_DEBUG_OBJECT (self,
"Skipping frame as requested: %" GST_TIME_FORMAT " < %"
GST_TIME_FORMAT, GST_TIME_ARGS (packet_time),
GST_TIME_ARGS (videosrc->skip_first_time + videosrc->first_time));
g_mutex_unlock (&self->input->lock);
return;
}
if (videosrc->output_stream_time)
timestamp = packet_time;
else

View file

@ -33,6 +33,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_decklink_video_src_debug);
#define DEFAULT_CONNECTION (GST_DECKLINK_CONNECTION_AUTO)
#define DEFAULT_BUFFER_SIZE (5)
#define DEFAULT_OUTPUT_STREAM_TIME (FALSE)
#define DEFAULT_SKIP_FIRST_TIME (0)
enum
{
@ -43,7 +44,8 @@ enum
PROP_BUFFER_SIZE,
PROP_VIDEO_FORMAT,
PROP_TIMECODE_FORMAT,
PROP_OUTPUT_STREAM_TIME
PROP_OUTPUT_STREAM_TIME,
PROP_SKIP_FIRST_TIME
};
typedef struct
@ -187,6 +189,12 @@ gst_decklink_video_src_class_init (GstDecklinkVideoSrcClass * klass)
DEFAULT_OUTPUT_STREAM_TIME,
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
g_object_class_install_property (gobject_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)));
templ_caps = gst_decklink_mode_get_template_caps ();
gst_element_class_add_pad_template (element_class,
gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, templ_caps));
@ -213,6 +221,7 @@ gst_decklink_video_src_init (GstDecklinkVideoSrc * self)
self->timecode_format = bmdTimecodeRP188Any;
self->no_signal = FALSE;
self->output_stream_time = DEFAULT_OUTPUT_STREAM_TIME;
self->skip_first_time = DEFAULT_SKIP_FIRST_TIME;
self->window_size = 64;
self->times = g_new (GstClockTime, 4 * self->window_size);
@ -281,6 +290,9 @@ gst_decklink_video_src_set_property (GObject * object, guint property_id,
case PROP_OUTPUT_STREAM_TIME:
self->output_stream_time = g_value_get_boolean (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, property_id, pspec);
break;
@ -316,6 +328,9 @@ gst_decklink_video_src_get_property (GObject * object, guint property_id,
case PROP_OUTPUT_STREAM_TIME:
g_value_set_boolean (value, self->output_stream_time);
break;
case PROP_SKIP_FIRST_TIME:
g_value_set_uint64 (value, self->skip_first_time);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@ -583,6 +598,18 @@ gst_decklink_video_src_got_frame (GstElement * element,
GST_TIME_ARGS (stream_time), GST_TIME_ARGS (stream_duration));
g_mutex_lock (&self->lock);
if (self->first_time == GST_CLOCK_TIME_NONE)
self->first_time = stream_time;
if (self->skip_first_time > 0
&& stream_time - self->first_time < self->skip_first_time) {
g_mutex_unlock (&self->lock);
GST_DEBUG_OBJECT (self,
"Skipping frame as requested: %" GST_TIME_FORMAT " < %" GST_TIME_FORMAT,
GST_TIME_ARGS (stream_time),
GST_TIME_ARGS (self->skip_first_time + self->first_time));
return;
}
gst_decklink_video_src_update_time_mapping (self, capture_time, stream_time);
if (self->output_stream_time) {
@ -907,6 +934,7 @@ gst_decklink_video_src_start_streams (GstElement * element)
GST_DEBUG_OBJECT (self, "Starting streams");
g_mutex_lock (&self->lock);
self->first_time = GST_CLOCK_TIME_NONE;
self->window_fill = 0;
self->window_filled = FALSE;
self->window_skip = 1;

View file

@ -56,6 +56,7 @@ struct _GstDecklinkVideoSrc
GstDecklinkConnectionEnum connection;
gint device_number;
gboolean output_stream_time;
GstClockTime skip_first_time;
GstVideoInfo info;
GstDecklinkVideoFormat video_format;
@ -72,6 +73,8 @@ struct _GstDecklinkVideoSrc
guint buffer_size;
/* Protected by lock */
GstClockTime first_time;
GstClockTime *times;
GstClockTime *times_temp;
guint window_size, window_fill;