diff --git a/subprojects/gst-plugins-base/gst-libs/gst/video/gstvideotimecode.c b/subprojects/gst-plugins-base/gst-libs/gst/video/gstvideotimecode.c index 5713032a47..bacf2cdd47 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/video/gstvideotimecode.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/video/gstvideotimecode.c @@ -183,7 +183,9 @@ gst_video_time_code_to_date_time (const GstVideoTimeCode * tc) { GDateTime *ret; GDateTime *ret2; - gdouble add_us; + guint64 nseconds; + gdouble seconds; + gint hours, minutes; g_return_val_if_fail (gst_video_time_code_is_valid (tc), NULL); @@ -198,22 +200,30 @@ gst_video_time_code_to_date_time (const GstVideoTimeCode * tc) ret = g_date_time_ref (tc->config.latest_daily_jam); - gst_util_fraction_to_double (tc->frames * tc->config.fps_d, tc->config.fps_n, - &add_us); + nseconds = gst_video_time_code_nsec_since_daily_jam (tc); + + hours = nseconds / GST_SECOND / 60 / 60; + nseconds -= hours * GST_SECOND * 60 * 60; + + minutes = nseconds / GST_SECOND / 60; + nseconds -= minutes * GST_SECOND * 60; + + seconds = nseconds / 1000000000.0; + if ((tc->config.flags & GST_VIDEO_TIME_CODE_FLAGS_INTERLACED) && tc->field_count == 1) { - gdouble sub_us; + gdouble sub_s; gst_util_fraction_to_double (tc->config.fps_d, 2 * tc->config.fps_n, - &sub_us); - add_us -= sub_us; + &sub_s); + seconds -= sub_s; } - ret2 = g_date_time_add_seconds (ret, add_us + tc->seconds); + ret2 = g_date_time_add_seconds (ret, seconds); g_date_time_unref (ret); - ret = g_date_time_add_minutes (ret2, tc->minutes); + ret = g_date_time_add_minutes (ret2, minutes); g_date_time_unref (ret2); - ret2 = g_date_time_add_hours (ret, tc->hours); + ret2 = g_date_time_add_hours (ret, hours); g_date_time_unref (ret); return ret2; diff --git a/subprojects/gst-plugins-base/tests/check/libs/videotimecode.c b/subprojects/gst-plugins-base/tests/check/libs/videotimecode.c index 14ce39ec49..9d1965570b 100644 --- a/subprojects/gst-plugins-base/tests/check/libs/videotimecode.c +++ b/subprojects/gst-plugins-base/tests/check/libs/videotimecode.c @@ -337,6 +337,63 @@ GST_START_TEST (videotimecode_dailyjam_todatetime) gst_video_time_code_free (tc1); g_date_time_unref (dt2); g_date_time_unref (dt1); + + dt1 = g_date_time_new_utc (2016, 7, 29, 0, 0, 0); + + tc1 = + gst_video_time_code_new (30000, 1001, dt1, + GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME, 1, 4, 0, 2, 0); + /* 1 hour, 4 minutes, 0 seconds, and 2 frames + * + * Note: timecodes with 0 and 1 frames do not exist every full minute + * except for every 10th minute! + */ + fail_unless (gst_video_time_code_is_valid (tc1)); + fail_unless (tc1->hours == 1); + fail_unless (tc1->minutes == 4); + fail_unless (tc1->seconds == 0); + fail_unless (tc1->frames == 2); + fail_unless_equals_uint64 (gst_video_time_code_frames_since_daily_jam (tc1), + 115086); + fail_unless_equals_uint64 (gst_video_time_code_nsec_since_daily_jam (tc1), + 3840036200000); + + dt2 = gst_video_time_code_to_date_time (tc1); + fail_unless (g_date_time_get_year (dt2) == 2016); + fail_unless (g_date_time_get_month (dt2) == 7); + fail_unless (g_date_time_get_day_of_month (dt2) == 29); + fail_unless (g_date_time_get_hour (dt2) == 1); + fail_unless (g_date_time_get_minute (dt2) == 4); + fail_unless_equals_float (g_date_time_get_seconds (dt2), 0.0362); + g_date_time_unref (dt2); + + /* 1 hour, 3 minutes, 59 seconds, and 29 frames + * + * Note: timecodes with 0 and 1 frames do not exist every full minute + * except for every 10th minute! + */ + gst_video_time_code_add_frames (tc1, -1); + fail_unless (gst_video_time_code_is_valid (tc1)); + fail_unless (tc1->hours == 1); + fail_unless (tc1->minutes == 3); + fail_unless (tc1->seconds == 59); + fail_unless (tc1->frames == 29); + fail_unless_equals_uint64 (gst_video_time_code_frames_since_daily_jam (tc1), + 115085); + fail_unless_equals_uint64 (gst_video_time_code_nsec_since_daily_jam (tc1), + 3840002833333); + + dt2 = gst_video_time_code_to_date_time (tc1); + fail_unless (g_date_time_get_year (dt2) == 2016); + fail_unless (g_date_time_get_month (dt2) == 7); + fail_unless (g_date_time_get_day_of_month (dt2) == 29); + fail_unless (g_date_time_get_hour (dt2) == 1); + fail_unless (g_date_time_get_minute (dt2) == 4); + fail_unless_equals_float (g_date_time_get_seconds (dt2), 0.002833); + + gst_video_time_code_free (tc1); + g_date_time_unref (dt2); + g_date_time_unref (dt1); } GST_END_TEST;