1 /* GStreamer
2  *
3  * Copyright (C) 2016 Vivia Nikolaidou <vivia@toolsonair.com>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20 
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24 #include <gst/gst.h>
25 #include <gst/check/gstcheck.h>
26 #include <gst/video/video.h>
27 
28 
GST_START_TEST(videotimecode_compare_equal)29 GST_START_TEST (videotimecode_compare_equal)
30 {
31   GstVideoTimeCode *tc1, *tc2;
32 
33   tc2 = gst_video_time_code_new (50, 1, NULL, 0, 10, 10, 10, 10, 0);
34   tc1 = gst_video_time_code_new (50, 1, NULL, 0, 10, 10, 10, 10, 0);
35   fail_unless (gst_video_time_code_compare (tc1, tc2) == 0);
36   gst_video_time_code_free (tc1);
37   gst_video_time_code_free (tc2);
38 }
39 
40 GST_END_TEST;
41 
GST_START_TEST(videotimecode_compare_fps_n)42 GST_START_TEST (videotimecode_compare_fps_n)
43 {
44   GstVideoTimeCode *tc1, *tc2;
45 
46   tc1 = gst_video_time_code_new (50, 1, NULL, 0, 10, 10, 10, 10, 0);
47   tc2 = gst_video_time_code_new (25, 1, NULL, 0, 10, 10, 10, 10, 0);
48   fail_unless (gst_video_time_code_compare (tc1, tc2) == 1);
49   fail_unless (gst_video_time_code_compare (tc2, tc1) == -1);
50   gst_video_time_code_free (tc1);
51   gst_video_time_code_free (tc2);
52 }
53 
54 GST_END_TEST;
55 
GST_START_TEST(videotimecode_compare_fps_d)56 GST_START_TEST (videotimecode_compare_fps_d)
57 {
58   GstVideoTimeCode *tc1, *tc2;
59 
60   tc1 = gst_video_time_code_new (50, 1, NULL, 0, 10, 10, 10, 10, 0);
61   tc2 = gst_video_time_code_new (50, 2, NULL, 0, 10, 10, 10, 10, 0);
62   fail_unless (gst_video_time_code_compare (tc1, tc2) == 1);
63   fail_unless (gst_video_time_code_compare (tc2, tc1) == -1);
64   gst_video_time_code_free (tc1);
65   gst_video_time_code_free (tc2);
66 }
67 
68 GST_END_TEST;
69 
GST_START_TEST(videotimecode_compare_frames)70 GST_START_TEST (videotimecode_compare_frames)
71 {
72   GstVideoTimeCode *tc1, *tc2;
73 
74   tc1 = gst_video_time_code_new (50, 1, NULL, 0, 10, 10, 10, 10, 0);
75   tc2 = gst_video_time_code_new (50, 1, NULL, 0, 10, 10, 10, 9, 0);
76   fail_unless (gst_video_time_code_compare (tc1, tc2) == 1);
77   fail_unless (gst_video_time_code_compare (tc2, tc1) == -1);
78   gst_video_time_code_free (tc1);
79   gst_video_time_code_free (tc2);
80 }
81 
82 GST_END_TEST;
83 
GST_START_TEST(videotimecode_compare_seconds)84 GST_START_TEST (videotimecode_compare_seconds)
85 {
86   GstVideoTimeCode *tc1, *tc2;
87 
88   tc1 = gst_video_time_code_new (50, 1, NULL, 0, 10, 10, 10, 10, 0);
89   tc2 = gst_video_time_code_new (50, 1, NULL, 0, 10, 10, 9, 10, 0);
90   fail_unless (gst_video_time_code_compare (tc1, tc2) == 1);
91   fail_unless (gst_video_time_code_compare (tc2, tc1) == -1);
92   gst_video_time_code_free (tc1);
93   gst_video_time_code_free (tc2);
94 }
95 
96 GST_END_TEST;
97 
GST_START_TEST(videotimecode_compare_minutes)98 GST_START_TEST (videotimecode_compare_minutes)
99 {
100   GstVideoTimeCode *tc1, *tc2;
101 
102   tc1 = gst_video_time_code_new (50, 1, NULL, 0, 10, 10, 10, 10, 0);
103   tc2 = gst_video_time_code_new (50, 1, NULL, 0, 10, 9, 10, 10, 0);
104   fail_unless (gst_video_time_code_compare (tc1, tc2) == 1);
105   fail_unless (gst_video_time_code_compare (tc2, tc1) == -1);
106   gst_video_time_code_free (tc1);
107   gst_video_time_code_free (tc2);
108 }
109 
110 GST_END_TEST;
111 
GST_START_TEST(videotimecode_compare_hours)112 GST_START_TEST (videotimecode_compare_hours)
113 {
114   GstVideoTimeCode *tc1, *tc2;
115 
116   tc1 = gst_video_time_code_new (50, 1, NULL, 0, 10, 10, 10, 10, 0);
117   tc2 = gst_video_time_code_new (50, 1, NULL, 0, 9, 10, 10, 10, 0);
118   fail_unless (gst_video_time_code_compare (tc1, tc2) == 1);
119   fail_unless (gst_video_time_code_compare (tc2, tc1) == -1);
120   gst_video_time_code_free (tc1);
121   gst_video_time_code_free (tc2);
122 }
123 
124 GST_END_TEST;
125 
GST_START_TEST(videotimecode_compare_fieldcounts)126 GST_START_TEST (videotimecode_compare_fieldcounts)
127 {
128   GstVideoTimeCode *tc1, *tc2;
129 
130   tc1 =
131       gst_video_time_code_new (50, 1, NULL,
132       GST_VIDEO_TIME_CODE_FLAGS_INTERLACED, 10, 10, 10, 10, 2);
133   tc2 =
134       gst_video_time_code_new (50, 1, NULL,
135       GST_VIDEO_TIME_CODE_FLAGS_INTERLACED, 10, 10, 10, 10, 1);
136   fail_unless (gst_video_time_code_compare (tc1, tc2) == 1);
137   fail_unless (gst_video_time_code_compare (tc2, tc1) == -1);
138   gst_video_time_code_free (tc1);
139   gst_video_time_code_free (tc2);
140 }
141 
142 GST_END_TEST;
143 
GST_START_TEST(videotimecode_addframe_10)144 GST_START_TEST (videotimecode_addframe_10)
145 {
146   GstVideoTimeCode *tc1;
147 
148   tc1 = gst_video_time_code_new (50, 1, NULL, 0, 10, 10, 10, 10, 0);
149   gst_video_time_code_increment_frame (tc1);
150   fail_unless (tc1->hours == 10);
151   fail_unless (tc1->minutes == 10);
152   fail_unless (tc1->seconds == 10);
153   fail_unless (tc1->frames == 11);
154   gst_video_time_code_free (tc1);
155 }
156 
157 GST_END_TEST;
158 
GST_START_TEST(videotimecode_addframe_0)159 GST_START_TEST (videotimecode_addframe_0)
160 {
161   GstVideoTimeCode *tc1;
162 
163   tc1 = gst_video_time_code_new (50, 1, NULL, 0, 0, 0, 0, 0, 0);
164   gst_video_time_code_increment_frame (tc1);
165   fail_unless (tc1->hours == 0);
166   fail_unless (tc1->minutes == 0);
167   fail_unless (tc1->seconds == 0);
168   fail_unless (tc1->frames == 1);
169   gst_video_time_code_free (tc1);
170 }
171 
172 GST_END_TEST;
173 
GST_START_TEST(videotimecode_addframe_high)174 GST_START_TEST (videotimecode_addframe_high)
175 {
176   GstVideoTimeCode *tc1;
177   /* Make sure nothing overflows */
178 
179   tc1 = gst_video_time_code_new (60, 1, NULL, 0, 23, 59, 59, 58, 0);
180   gst_video_time_code_increment_frame (tc1);
181   fail_unless (tc1->hours == 23);
182   fail_unless (tc1->minutes == 59);
183   fail_unless (tc1->seconds == 59);
184   fail_unless (tc1->frames == 59);
185   gst_video_time_code_free (tc1);
186 }
187 
188 GST_END_TEST;
189 
GST_START_TEST(videotimecode_addframe_dropframe)190 GST_START_TEST (videotimecode_addframe_dropframe)
191 {
192   GstVideoTimeCode *tc1;
193 
194   tc1 =
195       gst_video_time_code_new (30000, 1001, NULL,
196       GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME, 10, 10, 10, 10, 0);
197   gst_video_time_code_increment_frame (tc1);
198   fail_unless (tc1->hours == 10);
199   fail_unless (tc1->minutes == 10);
200   fail_unless (tc1->seconds == 10);
201   fail_unless (tc1->frames == 11);
202   gst_video_time_code_free (tc1);
203 }
204 
205 GST_END_TEST;
206 
GST_START_TEST(videotimecode_addframe_framedropped)207 GST_START_TEST (videotimecode_addframe_framedropped)
208 {
209   GstVideoTimeCode *tc1;
210 
211   tc1 =
212       gst_video_time_code_new (30000, 1001, NULL,
213       GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME, 10, 10, 59, 29, 0);
214   gst_video_time_code_increment_frame (tc1);
215   fail_unless (tc1->hours == 10);
216   fail_unless (tc1->minutes == 11);
217   fail_unless (tc1->seconds == 0);
218   fail_unless (tc1->frames == 2);
219   gst_video_time_code_free (tc1);
220 }
221 
222 GST_END_TEST;
223 
GST_START_TEST(videotimecode_addframe_wrapover)224 GST_START_TEST (videotimecode_addframe_wrapover)
225 {
226   GstVideoTimeCode *tc1;
227 
228   tc1 =
229       gst_video_time_code_new (30000, 1001, NULL,
230       GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME, 23, 59, 59, 29, 0);
231   gst_video_time_code_increment_frame (tc1);
232   fail_unless (tc1->hours == 0);
233   fail_unless (tc1->minutes == 0);
234   fail_unless (tc1->seconds == 0);
235   fail_unless (tc1->frames == 0);
236   gst_video_time_code_free (tc1);
237 }
238 
239 GST_END_TEST;
240 
GST_START_TEST(videotimecode_addframe_60drop_dropframe)241 GST_START_TEST (videotimecode_addframe_60drop_dropframe)
242 {
243   GstVideoTimeCode *tc1;
244 
245   tc1 =
246       gst_video_time_code_new (60000, 1001, NULL,
247       GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME, 10, 10, 10, 10, 0);
248   gst_video_time_code_increment_frame (tc1);
249   fail_unless (tc1->hours == 10);
250   fail_unless (tc1->minutes == 10);
251   fail_unless (tc1->seconds == 10);
252   fail_unless (tc1->frames == 11);
253   gst_video_time_code_free (tc1);
254 }
255 
256 GST_END_TEST;
257 
GST_START_TEST(videotimecode_addframe_60drop_framedropped)258 GST_START_TEST (videotimecode_addframe_60drop_framedropped)
259 {
260   GstVideoTimeCode *tc1;
261 
262   tc1 =
263       gst_video_time_code_new (60000, 1001, NULL,
264       GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME, 10, 10, 59, 59, 0);
265   gst_video_time_code_increment_frame (tc1);
266   fail_unless (tc1->hours == 10);
267   fail_unless (tc1->minutes == 11);
268   fail_unless (tc1->seconds == 0);
269   fail_unless (tc1->frames == 4);
270   gst_video_time_code_free (tc1);
271 }
272 
273 GST_END_TEST;
274 
GST_START_TEST(videotimecode_addframe_60drop_wrapover)275 GST_START_TEST (videotimecode_addframe_60drop_wrapover)
276 {
277   GstVideoTimeCode *tc1;
278   /* Make sure nothing overflows here either */
279 
280   tc1 =
281       gst_video_time_code_new (60000, 1001, NULL,
282       GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME, 23, 59, 59, 59, 0);
283   gst_video_time_code_increment_frame (tc1);
284   fail_unless (tc1->hours == 0);
285   fail_unless (tc1->minutes == 0);
286   fail_unless (tc1->seconds == 0);
287   fail_unless (tc1->frames == 0);
288   gst_video_time_code_free (tc1);
289 }
290 
291 GST_END_TEST;
292 
GST_START_TEST(videotimecode_addframe_loop)293 GST_START_TEST (videotimecode_addframe_loop)
294 {
295   GstVideoTimeCode *tc1;
296   guint64 i;
297   /* Loop for an hour and a bit, make sure no assertions explode */
298 
299   tc1 =
300       gst_video_time_code_new (60000, 1001, NULL,
301       GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME, 12, 12, 12, 12, 0);
302   for (i = 0; i < 220000; i++)
303     gst_video_time_code_increment_frame (tc1);
304   gst_video_time_code_init (tc1, 60, 1, NULL, 0, 12, 12, 12, 12, 0);
305   for (i = 0; i < 220000; i++)
306     gst_video_time_code_increment_frame (tc1);
307   gst_video_time_code_free (tc1);
308 }
309 
310 GST_END_TEST;
311 
GST_START_TEST(videotimecode_dailyjam_todatetime)312 GST_START_TEST (videotimecode_dailyjam_todatetime)
313 {
314   GstVideoTimeCode *tc1;
315   GDateTime *dt1, *dt2;
316 
317   dt1 = g_date_time_new_utc (2016, 7, 29, 10, 32, 50);
318 
319   tc1 =
320       gst_video_time_code_new (50, 1, dt1,
321       GST_VIDEO_TIME_CODE_FLAGS_NONE, 0, 0, 0, 0, 0);
322   /* 1 hour, 4 minutes, 3 seconds, and 2 frames */
323   gst_video_time_code_add_frames (tc1, 192152);
324   fail_unless (tc1->hours == 1);
325   fail_unless (tc1->minutes == 4);
326   fail_unless (tc1->seconds == 3);
327   fail_unless (tc1->frames == 2);
328 
329   dt2 = gst_video_time_code_to_date_time (tc1);
330   fail_unless (g_date_time_get_year (dt2) == 2016);
331   fail_unless (g_date_time_get_month (dt2) == 7);
332   fail_unless (g_date_time_get_day_of_month (dt2) == 29);
333   fail_unless (g_date_time_get_hour (dt2) == 11);
334   fail_unless (g_date_time_get_minute (dt2) == 36);
335   fail_unless_equals_float (g_date_time_get_seconds (dt2), 53.04);
336 
337   gst_video_time_code_free (tc1);
338   g_date_time_unref (dt2);
339   g_date_time_unref (dt1);
340 }
341 
342 GST_END_TEST;
343 
GST_START_TEST(videotimecode_dailyjam_compare)344 GST_START_TEST (videotimecode_dailyjam_compare)
345 {
346   GstVideoTimeCode *tc1, *tc2;
347   GDateTime *dt1;
348 
349   dt1 = g_date_time_new_utc (2016, 7, 29, 10, 32, 50);
350 
351   tc1 =
352       gst_video_time_code_new (50, 1, dt1,
353       GST_VIDEO_TIME_CODE_FLAGS_NONE, 0, 0, 0, 0, 0);
354   tc2 = gst_video_time_code_copy (tc1);
355   fail_unless (gst_video_time_code_compare (tc1, tc2) == 0);
356   gst_video_time_code_increment_frame (tc1);
357   fail_unless (gst_video_time_code_compare (tc1, tc2) == 1);
358   gst_video_time_code_add_frames (tc2, 2);
359   fail_unless (gst_video_time_code_compare (tc1, tc2) == -1);
360 
361   gst_video_time_code_free (tc1);
362   gst_video_time_code_free (tc2);
363   g_date_time_unref (dt1);
364 }
365 
366 GST_END_TEST;
367 
GST_START_TEST(videotimecode_dailyjam_distance)368 GST_START_TEST (videotimecode_dailyjam_distance)
369 {
370   GstVideoTimeCode *tc;
371   GDateTime *dt;
372 
373   dt = g_date_time_new_utc (2016, 7, 29, 10, 32, 50);
374 
375   tc = gst_video_time_code_new (50, 1, dt,
376       GST_VIDEO_TIME_CODE_FLAGS_NONE, 0, 0, 0, 0, 0);
377 
378   fail_unless_equals_uint64 (gst_video_time_code_nsec_since_daily_jam (tc), 0);
379   fail_unless_equals_uint64 (gst_video_time_code_frames_since_daily_jam (tc),
380       0);
381 
382   gst_video_time_code_add_frames (tc, 10);
383   fail_unless_equals_uint64 (gst_video_time_code_nsec_since_daily_jam (tc),
384       200 * GST_MSECOND);
385   fail_unless_equals_uint64 (gst_video_time_code_frames_since_daily_jam (tc),
386       10);
387 
388   gst_video_time_code_add_frames (tc, 40);
389   fail_unless_equals_uint64 (gst_video_time_code_nsec_since_daily_jam (tc),
390       1 * GST_SECOND);
391   fail_unless_equals_uint64 (gst_video_time_code_frames_since_daily_jam (tc),
392       50);
393 
394   gst_video_time_code_add_frames (tc, 50);
395   fail_unless_equals_uint64 (gst_video_time_code_nsec_since_daily_jam (tc),
396       2 * GST_SECOND);
397   fail_unless_equals_uint64 (gst_video_time_code_frames_since_daily_jam (tc),
398       100);
399 
400   gst_video_time_code_add_frames (tc, 58 * 50);
401   fail_unless_equals_uint64 (gst_video_time_code_nsec_since_daily_jam (tc),
402       60 * GST_SECOND);
403   fail_unless_equals_uint64 (gst_video_time_code_frames_since_daily_jam (tc),
404       60 * 50);
405 
406   gst_video_time_code_add_frames (tc, 9 * 60 * 50);
407   fail_unless_equals_uint64 (gst_video_time_code_nsec_since_daily_jam (tc),
408       10 * 60 * GST_SECOND);
409   fail_unless_equals_uint64 (gst_video_time_code_frames_since_daily_jam (tc),
410       10 * 60 * 50);
411 
412   gst_video_time_code_add_frames (tc, 20 * 60 * 50);
413   fail_unless_equals_uint64 (gst_video_time_code_nsec_since_daily_jam (tc),
414       30 * 60 * GST_SECOND);
415   fail_unless_equals_uint64 (gst_video_time_code_frames_since_daily_jam (tc),
416       30 * 60 * 50);
417 
418   gst_video_time_code_add_frames (tc, 30 * 60 * 50);
419   fail_unless_equals_uint64 (gst_video_time_code_nsec_since_daily_jam (tc),
420       60 * 60 * GST_SECOND);
421   fail_unless_equals_uint64 (gst_video_time_code_frames_since_daily_jam (tc),
422       60 * 60 * 50);
423 
424   gst_video_time_code_add_frames (tc, 9 * 60 * 60 * 50);
425   fail_unless_equals_uint64 (gst_video_time_code_nsec_since_daily_jam (tc),
426       10 * 60 * 60 * GST_SECOND);
427   fail_unless_equals_uint64 (gst_video_time_code_frames_since_daily_jam (tc),
428       10 * 60 * 60 * 50);
429 
430   gst_video_time_code_free (tc);
431 
432   /* Now test with drop-frame: while it is called "drop-frame", not actual
433    * frames are dropped but instead every once in a while timecodes are
434    * skipped. As such, every frame still has the same distance to its next
435    * frame. */
436   tc = gst_video_time_code_new (60000, 1001, dt,
437       GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME, 0, 0, 0, 0, 0);
438 
439   fail_unless_equals_uint64 (gst_video_time_code_nsec_since_daily_jam (tc), 0);
440   fail_unless_equals_uint64 (gst_video_time_code_frames_since_daily_jam (tc),
441       0);
442 
443   gst_video_time_code_add_frames (tc, 10);
444   fail_unless_equals_uint64 (gst_video_time_code_nsec_since_daily_jam (tc),
445       gst_util_uint64_scale (10, G_GUINT64_CONSTANT (1001) * GST_SECOND,
446           60000));
447   fail_unless_equals_uint64 (gst_video_time_code_frames_since_daily_jam (tc),
448       10);
449 
450   gst_video_time_code_add_frames (tc, 50);
451   fail_unless_equals_uint64 (gst_video_time_code_nsec_since_daily_jam (tc),
452       gst_util_uint64_scale (60, G_GUINT64_CONSTANT (1001) * GST_SECOND,
453           60000));
454   fail_unless_equals_uint64 (gst_video_time_code_frames_since_daily_jam (tc),
455       60);
456 
457   gst_video_time_code_add_frames (tc, 60);
458   fail_unless_equals_uint64 (gst_video_time_code_nsec_since_daily_jam (tc),
459       gst_util_uint64_scale (120, G_GUINT64_CONSTANT (1001) * GST_SECOND,
460           60000));
461   fail_unless_equals_uint64 (gst_video_time_code_frames_since_daily_jam (tc),
462       120);
463 
464   gst_video_time_code_add_frames (tc, 58 * 60);
465   fail_unless_equals_uint64 (gst_video_time_code_nsec_since_daily_jam (tc),
466       gst_util_uint64_scale (60 * 60, G_GUINT64_CONSTANT (1001) * GST_SECOND,
467           60000));
468   fail_unless_equals_uint64 (gst_video_time_code_frames_since_daily_jam (tc),
469       60 * 60);
470 
471   gst_video_time_code_add_frames (tc, 9 * 60 * 60);
472   fail_unless_equals_uint64 (gst_video_time_code_nsec_since_daily_jam (tc),
473       gst_util_uint64_scale (10 * 60 * 60,
474           G_GUINT64_CONSTANT (1001) * GST_SECOND, 60000));
475   fail_unless_equals_uint64 (gst_video_time_code_frames_since_daily_jam (tc),
476       10 * 60 * 60);
477 
478   gst_video_time_code_add_frames (tc, 20 * 60 * 60);
479   fail_unless_equals_uint64 (gst_video_time_code_nsec_since_daily_jam (tc),
480       gst_util_uint64_scale (30 * 60 * 60,
481           G_GUINT64_CONSTANT (1001) * GST_SECOND, 60000));
482   fail_unless_equals_uint64 (gst_video_time_code_frames_since_daily_jam (tc),
483       30 * 60 * 60);
484 
485   gst_video_time_code_add_frames (tc, 30 * 60 * 60);
486   fail_unless_equals_uint64 (gst_video_time_code_nsec_since_daily_jam (tc),
487       gst_util_uint64_scale (60 * 60 * 60,
488           G_GUINT64_CONSTANT (1001) * GST_SECOND, 60000));
489   fail_unless_equals_uint64 (gst_video_time_code_frames_since_daily_jam (tc),
490       60 * 60 * 60);
491 
492   gst_video_time_code_add_frames (tc, 9 * 60 * 60 * 60);
493   fail_unless_equals_uint64 (gst_video_time_code_nsec_since_daily_jam (tc),
494       gst_util_uint64_scale (10 * 60 * 60 * 60,
495           G_GUINT64_CONSTANT (1001) * GST_SECOND, 60000));
496   fail_unless_equals_uint64 (gst_video_time_code_frames_since_daily_jam (tc),
497       10 * 60 * 60 * 60);
498 
499   gst_video_time_code_free (tc);
500 
501   g_date_time_unref (dt);
502 }
503 
504 GST_END_TEST;
505 
GST_START_TEST(videotimecode_serialize_deserialize)506 GST_START_TEST (videotimecode_serialize_deserialize)
507 {
508   const gchar *str = "01:02:03:04";
509   gchar *str2;
510   GstVideoTimeCode *tc;
511   GValue v = G_VALUE_INIT;
512   GValue v2 = G_VALUE_INIT;
513 
514   g_value_init (&v, G_TYPE_STRING);
515   g_value_init (&v2, GST_TYPE_VIDEO_TIME_CODE);
516 
517   fail_unless (gst_value_deserialize (&v2, str));
518   tc = g_value_get_boxed (&v2);
519   str2 = gst_video_time_code_to_string (tc);
520   fail_unless_equals_string (str, str2);
521   g_free (str2);
522 
523   g_value_set_string (&v, str);
524 
525   g_value_transform (&v, &v2);
526   str2 = gst_value_serialize (&v2);
527   fail_unless_equals_string (str, str2);
528   g_free (str2);
529 
530   tc = g_value_get_boxed (&v2);
531   str2 = gst_video_time_code_to_string (tc);
532   fail_unless_equals_string (str, str2);
533   g_free (str2);
534 
535   g_value_transform (&v2, &v);
536   str2 = (gchar *) g_value_get_string (&v);
537   fail_unless_equals_string (str, str2);
538   g_value_unset (&v2);
539   g_value_unset (&v);
540 }
541 
542 GST_END_TEST;
543 
GST_START_TEST(videotimecode_interval)544 GST_START_TEST (videotimecode_interval)
545 {
546   GstVideoTimeCode *tc, *tc2;
547   GstVideoTimeCodeInterval *tc_diff;
548   int i;
549 
550   tc = gst_video_time_code_new (25, 1, NULL, 0, 1, 2, 3, 4, 0);
551   tc_diff = gst_video_time_code_interval_new (1, 1, 1, 1);
552   tc2 = gst_video_time_code_add_interval (tc, tc_diff);
553   fail_unless_equals_int (tc2->hours, 2);
554   fail_unless_equals_int (tc2->minutes, 3);
555   fail_unless_equals_int (tc2->seconds, 4);
556   fail_unless_equals_int (tc2->frames, 5);
557   fail_unless_equals_int (tc2->config.fps_n, tc->config.fps_n);
558   fail_unless_equals_int (tc2->config.fps_d, tc->config.fps_d);
559   gst_video_time_code_free (tc2);
560   gst_video_time_code_interval_free (tc_diff);
561 
562   gst_video_time_code_init (tc, 30000, 1001, NULL,
563       GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME, 0, 0, 0, 0, 0);
564   tc_diff = gst_video_time_code_interval_new (0, 1, 0, 0);
565   for (i = 1; i <= 9; i++) {
566     tc2 = gst_video_time_code_add_interval (tc, tc_diff);
567     fail_unless_equals_int (tc2->hours, 0);
568     fail_unless_equals_int (tc2->minutes, i);
569     fail_unless_equals_int (tc2->seconds, 0);
570     fail_unless_equals_int (tc2->frames, 2);
571     gst_video_time_code_free (tc);
572     tc = gst_video_time_code_copy (tc2);
573     gst_video_time_code_free (tc2);
574   }
575   tc2 = gst_video_time_code_add_interval (tc, tc_diff);
576   fail_unless_equals_int (tc2->hours, 0);
577   fail_unless_equals_int (tc2->minutes, 10);
578   fail_unless_equals_int (tc2->seconds, 0);
579   fail_unless_equals_int (tc2->frames, 0);
580   gst_video_time_code_free (tc2);
581   gst_video_time_code_free (tc);
582   gst_video_time_code_interval_free (tc_diff);
583 }
584 
585 GST_END_TEST;
586 
GST_START_TEST(videotimecode_invalid)587 GST_START_TEST (videotimecode_invalid)
588 {
589   GstVideoTimeCode *tc;
590 
591   tc = gst_video_time_code_new (25, 1, NULL,
592       GST_VIDEO_TIME_CODE_FLAGS_NONE, 1, 67, 4, 5, 0);
593   fail_unless (gst_video_time_code_is_valid (tc) == FALSE);
594   gst_video_time_code_free (tc);
595   tc = gst_video_time_code_new (60, 1, NULL,
596       GST_VIDEO_TIME_CODE_FLAGS_NONE, 28, 1, 2, 3, 0);
597   fail_unless (gst_video_time_code_is_valid (tc) == FALSE);
598   gst_video_time_code_free (tc);
599   tc = gst_video_time_code_new (30000, 1001, NULL,
600       GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME, 1, 23, 0, 0, 0);
601   fail_unless (gst_video_time_code_is_valid (tc) == FALSE);
602   gst_video_time_code_free (tc);
603   tc = gst_video_time_code_new (25, 1, NULL,
604       GST_VIDEO_TIME_CODE_FLAGS_NONE, 10, 11, 12, 13, 0);
605   fail_unless (gst_video_time_code_is_valid (tc) == TRUE);
606   gst_video_time_code_free (tc);
607 }
608 
609 GST_END_TEST;
610 
GST_START_TEST(videotimecode_from_date_time_1s)611 GST_START_TEST (videotimecode_from_date_time_1s)
612 {
613   GstVideoTimeCode *tc;
614   GDateTime *dt;
615 
616   dt = g_date_time_new_local (2017, 2, 16, 0, 0, 1);
617   tc = gst_video_time_code_new_from_date_time_full (30000, 1001, dt,
618       GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME, 0);
619 
620   fail_unless_equals_int (tc->hours, 0);
621   fail_unless_equals_int (tc->minutes, 0);
622   fail_unless_equals_int (tc->seconds, 1);
623   fail_unless_equals_int (tc->frames, 0);
624 
625   gst_video_time_code_free (tc);
626   g_date_time_unref (dt);
627 }
628 
629 GST_END_TEST;
630 
GST_START_TEST(videotimecode_from_date_time_halfsecond)631 GST_START_TEST (videotimecode_from_date_time_halfsecond)
632 {
633   GstVideoTimeCode *tc;
634   GDateTime *dt, *dt2;
635 
636   dt = g_date_time_new_local (2017, 2, 17, 14, 13, 0);
637   dt2 = g_date_time_add (dt, 500000);
638   g_date_time_unref (dt);
639   tc = gst_video_time_code_new_from_date_time_full (30000, 1001, dt2,
640       GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME, 0);
641 
642   fail_unless_equals_int (tc->hours, 14);
643   fail_unless_equals_int (tc->minutes, 13);
644   fail_unless_equals_int (tc->seconds, 0);
645   fail_unless_equals_int (tc->frames, 15);
646 
647   gst_video_time_code_free (tc);
648   g_date_time_unref (dt2);
649 }
650 
651 GST_END_TEST;
652 
GST_START_TEST(videotimecode_from_date_time)653 GST_START_TEST (videotimecode_from_date_time)
654 {
655   GstVideoTimeCode *tc;
656   GDateTime *dt;
657 
658   dt = g_date_time_new_local (2017, 2, 17, 14, 13, 30);
659   tc = gst_video_time_code_new_from_date_time_full (30000, 1001, dt,
660       GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME, 0);
661 
662   fail_unless_equals_int (tc->hours, 14);
663   fail_unless_equals_int (tc->minutes, 13);
664   fail_unless_equals_int (tc->seconds, 30);
665   fail_unless_equals_int (tc->frames, 0);
666 
667   gst_video_time_code_free (tc);
668   g_date_time_unref (dt);
669 }
670 
671 GST_END_TEST;
672 
673 static void
test_timecode_from_string(const gchar * str,gboolean success,guint hours,guint minutes,guint seconds,guint frames,gboolean drop_frame)674 test_timecode_from_string (const gchar * str, gboolean success, guint hours,
675     guint minutes, guint seconds, guint frames, gboolean drop_frame)
676 {
677   GstVideoTimeCode *tc;
678   gchar *s;
679 
680   tc = gst_video_time_code_new_from_string (str);
681 
682   if (success) {
683     fail_unless (tc);
684   } else {
685     fail_if (tc);
686     return;
687   }
688 
689   fail_unless_equals_int (tc->hours, hours);
690   fail_unless_equals_int (tc->minutes, minutes);
691   fail_unless_equals_int (tc->seconds, seconds);
692   fail_unless_equals_int (tc->frames, frames);
693 
694   if (drop_frame)
695     fail_unless (tc->config.flags & GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME);
696   else
697     fail_if (tc->config.flags & GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME);
698 
699   s = gst_video_time_code_to_string (tc);
700   fail_unless_equals_string (s, str);
701 
702   gst_video_time_code_free (tc);
703   g_free (s);
704 }
705 
GST_START_TEST(videotimecode_from_to_string)706 GST_START_TEST (videotimecode_from_to_string)
707 {
708   test_timecode_from_string ("11:12:13:14", TRUE, 11, 12, 13, 14, FALSE);
709   test_timecode_from_string ("11:12:13;14", TRUE, 11, 12, 13, 14, TRUE);
710   test_timecode_from_string ("11:12:13:", FALSE, 0, 0, 0, 0, FALSE);
711   test_timecode_from_string ("11:12:13:ab", FALSE, 0, 0, 0, 0, FALSE);
712   test_timecode_from_string ("a 11:12:13:14", FALSE, 0, 0, 0, 0, FALSE);
713 }
714 
715 GST_END_TEST;
716 
717 static Suite *
gst_videotimecode_suite(void)718 gst_videotimecode_suite (void)
719 {
720   Suite *s = suite_create ("GstVideoTimeCode");
721   TCase *tc = tcase_create ("general");
722 
723   suite_add_tcase (s, tc);
724 
725   tcase_add_test (tc, videotimecode_compare_equal);
726   tcase_add_test (tc, videotimecode_compare_fps_n);
727   tcase_add_test (tc, videotimecode_compare_fps_d);
728   tcase_add_test (tc, videotimecode_compare_frames);
729   tcase_add_test (tc, videotimecode_compare_seconds);
730   tcase_add_test (tc, videotimecode_compare_minutes);
731   tcase_add_test (tc, videotimecode_compare_hours);
732   tcase_add_test (tc, videotimecode_compare_fieldcounts);
733 
734   tcase_add_test (tc, videotimecode_addframe_10);
735   tcase_add_test (tc, videotimecode_addframe_0);
736   tcase_add_test (tc, videotimecode_addframe_high);
737   tcase_add_test (tc, videotimecode_addframe_dropframe);
738   tcase_add_test (tc, videotimecode_addframe_framedropped);
739   tcase_add_test (tc, videotimecode_addframe_wrapover);
740   tcase_add_test (tc, videotimecode_addframe_60drop_dropframe);
741   tcase_add_test (tc, videotimecode_addframe_60drop_framedropped);
742   tcase_add_test (tc, videotimecode_addframe_60drop_wrapover);
743   tcase_add_test (tc, videotimecode_addframe_loop);
744 
745   tcase_add_test (tc, videotimecode_dailyjam_todatetime);
746   tcase_add_test (tc, videotimecode_dailyjam_compare);
747   tcase_add_test (tc, videotimecode_dailyjam_distance);
748   tcase_add_test (tc, videotimecode_serialize_deserialize);
749   tcase_add_test (tc, videotimecode_interval);
750   tcase_add_test (tc, videotimecode_invalid);
751 
752   tcase_add_test (tc, videotimecode_from_date_time_1s);
753   tcase_add_test (tc, videotimecode_from_date_time_halfsecond);
754   tcase_add_test (tc, videotimecode_from_date_time);
755 
756   tcase_add_test (tc, videotimecode_from_to_string);
757 
758   return s;
759 }
760 
761 GST_CHECK_MAIN (gst_videotimecode);
762