mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
timecodestamper: Post element message with current timecode
timecodestamper will post an element message which contains the current timecode it just stamped. If a timecode was already found and not replaced, it will still post it in a message. https://bugzilla.gnome.org/show_bug.cgi?id=777048
This commit is contained in:
parent
3cb43f35b8
commit
b16cd484bf
2 changed files with 47 additions and 5 deletions
|
@ -57,13 +57,15 @@ enum
|
||||||
PROP_OVERRIDE_EXISTING,
|
PROP_OVERRIDE_EXISTING,
|
||||||
PROP_DROP_FRAME,
|
PROP_DROP_FRAME,
|
||||||
PROP_SOURCE_CLOCK,
|
PROP_SOURCE_CLOCK,
|
||||||
PROP_DAILY_JAM
|
PROP_DAILY_JAM,
|
||||||
|
PROP_POST_MESSAGES
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DEFAULT_OVERRIDE_EXISTING FALSE
|
#define DEFAULT_OVERRIDE_EXISTING FALSE
|
||||||
#define DEFAULT_DROP_FRAME FALSE
|
#define DEFAULT_DROP_FRAME FALSE
|
||||||
#define DEFAULT_SOURCE_CLOCK NULL
|
#define DEFAULT_SOURCE_CLOCK NULL
|
||||||
#define DEFAULT_DAILY_JAM NULL
|
#define DEFAULT_DAILY_JAM NULL
|
||||||
|
#define DEFAULT_POST_MESSAGES FALSE
|
||||||
|
|
||||||
static GstStaticPadTemplate gst_timecodestamper_src_template =
|
static GstStaticPadTemplate gst_timecodestamper_src_template =
|
||||||
GST_STATIC_PAD_TEMPLATE ("src",
|
GST_STATIC_PAD_TEMPLATE ("src",
|
||||||
|
@ -129,6 +131,10 @@ gst_timecodestamper_class_init (GstTimeCodeStamperClass * klass)
|
||||||
"Daily jam",
|
"Daily jam",
|
||||||
"The daily jam of the timecode",
|
"The daily jam of the timecode",
|
||||||
G_TYPE_DATE_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
G_TYPE_DATE_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
g_object_class_install_property (gobject_class, PROP_POST_MESSAGES,
|
||||||
|
g_param_spec_boolean ("post-messages", "Post element message",
|
||||||
|
"Post element message containing the current timecode",
|
||||||
|
DEFAULT_POST_MESSAGES, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
gst_element_class_add_pad_template (element_class,
|
gst_element_class_add_pad_template (element_class,
|
||||||
gst_static_pad_template_get (&gst_timecodestamper_sink_template));
|
gst_static_pad_template_get (&gst_timecodestamper_sink_template));
|
||||||
|
@ -150,6 +156,7 @@ gst_timecodestamper_init (GstTimeCodeStamper * timecodestamper)
|
||||||
timecodestamper->source_clock = DEFAULT_SOURCE_CLOCK;
|
timecodestamper->source_clock = DEFAULT_SOURCE_CLOCK;
|
||||||
timecodestamper->current_tc = gst_video_time_code_new_empty ();
|
timecodestamper->current_tc = gst_video_time_code_new_empty ();
|
||||||
timecodestamper->current_tc->config.latest_daily_jam = DEFAULT_DAILY_JAM;
|
timecodestamper->current_tc->config.latest_daily_jam = DEFAULT_DAILY_JAM;
|
||||||
|
timecodestamper->post_messages = DEFAULT_POST_MESSAGES;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -195,6 +202,9 @@ gst_timecodestamper_set_property (GObject * object, guint prop_id,
|
||||||
timecodestamper->current_tc->config.latest_daily_jam =
|
timecodestamper->current_tc->config.latest_daily_jam =
|
||||||
g_value_dup_boxed (value);
|
g_value_dup_boxed (value);
|
||||||
break;
|
break;
|
||||||
|
case PROP_POST_MESSAGES:
|
||||||
|
timecodestamper->post_messages = g_value_get_boolean (value);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -221,6 +231,9 @@ gst_timecodestamper_get_property (GObject * object, guint prop_id,
|
||||||
g_value_set_boxed (value,
|
g_value_set_boxed (value,
|
||||||
timecodestamper->current_tc->config.latest_daily_jam);
|
timecodestamper->current_tc->config.latest_daily_jam);
|
||||||
break;
|
break;
|
||||||
|
case PROP_POST_MESSAGES:
|
||||||
|
g_value_set_boolean (value, timecodestamper->post_messages);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -357,12 +370,15 @@ gst_timecodestamper_transform_ip (GstBaseTransform * vfilter,
|
||||||
{
|
{
|
||||||
GstTimeCodeStamper *timecodestamper = GST_TIME_CODE_STAMPER (vfilter);
|
GstTimeCodeStamper *timecodestamper = GST_TIME_CODE_STAMPER (vfilter);
|
||||||
GstClockTime ref_time;
|
GstClockTime ref_time;
|
||||||
|
GstVideoTimeCodeMeta *tc_meta;
|
||||||
|
GstVideoTimeCode *tc;
|
||||||
|
|
||||||
GST_OBJECT_LOCK (timecodestamper);
|
GST_OBJECT_LOCK (timecodestamper);
|
||||||
if (gst_buffer_get_video_time_code_meta (buffer)
|
tc_meta = gst_buffer_get_video_time_code_meta (buffer);
|
||||||
&& !timecodestamper->override_existing) {
|
if (tc_meta && !timecodestamper->override_existing) {
|
||||||
GST_OBJECT_UNLOCK (timecodestamper);
|
GST_OBJECT_UNLOCK (timecodestamper);
|
||||||
return GST_FLOW_OK;
|
tc = gst_video_time_code_copy (&tc_meta->tc);
|
||||||
|
goto beach;
|
||||||
} else if (timecodestamper->override_existing) {
|
} else if (timecodestamper->override_existing) {
|
||||||
gst_buffer_foreach_meta (buffer, remove_timecode_meta, NULL);
|
gst_buffer_foreach_meta (buffer, remove_timecode_meta, NULL);
|
||||||
}
|
}
|
||||||
|
@ -410,7 +426,7 @@ gst_timecodestamper_transform_ip (GstBaseTransform * vfilter,
|
||||||
gst_video_time_code_nsec_since_daily_jam (timecodestamper->current_tc);
|
gst_video_time_code_nsec_since_daily_jam (timecodestamper->current_tc);
|
||||||
ref_time =
|
ref_time =
|
||||||
gst_segment_to_stream_time (&vfilter->segment, GST_FORMAT_TIME,
|
gst_segment_to_stream_time (&vfilter->segment, GST_FORMAT_TIME,
|
||||||
buffer->pts);
|
GST_BUFFER_PTS (buffer));
|
||||||
if (timecode_time != GST_CLOCK_TIME_NONE && ref_time != GST_CLOCK_TIME_NONE
|
if (timecode_time != GST_CLOCK_TIME_NONE && ref_time != GST_CLOCK_TIME_NONE
|
||||||
&& ((timecode_time > ref_time && timecode_time - ref_time > GST_SECOND)
|
&& ((timecode_time > ref_time && timecode_time - ref_time > GST_SECOND)
|
||||||
|| (ref_time > timecode_time
|
|| (ref_time > timecode_time
|
||||||
|
@ -426,7 +442,32 @@ gst_timecodestamper_transform_ip (GstBaseTransform * vfilter,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gst_buffer_add_video_time_code_meta (buffer, timecodestamper->current_tc);
|
gst_buffer_add_video_time_code_meta (buffer, timecodestamper->current_tc);
|
||||||
|
tc = gst_video_time_code_copy (timecodestamper->current_tc);
|
||||||
gst_video_time_code_increment_frame (timecodestamper->current_tc);
|
gst_video_time_code_increment_frame (timecodestamper->current_tc);
|
||||||
GST_OBJECT_UNLOCK (timecodestamper);
|
GST_OBJECT_UNLOCK (timecodestamper);
|
||||||
|
|
||||||
|
beach:
|
||||||
|
if (timecodestamper->post_messages) {
|
||||||
|
GstClockTime stream_time, running_time, duration;
|
||||||
|
GstStructure *s;
|
||||||
|
GstMessage *msg;
|
||||||
|
|
||||||
|
running_time =
|
||||||
|
gst_segment_to_running_time (&vfilter->segment, GST_FORMAT_TIME,
|
||||||
|
GST_BUFFER_PTS (buffer));
|
||||||
|
stream_time =
|
||||||
|
gst_segment_to_stream_time (&vfilter->segment, GST_FORMAT_TIME,
|
||||||
|
GST_BUFFER_PTS (buffer));
|
||||||
|
duration =
|
||||||
|
gst_util_uint64_scale_int (GST_SECOND, timecodestamper->vinfo.fps_d,
|
||||||
|
timecodestamper->vinfo.fps_n);
|
||||||
|
s = gst_structure_new ("timecodestamper", "timestamp", G_TYPE_UINT64,
|
||||||
|
GST_BUFFER_PTS (buffer), "stream-time", G_TYPE_UINT64, stream_time,
|
||||||
|
"running-time", G_TYPE_UINT64, running_time, "duration", G_TYPE_UINT64,
|
||||||
|
duration, "timecode", GST_TYPE_VIDEO_TIME_CODE, tc, NULL);
|
||||||
|
msg = gst_message_new_element (GST_OBJECT (timecodestamper), s);
|
||||||
|
gst_element_post_message (GST_ELEMENT (timecodestamper), msg);
|
||||||
|
}
|
||||||
|
gst_video_time_code_free (tc);
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,7 @@ struct _GstTimeCodeStamper
|
||||||
GstVideoTimeCode *current_tc;
|
GstVideoTimeCode *current_tc;
|
||||||
GstVideoInfo vinfo;
|
GstVideoInfo vinfo;
|
||||||
GstClock *source_clock;
|
GstClock *source_clock;
|
||||||
|
gboolean post_messages;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstTimeCodeStamperClass
|
struct _GstTimeCodeStamperClass
|
||||||
|
|
Loading…
Reference in a new issue