videoencoder: Add test for correct force-keyunit event handling

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/684>
This commit is contained in:
Sebastian Dröge 2020-06-03 20:49:12 +03:00 committed by GStreamer Merge Bot
parent 01eecc69bd
commit 931b5ad996

View file

@ -917,6 +917,177 @@ GST_START_TEST (videoencoder_playback_events_subframes)
GST_END_TEST;
GST_START_TEST (videoencoder_force_keyunit_handling)
{
GstSegment segment;
GstBuffer *buffer;
GList *l;
gint i;
setup_videoencodertester ();
gst_pad_set_active (mysrcpad, TRUE);
gst_element_set_state (enc, GST_STATE_PLAYING);
gst_pad_set_active (mysinkpad, TRUE);
send_startup_events ();
/* push a new segment */
gst_segment_init (&segment, GST_FORMAT_TIME);
fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
/* push the first buffer */
buffer = create_test_buffer (0);
fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
buffer = NULL;
fail_unless_equals_int (g_list_length (buffers), 1);
buffer = create_test_buffer (1);
fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
buffer = NULL;
fail_unless_equals_int (g_list_length (buffers), 2);
/* send a force-keyunit event, the next buffer should be a keyframe now */
fail_unless (gst_pad_push_event (mysinkpad,
gst_video_event_new_upstream_force_key_unit (GST_CLOCK_TIME_NONE,
TRUE, 1)));
buffer = create_test_buffer (2);
fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
buffer = NULL;
fail_unless_equals_int (g_list_length (buffers), 3);
buffer = create_test_buffer (3);
fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
buffer = NULL;
fail_unless_equals_int (g_list_length (buffers), 4);
/* send multiple force-keyunit events now, this should still only cause a
* single keyframe */
fail_unless (gst_pad_push_event (mysinkpad,
gst_video_event_new_upstream_force_key_unit (GST_CLOCK_TIME_NONE,
TRUE, 1)));
fail_unless (gst_pad_push_event (mysinkpad,
gst_video_event_new_upstream_force_key_unit (GST_CLOCK_TIME_NONE,
TRUE, 1)));
buffer = create_test_buffer (4);
fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
buffer = NULL;
fail_unless_equals_int (g_list_length (buffers), 5);
buffer = create_test_buffer (5);
fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
buffer = NULL;
fail_unless_equals_int (g_list_length (buffers), 6);
/* send a force-keyunit event for the running time of the next buffer */
fail_unless (gst_pad_push_event (mysinkpad,
gst_video_event_new_upstream_force_key_unit
(gst_util_uint64_scale_round (6, GST_SECOND * TEST_VIDEO_FPS_D,
TEST_VIDEO_FPS_N), TRUE, 1)));
buffer = create_test_buffer (6);
fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
buffer = NULL;
fail_unless_equals_int (g_list_length (buffers), 7);
buffer = create_test_buffer (7);
fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
buffer = NULL;
fail_unless_equals_int (g_list_length (buffers), 8);
/* send a force-keyunit event for the running time of the next buffer
* and another one right before. This should only cause a single keyframe
* again */
fail_unless (gst_pad_push_event (mysinkpad,
gst_video_event_new_upstream_force_key_unit
(gst_util_uint64_scale_round (8, GST_SECOND * TEST_VIDEO_FPS_D,
TEST_VIDEO_FPS_N), TRUE, 1)));
fail_unless (gst_pad_push_event (mysinkpad,
gst_video_event_new_upstream_force_key_unit
(gst_util_uint64_scale_round (8, GST_SECOND * TEST_VIDEO_FPS_D,
TEST_VIDEO_FPS_N) - 10 * GST_MSECOND, TRUE, 1)));
buffer = create_test_buffer (8);
fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
buffer = NULL;
fail_unless_equals_int (g_list_length (buffers), 9);
buffer = create_test_buffer (9);
fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
buffer = NULL;
fail_unless_equals_int (g_list_length (buffers), 10);
/* send a force-keyunit event for the 12th buffer, see below */
fail_unless (gst_pad_push_event (mysinkpad,
gst_video_event_new_upstream_force_key_unit
(gst_util_uint64_scale_round (12, GST_SECOND * TEST_VIDEO_FPS_D,
TEST_VIDEO_FPS_N), TRUE, 1)));
/* send two force-keyunit events. This should only cause a single keyframe
* again */
fail_unless (gst_pad_push_event (mysinkpad,
gst_video_event_new_upstream_force_key_unit
(gst_util_uint64_scale_round (10, GST_SECOND * TEST_VIDEO_FPS_D,
TEST_VIDEO_FPS_N), TRUE, 1)));
fail_unless (gst_pad_push_event (mysinkpad,
gst_video_event_new_upstream_force_key_unit
(gst_util_uint64_scale_round (10, GST_SECOND * TEST_VIDEO_FPS_D,
TEST_VIDEO_FPS_N) - 10 * GST_MSECOND, TRUE, 1)));
buffer = create_test_buffer (10);
fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
buffer = NULL;
fail_unless_equals_int (g_list_length (buffers), 11);
buffer = create_test_buffer (11);
fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
buffer = NULL;
fail_unless_equals_int (g_list_length (buffers), 12);
/* we already sent a force-keyunit event for the 12th buffer long ago */
buffer = create_test_buffer (12);
fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
buffer = NULL;
fail_unless_equals_int (g_list_length (buffers), 13);
buffer = create_test_buffer (13);
fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
buffer = NULL;
fail_unless_equals_int (g_list_length (buffers), 14);
/* every second buffer should be a keyframe */
for (l = buffers, i = 0; l; l = l->next, i++) {
if (i % 2 == 0)
fail_if (GST_BUFFER_FLAG_IS_SET (l->data, GST_BUFFER_FLAG_DELTA_UNIT));
else
fail_unless (GST_BUFFER_FLAG_IS_SET (l->data,
GST_BUFFER_FLAG_DELTA_UNIT));
}
g_list_free_full (buffers, (GDestroyNotify) gst_buffer_unref);
buffers = NULL;
cleanup_videoencodertest ();
}
GST_END_TEST;
static Suite *
gst_videoencoder_suite (void)
{
@ -933,6 +1104,7 @@ gst_videoencoder_suite (void)
tcase_add_test (tc, videoencoder_qos);
tcase_add_test (tc, videoencoder_playback_subframes);
tcase_add_test (tc, videoencoder_playback_events_subframes);
tcase_add_test (tc, videoencoder_force_keyunit_handling);
return s;
}