445d1526610b611adacaebffa42eb7fb540a5263
[platform/upstream/gst-plugins-good.git] / tests / check / elements / rtph265.c
1 /* GStreamer RTP H.265 unit test
2  *
3  * Copyright (C) 2017 Centricular Ltd
4  *   @author: Tim-Philipp Müller <tim@centricular.com>
5  * Copyright (C) 2018 Collabora Ltd
6  *   @author: Nicolas Dufresne <nicolas.dufresne@collabora.com>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  */
23
24 #include <gst/check/check.h>
25 #include <gst/app/app.h>
26 #include <gst/rtp/gstrtpbuffer.h>
27
28 #define ALLOCATOR_CUSTOM_SYSMEM "CustomSysMem"
29
30 static GstAllocator *custom_sysmem_allocator;   /* NULL */
31
32 /* Custom memory */
33
34 typedef struct
35 {
36   GstMemory mem;
37   guint8 *data;
38   guint8 *allocdata;
39 } CustomSysmem;
40
41 static CustomSysmem *
42 custom_sysmem_new (GstMemoryFlags flags, gsize maxsize, gsize align,
43     gsize offset, gsize size)
44 {
45   gsize aoffset, padding;
46   CustomSysmem *mem;
47
48   /* ensure configured alignment */
49   align |= gst_memory_alignment;
50   /* allocate more to compensate for alignment */
51   maxsize += align;
52
53   mem = g_new0 (CustomSysmem, 1);
54
55   mem->allocdata = g_malloc (maxsize);
56
57   mem->data = mem->allocdata;
58
59   /* do alignment */
60   if ((aoffset = ((guintptr) mem->data & align))) {
61     aoffset = (align + 1) - aoffset;
62     mem->data += aoffset;
63     maxsize -= aoffset;
64   }
65
66   if (offset && (flags & GST_MEMORY_FLAG_ZERO_PREFIXED))
67     memset (mem->data, 0, offset);
68
69   padding = maxsize - (offset + size);
70   if (padding && (flags & GST_MEMORY_FLAG_ZERO_PADDED))
71     memset (mem->data + offset + size, 0, padding);
72
73   gst_memory_init (GST_MEMORY_CAST (mem), flags, custom_sysmem_allocator,
74       NULL, maxsize, align, offset, size);
75
76   return mem;
77 }
78
79 static gpointer
80 custom_sysmem_map (CustomSysmem * mem, gsize maxsize, GstMapFlags flags)
81 {
82   return mem->data;
83 }
84
85 static gboolean
86 custom_sysmem_unmap (CustomSysmem * mem)
87 {
88   return TRUE;
89 }
90
91 static CustomSysmem *
92 custom_sysmem_copy (CustomSysmem * mem, gssize offset, gsize size)
93 {
94   g_return_val_if_reached (NULL);
95 }
96
97 static CustomSysmem *
98 custom_sysmem_share (CustomSysmem * mem, gssize offset, gsize size)
99 {
100   g_return_val_if_reached (NULL);
101 }
102
103 static gboolean
104 custom_sysmem_is_span (CustomSysmem * mem1, CustomSysmem * mem2, gsize * offset)
105 {
106   g_return_val_if_reached (FALSE);
107 }
108
109 /* Custom allocator */
110
111 typedef struct
112 {
113   GstAllocator allocator;
114 } CustomSysmemAllocator;
115
116 typedef struct
117 {
118   GstAllocatorClass allocator_class;
119 } CustomSysmemAllocatorClass;
120
121 GType custom_sysmem_allocator_get_type (void);
122 G_DEFINE_TYPE (CustomSysmemAllocator, custom_sysmem_allocator,
123     GST_TYPE_ALLOCATOR);
124
125 static GstMemory *
126 custom_sysmem_allocator_alloc (GstAllocator * allocator, gsize size,
127     GstAllocationParams * params)
128 {
129   gsize maxsize = size + params->prefix + params->padding;
130
131   return (GstMemory *) custom_sysmem_new (params->flags,
132       maxsize, params->align, params->prefix, size);
133 }
134
135 static void
136 custom_sysmem_allocator_free (GstAllocator * allocator, GstMemory * mem)
137 {
138   CustomSysmem *csmem = (CustomSysmem *) mem;
139
140   g_free (csmem->allocdata);
141   g_free (csmem);
142 }
143
144 static void
145 custom_sysmem_allocator_class_init (CustomSysmemAllocatorClass * klass)
146 {
147   GstAllocatorClass *allocator_class = (GstAllocatorClass *) klass;
148
149   allocator_class->alloc = custom_sysmem_allocator_alloc;
150   allocator_class->free = custom_sysmem_allocator_free;
151 }
152
153 static void
154 custom_sysmem_allocator_init (CustomSysmemAllocator * allocator)
155 {
156   GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator);
157
158   alloc->mem_type = ALLOCATOR_CUSTOM_SYSMEM;
159   alloc->mem_map = (GstMemoryMapFunction) custom_sysmem_map;
160   alloc->mem_unmap = (GstMemoryUnmapFunction) custom_sysmem_unmap;
161   alloc->mem_copy = (GstMemoryCopyFunction) custom_sysmem_copy;
162   alloc->mem_share = (GstMemoryShareFunction) custom_sysmem_share;
163   alloc->mem_is_span = (GstMemoryIsSpanFunction) custom_sysmem_is_span;
164 }
165
166 /* AppSink subclass proposing our custom allocator to upstream */
167
168 typedef struct
169 {
170   GstAppSink appsink;
171 } CMemAppSink;
172
173 typedef struct
174 {
175   GstAppSinkClass appsink;
176 } CMemAppSinkClass;
177
178 GType c_mem_app_sink_get_type (void);
179
180 G_DEFINE_TYPE (CMemAppSink, c_mem_app_sink, GST_TYPE_APP_SINK);
181
182 static void
183 c_mem_app_sink_init (CMemAppSink * cmemsink)
184 {
185 }
186
187 static gboolean
188 c_mem_app_sink_propose_allocation (GstBaseSink * sink, GstQuery * query)
189 {
190   gst_query_add_allocation_param (query, custom_sysmem_allocator, NULL);
191   return TRUE;
192 }
193
194 static void
195 c_mem_app_sink_class_init (CMemAppSinkClass * klass)
196 {
197   GstBaseSinkClass *basesink_class = (GstBaseSinkClass *) klass;
198
199   basesink_class->propose_allocation = c_mem_app_sink_propose_allocation;
200 }
201
202 #define RTP_H265_FILE GST_TEST_FILES_PATH G_DIR_SEPARATOR_S "h265.rtp"
203
204 GST_START_TEST (test_rtph265depay_with_downstream_allocator)
205 {
206   GstElement *pipeline, *src, *depay, *sink;
207   GstMemory *mem;
208   GstSample *sample;
209   GstBuffer *buf;
210   GstCaps *caps;
211
212   custom_sysmem_allocator =
213       g_object_new (custom_sysmem_allocator_get_type (), NULL);
214
215   pipeline = gst_pipeline_new ("pipeline");
216
217   src = gst_element_factory_make ("appsrc", NULL);
218
219   caps = gst_caps_new_simple ("application/x-rtp",
220       "media", G_TYPE_STRING, "video",
221       "payload", G_TYPE_INT, 96,
222       "clock-rate", G_TYPE_INT, 90000,
223       "encoding-name", G_TYPE_STRING, "H265",
224       "ssrc", G_TYPE_UINT, 1990683810,
225       "timestamp-offset", G_TYPE_UINT, 3697583446,
226       "seqnum-offset", G_TYPE_UINT, 15568,
227       "a-framerate", G_TYPE_STRING, "30", NULL);
228   g_object_set (src, "format", GST_FORMAT_TIME, "caps", caps, NULL);
229   gst_bin_add (GST_BIN (pipeline), src);
230   gst_caps_unref (caps);
231
232   depay = gst_element_factory_make ("rtph265depay", NULL);
233   gst_bin_add (GST_BIN (pipeline), depay);
234
235   sink = g_object_new (c_mem_app_sink_get_type (), NULL);
236   gst_bin_add (GST_BIN (pipeline), sink);
237
238   gst_element_link_many (src, depay, sink, NULL);
239
240   gst_element_set_state (pipeline, GST_STATE_PAUSED);
241
242   {
243     gchar *data, *pdata;
244     gsize len;
245
246     fail_unless (g_file_get_contents (RTP_H265_FILE, &data, &len, NULL));
247     fail_unless (len > 2);
248
249     pdata = data;
250     while (len > 2) {
251       GstFlowReturn flow;
252       guint16 packet_len;
253
254       packet_len = GST_READ_UINT16_BE (pdata);
255       GST_INFO ("rtp packet length: %u (bytes left: %u)", packet_len,
256           (guint) len);
257       fail_unless (len >= 2 + packet_len);
258
259       flow = gst_app_src_push_buffer (GST_APP_SRC (src),
260           gst_buffer_new_wrapped (g_memdup (pdata + 2, packet_len),
261               packet_len));
262
263       fail_unless_equals_int (flow, GST_FLOW_OK);
264
265       pdata += 2 + packet_len;
266       len -= 2 + packet_len;
267     }
268
269     g_free (data);
270   }
271
272   gst_app_src_end_of_stream (GST_APP_SRC (src));
273
274   sample = gst_app_sink_pull_preroll (GST_APP_SINK (sink));
275   fail_unless (sample != NULL);
276
277   buf = gst_sample_get_buffer (sample);
278
279   GST_LOG ("buffer has %u memories", gst_buffer_n_memory (buf));
280   GST_LOG ("buffer size: %u", (guint) gst_buffer_get_size (buf));
281
282   fail_unless (gst_buffer_n_memory (buf) > 0);
283   mem = gst_buffer_peek_memory (buf, 0);
284   fail_unless (mem != NULL);
285
286   GST_LOG ("buffer memory type: %s", mem->allocator->mem_type);
287   fail_unless (gst_memory_is_type (mem, ALLOCATOR_CUSTOM_SYSMEM));
288
289   gst_sample_unref (sample);
290
291   gst_element_set_state (pipeline, GST_STATE_NULL);
292
293   gst_object_unref (pipeline);
294
295   g_object_unref (custom_sysmem_allocator);
296   custom_sysmem_allocator = NULL;
297 }
298
299 GST_END_TEST;
300
301
302 static GstBuffer *
303 wrap_static_buffer_with_pts (guint8 * buf, gsize size, GstClockTime pts)
304 {
305   GstBuffer *buffer;
306
307   buffer = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
308       buf, size, 0, size, NULL, NULL);
309   GST_BUFFER_PTS (buffer) = pts;
310
311   return buffer;
312 }
313
314 static GstBuffer *
315 wrap_static_buffer (guint8 * buf, gsize size)
316 {
317   return wrap_static_buffer_with_pts (buf, size, GST_CLOCK_TIME_NONE);
318 }
319
320 /* This was generated using pipeline:
321  * gst-launch-1.0 videotestsrc num-buffers=1 pattern=green \
322  *     ! video/x-raw,width=64,height=64 ! x265enc ! h265parse \
323  *     ! rtph265pay ! fakesink dump=1
324  */
325 /* RTP h265_idr + marker */
326 static guint8 rtp_h265_idr[] = {
327   0x80, 0xe0, 0x2c, 0x6a, 0xab, 0x7f, 0x71, 0xc0,
328   0x8d, 0x11, 0x33, 0x07, 0x28, 0x01, 0xaf, 0x05,
329   0x38, 0x4a, 0x03, 0x06, 0x7c, 0x7a, 0xb1, 0x8b,
330   0xff, 0xfe, 0xfd, 0xb7, 0xff, 0xff, 0xd1, 0xff,
331   0x40, 0x06, 0xd8, 0xd3, 0xb2, 0xf8
332 };
333
334 GST_START_TEST (test_rtph265depay_eos)
335 {
336   GstHarness *h = gst_harness_new ("rtph265depay");
337   GstBuffer *buffer;
338   GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
339   GstFlowReturn ret;
340
341   gst_harness_set_caps_str (h,
342       "application/x-rtp,media=video,clock-rate=90000,encoding-name=H265",
343       "video/x-h265,alignment=au,stream-format=byte-stream");
344
345   buffer = wrap_static_buffer (rtp_h265_idr, sizeof (rtp_h265_idr));
346   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_WRITE, &rtp));
347   gst_rtp_buffer_set_marker (&rtp, FALSE);
348   gst_rtp_buffer_unmap (&rtp);
349
350   ret = gst_harness_push (h, buffer);
351   fail_unless_equals_int (ret, GST_FLOW_OK);
352   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 0);
353
354   fail_unless (gst_harness_push_event (h, gst_event_new_eos ()));
355   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 1);
356
357   gst_harness_teardown (h);
358 }
359
360 GST_END_TEST;
361
362
363 GST_START_TEST (test_rtph265depay_marker_to_flag)
364 {
365   GstHarness *h = gst_harness_new ("rtph265depay");
366   GstBuffer *buffer;
367   GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
368   GstFlowReturn ret;
369   guint16 seq;
370
371   gst_harness_set_caps_str (h,
372       "application/x-rtp,media=video,clock-rate=90000,encoding-name=H265",
373       "video/x-h265,alignment=au,stream-format=byte-stream");
374
375   buffer = wrap_static_buffer (rtp_h265_idr, sizeof (rtp_h265_idr));
376   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
377   fail_unless (gst_rtp_buffer_get_marker (&rtp));
378   seq = gst_rtp_buffer_get_seq (&rtp);
379   gst_rtp_buffer_unmap (&rtp);
380
381   ret = gst_harness_push (h, buffer);
382   fail_unless_equals_int (ret, GST_FLOW_OK);
383   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 1);
384
385   buffer = wrap_static_buffer (rtp_h265_idr, sizeof (rtp_h265_idr));
386   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_WRITE, &rtp));
387   gst_rtp_buffer_set_marker (&rtp, FALSE);
388   gst_rtp_buffer_set_seq (&rtp, ++seq);
389   gst_rtp_buffer_unmap (&rtp);
390
391   ret = gst_harness_push (h, buffer);
392   fail_unless_equals_int (ret, GST_FLOW_OK);
393
394   /* the second NAL is blocked as there is no marker to let the payloader
395    * know it's a complete AU, we'll use an EOS to unblock it */
396   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 1);
397   fail_unless (gst_harness_push_event (h, gst_event_new_eos ()));
398   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 2);
399
400   buffer = gst_harness_pull (h);
401   fail_unless (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_MARKER));
402   gst_buffer_unref (buffer);
403
404   buffer = gst_harness_pull (h);
405   fail_if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_MARKER));
406   gst_buffer_unref (buffer);
407
408   gst_harness_teardown (h);
409 }
410
411 GST_END_TEST;
412
413 /* These were generated using pipeline:
414  * gst-launch-1.0 videotestsrc num-buffers=1 pattern=green \
415  *     ! video/x-raw,width=256,height=256 \
416  *     ! x265enc option-string="slices=2" \
417  *     ! fakesink dump=1
418  */
419
420 /* IDR Slice 1 */
421 static guint8 h265_idr_slice_1[] = {
422   0x00, 0x00, 0x00, 0x01, 0x28, 0x01, 0xaf, 0x08,
423   0xa2, 0xe6, 0xa3, 0xc6, 0x53, 0x90, 0xea, 0xc8,
424   0x3f, 0xfe, 0xfa, 0xf9, 0x3f, 0xf2, 0x61, 0x98,
425   0xef, 0xf4, 0xe9, 0x97, 0xe7, 0xc2, 0x74, 0x78,
426   0x98, 0x10, 0x01, 0x21, 0xa4, 0x3c, 0x4c, 0x08,
427   0x00, 0x3e, 0x40, 0x92, 0x0c, 0x78
428 };
429
430 /* IDR Slice 2 */
431 static guint8 h265_idr_slice_2[] = {
432   0x00, 0x00, 0x01, 0x28, 0x01, 0x30, 0xf0, 0x8a,
433   0x2e, 0x60, 0xa3, 0xc6, 0x53, 0x90, 0xea, 0xc8,
434   0x3f, 0xfe, 0xfa, 0xf9, 0x3f, 0xf2, 0x61, 0x98,
435   0xef, 0xf4, 0xe9, 0x97, 0xe7, 0xc2, 0x74, 0x78,
436   0x98, 0x10, 0x01, 0x21, 0xa4, 0x3c, 0x4c, 0x08,
437   0x00, 0x3e, 0x40, 0x92, 0x0c, 0x78
438 };
439
440 GST_START_TEST (test_rtph265pay_two_slices_timestamp)
441 {
442   GstHarness *h = gst_harness_new_parse ("rtph265pay timestamp-offset=123");
443   GstFlowReturn ret;
444   GstBuffer *buffer;
445   GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
446
447   gst_harness_set_src_caps_str (h,
448       "video/x-h265,alignment=nal,stream-format=byte-stream");
449
450   ret = gst_harness_push (h, wrap_static_buffer_with_pts (h265_idr_slice_1,
451           sizeof (h265_idr_slice_1), 0));
452   fail_unless_equals_int (ret, GST_FLOW_OK);
453
454   ret = gst_harness_push (h, wrap_static_buffer_with_pts (h265_idr_slice_2,
455           sizeof (h265_idr_slice_2), 0));
456   fail_unless_equals_int (ret, GST_FLOW_OK);
457
458   ret = gst_harness_push (h, wrap_static_buffer_with_pts (h265_idr_slice_1,
459           sizeof (h265_idr_slice_1), GST_SECOND));
460   fail_unless_equals_int (ret, GST_FLOW_OK);
461
462   ret = gst_harness_push (h, wrap_static_buffer_with_pts (h265_idr_slice_2,
463           sizeof (h265_idr_slice_2), GST_SECOND));
464   fail_unless_equals_int (ret, GST_FLOW_OK);
465
466   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 4);
467
468   buffer = gst_harness_pull (h);
469   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
470   fail_unless_equals_uint64 (GST_BUFFER_PTS (buffer), 0);
471   fail_unless_equals_uint64 (gst_rtp_buffer_get_timestamp (&rtp), 123);
472   gst_rtp_buffer_unmap (&rtp);
473   gst_buffer_unref (buffer);
474
475   buffer = gst_harness_pull (h);
476   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
477   fail_unless_equals_uint64 (GST_BUFFER_PTS (buffer), 0);
478   fail_unless_equals_uint64 (gst_rtp_buffer_get_timestamp (&rtp), 123);
479   gst_rtp_buffer_unmap (&rtp);
480   gst_buffer_unref (buffer);
481
482   buffer = gst_harness_pull (h);
483   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
484   fail_unless_equals_uint64 (GST_BUFFER_PTS (buffer), GST_SECOND);
485   fail_unless_equals_uint64 (gst_rtp_buffer_get_timestamp (&rtp), 123 + 90000);
486   gst_rtp_buffer_unmap (&rtp);
487   gst_buffer_unref (buffer);
488
489   buffer = gst_harness_pull (h);
490   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
491   fail_unless_equals_uint64 (GST_BUFFER_PTS (buffer), GST_SECOND);
492   fail_unless_equals_uint64 (gst_rtp_buffer_get_timestamp (&rtp), 123 + 90000);
493   gst_rtp_buffer_unmap (&rtp);
494   gst_buffer_unref (buffer);
495
496   gst_harness_teardown (h);
497 }
498
499 GST_END_TEST;
500
501 GST_START_TEST (test_rtph265pay_marker_for_flag)
502 {
503   GstHarness *h = gst_harness_new_parse ("rtph265pay timestamp-offset=123");
504   GstFlowReturn ret;
505   GstBuffer *buffer;
506   GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
507
508   gst_harness_set_src_caps_str (h,
509       "video/x-h265,alignment=nal,stream-format=byte-stream");
510
511   ret = gst_harness_push (h, wrap_static_buffer (h265_idr_slice_1,
512           sizeof (h265_idr_slice_1)));
513   fail_unless_equals_int (ret, GST_FLOW_OK);
514
515   buffer = wrap_static_buffer (h265_idr_slice_2, sizeof (h265_idr_slice_2));
516   GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_MARKER);
517   ret = gst_harness_push (h, buffer);
518   fail_unless_equals_int (ret, GST_FLOW_OK);
519
520   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 2);
521
522   buffer = gst_harness_pull (h);
523   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
524   fail_if (gst_rtp_buffer_get_marker (&rtp));
525   gst_rtp_buffer_unmap (&rtp);
526   gst_buffer_unref (buffer);
527
528   buffer = gst_harness_pull (h);
529   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
530   fail_unless (gst_rtp_buffer_get_marker (&rtp));
531   gst_rtp_buffer_unmap (&rtp);
532   gst_buffer_unref (buffer);
533
534   gst_harness_teardown (h);
535 }
536
537 GST_END_TEST;
538
539
540 GST_START_TEST (test_rtph265pay_marker_for_au)
541 {
542   GstHarness *h = gst_harness_new_parse ("rtph265pay timestamp-offset=123");
543   GstFlowReturn ret;
544   GstBuffer *slice1, *slice2, *buffer;
545   GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
546
547   gst_harness_set_src_caps_str (h,
548       "video/x-h265,alignment=au,stream-format=byte-stream");
549
550   slice1 = wrap_static_buffer (h265_idr_slice_1, sizeof (h265_idr_slice_1));
551   slice2 = wrap_static_buffer (h265_idr_slice_2, sizeof (h265_idr_slice_2));
552   buffer = gst_buffer_append (slice1, slice2);
553
554   ret = gst_harness_push (h, buffer);
555   fail_unless_equals_int (ret, GST_FLOW_OK);
556
557   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 2);
558
559   buffer = gst_harness_pull (h);
560   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
561   fail_if (gst_rtp_buffer_get_marker (&rtp));
562   gst_rtp_buffer_unmap (&rtp);
563   gst_buffer_unref (buffer);
564
565   buffer = gst_harness_pull (h);
566   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
567   fail_unless (gst_rtp_buffer_get_marker (&rtp));
568   gst_rtp_buffer_unmap (&rtp);
569   gst_buffer_unref (buffer);
570
571   gst_harness_teardown (h);
572 }
573
574 GST_END_TEST;
575
576
577 GST_START_TEST (test_rtph265pay_marker_for_fragmented_au)
578 {
579   GstHarness *h =
580       gst_harness_new_parse ("rtph265pay timestamp-offset=123 mtu=40");
581   GstFlowReturn ret;
582   GstBuffer *slice1, *slice2, *buffer;
583   GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
584   gint i;
585
586   gst_harness_set_src_caps_str (h,
587       "video/x-h265,alignment=au,stream-format=byte-stream");
588
589   slice1 = wrap_static_buffer (h265_idr_slice_1, sizeof (h265_idr_slice_1));
590   slice2 = wrap_static_buffer (h265_idr_slice_2, sizeof (h265_idr_slice_2));
591   buffer = gst_buffer_append (slice1, slice2);
592
593   ret = gst_harness_push (h, buffer);
594   fail_unless_equals_int (ret, GST_FLOW_OK);
595
596   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 4);
597
598   for (i = 0; i < 3; i++) {
599     buffer = gst_harness_pull (h);
600     fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
601     fail_if (gst_rtp_buffer_get_marker (&rtp));
602     gst_rtp_buffer_unmap (&rtp);
603     gst_buffer_unref (buffer);
604   }
605
606   buffer = gst_harness_pull (h);
607   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
608   fail_unless (gst_rtp_buffer_get_marker (&rtp));
609   gst_rtp_buffer_unmap (&rtp);
610   gst_buffer_unref (buffer);
611
612   gst_harness_teardown (h);
613 }
614
615 GST_END_TEST;
616
617
618 static Suite *
619 rtph265_suite (void)
620 {
621   Suite *s = suite_create ("rtph265");
622   TCase *tc_chain;
623
624   tc_chain = tcase_create ("rtph265depay");
625   suite_add_tcase (s, tc_chain);
626   tcase_add_test (tc_chain, test_rtph265depay_with_downstream_allocator);
627   tcase_add_test (tc_chain, test_rtph265depay_eos);
628   tcase_add_test (tc_chain, test_rtph265depay_marker_to_flag);
629
630   tc_chain = tcase_create ("rtph265pay");
631   suite_add_tcase (s, tc_chain);
632   tcase_add_test (tc_chain, test_rtph265pay_two_slices_timestamp);
633   tcase_add_test (tc_chain, test_rtph265pay_marker_for_flag);
634   tcase_add_test (tc_chain, test_rtph265pay_marker_for_au);
635   tcase_add_test (tc_chain, test_rtph265pay_marker_for_fragmented_au);
636
637   return s;
638 }
639
640 GST_CHECK_MAIN (rtph265);