• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GStreamer RTP H.264 unit test
2  *
3  * Copyright (C) 2017 Centricular Ltd
4  *   @author: Tim-Philipp Müller <tim@centricular.com>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24 
25 #include <gst/check/check.h>
26 #include <gst/app/app.h>
27 #include <gst/rtp/gstrtpbuffer.h>
28 
29 #define ALLOCATOR_CUSTOM_SYSMEM "CustomSysMem"
30 
31 static GstAllocator *custom_sysmem_allocator;   /* NULL */
32 
33 /* Custom memory */
34 
35 typedef struct
36 {
37   GstMemory mem;
38   guint8 *data;
39   guint8 *allocdata;
40 } CustomSysmem;
41 
42 static CustomSysmem *
custom_sysmem_new(GstMemoryFlags flags,gsize maxsize,gsize align,gsize offset,gsize size)43 custom_sysmem_new (GstMemoryFlags flags, gsize maxsize, gsize align,
44     gsize offset, gsize size)
45 {
46   gsize aoffset, padding;
47   CustomSysmem *mem;
48 
49   /* ensure configured alignment */
50   align |= gst_memory_alignment;
51   /* allocate more to compensate for alignment */
52   maxsize += align;
53 
54   mem = g_new0 (CustomSysmem, 1);
55 
56   mem->allocdata = g_malloc (maxsize);
57 
58   mem->data = mem->allocdata;
59 
60   /* do alignment */
61   if ((aoffset = ((guintptr) mem->data & align))) {
62     aoffset = (align + 1) - aoffset;
63     mem->data += aoffset;
64     maxsize -= aoffset;
65   }
66 
67   if (offset && (flags & GST_MEMORY_FLAG_ZERO_PREFIXED))
68     memset (mem->data, 0, offset);
69 
70   padding = maxsize - (offset + size);
71   if (padding && (flags & GST_MEMORY_FLAG_ZERO_PADDED))
72     memset (mem->data + offset + size, 0, padding);
73 
74   gst_memory_init (GST_MEMORY_CAST (mem), flags, custom_sysmem_allocator,
75       NULL, maxsize, align, offset, size);
76 
77   return mem;
78 }
79 
80 static gpointer
custom_sysmem_map(CustomSysmem * mem,gsize maxsize,GstMapFlags flags)81 custom_sysmem_map (CustomSysmem * mem, gsize maxsize, GstMapFlags flags)
82 {
83   return mem->data;
84 }
85 
86 static gboolean
custom_sysmem_unmap(CustomSysmem * mem)87 custom_sysmem_unmap (CustomSysmem * mem)
88 {
89   return TRUE;
90 }
91 
92 static CustomSysmem *
custom_sysmem_copy(CustomSysmem * mem,gssize offset,gsize size)93 custom_sysmem_copy (CustomSysmem * mem, gssize offset, gsize size)
94 {
95   g_return_val_if_reached (NULL);
96 }
97 
98 static CustomSysmem *
custom_sysmem_share(CustomSysmem * mem,gssize offset,gsize size)99 custom_sysmem_share (CustomSysmem * mem, gssize offset, gsize size)
100 {
101   g_return_val_if_reached (NULL);
102 }
103 
104 static gboolean
custom_sysmem_is_span(CustomSysmem * mem1,CustomSysmem * mem2,gsize * offset)105 custom_sysmem_is_span (CustomSysmem * mem1, CustomSysmem * mem2, gsize * offset)
106 {
107   g_return_val_if_reached (FALSE);
108 }
109 
110 /* Custom allocator */
111 
112 typedef struct
113 {
114   GstAllocator allocator;
115 } CustomSysmemAllocator;
116 
117 typedef struct
118 {
119   GstAllocatorClass allocator_class;
120 } CustomSysmemAllocatorClass;
121 
122 GType custom_sysmem_allocator_get_type (void);
123 G_DEFINE_TYPE (CustomSysmemAllocator, custom_sysmem_allocator,
124     GST_TYPE_ALLOCATOR);
125 
126 static GstMemory *
custom_sysmem_allocator_alloc(GstAllocator * allocator,gsize size,GstAllocationParams * params)127 custom_sysmem_allocator_alloc (GstAllocator * allocator, gsize size,
128     GstAllocationParams * params)
129 {
130   gsize maxsize = size + params->prefix + params->padding;
131 
132   return (GstMemory *) custom_sysmem_new (params->flags,
133       maxsize, params->align, params->prefix, size);
134 }
135 
136 static void
custom_sysmem_allocator_free(GstAllocator * allocator,GstMemory * mem)137 custom_sysmem_allocator_free (GstAllocator * allocator, GstMemory * mem)
138 {
139   CustomSysmem *csmem = (CustomSysmem *) mem;
140 
141   g_free (csmem->allocdata);
142   g_free (csmem);
143 }
144 
145 static void
custom_sysmem_allocator_class_init(CustomSysmemAllocatorClass * klass)146 custom_sysmem_allocator_class_init (CustomSysmemAllocatorClass * klass)
147 {
148   GstAllocatorClass *allocator_class = (GstAllocatorClass *) klass;
149 
150   allocator_class->alloc = custom_sysmem_allocator_alloc;
151   allocator_class->free = custom_sysmem_allocator_free;
152 }
153 
154 static void
custom_sysmem_allocator_init(CustomSysmemAllocator * allocator)155 custom_sysmem_allocator_init (CustomSysmemAllocator * allocator)
156 {
157   GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator);
158 
159   alloc->mem_type = ALLOCATOR_CUSTOM_SYSMEM;
160   alloc->mem_map = (GstMemoryMapFunction) custom_sysmem_map;
161   alloc->mem_unmap = (GstMemoryUnmapFunction) custom_sysmem_unmap;
162   alloc->mem_copy = (GstMemoryCopyFunction) custom_sysmem_copy;
163   alloc->mem_share = (GstMemoryShareFunction) custom_sysmem_share;
164   alloc->mem_is_span = (GstMemoryIsSpanFunction) custom_sysmem_is_span;
165 }
166 
167 /* AppSink subclass proposing our custom allocator to upstream */
168 
169 typedef struct
170 {
171   GstAppSink appsink;
172 } CMemAppSink;
173 
174 typedef struct
175 {
176   GstAppSinkClass appsink;
177 } CMemAppSinkClass;
178 
179 GType c_mem_app_sink_get_type (void);
180 
181 G_DEFINE_TYPE (CMemAppSink, c_mem_app_sink, GST_TYPE_APP_SINK);
182 
183 static void
c_mem_app_sink_init(CMemAppSink * cmemsink)184 c_mem_app_sink_init (CMemAppSink * cmemsink)
185 {
186 }
187 
188 static gboolean
c_mem_app_sink_propose_allocation(GstBaseSink * sink,GstQuery * query)189 c_mem_app_sink_propose_allocation (GstBaseSink * sink, GstQuery * query)
190 {
191   gst_query_add_allocation_param (query, custom_sysmem_allocator, NULL);
192   return TRUE;
193 }
194 
195 static void
c_mem_app_sink_class_init(CMemAppSinkClass * klass)196 c_mem_app_sink_class_init (CMemAppSinkClass * klass)
197 {
198   GstBaseSinkClass *basesink_class = (GstBaseSinkClass *) klass;
199 
200   basesink_class->propose_allocation = c_mem_app_sink_propose_allocation;
201 }
202 
203 #define RTP_H264_FILE GST_TEST_FILES_PATH G_DIR_SEPARATOR_S "h264.rtp"
204 
205 static GstBuffer *
create_codec_data(guint8 * sps,gsize sps_size,guint8 * pps,gsize pps_size)206 create_codec_data (guint8 * sps, gsize sps_size, guint8 * pps, gsize pps_size)
207 {
208   unsigned int offset = 0;
209   GstBuffer *codec_data_buffer;
210   GstMemory *mem;
211   GstMapInfo map_info;
212   guint8 *codec_data;
213 
214   codec_data_buffer =
215       gst_buffer_new_allocate (NULL, sps_size + pps_size + 11, NULL);
216   mem = gst_buffer_peek_memory (codec_data_buffer, 0);
217   gst_memory_map (mem, &map_info, GST_MAP_WRITE);
218 
219   codec_data = map_info.data;
220 
221   codec_data[offset++] = 0x01;  /* Configuration Version */
222   codec_data[offset++] = sps[1];        /* AVCProfileIndication */
223   codec_data[offset++] = sps[2];        /* profile_compatibility */
224   codec_data[offset++] = sps[3];        /* AVCLevelIndication */
225   codec_data[offset++] = 0xff;  /* lengthSizeMinusOne == 3 -> length == 4 byte */
226 
227   /* SPS */
228   codec_data[offset++] = 0xe1;  /* numOfSequenceParameterSets | b11100000 -> numSPS == 1 */
229 
230   g_assert (sps_size <= 0xffff);
231   codec_data[offset++] = (sps_size >> 8) & 0xff;        /* numOfSequenceParameterSets high 8bit */
232   codec_data[offset++] = sps_size & 0xff;       /* numOfSequenceParameterSets low 8bit */
233   memcpy (codec_data + offset, sps, sps_size);
234   offset += sps_size;
235 
236   /* PPS */
237   codec_data[offset++] = 0x1;   /* numOfPictureParameterSets == 1 */
238 
239   g_assert (pps_size <= 0xffff);
240   codec_data[offset++] = (pps_size >> 8) & 0xff;
241   codec_data[offset++] = pps_size & 0xff;
242   memcpy (codec_data + offset, pps, pps_size);
243   offset += pps_size;
244 
245   gst_memory_unmap (mem, &map_info);
246 
247   g_assert (offset == gst_buffer_get_size (codec_data_buffer));
248 
249   return codec_data_buffer;
250 }
251 
GST_START_TEST(test_rtph264depay_with_downstream_allocator)252 GST_START_TEST (test_rtph264depay_with_downstream_allocator)
253 {
254   GstElement *pipeline, *src, *depay, *sink;
255   GstMemory *mem;
256   GstSample *sample;
257   GstBuffer *buf;
258   GstCaps *caps;
259 
260   custom_sysmem_allocator =
261       g_object_new (custom_sysmem_allocator_get_type (), NULL);
262 
263   pipeline = gst_pipeline_new ("pipeline");
264 
265   src = gst_element_factory_make ("appsrc", NULL);
266 
267   caps = gst_caps_new_simple ("application/x-rtp",
268       "media", G_TYPE_STRING, "video",
269       "payload", G_TYPE_INT, 96,
270       "clock-rate", G_TYPE_INT, 90000,
271       "encoding-name", G_TYPE_STRING, "H264",
272       "ssrc", G_TYPE_UINT, 1990683810,
273       "timestamp-offset", G_TYPE_UINT, 3697583446UL,
274       "seqnum-offset", G_TYPE_UINT, 15568,
275       "a-framerate", G_TYPE_STRING, "30", NULL);
276   g_object_set (src, "format", GST_FORMAT_TIME, "caps", caps, NULL);
277   gst_bin_add (GST_BIN (pipeline), src);
278   gst_caps_unref (caps);
279 
280   depay = gst_element_factory_make ("rtph264depay", NULL);
281   gst_bin_add (GST_BIN (pipeline), depay);
282 
283   sink = g_object_new (c_mem_app_sink_get_type (), NULL);
284   gst_bin_add (GST_BIN (pipeline), sink);
285 
286   gst_element_link_many (src, depay, sink, NULL);
287 
288   gst_element_set_state (pipeline, GST_STATE_PAUSED);
289 
290   {
291     gchar *data, *pdata;
292     gsize len;
293 
294     fail_unless (g_file_get_contents (RTP_H264_FILE, &data, &len, NULL));
295     fail_unless (len > 2);
296 
297     pdata = data;
298     while (len > 2) {
299       GstFlowReturn flow;
300       guint16 packet_len;
301 
302       packet_len = GST_READ_UINT16_BE (pdata);
303       GST_INFO ("rtp packet length: %u (bytes left: %u)", packet_len,
304           (guint) len);
305       fail_unless (len >= 2 + packet_len);
306 
307       flow = gst_app_src_push_buffer (GST_APP_SRC (src),
308           gst_buffer_new_memdup (pdata + 2, packet_len));
309 
310       fail_unless_equals_int (flow, GST_FLOW_OK);
311 
312       pdata += 2 + packet_len;
313       len -= 2 + packet_len;
314     }
315 
316     g_free (data);
317   }
318 
319   gst_app_src_end_of_stream (GST_APP_SRC (src));
320 
321   sample = gst_app_sink_pull_preroll (GST_APP_SINK (sink));
322   fail_unless (sample != NULL);
323 
324   buf = gst_sample_get_buffer (sample);
325 
326   GST_LOG ("buffer has %u memories", gst_buffer_n_memory (buf));
327   GST_LOG ("buffer size: %u", (guint) gst_buffer_get_size (buf));
328 
329   fail_unless (gst_buffer_n_memory (buf) > 0);
330   mem = gst_buffer_peek_memory (buf, 0);
331   fail_unless (mem != NULL);
332 
333   GST_LOG ("buffer memory type: %s", mem->allocator->mem_type);
334   fail_unless (gst_memory_is_type (mem, ALLOCATOR_CUSTOM_SYSMEM));
335 
336   gst_sample_unref (sample);
337 
338   gst_element_set_state (pipeline, GST_STATE_NULL);
339 
340   gst_object_unref (pipeline);
341 
342   g_object_unref (custom_sysmem_allocator);
343   custom_sysmem_allocator = NULL;
344 }
345 
346 GST_END_TEST;
347 
348 
349 static GstBuffer *
wrap_static_buffer_with_pts_full(guint8 * buf,gsize size,GstClockTime pts,gpointer user_data,GDestroyNotify notify)350 wrap_static_buffer_with_pts_full (guint8 * buf, gsize size, GstClockTime pts,
351     gpointer user_data, GDestroyNotify notify)
352 {
353   GstBuffer *buffer;
354 
355   buffer = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
356       buf, size, 0, size, user_data, notify);
357   GST_BUFFER_PTS (buffer) = pts;
358 
359   return buffer;
360 }
361 
362 static GstBuffer *
wrap_static_buffer_full(guint8 * buf,gsize size,gpointer user_data,GDestroyNotify notify)363 wrap_static_buffer_full (guint8 * buf, gsize size, gpointer user_data,
364     GDestroyNotify notify)
365 {
366   return wrap_static_buffer_with_pts_full (buf, size, GST_CLOCK_TIME_NONE,
367       user_data, notify);
368 }
369 
370 static GstBuffer *
wrap_static_buffer_with_pts(guint8 * buf,gsize size,GstClockTime pts)371 wrap_static_buffer_with_pts (guint8 * buf, gsize size, GstClockTime pts)
372 {
373   return wrap_static_buffer_with_pts_full (buf, size, pts, NULL, NULL);
374 }
375 
376 static GstBuffer *
wrap_static_buffer(guint8 * buf,gsize size)377 wrap_static_buffer (guint8 * buf, gsize size)
378 {
379   return wrap_static_buffer_full (buf, size, NULL, NULL);
380 }
381 
382 /* This was generated using pipeline:
383  * gst-launch-1.0 videotestsrc num-buffers=1 pattern=green \
384  *     ! video/x-raw,width=16,height=16 \
385  *     ! openh264enc ! rtph264pay ! fakesink dump=1
386  */
387 /* RTP h264_idr + marker */
388 static guint8 rtp_h264_idr[] = {
389   0x80, 0xe0, 0x3e, 0xf0, 0xd9, 0xbe, 0x80, 0x28,
390   0xf4, 0x2d, 0xe1, 0x70, 0x65, 0xb8, 0x00, 0x04,
391   0x00, 0x00, 0x09, 0xff, 0xff, 0xf8, 0x22, 0x8a,
392   0x00, 0x1f, 0x1c, 0x00, 0x04, 0x1c, 0xe3, 0x80,
393   0x00, 0x84, 0xde
394 };
395 
GST_START_TEST(test_rtph264depay_eos)396 GST_START_TEST (test_rtph264depay_eos)
397 {
398   GstHarness *h = gst_harness_new ("rtph264depay");
399   GstBuffer *buffer;
400   GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
401   GstFlowReturn ret;
402 
403   gst_harness_set_caps_str (h,
404       "application/x-rtp,media=video,clock-rate=90000,encoding-name=H264",
405       "video/x-h264,alignment=au,stream-format=byte-stream");
406 
407   buffer = wrap_static_buffer (rtp_h264_idr, sizeof (rtp_h264_idr));
408   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_WRITE, &rtp));
409   gst_rtp_buffer_set_marker (&rtp, FALSE);
410   gst_rtp_buffer_unmap (&rtp);
411 
412   ret = gst_harness_push (h, buffer);
413   fail_unless_equals_int (ret, GST_FLOW_OK);
414   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 0);
415 
416   fail_unless (gst_harness_push_event (h, gst_event_new_eos ()));
417   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 1);
418 
419   gst_harness_teardown (h);
420 }
421 
422 GST_END_TEST;
423 
424 
GST_START_TEST(test_rtph264depay_marker_to_flag)425 GST_START_TEST (test_rtph264depay_marker_to_flag)
426 {
427   GstHarness *h = gst_harness_new ("rtph264depay");
428   GstBuffer *buffer;
429   GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
430   GstFlowReturn ret;
431   guint16 seq;
432 
433   gst_harness_set_caps_str (h,
434       "application/x-rtp,media=video,clock-rate=90000,encoding-name=H264",
435       "video/x-h264,alignment=au,stream-format=byte-stream");
436 
437   buffer = wrap_static_buffer (rtp_h264_idr, sizeof (rtp_h264_idr));
438   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
439   fail_unless (gst_rtp_buffer_get_marker (&rtp));
440   seq = gst_rtp_buffer_get_seq (&rtp);
441   gst_rtp_buffer_unmap (&rtp);
442 
443   ret = gst_harness_push (h, buffer);
444   fail_unless_equals_int (ret, GST_FLOW_OK);
445   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 1);
446 
447   buffer = wrap_static_buffer (rtp_h264_idr, sizeof (rtp_h264_idr));
448   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_WRITE, &rtp));
449   gst_rtp_buffer_set_marker (&rtp, FALSE);
450   gst_rtp_buffer_set_seq (&rtp, ++seq);
451   gst_rtp_buffer_unmap (&rtp);
452 
453   ret = gst_harness_push (h, buffer);
454   fail_unless_equals_int (ret, GST_FLOW_OK);
455 
456   /* the second NAL is blocked as there is no marker to let the payloader
457    * know it's a complete AU, we'll use an EOS to unblock it */
458   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 1);
459   fail_unless (gst_harness_push_event (h, gst_event_new_eos ()));
460   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 2);
461 
462   buffer = gst_harness_pull (h);
463   fail_unless (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_MARKER));
464   gst_buffer_unref (buffer);
465 
466   buffer = gst_harness_pull (h);
467   fail_if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_MARKER));
468   gst_buffer_unref (buffer);
469 
470   gst_harness_teardown (h);
471 }
472 
473 GST_END_TEST;
474 
475 /* This was generated using pipeline:
476  * gst-launch-1.0 videotestsrc num-buffers=1 pattern=green \
477  *     ! video/x-raw,width=24,height=16 \
478  *     ! openh264enc ! rtph264pay mtu=32 ! fakesink dump=1
479  */
480 /* RTP h264_idr FU-A */
481 static guint8 rtp_h264_idr_fu_start[] = {
482   0x80, 0x60, 0x5f, 0xd2, 0x20, 0x3b, 0x6e, 0xcf,
483   0x6c, 0x54, 0x21, 0x8d, 0x7c, 0x85, 0xb8, 0x00,
484   0x04, 0x00, 0x00, 0x09, 0xff, 0xff, 0xf8, 0x22,
485   0x8a, 0x00, 0x1f, 0x1c, 0x00, 0x04, 0x1c, 0xe3,
486 };
487 
488 static guint8 rtp_h264_idr_fu_middle[] = {
489   0x80, 0x60, 0x5f, 0xd3, 0x20, 0x3b, 0x6e, 0xcf,
490   0x6c, 0x54, 0x21, 0x8d, 0x7c, 0x05, 0x80, 0x00,
491   0x84, 0xdf, 0xf8, 0x7f, 0xe0, 0x8e, 0x28, 0x00,
492   0x08, 0x37, 0xf8, 0x80, 0x00, 0x20, 0x52, 0x00,
493 };
494 
495 static guint8 rtp_h264_idr_fu_end[] = {
496   0x80, 0xe0, 0x5f, 0xd4, 0x20, 0x3b, 0x6e, 0xcf,
497   0x6c, 0x54, 0x21, 0x8d, 0x7c, 0x45, 0x02, 0x01,
498   0x91, 0x00, 0x00, 0x40, 0xf4, 0x00, 0x04, 0x08,
499   0x30,
500 };
501 
GST_START_TEST(test_rtph264depay_fu_a)502 GST_START_TEST (test_rtph264depay_fu_a)
503 {
504   GstHarness *h = gst_harness_new ("rtph264depay");
505   GstBuffer *buffer;
506   GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
507   GstFlowReturn ret;
508 
509   gst_harness_set_caps_str (h,
510       "application/x-rtp,media=video,clock-rate=90000,encoding-name=H264",
511       "video/x-h264,alignment=au,stream-format=byte-stream");
512 
513   buffer =
514       wrap_static_buffer (rtp_h264_idr_fu_start,
515       sizeof (rtp_h264_idr_fu_start));
516   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
517   gst_rtp_buffer_unmap (&rtp);
518 
519   ret = gst_harness_push (h, buffer);
520   fail_unless_equals_int (ret, GST_FLOW_OK);
521   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 0);
522 
523   buffer =
524       wrap_static_buffer (rtp_h264_idr_fu_middle,
525       sizeof (rtp_h264_idr_fu_middle));
526   ret = gst_harness_push (h, buffer);
527   fail_unless_equals_int (ret, GST_FLOW_OK);
528 
529   buffer =
530       wrap_static_buffer (rtp_h264_idr_fu_end, sizeof (rtp_h264_idr_fu_end));
531   ret = gst_harness_push (h, buffer);
532   fail_unless_equals_int (ret, GST_FLOW_OK);
533 
534   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 1);
535 
536   buffer = gst_harness_pull (h);
537   fail_unless (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_MARKER));
538   gst_buffer_unref (buffer);
539 
540   gst_harness_teardown (h);
541 }
542 
543 GST_END_TEST;
544 
GST_START_TEST(test_rtph264depay_fu_a_missing_start)545 GST_START_TEST (test_rtph264depay_fu_a_missing_start)
546 {
547   GstHarness *h = gst_harness_new ("rtph264depay");
548   GstBuffer *buffer;
549   GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
550   GstFlowReturn ret;
551   guint16 seq;
552 
553   gst_harness_set_caps_str (h,
554       "application/x-rtp,media=video,clock-rate=90000,encoding-name=H264",
555       "video/x-h264,alignment=au,stream-format=byte-stream");
556 
557   buffer =
558       wrap_static_buffer (rtp_h264_idr_fu_start,
559       sizeof (rtp_h264_idr_fu_start));
560 
561   ret = gst_harness_push (h, buffer);
562   fail_unless_equals_int (ret, GST_FLOW_OK);
563 
564   buffer =
565       wrap_static_buffer (rtp_h264_idr_fu_middle,
566       sizeof (rtp_h264_idr_fu_middle));
567   ret = gst_harness_push (h, buffer);
568   fail_unless_equals_int (ret, GST_FLOW_OK);
569 
570   buffer =
571       wrap_static_buffer (rtp_h264_idr_fu_end, sizeof (rtp_h264_idr_fu_end));
572   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
573   seq = gst_rtp_buffer_get_seq (&rtp);
574   gst_rtp_buffer_unmap (&rtp);
575   ret = gst_harness_push (h, buffer);
576   fail_unless_equals_int (ret, GST_FLOW_OK);
577   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 1);
578 
579   /* A broken sender case seen in the wild where the seqnums are continuous
580    * but only contain a FU with an end-bit, no start-bit */
581   buffer =
582       wrap_static_buffer (rtp_h264_idr_fu_end, sizeof (rtp_h264_idr_fu_end));
583   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_WRITE, &rtp));
584   gst_rtp_buffer_set_seq (&rtp, ++seq);
585   gst_rtp_buffer_unmap (&rtp);
586   ret = gst_harness_push (h, buffer);
587   fail_unless_equals_int (ret, GST_FLOW_OK);
588 
589   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 1);
590 
591   gst_harness_teardown (h);
592 }
593 
594 GST_END_TEST;
595 
596 
597 /* As GStreamer does not have STAP-A yet, this was extracted from
598  * issue #557 provided sample */
599 static guint8 rtp_stapa_pps_sps[] = {
600   0x80, 0x60, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
601   0xd8, 0xd9, 0x06, 0x7f, 0x38, 0x00, 0x1c, 0x27,
602   0x64, 0x00, 0x29, 0xac, 0x13, 0x16, 0x50, 0x28,
603   0x0f, 0x6c, 0x00, 0x30, 0x30, 0x00, 0x5d, 0xc0,
604   0x00, 0x17, 0x70, 0x5e, 0xf7, 0xc1, 0xda, 0x08,
605   0x84, 0x65, 0x80, 0x00, 0x04, 0x28, 0xef, 0x1f,
606   0x2c
607 };
608 
609 static guint8 rtp_stapa_slices_marker[] = {
610   0x80, 0xe0, 0x00, 0x0c, 0x00, 0x00, 0x57, 0xe4,
611   0xd8, 0xd9, 0x06, 0x7f, 0x38, 0x00, 0x28, 0x21,
612   0xe0, 0x02, 0x00, 0x10, 0x73, 0x84, 0x12, 0xff,
613   0x00, 0x1f, 0x0c, 0xbf, 0x0c, 0xb7, 0xb8, 0x73,
614   0xd3, 0xf2, 0xfc, 0xba, 0x7b, 0xce, 0x3c, 0xaf,
615   0x90, 0x11, 0xb3, 0x15, 0xa2, 0x53, 0x96, 0xc1,
616   0xa8, 0x27, 0x01, 0xdb, 0xde, 0xc8, 0x80, 0x00,
617   0x35, 0x21, 0x00, 0xa0, 0xe0, 0x02, 0x00, 0x10,
618   0x73, 0x84, 0x12, 0xff, 0x79, 0x9d, 0x3b, 0x38,
619   0xc6, 0x26, 0x47, 0x01, 0x02, 0x6b, 0xd6, 0x40,
620   0x17, 0x06, 0x0b, 0x8c, 0x22, 0xd0, 0x04, 0xe4,
621   0xea, 0x5e, 0x3f, 0xb8, 0x6a, 0x03, 0x4e, 0x15,
622   0x1f, 0x74, 0x62, 0x51, 0x78, 0xef, 0x5a, 0xd1,
623   0xf0, 0x3e, 0xb8, 0x56, 0xbb, 0x08, 0x00, 0x2e,
624   0x21, 0x00, 0x50, 0x38, 0x00, 0x80, 0x04, 0x1c,
625   0xe1, 0x04, 0xbf, 0x00, 0xa8, 0x40, 0x67, 0x09,
626   0xa8, 0x4d, 0x95, 0x5b, 0x0e, 0x2b, 0xba, 0x34,
627   0xc7, 0xa6, 0x78, 0x27, 0xe4, 0x5c, 0x74, 0xa0,
628   0xa2, 0xce, 0x30, 0x51, 0x78, 0x30, 0x56, 0xd0,
629   0x7a, 0xcd, 0x12, 0xbc, 0xba, 0xe0, 0x00, 0x1e,
630   0x21, 0x00, 0x78, 0x38, 0x00, 0x80, 0x04, 0x1c,
631   0xe1, 0x04, 0xbf, 0x67, 0x37, 0xc0, 0x86, 0x26,
632   0x7d, 0x4c, 0x52, 0x4b, 0x80, 0x9a, 0x3c, 0xa3,
633   0x02, 0xcd, 0x8d, 0xcd, 0x18, 0xd8
634 };
635 
GST_START_TEST(test_rtph264depay_stap_a_marker)636 GST_START_TEST (test_rtph264depay_stap_a_marker)
637 {
638   GstHarness *h = gst_harness_new ("rtph264depay");
639   GstBuffer *buffer;
640   GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
641   GstFlowReturn ret;
642 
643   gst_harness_set_caps_str (h,
644       "application/x-rtp,media=video,clock-rate=90000,encoding-name=H264",
645       "video/x-h264,alignment=au,stream-format=byte-stream");
646 
647   ret = gst_harness_push (h,
648       wrap_static_buffer (rtp_stapa_pps_sps, sizeof (rtp_stapa_pps_sps)));
649   fail_unless_equals_int (ret, GST_FLOW_OK);
650   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 0);
651 
652   buffer = wrap_static_buffer (rtp_stapa_slices_marker,
653       sizeof (rtp_stapa_slices_marker));
654   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_WRITE, &rtp));
655   gst_rtp_buffer_set_seq (&rtp, 2);
656   gst_rtp_buffer_unmap (&rtp);
657   ret = gst_harness_push (h, buffer);
658   fail_unless_equals_int (ret, GST_FLOW_OK);
659 
660   /* Only one AU should have been pushed */
661   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 1);
662 
663   gst_harness_teardown (h);
664 }
665 
666 GST_END_TEST;
667 
668 
669 /* AUD */
670 static guint8 h264_aud[] = {
671   0x00, 0x00, 0x00, 0x01, 0x09, 0xf0
672 };
673 
674 /* These were generated using pipeline:
675  * gst-launch-1.0 videotestsrc num-buffers=1 pattern=green \
676  *     ! video/x-raw,width=128,height=128 \
677  *     ! openh264enc num-slices=2 \
678  *     ! fakesink dump=1
679  */
680 
681 /* SPS */
682 static guint8 h264_sps[] = {
683   0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0xc0, 0x29,
684   0x8c, 0x8d, 0x41, 0x02, 0x24, 0x03, 0xc2, 0x21,
685   0x1a, 0x80
686 };
687 
688 /* PPS */
689 static guint8 h264_pps[] = {
690   0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x3c, 0x80
691 };
692 
693 /* IDR Slice 1 */
694 static guint8 h264_idr_slice_1[] = {
695   0x00, 0x00, 0x00, 0x01, 0x65, 0xb8, 0x00, 0x04,
696   0x00, 0x00, 0x11, 0xff, 0xff, 0xf8, 0x22, 0x8a,
697   0x1f, 0x1c, 0x00, 0x04, 0x0a, 0x63, 0x80, 0x00,
698   0x81, 0xec, 0x9a, 0x93, 0x93, 0x93, 0x93, 0x93,
699   0x93, 0xad, 0x57, 0x5d, 0x75, 0xd7, 0x5d, 0x75,
700   0xd7, 0x5d, 0x75, 0xd7, 0x5d, 0x75, 0xd7, 0x5d,
701   0x75, 0xd7, 0x5d, 0x78
702 };
703 
704 /* IDR Slice 2 */
705 static guint8 h264_idr_slice_2[] = {
706   0x00, 0x00, 0x00, 0x01, 0x65, 0x04, 0x2e, 0x00,
707   0x01, 0x00, 0x00, 0x04, 0x7f, 0xff, 0xfe, 0x08,
708   0xa2, 0x87, 0xc7, 0x00, 0x01, 0x02, 0x98, 0xe0,
709   0x00, 0x20, 0x7b, 0x26, 0xa4, 0xe4, 0xe4, 0xe4,
710   0xe4, 0xe4, 0xeb, 0x55, 0xd7, 0x5d, 0x75, 0xd7,
711   0x5d, 0x75, 0xd7, 0x5d, 0x75, 0xd7, 0x5d, 0x75,
712   0xd7, 0x5d, 0x75, 0xd7, 0x5e
713 };
714 
715 /* SPS */
716 static guint8 h264_sps_avc[] = {
717   0x00, 0x00, 0x00, 0x0E, 0x67, 0x42, 0xc0, 0x29,
718   0x8c, 0x8d, 0x41, 0x02, 0x24, 0x03, 0xc2, 0x21,
719   0x1a, 0x80
720 };
721 
722 /* PPS */
723 static guint8 h264_pps_avc[] = {
724   0x00, 0x00, 0x00, 0x04, 0x68, 0xce, 0x3c, 0x80
725 };
726 
727 /* IDR Slice 1 */
728 static guint8 h264_idr_slice_1_avc[] = {
729   0x00, 0x00, 0x00, 0x30, 0x65, 0xb8, 0x00, 0x04,
730   0x00, 0x00, 0x11, 0xff, 0xff, 0xf8, 0x22, 0x8a,
731   0x1f, 0x1c, 0x00, 0x04, 0x0a, 0x63, 0x80, 0x00,
732   0x81, 0xec, 0x9a, 0x93, 0x93, 0x93, 0x93, 0x93,
733   0x93, 0xad, 0x57, 0x5d, 0x75, 0xd7, 0x5d, 0x75,
734   0xd7, 0x5d, 0x75, 0xd7, 0x5d, 0x75, 0xd7, 0x5d,
735   0x75, 0xd7, 0x5d, 0x78
736 };
737 
738 /* IDR Slice 2 */
739 static guint8 h264_idr_slice_2_avc[] = {
740   0x00, 0x00, 0x00, 0x31, 0x65, 0x04, 0x2e, 0x00,
741   0x01, 0x00, 0x00, 0x04, 0x7f, 0xff, 0xfe, 0x08,
742   0xa2, 0x87, 0xc7, 0x00, 0x01, 0x02, 0x98, 0xe0,
743   0x00, 0x20, 0x7b, 0x26, 0xa4, 0xe4, 0xe4, 0xe4,
744   0xe4, 0xe4, 0xeb, 0x55, 0xd7, 0x5d, 0x75, 0xd7,
745   0x5d, 0x75, 0xd7, 0x5d, 0x75, 0xd7, 0x5d, 0x75,
746   0xd7, 0x5d, 0x75, 0xd7, 0x5e
747 };
748 
749 /* The RFC makes special use of NAL type 24 to 27, this test makes sure that
750  * such a NAL from the outside gets ignored properly. */
GST_START_TEST(test_rtph264pay_reserved_nals)751 GST_START_TEST (test_rtph264pay_reserved_nals)
752 {
753   GstHarness *h = gst_harness_new_parse ("rtph264pay aggregate-mode=none");
754   /* we simply hack an AUD with the reserved nal types */
755   guint8 nal_24[sizeof (h264_aud)];
756   guint8 nal_25[sizeof (h264_aud)];
757   guint8 nal_26[sizeof (h264_aud)];
758   guint8 nal_27[sizeof (h264_aud)];
759   GstFlowReturn ret;
760 
761   gst_harness_set_src_caps_str (h,
762       "video/x-h264,alignment=nal,stream-format=byte-stream");
763 
764   ret = gst_harness_push (h, wrap_static_buffer (h264_sps, sizeof (h264_sps)));
765   fail_unless_equals_int (ret, GST_FLOW_OK);
766 
767   ret = gst_harness_push (h, wrap_static_buffer (h264_pps, sizeof (h264_pps)));
768   fail_unless_equals_int (ret, GST_FLOW_OK);
769 
770   memcpy (nal_24, h264_aud, sizeof (h264_aud));
771   nal_24[4] = 24;
772   ret = gst_harness_push (h, wrap_static_buffer (nal_24, sizeof (nal_24)));
773   fail_unless_equals_int (ret, GST_FLOW_OK);
774 
775   memcpy (nal_25, h264_aud, sizeof (h264_aud));
776   nal_25[4] = 25;
777   ret = gst_harness_push (h, wrap_static_buffer (nal_25, sizeof (nal_25)));
778   fail_unless_equals_int (ret, GST_FLOW_OK);
779 
780 
781   memcpy (nal_26, h264_aud, sizeof (h264_aud));
782   nal_26[4] = 26;
783   ret = gst_harness_push (h, wrap_static_buffer (nal_26, sizeof (nal_26)));
784   fail_unless_equals_int (ret, GST_FLOW_OK);
785 
786 
787   memcpy (nal_27, h264_aud, sizeof (h264_aud));
788   nal_27[4] = 27;
789   ret = gst_harness_push (h, wrap_static_buffer (nal_27, sizeof (nal_27)));
790   fail_unless_equals_int (ret, GST_FLOW_OK);
791 
792   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 2);
793   gst_harness_teardown (h);
794 }
795 
796 GST_END_TEST;
797 
798 
GST_START_TEST(test_rtph264pay_two_slices_timestamp)799 GST_START_TEST (test_rtph264pay_two_slices_timestamp)
800 {
801   GstHarness *h = gst_harness_new_parse ("rtph264pay timestamp-offset=123"
802       " aggregate-mode=zero-latency");
803   GstFlowReturn ret;
804   GstBuffer *buffer;
805   GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
806 
807   gst_harness_set_src_caps_str (h,
808       "video/x-h264,alignment=nal,stream-format=byte-stream");
809 
810   ret = gst_harness_push (h, wrap_static_buffer_with_pts (h264_idr_slice_1,
811           sizeof (h264_idr_slice_1), 0));
812   fail_unless_equals_int (ret, GST_FLOW_OK);
813 
814   ret = gst_harness_push (h, wrap_static_buffer_with_pts (h264_idr_slice_2,
815           sizeof (h264_idr_slice_2), 0));
816   fail_unless_equals_int (ret, GST_FLOW_OK);
817 
818   ret = gst_harness_push (h, wrap_static_buffer_with_pts (h264_idr_slice_1,
819           sizeof (h264_idr_slice_1), GST_SECOND));
820   fail_unless_equals_int (ret, GST_FLOW_OK);
821 
822   ret = gst_harness_push (h, wrap_static_buffer_with_pts (h264_idr_slice_2,
823           sizeof (h264_idr_slice_2), GST_SECOND));
824   fail_unless_equals_int (ret, GST_FLOW_OK);
825 
826   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 4);
827 
828   buffer = gst_harness_pull (h);
829   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
830   fail_unless_equals_uint64 (GST_BUFFER_PTS (buffer), 0);
831   fail_unless_equals_uint64 (gst_rtp_buffer_get_timestamp (&rtp), 123);
832   gst_rtp_buffer_unmap (&rtp);
833   gst_buffer_unref (buffer);
834 
835   buffer = gst_harness_pull (h);
836   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
837   fail_unless_equals_uint64 (GST_BUFFER_PTS (buffer), 0);
838   fail_unless_equals_uint64 (gst_rtp_buffer_get_timestamp (&rtp), 123);
839   gst_rtp_buffer_unmap (&rtp);
840   gst_buffer_unref (buffer);
841 
842   buffer = gst_harness_pull (h);
843   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
844   fail_unless_equals_uint64 (GST_BUFFER_PTS (buffer), GST_SECOND);
845   fail_unless_equals_uint64 (gst_rtp_buffer_get_timestamp (&rtp), 123 + 90000);
846   gst_rtp_buffer_unmap (&rtp);
847   gst_buffer_unref (buffer);
848 
849   buffer = gst_harness_pull (h);
850   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
851   fail_unless_equals_uint64 (GST_BUFFER_PTS (buffer), GST_SECOND);
852   fail_unless_equals_uint64 (gst_rtp_buffer_get_timestamp (&rtp), 123 + 90000);
853   gst_rtp_buffer_unmap (&rtp);
854   gst_buffer_unref (buffer);
855 
856   gst_harness_teardown (h);
857 }
858 
859 GST_END_TEST;
860 
GST_START_TEST(test_rtph264pay_marker_for_flag)861 GST_START_TEST (test_rtph264pay_marker_for_flag)
862 {
863   GstHarness *h = gst_harness_new_parse ("rtph264pay timestamp-offset=123"
864       " aggregate-mode=zero-latency");
865   GstFlowReturn ret;
866   GstBuffer *buffer;
867   GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
868 
869   gst_harness_set_src_caps_str (h,
870       "video/x-h264,alignment=nal,stream-format=byte-stream");
871 
872   ret = gst_harness_push (h, wrap_static_buffer (h264_idr_slice_1,
873           sizeof (h264_idr_slice_1)));
874   fail_unless_equals_int (ret, GST_FLOW_OK);
875 
876   buffer = wrap_static_buffer (h264_idr_slice_2, sizeof (h264_idr_slice_2));
877   GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_MARKER);
878   ret = gst_harness_push (h, buffer);
879   fail_unless_equals_int (ret, GST_FLOW_OK);
880 
881   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 2);
882 
883   buffer = gst_harness_pull (h);
884   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
885   fail_if (gst_rtp_buffer_get_marker (&rtp));
886   gst_rtp_buffer_unmap (&rtp);
887   gst_buffer_unref (buffer);
888 
889   buffer = gst_harness_pull (h);
890   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
891   fail_unless (gst_rtp_buffer_get_marker (&rtp));
892   gst_rtp_buffer_unmap (&rtp);
893   gst_buffer_unref (buffer);
894 
895   gst_harness_teardown (h);
896 }
897 
898 GST_END_TEST;
899 
900 
GST_START_TEST(test_rtph264pay_marker_for_au)901 GST_START_TEST (test_rtph264pay_marker_for_au)
902 {
903   GstHarness *h =
904       gst_harness_new_parse
905       ("rtph264pay timestamp-offset=123 aggregate-mode=none");
906   GstFlowReturn ret;
907   GstBuffer *slice1, *slice2, *buffer;
908   GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
909 
910   gst_harness_set_src_caps_str (h,
911       "video/x-h264,alignment=au,stream-format=byte-stream");
912 
913   slice1 = wrap_static_buffer (h264_idr_slice_1, sizeof (h264_idr_slice_1));
914   slice2 = wrap_static_buffer (h264_idr_slice_2, sizeof (h264_idr_slice_2));
915   buffer = gst_buffer_append (slice1, slice2);
916 
917   ret = gst_harness_push (h, buffer);
918   fail_unless_equals_int (ret, GST_FLOW_OK);
919 
920   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 2);
921 
922   buffer = gst_harness_pull (h);
923   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
924   fail_if (gst_rtp_buffer_get_marker (&rtp));
925   gst_rtp_buffer_unmap (&rtp);
926   gst_buffer_unref (buffer);
927 
928   buffer = gst_harness_pull (h);
929   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
930   fail_unless (gst_rtp_buffer_get_marker (&rtp));
931   gst_rtp_buffer_unmap (&rtp);
932   gst_buffer_unref (buffer);
933 
934   gst_harness_teardown (h);
935 }
936 
937 GST_END_TEST;
938 
939 
GST_START_TEST(test_rtph264pay_marker_for_fragmented_au)940 GST_START_TEST (test_rtph264pay_marker_for_fragmented_au)
941 {
942   GstHarness *h =
943       gst_harness_new_parse ("rtph264pay timestamp-offset=123 mtu=40"
944       " aggregate-mode=zero-latency");
945   GstFlowReturn ret;
946   GstBuffer *slice1, *slice2, *buffer;
947   GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
948   gint i;
949 
950   gst_harness_set_src_caps_str (h,
951       "video/x-h264,alignment=au,stream-format=byte-stream");
952 
953   slice1 = wrap_static_buffer (h264_idr_slice_1, sizeof (h264_idr_slice_1));
954   slice2 = wrap_static_buffer (h264_idr_slice_2, sizeof (h264_idr_slice_2));
955   buffer = gst_buffer_append (slice1, slice2);
956 
957   ret = gst_harness_push (h, buffer);
958   fail_unless_equals_int (ret, GST_FLOW_OK);
959 
960   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 4);
961 
962   for (i = 0; i < 3; i++) {
963     buffer = gst_harness_pull (h);
964     fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
965     fail_if (gst_rtp_buffer_get_marker (&rtp));
966     gst_rtp_buffer_unmap (&rtp);
967     gst_buffer_unref (buffer);
968   }
969 
970   buffer = gst_harness_pull (h);
971   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
972   fail_unless (gst_rtp_buffer_get_marker (&rtp));
973   gst_rtp_buffer_unmap (&rtp);
974   gst_buffer_unref (buffer);
975 
976   gst_harness_teardown (h);
977 }
978 
979 GST_END_TEST;
980 
GST_START_TEST(test_rtph264pay_aggregate_two_slices_per_buffer)981 GST_START_TEST (test_rtph264pay_aggregate_two_slices_per_buffer)
982 {
983   GstHarness *h = gst_harness_new_parse ("rtph264pay timestamp-offset=123"
984       " name=p");
985   GstFlowReturn ret;
986   GstBuffer *buffer;
987   GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
988   GstElement *e = gst_bin_get_by_name (GST_BIN (h->element), "p");
989   gint i;
990 
991   gst_harness_set_src_caps_str (h,
992       "video/x-h264,alignment=nal,stream-format=byte-stream");
993 
994   /* No aggregation mode */
995   g_object_set (e, "aggregate-mode", 0, NULL);
996 
997   buffer = wrap_static_buffer_with_pts (h264_idr_slice_1,
998       sizeof (h264_idr_slice_1), 0);
999   buffer = gst_buffer_append (buffer,
1000       wrap_static_buffer_with_pts (h264_idr_slice_2, sizeof (h264_idr_slice_2),
1001           0));
1002   ret = gst_harness_push (h, buffer);
1003   fail_unless_equals_int (ret, GST_FLOW_OK);
1004 
1005   buffer = wrap_static_buffer_with_pts (h264_idr_slice_1,
1006       sizeof (h264_idr_slice_1), 0);
1007   buffer = gst_buffer_append (buffer,
1008       wrap_static_buffer_with_pts (h264_idr_slice_2, sizeof (h264_idr_slice_2),
1009           0));
1010   ret = gst_harness_push (h, buffer);
1011   fail_unless_equals_int (ret, GST_FLOW_OK);
1012 
1013   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 4);
1014 
1015   for (i = 0; i < 4; i++) {
1016     buffer = gst_harness_pull (h);
1017     fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
1018     fail_unless_equals_uint64 (GST_BUFFER_PTS (buffer), 0);
1019     fail_unless_equals_uint64 (gst_rtp_buffer_get_timestamp (&rtp), 123);
1020     fail_unless_equals_int (gst_buffer_get_size (buffer), 12 +
1021         ((i % 2) ? sizeof (h264_idr_slice_2) : sizeof (h264_idr_slice_1)) - 4);
1022     gst_rtp_buffer_unmap (&rtp);
1023     gst_buffer_unref (buffer);
1024   }
1025 
1026   /* Zero latency mode */
1027   g_object_set (e, "aggregate-mode", 1, NULL);
1028 
1029   buffer = wrap_static_buffer_with_pts (h264_idr_slice_1,
1030       sizeof (h264_idr_slice_1), 0);
1031   buffer = gst_buffer_append (buffer,
1032       wrap_static_buffer_with_pts (h264_idr_slice_2, sizeof (h264_idr_slice_2),
1033           0));
1034   ret = gst_harness_push (h, buffer);
1035   fail_unless_equals_int (ret, GST_FLOW_OK);
1036 
1037   buffer = wrap_static_buffer_with_pts (h264_idr_slice_1,
1038       sizeof (h264_idr_slice_1), 0);
1039   buffer = gst_buffer_append (buffer,
1040       wrap_static_buffer_with_pts (h264_idr_slice_2, sizeof (h264_idr_slice_2),
1041           0));
1042   ret = gst_harness_push (h, buffer);
1043   fail_unless_equals_int (ret, GST_FLOW_OK);
1044 
1045   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 2);
1046 
1047   for (i = 0; i < 2; i++) {
1048     buffer = gst_harness_pull (h);
1049     fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
1050     fail_unless_equals_uint64 (GST_BUFFER_PTS (buffer), 0);
1051     fail_unless_equals_uint64 (gst_rtp_buffer_get_timestamp (&rtp), 123);
1052     /* RTP header = 12,  STAP header = 1, 2 bytes length per NAL */
1053     fail_unless_equals_int (gst_buffer_get_size (buffer), 12 + 1 +
1054         (2 + sizeof (h264_idr_slice_2) - 4) +
1055         (2 + sizeof (h264_idr_slice_1) - 4));
1056     gst_rtp_buffer_unmap (&rtp);
1057     gst_buffer_unref (buffer);
1058   }
1059 
1060   /* Max aggregation */
1061   g_object_set (e, "aggregate-mode", 2, NULL);
1062 
1063   buffer = wrap_static_buffer_with_pts (h264_idr_slice_1,
1064       sizeof (h264_idr_slice_1), 0);
1065   buffer = gst_buffer_append (buffer,
1066       wrap_static_buffer_with_pts (h264_idr_slice_2, sizeof (h264_idr_slice_2),
1067           0));
1068   ret = gst_harness_push (h, buffer);
1069   fail_unless_equals_int (ret, GST_FLOW_OK);
1070 
1071   buffer = wrap_static_buffer_with_pts (h264_idr_slice_1,
1072       sizeof (h264_idr_slice_1), 0);
1073   buffer = gst_buffer_append (buffer,
1074       wrap_static_buffer_with_pts (h264_idr_slice_2, sizeof (h264_idr_slice_2),
1075           0));
1076   ret = gst_harness_push (h, buffer);
1077   fail_unless_equals_int (ret, GST_FLOW_OK);
1078 
1079   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 0);
1080 
1081   /* Push EOS to send it out */
1082   gst_harness_push_event (h, gst_event_new_eos ());
1083 
1084   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 1);
1085 
1086   buffer = gst_harness_pull (h);
1087   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
1088   fail_unless_equals_uint64 (GST_BUFFER_PTS (buffer), 0);
1089   fail_unless_equals_uint64 (gst_rtp_buffer_get_timestamp (&rtp), 123);
1090   /* RTP header = 12,  STAP header = 1, 2 bytes length per NAL */
1091   fail_unless_equals_int (gst_buffer_get_size (buffer), 12 + 1 +
1092       2 * (2 + sizeof (h264_idr_slice_2) - 4) +
1093       2 * (2 + sizeof (h264_idr_slice_1) - 4));
1094   gst_rtp_buffer_unmap (&rtp);
1095   gst_buffer_unref (buffer);
1096 
1097 
1098   g_object_unref (e);
1099   gst_harness_teardown (h);
1100 }
1101 
1102 GST_END_TEST;
1103 
1104 
GST_START_TEST(test_rtph264pay_aggregate_with_aud)1105 GST_START_TEST (test_rtph264pay_aggregate_with_aud)
1106 {
1107   GstHarness *h = gst_harness_new_parse ("rtph264pay timestamp-offset=123"
1108       " aggregate-mode=zero-latency");
1109   GstFlowReturn ret;
1110   GstBuffer *buffer;
1111   GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
1112 
1113   gst_harness_set_src_caps_str (h,
1114       "video/x-h264,alignment=nal,stream-format=byte-stream");
1115 
1116   buffer = wrap_static_buffer_with_pts (h264_idr_slice_1,
1117       sizeof (h264_idr_slice_1), 0);
1118   buffer = gst_buffer_append (buffer,
1119       wrap_static_buffer_with_pts (h264_aud, sizeof (h264_aud), 0));
1120   buffer = gst_buffer_append (buffer,
1121       wrap_static_buffer_with_pts (h264_idr_slice_1, sizeof (h264_idr_slice_1),
1122           0));
1123 
1124   ret = gst_harness_push (h, buffer);
1125   fail_unless_equals_int (ret, GST_FLOW_OK);
1126 
1127   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 2);
1128 
1129   buffer = gst_harness_pull (h);
1130   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
1131   fail_unless_equals_uint64 (GST_BUFFER_PTS (buffer), 0);
1132   fail_unless_equals_uint64 (gst_rtp_buffer_get_timestamp (&rtp), 123);
1133   /* RTP header = 12 */
1134   fail_unless_equals_int (gst_buffer_get_size (buffer), 12 +
1135       (sizeof (h264_idr_slice_1) - 4));
1136   gst_rtp_buffer_unmap (&rtp);
1137   gst_buffer_unref (buffer);
1138 
1139   buffer = gst_harness_pull (h);
1140   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
1141   fail_unless_equals_uint64 (GST_BUFFER_PTS (buffer), 0);
1142   fail_unless_equals_uint64 (gst_rtp_buffer_get_timestamp (&rtp), 123);
1143   /* RTP header = 12,  STAP header = 1, 2 bytes length per NAL */
1144   fail_unless_equals_int (gst_buffer_get_size (buffer), 12 + 1 +
1145       (2 + sizeof (h264_aud) - 4) + (2 + sizeof (h264_idr_slice_1) - 4));
1146   gst_rtp_buffer_unmap (&rtp);
1147   gst_buffer_unref (buffer);
1148 
1149 
1150   gst_harness_teardown (h);
1151 }
1152 
1153 GST_END_TEST;
1154 
GST_START_TEST(test_rtph264pay_aggregate_with_ts_change)1155 GST_START_TEST (test_rtph264pay_aggregate_with_ts_change)
1156 {
1157   GstHarness *h = gst_harness_new_parse ("rtph264pay timestamp-offset=123 "
1158       "aggregate-mode=max-stap");
1159   GstFlowReturn ret;
1160   GstBuffer *buffer;
1161   GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
1162 
1163   gst_harness_set_src_caps_str (h,
1164       "video/x-h264,alignment=nal,stream-format=byte-stream");
1165 
1166   buffer = wrap_static_buffer_with_pts (h264_idr_slice_1,
1167       sizeof (h264_idr_slice_1), 0);
1168   buffer = gst_buffer_append (buffer,
1169       wrap_static_buffer_with_pts (h264_idr_slice_2, sizeof (h264_idr_slice_2),
1170           0));
1171   ret = gst_harness_push (h, buffer);
1172   fail_unless_equals_int (ret, GST_FLOW_OK);
1173 
1174   buffer = wrap_static_buffer_with_pts (h264_idr_slice_1,
1175       sizeof (h264_idr_slice_1), GST_SECOND);
1176   buffer = gst_buffer_append (buffer,
1177       wrap_static_buffer_with_pts (h264_idr_slice_2, sizeof (h264_idr_slice_2),
1178           GST_SECOND));
1179   ret = gst_harness_push (h, buffer);
1180   fail_unless_equals_int (ret, GST_FLOW_OK);
1181 
1182   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 1);
1183 
1184   /* Push EOS to send the second one out */
1185   gst_harness_push_event (h, gst_event_new_eos ());
1186 
1187   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 2);
1188 
1189   buffer = gst_harness_pull (h);
1190   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
1191   fail_unless_equals_uint64 (GST_BUFFER_PTS (buffer), 0);
1192   fail_unless_equals_uint64 (gst_rtp_buffer_get_timestamp (&rtp), 123);
1193   /* RTP header = 12,  STAP header = 1, 2 bytes length per NAL */
1194   fail_unless_equals_int (gst_buffer_get_size (buffer), 12 + 1 +
1195       (2 + sizeof (h264_idr_slice_1) - 4) +
1196       (2 + sizeof (h264_idr_slice_2) - 4));
1197   gst_rtp_buffer_unmap (&rtp);
1198   gst_buffer_unref (buffer);
1199 
1200   buffer = gst_harness_pull (h);
1201   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
1202   fail_unless_equals_uint64 (GST_BUFFER_PTS (buffer), GST_SECOND);
1203   fail_unless_equals_uint64 (gst_rtp_buffer_get_timestamp (&rtp), 123 + 90000);
1204   /* RTP header = 12,  STAP header = 1, 2 bytes length per NAL */
1205   fail_unless_equals_int (gst_buffer_get_size (buffer), 12 + 1 +
1206       (2 + sizeof (h264_idr_slice_1) - 4) +
1207       (2 + sizeof (h264_idr_slice_2) - 4));
1208   gst_rtp_buffer_unmap (&rtp);
1209   gst_buffer_unref (buffer);
1210 
1211 
1212   gst_harness_teardown (h);
1213 }
1214 
1215 GST_END_TEST;
1216 
GST_START_TEST(test_rtph264pay_aggregate_with_discont)1217 GST_START_TEST (test_rtph264pay_aggregate_with_discont)
1218 {
1219   GstHarness *h = gst_harness_new_parse ("rtph264pay timestamp-offset=123"
1220       " aggregate-mode=zero-latency");
1221   GstFlowReturn ret;
1222   GstBuffer *buffer;
1223   GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
1224 
1225   gst_harness_set_src_caps_str (h,
1226       "video/x-h264,alignment=nal,stream-format=byte-stream");
1227 
1228   buffer = wrap_static_buffer_with_pts (h264_idr_slice_1,
1229       sizeof (h264_idr_slice_1), 0);
1230   buffer = gst_buffer_append (buffer,
1231       wrap_static_buffer_with_pts (h264_idr_slice_2, sizeof (h264_idr_slice_2),
1232           0));
1233   ret = gst_harness_push (h, buffer);
1234   fail_unless_equals_int (ret, GST_FLOW_OK);
1235 
1236   buffer = wrap_static_buffer_with_pts (h264_idr_slice_1,
1237       sizeof (h264_idr_slice_1), 0);
1238   buffer = gst_buffer_append (buffer,
1239       wrap_static_buffer_with_pts (h264_idr_slice_2, sizeof (h264_idr_slice_2),
1240           0));
1241   GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
1242   ret = gst_harness_push (h, buffer);
1243   fail_unless_equals_int (ret, GST_FLOW_OK);
1244 
1245   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 2);
1246 
1247   buffer = gst_harness_pull (h);
1248   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
1249   fail_unless_equals_uint64 (GST_BUFFER_PTS (buffer), 0);
1250   fail_unless_equals_uint64 (gst_rtp_buffer_get_timestamp (&rtp), 123);
1251   /* RTP header = 12,  STAP header = 1, 2 bytes length per NAL */
1252   fail_unless_equals_int (gst_buffer_get_size (buffer), 12 + 1 +
1253       (2 + sizeof (h264_idr_slice_1) - 4) +
1254       (2 + sizeof (h264_idr_slice_2) - 4));
1255   gst_rtp_buffer_unmap (&rtp);
1256   gst_buffer_unref (buffer);
1257 
1258   buffer = gst_harness_pull (h);
1259   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
1260   fail_unless_equals_uint64 (GST_BUFFER_PTS (buffer), 0);
1261   fail_unless_equals_uint64 (gst_rtp_buffer_get_timestamp (&rtp), 123 + 0);
1262   /* RTP header = 12,  STAP header = 1, 2 bytes length per NAL */
1263   fail_unless_equals_int (gst_buffer_get_size (buffer), 12 + 1 +
1264       (2 + sizeof (h264_idr_slice_1) - 4) +
1265       (2 + sizeof (h264_idr_slice_2) - 4));
1266   gst_rtp_buffer_unmap (&rtp);
1267   gst_buffer_unref (buffer);
1268 
1269 
1270   gst_harness_teardown (h);
1271 }
1272 
1273 GST_END_TEST;
1274 
GST_START_TEST(test_rtph264pay_aggregate_until_vcl)1275 GST_START_TEST (test_rtph264pay_aggregate_until_vcl)
1276 {
1277   GstHarness *h = gst_harness_new_parse ("rtph264pay timestamp-offset=123"
1278       " name=p aggregate-mode=zero-latency");
1279   GstFlowReturn ret;
1280   GstBuffer *buffer;
1281   GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
1282 
1283   gst_harness_set_src_caps_str (h,
1284       "video/x-h264,alignment=nal,stream-format=byte-stream");
1285 
1286   buffer = wrap_static_buffer_with_pts (h264_sps, sizeof (h264_sps), 0);
1287   ret = gst_harness_push (h, buffer);
1288   fail_unless_equals_int (ret, GST_FLOW_OK);
1289 
1290   buffer = wrap_static_buffer_with_pts (h264_pps, sizeof (h264_pps), 0);
1291   ret = gst_harness_push (h, buffer);
1292   fail_unless_equals_int (ret, GST_FLOW_OK);
1293 
1294   buffer = wrap_static_buffer_with_pts (h264_idr_slice_1,
1295       sizeof (h264_idr_slice_1), 0);
1296   ret = gst_harness_push (h, buffer);
1297   fail_unless_equals_int (ret, GST_FLOW_OK);
1298 
1299 
1300   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 1);
1301 
1302   buffer = gst_harness_pull (h);
1303   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
1304   fail_unless_equals_uint64 (GST_BUFFER_PTS (buffer), 0);
1305   fail_unless_equals_uint64 (gst_rtp_buffer_get_timestamp (&rtp), 123);
1306   /* RTP header = 12,  STAP header = 1, 2 bytes length per NAL */
1307   fail_unless_equals_int (gst_buffer_get_size (buffer), 12 + 1 +
1308       (2 + sizeof (h264_sps) - 4) +
1309       (2 + sizeof (h264_pps) - 4) + (2 + sizeof (h264_idr_slice_1) - 4));
1310   gst_rtp_buffer_unmap (&rtp);
1311   gst_buffer_unref (buffer);
1312 
1313   gst_harness_teardown (h);
1314 }
1315 
1316 GST_END_TEST;
1317 
GST_START_TEST(test_rtph264pay_avc)1318 GST_START_TEST (test_rtph264pay_avc)
1319 {
1320   GstHarness *h = gst_harness_new_parse ("rtph264pay timestamp-offset=123"
1321       " aggregate-mode=zero-latency");
1322   GstFlowReturn ret;
1323   GstBuffer *buffer;
1324   GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
1325   GstCaps *caps;
1326   GstBuffer *codec_data;
1327 
1328   codec_data = create_codec_data (h264_sps_avc, sizeof (h264_sps_avc) - 4,
1329       h264_pps_avc, sizeof (h264_pps_avc) - 4);
1330   caps = gst_caps_from_string ("video/x-h264,alignment=au,stream-format=avc");
1331   gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, codec_data, NULL);
1332   gst_buffer_unref (codec_data);
1333 
1334   GST_DEBUG ("caps are %" GST_PTR_FORMAT, caps);
1335 
1336   gst_harness_set_src_caps (h, caps);
1337 
1338   ret = gst_harness_push (h, wrap_static_buffer (h264_idr_slice_1_avc,
1339           sizeof (h264_idr_slice_1_avc)));
1340   fail_unless_equals_int (ret, GST_FLOW_OK);
1341 
1342   buffer =
1343       wrap_static_buffer (h264_idr_slice_2_avc, sizeof (h264_idr_slice_2_avc));
1344   GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_MARKER);
1345   ret = gst_harness_push (h, buffer);
1346   fail_unless_equals_int (ret, GST_FLOW_OK);
1347 
1348   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 2);
1349 
1350   buffer = gst_harness_pull (h);
1351   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
1352   fail_unless (gst_rtp_buffer_get_marker (&rtp));
1353   gst_rtp_buffer_unmap (&rtp);
1354   gst_buffer_unref (buffer);
1355 
1356   buffer = gst_harness_pull (h);
1357   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
1358   fail_unless (gst_rtp_buffer_get_marker (&rtp));
1359   gst_rtp_buffer_unmap (&rtp);
1360   gst_buffer_unref (buffer);
1361 
1362   gst_harness_teardown (h);
1363 }
1364 
1365 GST_END_TEST;
1366 
1367 /*
1368  *  +------------------------------------------------+
1369  *  | GstBuffer                                      |
1370  *  +------------------------------------------------+
1371  *  | GstMemory 1         | GstMemory 2              |
1372  *  +------------------------------------------------+
1373  *  | Slice 1 Part 1      | Slice 1 Part2, Slice 2   |
1374  *  +------------------------------------------------+
1375  *
1376  *  "Slice 1 Part 1" is of size @memory1_len
1377  *
1378  */
1379 static void
test_rtph264pay_avc_two_slices(gsize memory1_len,guint num_slices)1380 test_rtph264pay_avc_two_slices (gsize memory1_len, guint num_slices)
1381 {
1382   GstHarness *h = gst_harness_new_parse ("rtph264pay timestamp-offset=123"
1383       " aggregate-mode=zero-latency");
1384   GstFlowReturn ret;
1385   GstBuffer *slice1;
1386   GstBuffer *slice2;
1387   GstBuffer *buffer;
1388   GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
1389   GstCaps *caps;
1390   GstBuffer *codec_data;
1391   guint8 *rest_of_image;
1392   gsize rest_of_slice_1_size;
1393   gsize rest_of_image_size;
1394 
1395   fail_unless (num_slices <= 2);
1396 
1397   codec_data = create_codec_data (h264_sps_avc, sizeof (h264_sps_avc) - 4,
1398       h264_pps_avc, sizeof (h264_pps_avc) - 4);
1399   caps = gst_caps_from_string ("video/x-h264,alignment=au,stream-format=avc");
1400   gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, codec_data, NULL);
1401   gst_buffer_unref (codec_data);
1402 
1403   GST_DEBUG ("caps are %" GST_PTR_FORMAT, caps);
1404 
1405   gst_harness_set_src_caps (h, caps);
1406 
1407   slice1 = wrap_static_buffer (h264_idr_slice_1_avc, memory1_len);
1408   rest_of_slice_1_size = sizeof (h264_idr_slice_1_avc) - memory1_len;
1409 
1410   if (num_slices == 2) {
1411     rest_of_image_size = rest_of_slice_1_size + sizeof (h264_idr_slice_2_avc);
1412     rest_of_image = g_malloc (rest_of_image_size);
1413 
1414     memcpy (rest_of_image, h264_idr_slice_1_avc + memory1_len,
1415         rest_of_slice_1_size);
1416     memcpy (rest_of_image + rest_of_slice_1_size, h264_idr_slice_2_avc,
1417         sizeof (h264_idr_slice_2_avc));
1418 
1419     slice2 =
1420         wrap_static_buffer_full (rest_of_image, rest_of_image_size,
1421         rest_of_image, g_free);
1422     buffer = gst_buffer_append (slice1, slice2);
1423   } else
1424     buffer = slice1;
1425 
1426   GST_DEBUG ("number of memories: %d", gst_buffer_n_memory (buffer));
1427 
1428   ret = gst_harness_push (h, buffer);
1429   fail_unless_equals_int (ret, GST_FLOW_OK);
1430 
1431   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 1);
1432 
1433   buffer = gst_harness_pull (h);
1434 
1435   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
1436   gst_rtp_buffer_unmap (&rtp);
1437   gst_buffer_unref (buffer);
1438 
1439   gst_harness_teardown (h);
1440 }
1441 
GST_START_TEST(test_rtph264pay_avc_two_slices_per_buffer)1442 GST_START_TEST (test_rtph264pay_avc_two_slices_per_buffer)
1443 {
1444   test_rtph264pay_avc_two_slices (1, 2);
1445   test_rtph264pay_avc_two_slices (2, 2);
1446   test_rtph264pay_avc_two_slices (sizeof (h264_idr_slice_1_avc) - 10, 2);
1447 }
1448 
1449 GST_END_TEST;
1450 
GST_START_TEST(test_rtph264pay_avc_incomplete_nal)1451 GST_START_TEST (test_rtph264pay_avc_incomplete_nal)
1452 {
1453   test_rtph264pay_avc_two_slices (sizeof (h264_idr_slice_1_avc) - 10, 1);
1454 }
1455 
1456 GST_END_TEST;
1457 
1458 static Suite *
rtph264_suite(void)1459 rtph264_suite (void)
1460 {
1461   Suite *s = suite_create ("rtph264");
1462   TCase *tc_chain;
1463 
1464   tc_chain = tcase_create ("rtph264depay");
1465   suite_add_tcase (s, tc_chain);
1466   tcase_add_test (tc_chain, test_rtph264depay_with_downstream_allocator);
1467   tcase_add_test (tc_chain, test_rtph264depay_eos);
1468   tcase_add_test (tc_chain, test_rtph264depay_marker_to_flag);
1469   tcase_add_test (tc_chain, test_rtph264depay_stap_a_marker);
1470   tcase_add_test (tc_chain, test_rtph264depay_fu_a);
1471   tcase_add_test (tc_chain, test_rtph264depay_fu_a_missing_start);
1472 
1473   tc_chain = tcase_create ("rtph264pay");
1474   suite_add_tcase (s, tc_chain);
1475   tcase_add_test (tc_chain, test_rtph264pay_reserved_nals);
1476   tcase_add_test (tc_chain, test_rtph264pay_two_slices_timestamp);
1477   tcase_add_test (tc_chain, test_rtph264pay_marker_for_flag);
1478   tcase_add_test (tc_chain, test_rtph264pay_marker_for_au);
1479   tcase_add_test (tc_chain, test_rtph264pay_marker_for_fragmented_au);
1480   tcase_add_test (tc_chain, test_rtph264pay_aggregate_two_slices_per_buffer);
1481   tcase_add_test (tc_chain, test_rtph264pay_aggregate_with_aud);
1482   tcase_add_test (tc_chain, test_rtph264pay_aggregate_with_ts_change);
1483   tcase_add_test (tc_chain, test_rtph264pay_aggregate_with_discont);
1484   tcase_add_test (tc_chain, test_rtph264pay_aggregate_until_vcl);
1485 
1486   tcase_add_test (tc_chain, test_rtph264pay_avc);
1487   tcase_add_test (tc_chain, test_rtph264pay_avc_two_slices_per_buffer);
1488   tcase_add_test (tc_chain, test_rtph264pay_avc_incomplete_nal);
1489 
1490   return s;
1491 }
1492 
1493 GST_CHECK_MAIN (rtph264);
1494