tests: Add the tests for CRF Checker element

This adds tests to ensure the avtpcrfchecker element validates and drops the
packets which do not match the CRF Synchronization criteria.
This commit is contained in:
Vedang Patel 2019-09-26 18:11:42 -07:00 committed by vedangpatel1
parent da810db63d
commit 4b6a290beb
2 changed files with 248 additions and 0 deletions

View file

@ -0,0 +1,247 @@
/*
* GStreamer AVTP Plugin
* Copyright (C) 2019 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later
* version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#include <avtp.h>
#include <avtp_crf.h>
#include <avtp_aaf.h>
#include <avtp_cvf.h>
#include <gst/check/gstcheck.h>
#include <gst/check/gstharness.h>
#include "../../../ext/avtp/gstavtpcrfutil.h"
#define STREAM_ID 0xDEADC0DEDEADC0DE
static GstHarness *
setup_harness (void)
{
GstHarness *h;
h = gst_harness_new_parse
("avtpcrfcheck streamid=0xDEADC0DEDEADC0DE drop_invalid=1");
if (!h)
GST_ERROR ("Cannot create harness!");
gst_harness_set_src_caps_str (h, "application/x-avtp");
return h;
}
static void
fill_buffer_video_data (struct avtp_stream_pdu *pdu)
{
const gint DATA_LEN = sizeof (guint32) + 3;
avtp_cvf_pdu_init (pdu, AVTP_CVF_FORMAT_SUBTYPE_H264);
avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_ID, STREAM_ID);
avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TV, 1);
avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 1);
avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TIMESTAMP, 0);
avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_PTV, 1);
avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_TIMESTAMP, 0);
avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN);
}
static void
fill_buffer_audio_data (struct avtp_stream_pdu *pdu)
{
const int DATA_LEN = 4;
avtp_aaf_pdu_init (pdu);
avtp_aaf_pdu_set (pdu, AVTP_AAF_FIELD_TV, 1);
avtp_aaf_pdu_set (pdu, AVTP_AAF_FIELD_STREAM_ID, 0xDEADC0DEDEADC0DE);
avtp_aaf_pdu_set (pdu, AVTP_AAF_FIELD_FORMAT, AVTP_AAF_FORMAT_INT_16BIT);
avtp_aaf_pdu_set (pdu, AVTP_AAF_FIELD_NSR, AVTP_AAF_PCM_NSR_48KHZ);
avtp_aaf_pdu_set (pdu, AVTP_AAF_FIELD_CHAN_PER_FRAME, 2);
avtp_aaf_pdu_set (pdu, AVTP_AAF_FIELD_BIT_DEPTH, 16);
avtp_aaf_pdu_set (pdu, AVTP_AAF_FIELD_SP, AVTP_AAF_PCM_SP_NORMAL);
avtp_aaf_pdu_set (pdu, AVTP_AAF_FIELD_TIMESTAMP, 0);
avtp_aaf_pdu_set (pdu, AVTP_AAF_FIELD_STREAM_DATA_LEN, DATA_LEN);
}
static GstBuffer *
create_input_buffer (GstHarness * h, guint32 subtype)
{
struct avtp_stream_pdu *pdu;
GstMapInfo info;
GstBuffer *buf;
const gint DATA_LEN = sizeof (guint32) + 3;
buf = gst_harness_create_buffer (h, sizeof (struct avtp_stream_pdu) +
DATA_LEN);
gst_buffer_map (buf, &info, GST_MAP_WRITE);
pdu = (struct avtp_stream_pdu *) info.data;
if (subtype == AVTP_SUBTYPE_AAF)
fill_buffer_audio_data (pdu);
else
fill_buffer_video_data (pdu);
gst_buffer_unmap (buf, &info);
return buf;
}
static void
set_buffer_tstamps (GstBuffer * buf, GstClockTime avtp_tstamp,
GstClockTime h264_tstamp)
{
struct avtp_stream_pdu *pdu;
GstMapInfo info;
guint32 type;
gst_buffer_map (buf, &info, GST_MAP_WRITE);
pdu = (struct avtp_stream_pdu *) info.data;
avtp_pdu_get ((struct avtp_common_pdu *) pdu, AVTP_FIELD_SUBTYPE, &type);
if (type == AVTP_SUBTYPE_AAF)
avtp_aaf_pdu_set (pdu, AVTP_AAF_FIELD_TIMESTAMP, avtp_tstamp);
else if (type == AVTP_SUBTYPE_CVF) {
avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TIMESTAMP, avtp_tstamp);
avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_TIMESTAMP, h264_tstamp);
}
gst_buffer_unmap (buf, &info);
}
static void
test_crf_tstamps (GstHarness * h, GstBuffer * buf, GstClockTime avtp_tstamp,
GstClockTime h264_tstamp, guint expected_buffers)
{
set_buffer_tstamps (buf, avtp_tstamp, h264_tstamp);
gst_harness_push (h, gst_buffer_copy (buf));
fail_unless_equals_uint64 (gst_harness_buffers_received (h),
expected_buffers);
}
GST_START_TEST (test_properties)
{
const guint64 streamid = 0xAABBCCDDEEFF0001;
const gchar *address = "01:AA:BB:CC:DD:EE";
const gchar *ifname = "enp1s0";
const gboolean drop_invalid = TRUE;
GstElement *element;
guint64 val64;
gboolean val;
gchar *str;
element = gst_check_setup_element ("avtpcrfcheck");
g_object_set (G_OBJECT (element), "ifname", ifname, NULL);
g_object_get (G_OBJECT (element), "ifname", &str, NULL);
fail_unless_equals_string (str, ifname);
g_free (str);
g_object_set (G_OBJECT (element), "address", address, NULL);
g_object_get (G_OBJECT (element), "address", &str, NULL);
fail_unless_equals_string (str, address);
g_free (str);
g_object_set (G_OBJECT (element), "streamid", streamid, NULL);
g_object_get (G_OBJECT (element), "streamid", &val64, NULL);
fail_unless (val64 == streamid);
g_object_set (G_OBJECT (element), "drop-invalid", drop_invalid, NULL);
g_object_get (G_OBJECT (element), "drop-invalid", &val, NULL);
fail_unless (val == drop_invalid);
}
GST_END_TEST;
GST_START_TEST (test_crf_cvf_data)
{
GstAvtpCrfBase *avtpcrfbase;
GstBuffer *buf;
GstHarness *h;
h = setup_harness ();
buf = create_input_buffer (h, AVTP_SUBTYPE_CVF);
avtpcrfbase = (GstAvtpCrfBase *) gst_harness_find_element (h, "avtpcrfcheck");
avtpcrfbase->thread_data.average_period = 3300;
avtpcrfbase->thread_data.current_ts = 110000;
test_crf_tstamps (h, buf, 110000, 109204, 1);
test_crf_tstamps (h, buf, 113600, 119400, 2);
test_crf_tstamps (h, buf, 218000, 119400, 2);
test_crf_tstamps (h, buf, 218000, 102000, 2);
gst_harness_teardown (h);
}
GST_END_TEST;
GST_START_TEST (test_crf_aaf_data)
{
GstAvtpCrfBase *avtpcrfbase;
GstBuffer *buf;
GstHarness *h;
h = setup_harness ();
buf = create_input_buffer (h, AVTP_SUBTYPE_AAF);
avtpcrfbase = (GstAvtpCrfBase *) gst_harness_find_element (h, "avtpcrfcheck");
avtpcrfbase->thread_data.average_period = 3300;
avtpcrfbase->thread_data.current_ts = 110000;
test_crf_tstamps (h, buf, 113300, 0, 1);
test_crf_tstamps (h, buf, 112900, 0, 2);
test_crf_tstamps (h, buf, 210000, 0, 2);
gst_harness_teardown (h);
}
GST_END_TEST;
GST_START_TEST (test_crf_period_zero)
{
GstAvtpCrfBase *avtpcrfbase;
GstBuffer *buf;
GstHarness *h;
h = setup_harness ();
buf = create_input_buffer (h, AVTP_SUBTYPE_CVF);
avtpcrfbase = (GstAvtpCrfBase *) gst_harness_find_element (h, "avtpcrfcheck");
avtpcrfbase->thread_data.average_period = 0.0;
avtpcrfbase->thread_data.current_ts = 110;
test_crf_tstamps (h, buf, 112, 110, 1);
gst_harness_teardown (h);
}
GST_END_TEST;
static Suite *
avtpcrfcheck_suite (void)
{
Suite *s = suite_create ("avtpcrfcheck");
TCase *tc_chain = tcase_create ("general");
suite_add_tcase (s, tc_chain);
tcase_add_test (tc_chain, test_properties);
tcase_add_test (tc_chain, test_crf_cvf_data);
tcase_add_test (tc_chain, test_crf_aaf_data);
tcase_add_test (tc_chain, test_crf_period_zero);
return s;
}
GST_CHECK_MAIN (avtpcrfcheck);

View file

@ -82,6 +82,7 @@ if host_machine.system() != 'windows'
[['elements/avtpaafpay.c'], not avtp_dep.found(), [avtp_dep]],
[['elements/avtpaafdepay.c'], not avtp_dep.found(), [avtp_dep]],
[['elements/avtpcrfbase.c'], not avtp_dep.found(), [avtp_dep]],
[['elements/avtpcrfcheck.c'], not avtp_dep.found(), [avtp_dep], ['../../ext/avtp/gstavtpcrfutil.c']],
[['elements/avtpcrfsync.c'], not avtp_dep.found(), [avtp_dep], ['../../ext/avtp/gstavtpcrfutil.c', '../../ext/avtp/gstavtpcrfbase.c']],
[['elements/avtpcvfpay.c'], not avtp_dep.found(), [avtp_dep]],
[['elements/avtpcvfdepay.c'], not avtp_dep.found(), [avtp_dep]],