Commit 4df3669c authored by Tim-Philipp Müller's avatar Tim-Philipp Müller

tests: rtp-payloading: add test for rtph264depay avc/byte-stream output

Make sure avc output doesn't contain SPS/PPS inline, but
byte-stream output does.
parent e7e7f262
......@@ -483,8 +483,8 @@ elements_rglimiter_LDADD = $(GST_PLUGINS_BASE_LIBS) -lgstaudio-$(GST_API_VERSION
elements_rgvolume_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(CFLAGS) $(AM_CFLAGS)
elements_rgvolume_LDADD = $(GST_PLUGINS_BASE_LIBS) -lgstaudio-$(GST_API_VERSION) $(LDADD) $(LIBM)
elements_rtp_payloading_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(CFLAGS) $(AM_CFLAGS)
elements_rtp_payloading_LDADD = $(GST_PLUGINS_BASE_LIBS) -lgstaudio-$(GST_API_VERSION) $(LDADD)
elements_rtp_payloading_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(CFLAGS) $(AM_CFLAGS)
elements_rtp_payloading_LDADD = $(GST_PLUGINS_BASE_LIBS) -lgstaudio-$(GST_API_VERSION) $(GST_BASE_LIBS) $(LDADD)
elements_spectrum_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(CFLAGS) $(AM_CFLAGS)
elements_spectrum_LDADD = $(GST_PLUGINS_BASE_LIBS) -lgstaudio-$(GST_API_VERSION) $(LDADD)
......
......@@ -20,6 +20,7 @@
#include <gst/check/gstcheck.h>
#include <gst/check/gstharness.h>
#include <gst/audio/audio.h>
#include <gst/base/base.h>
#include <stdlib.h>
#include <unistd.h>
......@@ -650,6 +651,174 @@ GST_START_TEST (rtp_h264)
}
GST_END_TEST;
/* H264 data generated with:
* videotestsrc pattern=black ! video/x-raw,width=16,height=16 ! openh264enc */
static const guint8 h264_16x16_black_bs[] = {
0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0xd0, 0x0b,
0x8c, 0x8d, 0x4e, 0x40, 0x3c, 0x22, 0x11, 0xa8,
0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x3c, 0x80,
0x00, 0x00, 0x00, 0x01, 0x65, 0xb8, 0x00, 0x04,
0x00, 0x00, 0x09, 0xe4, 0xc5, 0x00, 0x01, 0x19,
0xfc
};
static GstSample *
rtp_h264depay_run (const gchar * stream_format)
{
GstHarness *h;
GstSample *sample;
GstBuffer *buf;
GstEvent *e;
GstCaps *out_caps;
GstCaps *in_caps;
gboolean seen_caps = FALSE;
gsize size;
h = gst_harness_new_parse ("rtph264pay ! rtph264depay");
/* Our input data is in byte-stream format (not that it matters) */
in_caps = gst_caps_new_simple ("video/x-h264",
"stream-format", G_TYPE_STRING, "byte-stream",
"alignment", G_TYPE_STRING, "au",
"profile", G_TYPE_STRING, "baseline",
"width", G_TYPE_INT, 16,
"height", G_TYPE_INT, 16, "framerate", GST_TYPE_FRACTION, 30, 1, NULL);
/* Force rtph264depay to output format as requested */
out_caps = gst_caps_new_simple ("video/x-h264",
"stream-format", G_TYPE_STRING, stream_format,
"alignment", G_TYPE_STRING, "au", NULL);
gst_harness_set_caps (h, in_caps, out_caps);
in_caps = NULL;
out_caps = NULL;
gst_harness_play (h);
size = sizeof (h264_16x16_black_bs);
buf = gst_buffer_new_wrapped (g_memdup (h264_16x16_black_bs, size), size);
fail_unless_equals_int (gst_harness_push (h, buf), GST_FLOW_OK);
fail_unless (gst_harness_push_event (h, gst_event_new_eos ()));
while ((e = gst_harness_try_pull_event (h))) {
if (GST_EVENT_TYPE (e) == GST_EVENT_CAPS) {
GstCaps *caps = NULL;
gst_event_parse_caps (e, &caps);
gst_caps_replace (&out_caps, caps);
seen_caps = TRUE;
}
gst_event_unref (e);
}
fail_unless (seen_caps);
buf = gst_harness_pull (h);
sample = gst_sample_new (buf, out_caps, NULL, NULL);
gst_buffer_unref (buf);
gst_caps_replace (&out_caps, NULL);
gst_harness_teardown (h);
return sample;
}
GST_START_TEST (rtp_h264depay_avc)
{
const GValue *val;
GstStructure *st;
GstMapInfo map = GST_MAP_INFO_INIT;
GstBuffer *buf;
GstSample *s;
GstCaps *caps;
s = rtp_h264depay_run ("avc");
/* must have codec_data in output caps */
caps = gst_sample_get_caps (s);
st = gst_caps_get_structure (caps, 0);
GST_LOG ("caps: %" GST_PTR_FORMAT, caps);
fail_unless (gst_structure_has_field (st, "stream-format"));
fail_unless (gst_structure_has_field (st, "alignment"));
fail_unless (gst_structure_has_field (st, "level"));
fail_unless (gst_structure_has_field (st, "profile"));
val = gst_structure_get_value (st, "codec_data");
fail_unless (val != NULL);
buf = gst_sample_get_buffer (s);
fail_unless (gst_buffer_map (buf, &map, GST_MAP_READ));
GST_MEMDUMP ("H.264 AVC frame", map.data, map.size);
fail_unless (map.size >= 4 + 13);
/* Want IDR slice as very first thing.
* We assume nal size markers are 4 bytes here. */
fail_unless_equals_int (map.data[4] & 0x1f, 5);
gst_buffer_unmap (buf, &map);
gst_sample_unref (s);
}
GST_END_TEST;
GST_START_TEST (rtp_h264depay_bytestream)
{
GstByteReader br;
GstStructure *st;
GstMapInfo map = GST_MAP_INFO_INIT;
GstBuffer *buf;
GstSample *s;
GstCaps *caps;
guint32 dw;
guint8 b;
guint off, left;
s = rtp_h264depay_run ("byte-stream");
/* must not have codec_data in output caps */
caps = gst_sample_get_caps (s);
st = gst_caps_get_structure (caps, 0);
GST_LOG ("caps: %" GST_PTR_FORMAT, caps);
fail_if (gst_structure_has_field (st, "codec_data"));
buf = gst_sample_get_buffer (s);
fail_unless (gst_buffer_map (buf, &map, GST_MAP_READ));
GST_MEMDUMP ("H.264 byte-stream frame", map.data, map.size);
fail_unless (map.size > 40);
gst_byte_reader_init (&br, map.data, map.size);
/* We assume nal sync markers are 4 bytes... */
fail_unless (gst_byte_reader_get_uint32_be (&br, &dw));
fail_unless_equals_int (dw, 0x00000001);
/* Want SPS as very first thing */
fail_unless (gst_byte_reader_get_uint8 (&br, &b));
fail_unless_equals_int (b & 0x1f, 7);
/* Then, we want the PPS */
left = gst_byte_reader_get_remaining (&br);
off = gst_byte_reader_masked_scan_uint32 (&br, 0xffffffff, 1, 0, left);
fail_if (off == (guint) - 1);
gst_byte_reader_skip (&br, off + 4);
fail_unless (gst_byte_reader_get_uint8 (&br, &b));
fail_unless_equals_int (b & 0x1f, 8);
/* FIXME: looks like we get two sets of SPS/PPS ?! */
left = gst_byte_reader_get_remaining (&br);
off = gst_byte_reader_masked_scan_uint32 (&br, 0xffffffff, 1, 0, left);
fail_if (off == (guint) - 1);
gst_byte_reader_skip (&br, off + 4);
left = gst_byte_reader_get_remaining (&br);
off = gst_byte_reader_masked_scan_uint32 (&br, 0xffffffff, 1, 0, left);
fail_if (off == (guint) - 1);
gst_byte_reader_skip (&br, off + 4);
/* Finally, we want an IDR slice */
left = gst_byte_reader_get_remaining (&br);
off = gst_byte_reader_masked_scan_uint32 (&br, 0xffffffff, 1, 0, left);
fail_if (off == (guint) - 1);
gst_byte_reader_skip (&br, off + 4);
fail_unless (gst_byte_reader_get_uint8 (&br, &b));
fail_unless_equals_int (b & 0x1f, 5);
gst_buffer_unmap (buf, &map);
gst_sample_unref (s);
}
GST_END_TEST;
static const guint8 rtp_h264_list_lt_mtu_frame_data[] =
/* not packetized, next NAL starts with 0001 */
{ 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
......@@ -1446,6 +1615,8 @@ rtp_payloading_suite (void)
tcase_add_test (tc_chain, rtp_h263);
tcase_add_test (tc_chain, rtp_h263p);
tcase_add_test (tc_chain, rtp_h264);
tcase_add_test (tc_chain, rtp_h264depay_avc);
tcase_add_test (tc_chain, rtp_h264depay_bytestream);
tcase_add_test (tc_chain, rtp_h264_list_lt_mtu);
tcase_add_test (tc_chain, rtp_h264_list_lt_mtu_avc);
tcase_add_test (tc_chain, rtp_h264_list_gt_mtu);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment