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