From b3df5786a94a9d40adb88fd3f179f91cd51644de Mon Sep 17 00:00:00 2001 From: Georg Lippitsch Date: Wed, 15 Feb 2017 18:40:21 +0100 Subject: [PATCH] videotimecode: Init from GDateTime Add a function to init the time code from a GDateTime https://bugzilla.gnome.org/show_bug.cgi?id=778702 --- docs/libs/gst-plugins-base-libs-sections.txt | 2 + gst-libs/gst/video/gstvideotimecode.c | 74 ++++++++++++++++++++ gst-libs/gst/video/gstvideotimecode.h | 11 +++ tests/check/libs/videotimecode.c | 66 +++++++++++++++++ win32/common/libgstvideo.def | 2 + 5 files changed, 155 insertions(+) diff --git a/docs/libs/gst-plugins-base-libs-sections.txt b/docs/libs/gst-plugins-base-libs-sections.txt index 1eaea9584e..87c8ef1cf4 100644 --- a/docs/libs/gst-plugins-base-libs-sections.txt +++ b/docs/libs/gst-plugins-base-libs-sections.txt @@ -2775,6 +2775,7 @@ gst_video_time_code_new_empty gst_video_time_code_free gst_video_time_code_copy gst_video_time_code_init +gst_video_time_code_init_from_date_time gst_video_time_code_clear gst_video_time_code_is_valid gst_video_time_code_compare @@ -2786,6 +2787,7 @@ gst_video_time_code_to_date_time gst_video_time_code_to_string gst_video_time_code_add_interval gst_video_time_code_new_from_string +gst_video_time_code_new_from_date_time GstVideoTimeCodeInterval diff --git a/gst-libs/gst/video/gstvideotimecode.c b/gst-libs/gst/video/gstvideotimecode.c index 187c92b9d0..7a7535b8a9 100644 --- a/gst-libs/gst/video/gstvideotimecode.c +++ b/gst-libs/gst/video/gstvideotimecode.c @@ -190,6 +190,55 @@ gst_video_time_code_to_date_time (const GstVideoTimeCode * tc) return ret2; } +/** + * gst_video_time_code_init_from_date_time: + * @tc: a #GstVideoTimeCode + * @fps_n: Numerator of the frame rate + * @fps_d: Denominator of the frame rate + * @dt: #GDateTime to convert + * @flags: #GstVideoTimeCodeFlags + * @field_count: Interlaced video field count + * + * The resulting config->latest_daily_jam is set to + * midnight, and timecode is set to the given time. + * + * Since: 1.12 + */ + +void +gst_video_time_code_init_from_date_time (GstVideoTimeCode * tc, + guint fps_n, guint fps_d, + GDateTime * dt, GstVideoTimeCodeFlags flags, guint field_count) +{ + GDateTime *jam; + guint64 frames; + + jam = g_date_time_new_local (g_date_time_get_year (dt), + g_date_time_get_month (dt), g_date_time_get_day_of_month (dt), 0, 0, 0.0); + + /* Note: This might be inaccurate for 1 frame + * in case we have a drop frame timecode */ + frames = + gst_util_uint64_scale_round (g_date_time_get_microsecond (dt) * + G_GINT64_CONSTANT (1000), fps_n, fps_d * GST_SECOND); + + gst_video_time_code_init (tc, fps_n, fps_d, jam, flags, + g_date_time_get_hour (dt), g_date_time_get_minute (dt), + g_date_time_get_second (dt), frames, field_count); + + if (tc->config.flags & GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME) { + guint df = (tc->config.fps_n + (tc->config.fps_d >> 1)) / + (15 * tc->config.fps_d); + if (tc->minutes % 10 && tc->seconds == 0 && tc->frames < df) { + tc->frames = df; + } + } + + g_date_time_unref (jam); + + g_return_if_fail (gst_video_time_code_is_valid (tc)); +} + /** * gst_video_time_code_nsec_since_daily_jam: * @tc: a #GstVideoTimeCode @@ -618,6 +667,31 @@ gst_video_time_code_new_from_string (const gchar * tc_str) } } +/** + * gst_video_time_code_new_from_date_time: + * @fps_n: Numerator of the frame rate + * @fps_d: Denominator of the frame rate + * @dt: #GDateTime to convert + * @flags: #GstVideoTimeCodeFlags + * @field_count: Interlaced video field count + * + * The resulting config->latest_daily_jam is set to + * midnight, and timecode is set to the given time. + * + * Returns: the #GVideoTimeCode representation of @dt. + * + * Since: 1.12 + */ +GstVideoTimeCode * +gst_video_time_code_new_from_date_time (guint fps_n, guint fps_d, + GDateTime * dt, GstVideoTimeCodeFlags flags, guint field_count) +{ + GstVideoTimeCode *tc; + tc = gst_video_time_code_new_empty (); + gst_video_time_code_init_from_date_time (tc, fps_n, fps_d, dt, flags, + field_count); + return tc; +} /** * gst_video_time_code_init: diff --git a/gst-libs/gst/video/gstvideotimecode.h b/gst-libs/gst/video/gstvideotimecode.h index 7fc7d4046f..402b755ac3 100644 --- a/gst-libs/gst/video/gstvideotimecode.h +++ b/gst-libs/gst/video/gstvideotimecode.h @@ -135,6 +135,11 @@ GstVideoTimeCode * gst_video_time_code_new (guint fp guint field_count); GstVideoTimeCode * gst_video_time_code_new_empty (void); GstVideoTimeCode * gst_video_time_code_new_from_string (const gchar * tc_str); +GstVideoTimeCode * gst_video_time_code_new_from_date_time (guint fps_n, + guint fps_d, + GDateTime * dt, + GstVideoTimeCodeFlags flags, + guint field_count); void gst_video_time_code_free (GstVideoTimeCode * tc); GstVideoTimeCode * gst_video_time_code_copy (const GstVideoTimeCode * tc); @@ -149,6 +154,12 @@ void gst_video_time_code_init (GstVideoTimeCode * tc guint seconds, guint frames, guint field_count); +void gst_video_time_code_init_from_date_time (GstVideoTimeCode * tc, + guint fps_n, + guint fps_d, + GDateTime * dt, + GstVideoTimeCodeFlags flags, + guint field_count); void gst_video_time_code_clear (GstVideoTimeCode * tc); gboolean gst_video_time_code_is_valid (const GstVideoTimeCode * tc); diff --git a/tests/check/libs/videotimecode.c b/tests/check/libs/videotimecode.c index 3b75364447..6987dc00de 100644 --- a/tests/check/libs/videotimecode.c +++ b/tests/check/libs/videotimecode.c @@ -584,6 +584,68 @@ GST_START_TEST (videotimecode_interval) GST_END_TEST; +GST_START_TEST (videotimecode_from_date_time_1s) +{ + GstVideoTimeCode *tc; + GDateTime *dt; + + dt = g_date_time_new_local (2017, 2, 16, 0, 0, 1); + tc = gst_video_time_code_new_from_date_time (30000, 1001, dt, + GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME, 0); + + fail_unless_equals_int (tc->hours, 0); + fail_unless_equals_int (tc->minutes, 0); + fail_unless_equals_int (tc->seconds, 1); + fail_unless_equals_int (tc->frames, 0); + + gst_video_time_code_free (tc); + g_date_time_unref (dt); +} + +GST_END_TEST; + +GST_START_TEST (videotimecode_from_date_time_halfsecond) +{ + GstVideoTimeCode *tc; + GDateTime *dt, *dt2; + + dt = g_date_time_new_local (2017, 2, 17, 14, 13, 0); + dt2 = g_date_time_add (dt, 500000); + g_date_time_unref (dt); + tc = gst_video_time_code_new_from_date_time (30000, 1001, dt2, + GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME, 0); + + fail_unless_equals_int (tc->hours, 14); + fail_unless_equals_int (tc->minutes, 13); + fail_unless_equals_int (tc->seconds, 0); + fail_unless_equals_int (tc->frames, 15); + + gst_video_time_code_free (tc); + g_date_time_unref (dt2); +} + +GST_END_TEST; + +GST_START_TEST (videotimecode_from_date_time) +{ + GstVideoTimeCode *tc; + GDateTime *dt; + + dt = g_date_time_new_local (2017, 2, 17, 14, 13, 30); + tc = gst_video_time_code_new_from_date_time (30000, 1001, dt, + GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME, 0); + + fail_unless_equals_int (tc->hours, 14); + fail_unless_equals_int (tc->minutes, 13); + fail_unless_equals_int (tc->seconds, 30); + fail_unless_equals_int (tc->frames, 0); + + gst_video_time_code_free (tc); + g_date_time_unref (dt); +} + +GST_END_TEST; + static Suite * gst_videotimecode_suite (void) { @@ -617,6 +679,10 @@ gst_videotimecode_suite (void) tcase_add_test (tc, videotimecode_dailyjam_distance); tcase_add_test (tc, videotimecode_serialize_deserialize); tcase_add_test (tc, videotimecode_interval); + + tcase_add_test (tc, videotimecode_from_date_time_1s); + tcase_add_test (tc, videotimecode_from_date_time_halfsecond); + tcase_add_test (tc, videotimecode_from_date_time); return s; } diff --git a/win32/common/libgstvideo.def b/win32/common/libgstvideo.def index c07cd9aedb..ddac6c02ac 100644 --- a/win32/common/libgstvideo.def +++ b/win32/common/libgstvideo.def @@ -301,6 +301,7 @@ EXPORTS gst_video_time_code_get_type gst_video_time_code_increment_frame gst_video_time_code_init + gst_video_time_code_init_from_date_time gst_video_time_code_interval_clear gst_video_time_code_interval_copy gst_video_time_code_interval_free @@ -313,6 +314,7 @@ EXPORTS gst_video_time_code_meta_get_info gst_video_time_code_new gst_video_time_code_new_empty + gst_video_time_code_new_from_date_time gst_video_time_code_new_from_string gst_video_time_code_nsec_since_daily_jam gst_video_time_code_to_date_time