Skip to content

Commit bb19396

Browse files
committed
TWCCMan evaluates recovery pct for FEC
Major rework of twcc manager internals caused by need to evaluate recovery percentage in case of FEC. Sent Packet structs are stored GstQueueArray to keep their pointers persistent. TWCC feedback parser creates a list of packets updated by this feedback, which then is passed into statistic gathering context. Then the remaining work is done in get_windowed_stats call.
1 parent e0d743d commit bb19396

File tree

7 files changed

+1077
-411
lines changed

7 files changed

+1077
-411
lines changed
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
/* GStreamer
2+
* Copyright (C) <2024> Mikhail Baranov <[email protected]>
3+
*
4+
* This library is free software; you can redistribute it and/or
5+
* modify it under the terms of the GNU Library General Public
6+
* License as published by the Free Software Foundation; either
7+
* version 2 of the License, or (at your option) any later version.
8+
*
9+
* This library is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+
* Library General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Library General Public
15+
* License along with this library; if not, write to the
16+
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17+
* Boston, MA 02110-1301, USA.
18+
*/
19+
20+
#ifdef HAVE_CONFIG_H
21+
#include "config.h"
22+
#endif
23+
24+
#include "gstrtprepairmeta.h"
25+
#include <string.h>
26+
27+
static gboolean gst_rtp_repair_meta_init(GstRTPRepairMeta * meta,
28+
G_GNUC_UNUSED gpointer params, G_GNUC_UNUSED GstBuffer * buffer);
29+
static void gst_rtp_repair_meta_free(GstRTPRepairMeta *meta,
30+
G_GNUC_UNUSED GstBuffer *buffer);
31+
32+
33+
GType gst_rtp_repair_meta_api_get_type(void)
34+
{
35+
static GType type = 0;
36+
static const gchar *tags[] = {NULL};
37+
38+
if (g_once_init_enter(&type)) {
39+
GType _type = gst_meta_api_type_register("GstRTPRepairMetaAPI", tags);
40+
g_once_init_leave(&type, _type);
41+
}
42+
43+
return type;
44+
}
45+
46+
const GstMetaInfo *gst_rtp_repair_meta_get_info(void)
47+
{
48+
static const GstMetaInfo *meta_info = NULL;
49+
50+
if (g_once_init_enter(&meta_info)) {
51+
const GstMetaInfo *mi = gst_meta_register( GST_RTP_REPAIR_META_API_TYPE,
52+
"GstRTPRepairMeta",
53+
sizeof(GstRTPRepairMeta),
54+
(GstMetaInitFunction) gst_rtp_repair_meta_init,
55+
(GstMetaFreeFunction) gst_rtp_repair_meta_free,
56+
NULL );
57+
g_once_init_leave(&meta_info, mi);
58+
}
59+
60+
return meta_info;
61+
}
62+
63+
GstRTPRepairMeta *gst_buffer_get_rtp_repair_meta(GstBuffer *buffer)
64+
{
65+
return (GstRTPRepairMeta *)gst_buffer_get_meta(buffer,
66+
gst_rtp_repair_meta_api_get_type());
67+
}
68+
69+
GstRTPRepairMeta *gst_buffer_add_rtp_repair_meta(GstBuffer *buffer,
70+
const guint32 ssrc, const guint16 *seqnum, guint seqnum_count)
71+
{
72+
GstRTPRepairMeta *repair_meta = (GstRTPRepairMeta *) gst_buffer_add_meta (buffer,
73+
GST_RTP_REPAIR_META_INFO, NULL);
74+
if (repair_meta == NULL) {
75+
return NULL;
76+
}
77+
78+
repair_meta->ssrc = ssrc;
79+
g_array_insert_vals (repair_meta->seqnums, 0, seqnum, seqnum_count);
80+
81+
return repair_meta;
82+
}
83+
84+
gboolean gst_buffer_repairs_seqnum(GstBuffer *buffer, guint16 seqnum, guint32 ssrc)
85+
{
86+
GstRTPRepairMeta *repair_meta = gst_buffer_get_rtp_repair_meta(buffer);
87+
if (repair_meta) {
88+
if (repair_meta->ssrc != ssrc) {
89+
return FALSE;
90+
}
91+
92+
for (guint i = 0; i < repair_meta->seqnums->len; i++) {
93+
guint16 stored_seqnum = g_array_index(repair_meta->seqnums, guint16, i);
94+
if (stored_seqnum == seqnum) {
95+
return TRUE;
96+
}
97+
}
98+
}
99+
return FALSE;
100+
}
101+
102+
gboolean gst_buffer_get_repair_seqnums(GstBuffer *buffer, guint32 *ssrc,
103+
GArray **seqnums)
104+
{
105+
GstRTPRepairMeta *repair_meta = gst_buffer_get_rtp_repair_meta(buffer);
106+
if (repair_meta && repair_meta->seqnums->len > 0) {
107+
if (ssrc) {
108+
*ssrc = repair_meta->ssrc;
109+
}
110+
if (seqnums) {
111+
*seqnums = g_array_ref (repair_meta->seqnums);
112+
}
113+
return TRUE;
114+
} else {
115+
*ssrc = 0;
116+
*seqnums = NULL;
117+
}
118+
return FALSE;
119+
}
120+
121+
static gboolean
122+
gst_rtp_repair_meta_init(GstRTPRepairMeta * meta, G_GNUC_UNUSED gpointer params,
123+
G_GNUC_UNUSED GstBuffer * buffer)
124+
{
125+
meta->ssrc = 0;
126+
meta->seqnums = g_array_new(FALSE, FALSE, sizeof(guint16));
127+
128+
return TRUE;
129+
}
130+
131+
static void
132+
gst_rtp_repair_meta_free(GstRTPRepairMeta *meta,
133+
G_GNUC_UNUSED GstBuffer *buffer)
134+
{
135+
g_array_unref (meta->seqnums);
136+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/* GStreamer
2+
* Copyright (C) <2024> Mikhail Baranov <[email protected]>
3+
*
4+
* This library is free software; you can redistribute it and/or
5+
* modify it under the terms of the GNU Library General Public
6+
* License as published by the Free Software Foundation; either
7+
* version 2 of the License, or (at your option) any later version.
8+
*
9+
* This library is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+
* Library General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Library General Public
15+
* License along with this library; if not, write to the
16+
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17+
* Boston, MA 02110-1301, USA.
18+
*/
19+
20+
#ifndef __GST_RTP_REPAIR_META_H__
21+
#define __GST_RTP_REPAIR_META_H__
22+
23+
#include <gst/gst.h>
24+
#include <glib.h>
25+
#include <gst/rtp/rtp-prelude.h>
26+
27+
G_BEGIN_DECLS
28+
29+
#define GST_RTP_REPAIR_META_API_TYPE (gst_rtp_repair_meta_api_get_type())
30+
#define GST_RTP_REPAIR_META_INFO (gst_rtp_repair_meta_get_info())
31+
typedef struct _GstRTPRepairMeta GstRTPRepairMeta;
32+
33+
struct _GstRTPRepairMeta
34+
{
35+
GstMeta meta;
36+
37+
guint32 ssrc;
38+
GArray *seqnums;
39+
};
40+
41+
GST_RTP_API
42+
GType gst_rtp_repair_meta_api_get_type (void);
43+
44+
GST_RTP_API
45+
GstRTPRepairMeta * gst_buffer_add_rtp_repair_meta (GstBuffer *buffer, const guint32 ssrc,
46+
const guint16 *seqnum, guint seqnum_count);
47+
48+
GST_RTP_API
49+
GstRTPRepairMeta * gst_buffer_get_rtp_repair_meta (GstBuffer * buffer);
50+
51+
GST_RTP_API
52+
gboolean gst_buffer_repairs_seqnum(GstBuffer *buffer, guint16 seqnum, guint32 ssrc);
53+
54+
GST_RTP_API
55+
gboolean gst_buffer_get_repair_seqnums(GstBuffer *buffer, guint32 * ssrc,
56+
GArray ** seqnums);
57+
58+
GST_RTP_API
59+
const GstMetaInfo * gst_rtp_repair_meta_get_info (void);
60+
61+
G_END_DECLS
62+
63+
#endif /* __GST_RTP_REPAIR_META_H__ */

subprojects/gst-plugins-base/gst-libs/gst/rtp/meson.build

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ rtp_sources = files([
44
'gstrtppayloads.c',
55
'gstrtphdrext.c',
66
'gstrtpmeta.c',
7+
'gstrtprepairmeta.c',
78
'gstrtpbaseaudiopayload.c',
89
'gstrtpbasepayload.c',
910
'gstrtpbasedepayload.c'
@@ -18,6 +19,7 @@ rtp_headers = files([
1819
'gstrtpdefs.h',
1920
'gstrtphdrext.h',
2021
'gstrtpmeta.h',
22+
'gstrtprepairmeta.h',
2123
'gstrtppayloads.h',
2224
'rtp-prelude.h',
2325
'rtp.h',

subprojects/gst-plugins-good/gst/rtpmanager/gstrtprtxsend.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646

4747
#include "gstrtprtxsend.h"
4848
#include "rtpstats.h"
49+
#include <gst/rtp/gstrtprepairmeta.h>
4950

5051
GST_DEBUG_CATEGORY_STATIC (gst_rtp_rtx_send_debug);
5152
#define GST_CAT_DEFAULT gst_rtp_rtx_send_debug
@@ -765,22 +766,32 @@ gst_rtp_rtx_buffer_new (GstRtpRtxSend * rtx, GstBuffer * buffer, guint8 padlen)
765766
SSRCRtxData *data;
766767
guint32 ssrc;
767768
guint16 seqnum;
769+
guint32 orig_ssrc;
770+
guint16 orig_seqnum;
768771
guint8 fmtp;
769772

770773
gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp);
771774

772775
/* get needed data from GstRtpRtxSend */
773-
ssrc = gst_rtp_buffer_get_ssrc (&rtp);
774-
data = gst_rtp_rtx_send_get_ssrc_data (rtx, ssrc);
776+
orig_ssrc = gst_rtp_buffer_get_ssrc (&rtp);
777+
data = gst_rtp_rtx_send_get_ssrc_data (rtx, orig_ssrc);
775778
ssrc = data->rtx_ssrc;
776779
seqnum = data->next_seqnum++;
777780
fmtp = GPOINTER_TO_UINT (g_hash_table_lookup (rtx->rtx_pt_map,
778781
GUINT_TO_POINTER (gst_rtp_buffer_get_payload_type (&rtp))));
782+
783+
orig_seqnum = gst_rtp_buffer_get_seq (&rtp);
779784

780785
GST_DEBUG_OBJECT (rtx, "creating rtx buffer, orig seqnum: %u, "
781-
"rtx seqnum: %u, rtx ssrc: %X", gst_rtp_buffer_get_seq (&rtp),
786+
"rtx seqnum: %u, rtx ssrc: %X", orig_seqnum,
782787
seqnum, ssrc);
783788

789+
GstRTPRepairMeta *repair_meta = gst_buffer_add_rtp_repair_meta (new_buffer,
790+
orig_ssrc, &orig_seqnum, 1);
791+
GST_DEBUG_OBJECT (rtx, "%p, %d", repair_meta->seqnums,
792+
repair_meta->seqnums->len);
793+
794+
784795
/* gst_rtp_buffer_map does not map the payload so do it now */
785796
gst_rtp_buffer_get_payload (&rtp);
786797

subprojects/gst-plugins-good/gst/rtpmanager/rtpsession.c

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2404,14 +2404,6 @@ update_packet (GstBuffer ** buffer, guint idx, RTPPacketInfo * pinfo)
24042404
/* RTP header extensions */
24052405
pinfo->header_ext = gst_rtp_buffer_get_extension_bytes (&rtp,
24062406
&pinfo->header_ext_bit_pattern);
2407-
2408-
/* if RTX, store the original seqnum (OSN) and SSRC */
2409-
if (GST_BUFFER_FLAG_IS_SET (*buffer, GST_RTP_BUFFER_FLAG_RETRANSMISSION)) {
2410-
guint8 *payload = gst_rtp_buffer_get_payload (&rtp);
2411-
if (payload) {
2412-
pinfo->rtx_osn = GST_READ_UINT16_BE (payload);
2413-
}
2414-
}
24152407
}
24162408

24172409
if (pinfo->ntp64_ext_id != 0 && pinfo->send && !pinfo->have_ntp64_ext) {
@@ -2482,8 +2474,6 @@ update_packet_info (RTPSession * sess, RTPPacketInfo * pinfo,
24822474
pinfo->marker = FALSE;
24832475
pinfo->ntp64_ext_id = send ? sess->send_ntp64_ext_id : 0;
24842476
pinfo->have_ntp64_ext = FALSE;
2485-
pinfo->rtx_osn = -1;
2486-
pinfo->rtx_ssrc = 0;
24872477

24882478
if (is_list) {
24892479
GstBufferList *list = GST_BUFFER_LIST_CAST (data);
@@ -2497,11 +2487,6 @@ update_packet_info (RTPSession * sess, RTPPacketInfo * pinfo,
24972487
pinfo->arrival_time = GST_BUFFER_DTS (buffer);
24982488
}
24992489

2500-
if (pinfo->rtx_osn != -1)
2501-
pinfo->rtx_ssrc =
2502-
GPOINTER_TO_UINT (g_hash_table_lookup (sess->rtx_ssrc_to_ssrc,
2503-
GUINT_TO_POINTER (pinfo->ssrc)));
2504-
25052490
return res;
25062491
}
25072492

subprojects/gst-plugins-good/gst/rtpmanager/rtpstats.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,6 @@ typedef struct {
114114
guint16 header_ext_bit_pattern;
115115
guint8 ntp64_ext_id;
116116
gboolean have_ntp64_ext;
117-
gint32 rtx_osn;
118-
guint32 rtx_ssrc;
119117
} RTPPacketInfo;
120118

121119
/**

0 commit comments

Comments
 (0)