videotimecode: Fix conversion of timecode to datetime with drop-frame timecodes
gst_video_time_code_to_date_time() simply calculated the date time based on adding the hours/minutes/seconds to the daily jam. This causes a gap every full minute (except for every 10th minute) with drop-frame timecodes as the first 2 (29.97fps) or 4 (59.94fps) timecodes are skipped (not frames!), e.g. with 29.97fps: timecode: 12:00:59;28 12:00:59;29 12:01:00;02 12:01:00;03 time : 12:00:59.950 12:00:59.983 12:01:00.017 12:01:00.050 and not time : 12:00:59.934 12:00:59.968 12:01:00.067 12:01:00.100 |-- gap of 2 frames --| The correct calculation would be to use gst_video_time_code_nsec_since_daily_jam() and add that to the daily jam. Also add a test for this. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8649>
This commit is contained in:
parent
0623581850
commit
18798440e3
subprojects/gst-plugins-base
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user