From 1b32cb1eae186b48e453b8a2a8da1ba943afb2c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Cr=C3=AAte?= Date: Tue, 18 Jun 2019 19:07:38 -0400 Subject: [PATCH] rtph265pay: Implement Aggregation packets Align with rtph264pay --- gst/rtp/gstrtph265pay.c | 355 ++++++++++++++++++++++++-- gst/rtp/gstrtph265pay.h | 15 ++ tests/check/elements/rtp-payloading.c | 2 +- tests/check/elements/rtph265.c | 3 +- 4 files changed, 356 insertions(+), 19 deletions(-) diff --git a/gst/rtp/gstrtph265pay.c b/gst/rtp/gstrtph265pay.c index 09a677068e..7cfeef25a6 100644 --- a/gst/rtp/gstrtph265pay.c +++ b/gst/rtp/gstrtph265pay.c @@ -35,11 +35,38 @@ #include "gstrtph265pay.h" #include "gstrtputils.h" +#define AP_TYPE_ID 48 #define FU_TYPE_ID 49 GST_DEBUG_CATEGORY_STATIC (rtph265pay_debug); #define GST_CAT_DEFAULT (rtph265pay_debug) +#define GST_TYPE_RTP_H265_AGGREGATE_MODE \ + (gst_rtp_h265_aggregate_mode_get_type ()) + + +static GType +gst_rtp_h265_aggregate_mode_get_type (void) +{ + static GType type = 0; + static const GEnumValue values[] = { + {GST_RTP_H265_AGGREGATE_NONE, "Do not aggregate NAL units", "none"}, + {GST_RTP_H265_AGGREGATE_ZERO_LATENCY, "Aggregate all that arrive together", + "zero-latency"}, + {GST_RTP_H265_AGGREGATE_MAX, + "Aggregate all NAL units with the same timestamp (adds one frame of" + " latency)", "max"}, + {0, NULL, NULL}, + }; + + if (!type) { + type = g_enum_register_static ("GstRtpH265AggregateMode", values); + } + return type; +} + + + /* references: * * Internet Draft RTP Payload Format for High Efficiency Video Coding @@ -104,12 +131,13 @@ GST_STATIC_PAD_TEMPLATE ("src", ); #define DEFAULT_CONFIG_INTERVAL 0 - +#define DEFAULT_AGGREGATE_MODE GST_RTP_H265_AGGREGATE_ZERO_LATENCY enum { PROP_0, PROP_CONFIG_INTERVAL, + PROP_AGGREGATE_MODE, }; static void gst_rtp_h265_pay_finalize (GObject * object); @@ -129,13 +157,10 @@ static gboolean gst_rtp_h265_pay_sink_event (GstRTPBasePayload * payload, GstEvent * event); static GstStateChangeReturn gst_rtp_h265_pay_change_state (GstElement * element, GstStateChange transition); -static GstFlowReturn gst_rtp_h265_pay_payload_nal_single (GstRTPBasePayload * - basepayload, GstBuffer * paybuf, GstClockTime dts, GstClockTime pts, - gboolean marker); -static GstFlowReturn gst_rtp_h265_pay_payload_nal_fragment (GstRTPBasePayload * - basepayload, GstBuffer * paybuf, GstClockTime dts, GstClockTime pts, - gboolean marker, guint mtu, guint8 nal_type, const guint8 * nal_header, - int size); +static gboolean gst_rtp_h265_pay_src_query (GstPad * pad, GstObject * parent, + GstQuery * query); + +static void gst_rtp_h265_pay_reset_bundle (GstRtpH265Pay * rtph265pay); #define gst_rtp_h265_pay_parent_class parent_class G_DEFINE_TYPE (GstRtpH265Pay, gst_rtp_h265_pay, GST_TYPE_RTP_BASE_PAYLOAD); @@ -165,6 +190,15 @@ gst_rtp_h265_pay_class_init (GstRtpH265PayClass * klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS) ); + g_object_class_install_property (G_OBJECT_CLASS (klass), + PROP_AGGREGATE_MODE, + g_param_spec_enum ("aggregate-mode", + "Attempt to use aggregate packets", + "Bundle suitable SPS/PPS NAL units into aggregate packets.", + GST_TYPE_RTP_H265_AGGREGATE_MODE, + DEFAULT_AGGREGATE_MODE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS) + ); + gobject_class->finalize = gst_rtp_h265_pay_finalize; gst_element_class_add_static_pad_template (gstelement_class, @@ -201,8 +235,12 @@ gst_rtp_h265_pay_init (GstRtpH265Pay * rtph265pay) (GDestroyNotify) gst_buffer_unref); rtph265pay->last_vps_sps_pps = -1; rtph265pay->vps_sps_pps_interval = DEFAULT_CONFIG_INTERVAL; + rtph265pay->aggregate_mode = DEFAULT_AGGREGATE_MODE; rtph265pay->adapter = gst_adapter_new (); + + gst_pad_set_query_function (GST_RTP_BASE_PAYLOAD_SRCPAD (rtph265pay), + gst_rtp_h265_pay_src_query); } static void @@ -228,9 +266,47 @@ gst_rtp_h265_pay_finalize (GObject * object) g_object_unref (rtph265pay->adapter); + gst_rtp_h265_pay_reset_bundle (rtph265pay); + G_OBJECT_CLASS (parent_class)->finalize (object); } +static gboolean +gst_rtp_h265_pay_src_query (GstPad * pad, GstObject * parent, GstQuery * query) +{ + GstRtpH265Pay *rtph265pay = GST_RTP_H265_PAY (parent); + + if (GST_QUERY_TYPE (query) == GST_QUERY_LATENCY) { + gboolean retval; + gboolean live; + GstClockTime min_latency, max_latency; + + retval = gst_pad_query_default (pad, parent, query); + if (!retval) + return retval; + + if (rtph265pay->stream_format == GST_H265_STREAM_FORMAT_UNKNOWN || + rtph265pay->alignment == GST_H265_ALIGNMENT_UNKNOWN) + return FALSE; + + gst_query_parse_latency (query, &live, &min_latency, &max_latency); + + if (rtph265pay->aggregate_mode == GST_RTP_H265_AGGREGATE_MAX && + rtph265pay->alignment != GST_H265_ALIGNMENT_AU && rtph265pay->fps_num) { + GstClockTime one_frame = gst_util_uint64_scale_int (GST_SECOND, + rtph265pay->fps_denum, rtph265pay->fps_num); + + min_latency += one_frame; + max_latency += one_frame; + gst_query_set_latency (query, live, min_latency, max_latency); + } + return TRUE; + } + + return gst_pad_query_default (pad, parent, query); +} + + static const gchar all_levels[][4] = { "1", "2", @@ -508,6 +584,11 @@ gst_rtp_h265_pay_setcaps (GstRTPBasePayload * basepayload, GstCaps * caps) rtph265pay->stream_format = GST_H265_STREAM_FORMAT_BYTESTREAM; } + if (!gst_structure_get_fraction (str, "framerate", &rtph265pay->fps_num, + &rtph265pay->fps_denum)) + rtph265pay->fps_num = rtph265pay->fps_denum = 0; + + /* packetized HEVC video has a codec_data */ if ((value = gst_structure_get_value (str, "codec_data"))) { guint num_vps, num_sps, num_pps; @@ -820,9 +901,18 @@ gst_rtp_h265_pay_decode_nal (GstRtpH265Pay * payloader, return updated; } -static GstFlowReturn -gst_rtp_h265_pay_payload_nal (GstRTPBasePayload * basepayload, - GPtrArray * paybufs, GstClockTime dts, GstClockTime pts); +static GstFlowReturn gst_rtp_h265_pay_payload_nal (GstRTPBasePayload * + basepayload, GPtrArray * paybufs, GstClockTime dts, GstClockTime pts); +static GstFlowReturn gst_rtp_h265_pay_payload_nal_single (GstRTPBasePayload * + basepayload, GstBuffer * paybuf, GstClockTime dts, GstClockTime pts, + gboolean marker); +static GstFlowReturn gst_rtp_h265_pay_payload_nal_fragment (GstRTPBasePayload * + basepayload, GstBuffer * paybuf, GstClockTime dts, GstClockTime pts, + gboolean marker, guint mtu, guint8 nal_type, const guint8 * nal_header, + int size); +static GstFlowReturn gst_rtp_h265_pay_payload_nal_bundle (GstRTPBasePayload * + basepayload, GstBuffer * paybuf, GstClockTime dts, GstClockTime pts, + gboolean marker, guint8 nal_type, const guint8 * nal_header, int size); static GstFlowReturn gst_rtp_h265_pay_send_vps_sps_pps (GstRTPBasePayload * basepayload, @@ -873,6 +963,14 @@ gst_rtp_h265_pay_send_vps_sps_pps (GstRTPBasePayload * basepayload, return ret; } +static void +gst_rtp_h265_pay_reset_bundle (GstRtpH265Pay * rtph265pay) +{ + g_clear_pointer (&rtph265pay->bundle, gst_buffer_list_unref); + rtph265pay->bundle_size = 0; + rtph265pay->bundle_contains_vcl = FALSE; +} + static GstFlowReturn gst_rtp_h265_pay_payload_nal (GstRTPBasePayload * basepayload, GPtrArray * paybufs, GstClockTime dts, GstClockTime pts) @@ -992,8 +1090,12 @@ gst_rtp_h265_pay_payload_nal (GstRTPBasePayload * basepayload, } } - ret = gst_rtp_h265_pay_payload_nal_fragment (basepayload, paybuf, dts, - pts, marker, mtu, nal_type, nal_header, size); + if (rtph265pay->aggregate_mode != GST_RTP_H265_AGGREGATE_NONE) + ret = gst_rtp_h265_pay_payload_nal_bundle (basepayload, paybuf, dts, pts, + marker, nal_type, nal_header, size); + else + ret = gst_rtp_h265_pay_payload_nal_fragment (basepayload, paybuf, dts, + pts, marker, mtu, nal_type, nal_header, size); } g_ptr_array_free (paybufs, TRUE); @@ -1123,6 +1225,193 @@ gst_rtp_h265_pay_payload_nal_fragment (GstRTPBasePayload * basepayload, return ret; } +static GstFlowReturn +gst_rtp_h265_pay_send_bundle (GstRtpH265Pay * rtph265pay, gboolean marker) +{ + GstRTPBasePayload *basepayload; + GstBufferList *bundle; + guint length, bundle_size; + GstBuffer *first, *outbuf; + GstClockTime dts, pts; + + bundle_size = rtph265pay->bundle_size; + + if (bundle_size == 0) { + GST_DEBUG_OBJECT (rtph265pay, "no bundle, nothing to send"); + return GST_FLOW_OK; + } + + basepayload = GST_RTP_BASE_PAYLOAD (rtph265pay); + bundle = rtph265pay->bundle; + length = gst_buffer_list_length (bundle); + + first = gst_buffer_list_get (bundle, 0); + dts = GST_BUFFER_DTS (first); + pts = GST_BUFFER_PTS (first); + + if (length == 1) { + /* Push unaggregated NALU */ + outbuf = gst_buffer_ref (first); + + GST_DEBUG_OBJECT (rtph265pay, + "sending NAL Unit unaggregated: datasize=%u", bundle_size - 2); + } else { + guint8 ap_header[2]; + guint i; + guint8 layer_id = 0xFF; + guint8 temporal_id = 0xFF; + + outbuf = gst_buffer_new_allocate (NULL, sizeof ap_header, NULL); + + for (i = 0; i < length; i++) { + GstBuffer *buf = gst_buffer_list_get (bundle, i); + guint8 nal_header[2]; + GstMemory *size_header; + GstMapInfo map; + guint8 nal_layer_id; + guint8 nal_temporal_id; + + gst_buffer_extract (buf, 0, &nal_header, sizeof nal_header); + + /* Propagate F bit */ + if ((nal_header[0] & 0x80)) + ap_header[0] |= 0x80; + + /* Select lowest layer_id & temporal_id */ + nal_layer_id = ((nal_header[0] & 0x01) << 5) | + ((nal_header[1] >> 3) & 0x1F); + nal_temporal_id = nal_header[1] & 0x7; + layer_id = MIN (layer_id, nal_layer_id); + temporal_id = MIN (temporal_id, nal_temporal_id); + + /* append NALU size */ + size_header = gst_allocator_alloc (NULL, 2, NULL); + gst_memory_map (size_header, &map, GST_MAP_WRITE); + GST_WRITE_UINT16_BE (map.data, gst_buffer_get_size (buf)); + gst_memory_unmap (size_header, &map); + gst_buffer_append_memory (outbuf, size_header); + + /* append NALU data */ + outbuf = gst_buffer_append (outbuf, gst_buffer_ref (buf)); + } + + ap_header[0] = (AP_TYPE_ID << 1) | (layer_id & 0x20); + ap_header[1] = ((layer_id & 0x1F) << 3) | (temporal_id | 0x07); + + gst_buffer_fill (outbuf, 0, &ap_header, sizeof ap_header); + + GST_DEBUG_OBJECT (rtph265pay, + "sending AP bundle: n=%u header=%02x%02x datasize=%u", + length, ap_header[0], ap_header[1], bundle_size); + } + + gst_rtp_h265_pay_reset_bundle (rtph265pay); + return gst_rtp_h265_pay_payload_nal_single (basepayload, outbuf, dts, pts, + marker); +} + +static gboolean +gst_rtp_h265_pay_payload_nal_bundle (GstRTPBasePayload * basepayload, + GstBuffer * paybuf, GstClockTime dts, GstClockTime pts, + gboolean marker, guint8 nal_type, const guint8 * nal_header, int size) +{ + GstRtpH265Pay *rtph265pay; + GstFlowReturn ret; + guint pay_size, bundle_size; + GstBufferList *bundle; + gboolean start_of_au; + guint mtu; + + rtph265pay = GST_RTP_H265_PAY (basepayload); + mtu = GST_RTP_BASE_PAYLOAD_MTU (rtph265pay); + pay_size = 2 + gst_buffer_get_size (paybuf); + bundle = rtph265pay->bundle; + start_of_au = FALSE; + + if (bundle) { + GstBuffer *first = gst_buffer_list_get (bundle, 0); + + if (nal_type == GST_H265_NAL_AUD) { + GST_DEBUG_OBJECT (rtph265pay, "found access delimiter"); + start_of_au = TRUE; + } else if (GST_BUFFER_IS_DISCONT (paybuf)) { + GST_DEBUG_OBJECT (rtph265pay, "found discont"); + start_of_au = TRUE; + } else if (GST_BUFFER_PTS (first) != pts || GST_BUFFER_DTS (first) != dts) { + GST_DEBUG_OBJECT (rtph265pay, "found timestamp mismatch"); + start_of_au = TRUE; + } + } + + if (start_of_au) { + GST_DEBUG_OBJECT (rtph265pay, "sending bundle before start of AU"); + + ret = gst_rtp_h265_pay_send_bundle (rtph265pay, TRUE); + if (ret != GST_FLOW_OK) + goto out; + + bundle = NULL; + } + + bundle_size = 2 + pay_size; + + if (gst_rtp_buffer_calc_packet_len (bundle_size, 0, 0) > mtu) { + GST_DEBUG_OBJECT (rtph265pay, "NAL Unit cannot fit in a bundle"); + + ret = gst_rtp_h265_pay_send_bundle (rtph265pay, FALSE); + if (ret != GST_FLOW_OK) + goto out; + + return gst_rtp_h265_pay_payload_nal_fragment (basepayload, paybuf, dts, pts, + marker, mtu, nal_type, nal_header, size); + } + + bundle_size = rtph265pay->bundle_size + pay_size; + + if (gst_rtp_buffer_calc_packet_len (bundle_size, 0, 0) > mtu) { + GST_DEBUG_OBJECT (rtph265pay, + "bundle overflows, sending: bundlesize=%u datasize=2+%u mtu=%u", + rtph265pay->bundle_size, pay_size - 2, mtu); + + ret = gst_rtp_h265_pay_send_bundle (rtph265pay, FALSE); + if (ret != GST_FLOW_OK) + goto out; + + bundle = NULL; + } + + if (!bundle) { + GST_DEBUG_OBJECT (rtph265pay, "creating new AP aggregate"); + bundle = rtph265pay->bundle = gst_buffer_list_new (); + bundle_size = rtph265pay->bundle_size = 2; + rtph265pay->bundle_contains_vcl = FALSE; + } + + GST_DEBUG_OBJECT (rtph265pay, + "bundling NAL Unit: bundlesize=%u datasize=2+%u mtu=%u", + rtph265pay->bundle_size, pay_size - 2, mtu); + + paybuf = gst_buffer_make_writable (paybuf); + GST_BUFFER_PTS (paybuf) = pts; + GST_BUFFER_DTS (paybuf) = dts; + + gst_buffer_list_add (bundle, gst_buffer_ref (paybuf)); + rtph265pay->bundle_size += pay_size; + ret = GST_FLOW_OK; + + /* In H.265, all VCL NAL units are < 32 */ + if (nal_type < 32) + rtph265pay->bundle_contains_vcl = TRUE; + + if (marker) { + GST_DEBUG_OBJECT (rtph265pay, "sending bundle at marker"); + ret = gst_rtp_h265_pay_send_bundle (rtph265pay, TRUE); + } + +out: + gst_buffer_unref (paybuf); + return ret; +} static GstFlowReturn gst_rtp_h265_pay_handle_buffer (GstRTPBasePayload * basepayload, @@ -1140,6 +1429,7 @@ gst_rtp_h265_pay_handle_buffer (GstRTPBasePayload * basepayload, GstBuffer *paybuf = NULL; gsize skip; gboolean marker = FALSE; + gboolean discont = FALSE; gboolean draining = (buffer == NULL); rtph265pay = GST_RTP_H265_PAY (basepayload); @@ -1162,6 +1452,8 @@ gst_rtp_h265_pay_handle_buffer (GstRTPBasePayload * basepayload, GST_DEBUG_OBJECT (basepayload, "got %" G_GSIZE_FORMAT " bytes", size); } else { if (buffer) { + if (gst_adapter_available (rtph265pay->adapter) == 0) + discont = GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT); marker = GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_MARKER); gst_adapter_push (rtph265pay->adapter, buffer); buffer = NULL; @@ -1181,10 +1473,7 @@ gst_rtp_h265_pay_handle_buffer (GstRTPBasePayload * basepayload, ret = GST_FLOW_OK; - /* now loop over all NAL units and put them in a packet - * FIXME, we should really try to pack multiple NAL units into one RTP packet - * if we can, especially for the config packets that won't cause decoder - * latency. */ + /* now loop over all NAL units and put them in a packet */ if (hevc) { guint nal_length_size; gsize offset = 0; @@ -1227,6 +1516,12 @@ gst_rtp_h265_pay_handle_buffer (GstRTPBasePayload * basepayload, GST_BUFFER_FLAG_SET (paybuf, GST_BUFFER_FLAG_MARKER); } + GST_BUFFER_FLAG_UNSET (paybuf, GST_BUFFER_FLAG_DISCONT); + if (discont) { + GST_BUFFER_FLAG_SET (paybuf, GST_BUFFER_FLAG_DISCONT); + discont = FALSE; + } + data += nal_len; offset += nal_len; size -= nal_len; @@ -1337,6 +1632,12 @@ gst_rtp_h265_pay_handle_buffer (GstRTPBasePayload * basepayload, GST_BUFFER_FLAG_SET (paybuf, GST_BUFFER_FLAG_MARKER); } + GST_BUFFER_FLAG_UNSET (paybuf, GST_BUFFER_FLAG_DISCONT); + if (discont) { + GST_BUFFER_FLAG_SET (paybuf, GST_BUFFER_FLAG_DISCONT); + discont = FALSE; + } + /* move to next NAL packet */ /* Skips the trailing zeros */ gst_adapter_flush (rtph265pay->adapter, nal_len - size); @@ -1346,6 +1647,12 @@ gst_rtp_h265_pay_handle_buffer (GstRTPBasePayload * basepayload, g_array_set_size (nal_queue, 0); } + if (ret == GST_FLOW_OK && + rtph265pay->aggregate_mode == GST_RTP_H265_AGGREGATE_ZERO_LATENCY) { + GST_DEBUG_OBJECT (rtph265pay, "sending bundle at end incoming packet"); + ret = gst_rtp_h265_pay_send_bundle (rtph265pay, FALSE); + } + done: if (hevc) { gst_buffer_unmap (buffer, &map); @@ -1371,10 +1678,12 @@ gst_rtp_h265_pay_sink_event (GstRTPBasePayload * payload, GstEvent * event) gboolean res; const GstStructure *s; GstRtpH265Pay *rtph265pay = GST_RTP_H265_PAY (payload); + GstFlowReturn ret = GST_FLOW_OK; switch (GST_EVENT_TYPE (event)) { case GST_EVENT_FLUSH_STOP: gst_adapter_clear (rtph265pay->adapter); + gst_rtp_h265_pay_reset_bundle (rtph265pay); break; case GST_EVENT_CUSTOM_DOWNSTREAM: s = gst_event_get_structure (event); @@ -1392,6 +1701,8 @@ gst_rtp_h265_pay_sink_event (GstRTPBasePayload * payload, GstEvent * event) * in byte-stream mode */ gst_rtp_h265_pay_handle_buffer (payload, NULL); + ret = gst_rtp_h265_pay_send_bundle (rtph265pay, TRUE); + break; } case GST_EVENT_STREAM_START: @@ -1403,6 +1714,9 @@ gst_rtp_h265_pay_sink_event (GstRTPBasePayload * payload, GstEvent * event) break; } + if (ret != GST_FLOW_OK) + return FALSE; + res = GST_RTP_BASE_PAYLOAD_CLASS (parent_class)->sink_event (payload, event); return res; @@ -1418,6 +1732,7 @@ gst_rtp_h265_pay_change_state (GstElement * element, GstStateChange transition) case GST_STATE_CHANGE_READY_TO_PAUSED: rtph265pay->send_vps_sps_pps = FALSE; gst_adapter_clear (rtph265pay->adapter); + gst_rtp_h265_pay_reset_bundle (rtph265pay); break; default: break; @@ -1449,6 +1764,9 @@ gst_rtp_h265_pay_set_property (GObject * object, guint prop_id, case PROP_CONFIG_INTERVAL: rtph265pay->vps_sps_pps_interval = g_value_get_int (value); break; + case PROP_AGGREGATE_MODE: + rtph265pay->aggregate_mode = g_value_get_enum (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1467,6 +1785,9 @@ gst_rtp_h265_pay_get_property (GObject * object, guint prop_id, case PROP_CONFIG_INTERVAL: g_value_set_int (value, rtph265pay->vps_sps_pps_interval); break; + case PROP_AGGREGATE_MODE: + g_value_set_enum (value, rtph265pay->aggregate_mode); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; diff --git a/gst/rtp/gstrtph265pay.h b/gst/rtp/gstrtph265pay.h index cd42fbad3e..070bc59b55 100644 --- a/gst/rtp/gstrtph265pay.h +++ b/gst/rtp/gstrtph265pay.h @@ -47,6 +47,13 @@ typedef enum GST_H265_ALIGNMENT_AU } GstH265Alignment; +typedef enum +{ + GST_RTP_H265_AGGREGATE_NONE, + GST_RTP_H265_AGGREGATE_ZERO_LATENCY, + GST_RTP_H265_AGGREGATE_MAX, +} GstRTPH265AggregateMode; + struct _GstRtpH265Pay { GstRTPBasePayload payload; @@ -55,6 +62,8 @@ struct _GstRtpH265Pay GstH265StreamFormat stream_format; GstH265Alignment alignment; + gint fps_num; + gint fps_denum; guint nal_length_size; GArray *queue; @@ -63,6 +72,12 @@ struct _GstRtpH265Pay gint vps_sps_pps_interval; gboolean send_vps_sps_pps; GstClockTime last_vps_sps_pps; + + /* aggregate buffers with AP */ + GstBufferList *bundle; + guint bundle_size; + gboolean bundle_contains_vcl; + GstRTPH265AggregateMode aggregate_mode; }; struct _GstRtpH265PayClass diff --git a/tests/check/elements/rtp-payloading.c b/tests/check/elements/rtp-payloading.c index 0dddd34987..bd430e749d 100644 --- a/tests/check/elements/rtp-payloading.c +++ b/tests/check/elements/rtp-payloading.c @@ -1033,7 +1033,7 @@ static const guint8 rtp_h265_list_lt_mtu_frame_data_hvc1[] = { }; /* length size is 3 bytes */ -static int rtp_h265_list_lt_mtu_bytes_sent_hvc1 = 2 * (16 - 2 * 3); +static int rtp_h265_list_lt_mtu_bytes_sent_hvc1 = 4 + 9; GST_START_TEST (rtp_h265_list_lt_mtu_hvc1) diff --git a/tests/check/elements/rtph265.c b/tests/check/elements/rtph265.c index b3a48bd21b..dd655c2cad 100644 --- a/tests/check/elements/rtph265.c +++ b/tests/check/elements/rtph265.c @@ -539,7 +539,8 @@ GST_END_TEST; GST_START_TEST (test_rtph265pay_marker_for_au) { - GstHarness *h = gst_harness_new_parse ("rtph265pay timestamp-offset=123"); + GstHarness *h = gst_harness_new_parse + ("rtph265pay timestamp-offset=123 aggregate-mode=none"); GstFlowReturn ret; GstBuffer *slice1, *slice2, *buffer; GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;