1 #include <gst/check/check.h>
2 #include <gst/check/gstharness.h>
3 #include <gst/rtp/gstrtpbuffer.h>
4
5 #define H261_RTP_CAPS_STR \
6 "application/x-rtp,media=video,encoding-name=H261,clock-rate=90000,payload=31"
7
8 typedef struct _GstRtpH261PayHeader
9 {
10 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
11 unsigned int v:1; /* Motion vector flag */
12 unsigned int i:1; /* Intra encoded data */
13 unsigned int ebit:3; /* End position */
14 unsigned int sbit:3; /* Start position */
15
16 unsigned int mbap1:4; /* MB address predictor - part1 */
17 unsigned int gobn:4; /* GOB number */
18
19 unsigned int hmvd1:2; /* Horizontal motion vector data - part1 */
20 unsigned int quant:5; /* Quantizer */
21 unsigned int mbap2:1; /* MB address predictor - part2 */
22
23 unsigned int vmvd:5; /* Horizontal motion vector data - part1 */
24 unsigned int hmvd2:3; /* Vertical motion vector data */
25 #elif G_BYTE_ORDER == G_BIG_ENDIAN
26 unsigned int sbit:3; /* Start position */
27 unsigned int ebit:3; /* End position */
28 unsigned int i:1; /* Intra encoded data */
29 unsigned int v:1; /* Motion vector flag */
30
31 unsigned int gobn:4; /* GOB number */
32 unsigned int mbap1:4; /* MB address predictor - part1 */
33
34 unsigned int mbap2:1; /* MB address predictor - part2 */
35 unsigned int quant:5; /* Quantizer */
36 unsigned int hmvd1:2; /* Horizontal motion vector data - part1 */
37
38 unsigned int hmvd2:3; /* Vertical motion vector data */
39 unsigned int vmvd:5; /* Horizontal motion vector data - part1 */
40 #else
41 #error "G_BYTE_ORDER should be big or little endian."
42 #endif
43 } GstRtpH261PayHeader;
44
45 #define GST_RTP_H261_PAYLOAD_HEADER_LEN 4
46
47 static guint8 *
create_h261_payload(gint sbit,gint ebit,gint psc,gsize size)48 create_h261_payload (gint sbit, gint ebit, gint psc, gsize size)
49 {
50 GstRtpH261PayHeader header;
51 const gint header_len = 4;
52 guint8 *data = g_malloc0 (size);
53
54 memset (&header, 0x00, sizeof (header));
55
56 header.sbit = sbit;
57 header.ebit = ebit;
58
59 memset (data, 0xff, size);
60 memcpy (data, &header, header_len);
61
62 if (psc) {
63 guint32 word = 0x000100ff >> sbit;
64 data[header_len + 0] = (word >> 24) & 0xff;
65 data[header_len + 1] = (word >> 16) & 0xff;
66 data[header_len + 2] = (word >> 8) & 0xff;
67 data[header_len + 3] = (word >> 0) & 0xff;
68 }
69
70 return data;
71 }
72
73 static GstBuffer *
create_rtp_copy_payload(const guint8 * data,gsize size,guint ts,guint16 seq,gboolean marker,guint csrcs)74 create_rtp_copy_payload (const guint8 * data, gsize size, guint ts, guint16 seq,
75 gboolean marker, guint csrcs)
76 {
77 GstBuffer *buf = gst_rtp_buffer_new_allocate (size, 0, csrcs);
78 GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
79
80 gst_rtp_buffer_map (buf, GST_MAP_WRITE, &rtp);
81
82 gst_rtp_buffer_set_seq (&rtp, seq);
83 gst_rtp_buffer_set_marker (&rtp, marker);
84 memcpy (gst_rtp_buffer_get_payload (&rtp), data, size);
85
86 GST_BUFFER_PTS (buf) = (ts) * (GST_SECOND / 30);
87 GST_BUFFER_DURATION (buf) = (GST_SECOND / 30);
88
89 gst_rtp_buffer_unmap (&rtp);
90
91 return buf;
92 }
93
GST_START_TEST(test_h263depay_empty_payload)94 GST_START_TEST (test_h263depay_empty_payload)
95 {
96 GstHarness *h = gst_harness_new ("rtph261depay");
97 gint sbit = 4;
98 gint ebit = 4;
99 gsize size;
100 guint8 *payload;
101 guint seq = 0;
102
103 gst_harness_set_src_caps_str (h, H261_RTP_CAPS_STR);
104
105 /* First send a proper packet with picture start code */
106 size = 100;
107 payload = create_h261_payload (sbit, ebit, TRUE, size);
108 gst_harness_push (h, create_rtp_copy_payload (payload, size, 0, seq++, FALSE,
109 0));
110 g_free (payload);
111
112 /* Not a complete frame */
113 fail_unless_equals_int (gst_harness_buffers_received (h), 0);
114
115 /* Second buffer has invalid empty payload */
116 size = GST_RTP_H261_PAYLOAD_HEADER_LEN;
117 payload = create_h261_payload (sbit, ebit, FALSE, size);
118 gst_harness_push (h, create_rtp_copy_payload (payload, size, 0, seq++, TRUE,
119 0));
120 g_free (payload);
121
122 /* Invalid payload should be dropped */
123 fail_unless_equals_int (gst_harness_buffers_received (h), 0);
124
125 gst_harness_teardown (h);
126 }
127
128 GST_END_TEST;
129
130 static Suite *
rtph261_suite(void)131 rtph261_suite (void)
132 {
133 Suite *s = suite_create ("rtph261");
134 TCase *tc_chain;
135
136 suite_add_tcase (s, (tc_chain = tcase_create ("h261depay")));
137 tcase_add_test (tc_chain, test_h263depay_empty_payload);
138
139 return s;
140 }
141
142 GST_CHECK_MAIN (rtph261);
143