From 9feb35638afb252ba9373ad5118ce5eb61ab2937 Mon Sep 17 00:00:00 2001 From: Yeongjin Jeong Date: Tue, 18 Feb 2020 18:36:36 +0900 Subject: [PATCH] tests: flvmux: Add test for rollover timestamp The timestamps that exceed uint32 maximum value should be handled to rollover. --- tests/check/elements/flvmux.c | 109 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 107 insertions(+), 2 deletions(-) diff --git a/tests/check/elements/flvmux.c b/tests/check/elements/flvmux.c index 7b0d182..1c820cd 100644 --- a/tests/check/elements/flvmux.c +++ b/tests/check/elements/flvmux.c @@ -935,8 +935,8 @@ GST_END_TEST; typedef struct { guint media_type; - gint ts; /* timestamp in ms */ - gint rt; /* running_time in ms */ + guint64 ts; /* timestamp in ms */ + guint64 rt; /* running_time in ms */ } InputData; GST_START_TEST (test_incrementing_timestamps) @@ -1034,6 +1034,110 @@ GST_START_TEST (test_incrementing_timestamps) GST_END_TEST; +GST_START_TEST (test_rollover_timestamps) +{ + GstPad *audio_sink, *video_sink, *audio_src, *video_src; + GstHarness *h, *audio, *video, *audio_q, *video_q; + GstTestClock *tclock; + guint i; + guint64 rollover_pts = (guint64) G_MAXUINT32 + 100; + InputData input[] = { + {AUDIO, 0, 1} + , + {VIDEO, 0, 2} + , + {VIDEO, (guint64) G_MAXUINT32 - 100, (guint64) G_MAXUINT32 - 99} + , + {AUDIO, (guint64) G_MAXUINT32 - 95, (guint64) G_MAXUINT32 - 90} + , + {AUDIO, rollover_pts, (guint64) G_MAXUINT32 + 110} + , + }; + + /* setup flvmuxer with queues in front */ + h = gst_harness_new_with_padnames ("flvmux", NULL, "src"); + audio = gst_harness_new_with_element (h->element, "audio", NULL); + video = gst_harness_new_with_element (h->element, "video", NULL); + audio_q = gst_harness_new ("queue"); + video_q = gst_harness_new ("queue"); + audio_sink = GST_PAD_PEER (audio->srcpad); + video_sink = GST_PAD_PEER (video->srcpad); + audio_src = GST_PAD_PEER (audio_q->sinkpad); + video_src = GST_PAD_PEER (video_q->sinkpad); + gst_pad_unlink (audio->srcpad, audio_sink); + gst_pad_unlink (video->srcpad, video_sink); + gst_pad_unlink (audio_src, audio_q->sinkpad); + gst_pad_unlink (video_src, video_q->sinkpad); + gst_pad_link (audio_src, audio_sink); + gst_pad_link (video_src, video_sink); + g_object_set (h->element, "streamable", TRUE, NULL); + + gst_harness_set_src_caps_str (audio_q, + "audio/mpeg, mpegversion=(int)4, " + "rate=(int)44100, channels=(int)1, " + "stream-format=(string)raw, codec_data=(buffer)1208"); + + gst_harness_set_src_caps_str (video_q, + "video/x-h264, stream-format=(string)avc, alignment=(string)au, " + "codec_data=(buffer)0142c00dffe1000d6742c00d95a0507c807844235001000468ce3c80"); + + tclock = gst_harness_get_testclock (h); + + for (i = 0; i < G_N_ELEMENTS (input); i++) { + InputData *d = &input[i]; + GstBuffer *buf = gst_buffer_new (); + GstClockTime now = d->rt * GST_MSECOND; + GstClockID pending, res; + + GST_BUFFER_DTS (buf) = GST_BUFFER_PTS (buf) = d->ts * GST_MSECOND; + GST_DEBUG ("Push media=%u, pts=%" G_GUINT64_FORMAT " (%" GST_TIME_FORMAT + ")", d->media_type, d->ts, GST_TIME_ARGS (GST_BUFFER_PTS (buf))); + gst_test_clock_set_time (tclock, now); + + if (d->media_type == AUDIO) + gst_harness_push (audio_q, buf); + else + gst_harness_push (video_q, buf); + + gst_test_clock_wait_for_next_pending_id (tclock, &pending); + res = gst_test_clock_process_next_clock_id (tclock); + gst_clock_id_unref (pending); + gst_clock_id_unref (res); + } + + /* pull the flv metadata */ + gst_buffer_unref (gst_harness_pull (h)); + gst_buffer_unref (gst_harness_pull (h)); + gst_buffer_unref (gst_harness_pull (h)); + gst_buffer_unref (gst_harness_pull (h)); + + /* verify rollover pts in the flvheader is handled */ + for (i = 0; i < G_N_ELEMENTS (input); i++) { + GstBuffer *buf = gst_harness_pull (h); + GstMapInfo map; + guint32 pts, pts_ext; + gst_buffer_map (buf, &map, GST_MAP_READ); + pts = GST_READ_UINT24_BE (map.data + 4); + pts_ext = GST_READ_UINT8 (map.data + 7); + pts |= pts_ext << 24; + GST_DEBUG ("media=%u, pts=%u (%" GST_TIME_FORMAT ")", + map.data[0], pts, GST_TIME_ARGS (pts * GST_MSECOND)); + fail_unless (pts == (guint32) input[i].ts); + gst_buffer_unmap (buf, &map); + gst_buffer_unref (buf); + } + + /* teardown */ + gst_object_unref (tclock); + gst_harness_teardown (h); + gst_harness_teardown (audio); + gst_harness_teardown (video); + gst_harness_teardown (audio_q); + gst_harness_teardown (video_q); +} + +GST_END_TEST; + static Suite * flvmux_suite (void) { @@ -1059,6 +1163,7 @@ flvmux_suite (void) tcase_add_test (tc_chain, test_audio_caps_change_streamable_single); tcase_add_test (tc_chain, test_video_caps_change_streamable_single); tcase_add_test (tc_chain, test_incrementing_timestamps); + tcase_add_test (tc_chain, test_rollover_timestamps); return s; } -- 2.7.4