mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
rtptwcc: fixes and optimizations around run-length chunks
Co-authored-by: Havard Graff <havard.graff@gmail.com> Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/927>
This commit is contained in:
parent
219749c40c
commit
4ef0ce282e
2 changed files with 409 additions and 100 deletions
|
@ -29,6 +29,9 @@ GST_DEBUG_CATEGORY_EXTERN (rtp_session_debug);
|
||||||
#define DELTA_UNIT (250 * GST_USECOND)
|
#define DELTA_UNIT (250 * GST_USECOND)
|
||||||
#define MAX_TS_DELTA (0xff * DELTA_UNIT)
|
#define MAX_TS_DELTA (0xff * DELTA_UNIT)
|
||||||
|
|
||||||
|
#define STATUS_VECTOR_MAX_CAPACITY 14
|
||||||
|
#define STATUS_VECTOR_TWO_BIT_MAX_CAPACITY 7
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
RTP_TWCC_CHUNK_TYPE_RUN_LENGTH = 0,
|
RTP_TWCC_CHUNK_TYPE_RUN_LENGTH = 0,
|
||||||
|
@ -83,6 +86,7 @@ struct _RTPTWCCManager
|
||||||
guint64 recv_media_ssrc;
|
guint64 recv_media_ssrc;
|
||||||
|
|
||||||
guint16 expected_recv_seqnum;
|
guint16 expected_recv_seqnum;
|
||||||
|
guint16 packet_count_no_marker;
|
||||||
|
|
||||||
gboolean first_fci_parse;
|
gboolean first_fci_parse;
|
||||||
guint16 expected_parsed_seqnum;
|
guint16 expected_parsed_seqnum;
|
||||||
|
@ -216,7 +220,7 @@ rtp_twcc_write_run_length_chunk (GArray * packet_chunks,
|
||||||
guint16 data = 0;
|
guint16 data = 0;
|
||||||
guint len = MIN (run_length - written, 8191);
|
guint len = MIN (run_length - written, 8191);
|
||||||
|
|
||||||
GST_LOG ("Writing a run-lenght of %u with status %u", len, status);
|
GST_LOG ("Writing a run-length of %u with status %u", len, status);
|
||||||
|
|
||||||
gst_bit_writer_init_with_data (&writer, (guint8 *) & data, 2, FALSE);
|
gst_bit_writer_init_with_data (&writer, (guint8 *) & data, 2, FALSE);
|
||||||
gst_bit_writer_put_bits_uint8 (&writer, RTP_TWCC_CHUNK_TYPE_RUN_LENGTH, 1);
|
gst_bit_writer_put_bits_uint8 (&writer, RTP_TWCC_CHUNK_TYPE_RUN_LENGTH, 1);
|
||||||
|
@ -276,7 +280,7 @@ chunk_bit_writer_get_available_slots (ChunkBitWriter * writer)
|
||||||
static guint
|
static guint
|
||||||
chunk_bit_writer_get_total_slots (ChunkBitWriter * writer)
|
chunk_bit_writer_get_total_slots (ChunkBitWriter * writer)
|
||||||
{
|
{
|
||||||
return 14 / writer->symbol_size;
|
return STATUS_VECTOR_MAX_CAPACITY / writer->symbol_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -359,13 +363,43 @@ run_lenght_helper_update (RunLengthHelper * rlh, RecvPacket * pkt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static guint
|
||||||
|
_get_max_packets_capacity (guint symbol_size)
|
||||||
|
{
|
||||||
|
if (symbol_size == 2)
|
||||||
|
return STATUS_VECTOR_TWO_BIT_MAX_CAPACITY;
|
||||||
|
|
||||||
|
return STATUS_VECTOR_MAX_CAPACITY;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_pkt_fits_run_length_chunk (RecvPacket * pkt, guint packets_per_chunks,
|
||||||
|
guint remaining_packets)
|
||||||
|
{
|
||||||
|
if (pkt->missing_run == 0) {
|
||||||
|
/* we have more or the same equal packets than the ones we can write in to a status chunk */
|
||||||
|
if (pkt->equal_run >= packets_per_chunks)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* we have more than one equal and not enough space for the remainings */
|
||||||
|
if (pkt->equal_run > 1 && remaining_packets > STATUS_VECTOR_MAX_CAPACITY)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* we have all equal packets for the remaining to write */
|
||||||
|
if (pkt->equal_run == remaining_packets)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rtp_twcc_write_chunks (GArray * packet_chunks,
|
rtp_twcc_write_chunks (GArray * packet_chunks,
|
||||||
GArray * twcc_packets, guint symbol_size)
|
GArray * twcc_packets, guint symbol_size)
|
||||||
{
|
{
|
||||||
ChunkBitWriter writer;
|
ChunkBitWriter writer;
|
||||||
guint i;
|
guint i;
|
||||||
guint bits_per_chunks = 7 * symbol_size;
|
guint packets_per_chunks = _get_max_packets_capacity (symbol_size);
|
||||||
|
|
||||||
chunk_bit_writer_init (&writer, packet_chunks, symbol_size);
|
chunk_bit_writer_init (&writer, packet_chunks, symbol_size);
|
||||||
|
|
||||||
|
@ -373,21 +407,26 @@ rtp_twcc_write_chunks (GArray * packet_chunks,
|
||||||
RecvPacket *pkt = &g_array_index (twcc_packets, RecvPacket, i);
|
RecvPacket *pkt = &g_array_index (twcc_packets, RecvPacket, i);
|
||||||
guint remaining_packets = twcc_packets->len - i;
|
guint remaining_packets = twcc_packets->len - i;
|
||||||
|
|
||||||
|
GST_LOG
|
||||||
|
("About to write pkt: #%u missing_run: %u equal_run: %u status: %u, remaining_packets: %u",
|
||||||
|
pkt->seqnum, pkt->missing_run, pkt->equal_run, pkt->status,
|
||||||
|
remaining_packets);
|
||||||
|
|
||||||
/* we can only start a run-length chunk if the status-chunk is
|
/* we can only start a run-length chunk if the status-chunk is
|
||||||
completed */
|
completed */
|
||||||
if (chunk_bit_writer_is_empty (&writer)) {
|
if (chunk_bit_writer_is_empty (&writer)) {
|
||||||
/* first write in any preceeding gaps, we use run-length
|
/* first write in any preceeding gaps, we use run-length
|
||||||
if it would take up more than one chunk (14/7) */
|
if it would take up more than one chunk (14/7) */
|
||||||
if (pkt->missing_run > bits_per_chunks) {
|
if (pkt->missing_run > packets_per_chunks) {
|
||||||
rtp_twcc_write_run_length_chunk (packet_chunks,
|
rtp_twcc_write_run_length_chunk (packet_chunks,
|
||||||
RTP_TWCC_PACKET_STATUS_NOT_RECV, pkt->missing_run);
|
RTP_TWCC_PACKET_STATUS_NOT_RECV, pkt->missing_run);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we have a run of the same status, write a run-length chunk and skip
|
/* we have a run of the same status, write a run-length chunk and skip
|
||||||
to the next point */
|
to the next point */
|
||||||
if (pkt->missing_run == 0 &&
|
if (_pkt_fits_run_length_chunk (pkt, packets_per_chunks,
|
||||||
(pkt->equal_run > bits_per_chunks ||
|
remaining_packets)) {
|
||||||
pkt->equal_run == remaining_packets)) {
|
|
||||||
rtp_twcc_write_run_length_chunk (packet_chunks,
|
rtp_twcc_write_run_length_chunk (packet_chunks,
|
||||||
pkt->status, pkt->equal_run);
|
pkt->status, pkt->equal_run);
|
||||||
i += pkt->equal_run - 1;
|
i += pkt->equal_run - 1;
|
||||||
|
@ -546,24 +585,7 @@ rtp_twcc_manager_create_feedback (RTPTWCCManager * twcc)
|
||||||
static gboolean
|
static gboolean
|
||||||
_exceeds_max_packets (RTPTWCCManager * twcc, guint16 seqnum)
|
_exceeds_max_packets (RTPTWCCManager * twcc, guint16 seqnum)
|
||||||
{
|
{
|
||||||
RecvPacket *first, *last;
|
if (twcc->recv_packets->len + 1 > twcc->max_packets_per_rtcp)
|
||||||
guint16 packet_count;
|
|
||||||
|
|
||||||
if (twcc->recv_packets->len == 0)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* find the delta betwen first stored packet and this seqnum */
|
|
||||||
first = &g_array_index (twcc->recv_packets, RecvPacket, 0);
|
|
||||||
packet_count = seqnum - first->seqnum + 1;
|
|
||||||
if (packet_count > twcc->max_packets_per_rtcp)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
/* then find the delta between last stored packet and this seqnum */
|
|
||||||
last =
|
|
||||||
&g_array_index (twcc->recv_packets, RecvPacket,
|
|
||||||
twcc->recv_packets->len - 1);
|
|
||||||
packet_count = seqnum - (last->seqnum + 1);
|
|
||||||
if (packet_count > twcc->max_packets_per_rtcp)
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -578,13 +600,20 @@ _many_packets_some_lost (RTPTWCCManager * twcc, guint16 seqnum)
|
||||||
RecvPacket *first;
|
RecvPacket *first;
|
||||||
guint16 packet_count;
|
guint16 packet_count;
|
||||||
guint received_packets = twcc->recv_packets->len;
|
guint received_packets = twcc->recv_packets->len;
|
||||||
|
guint lost_packets;
|
||||||
if (received_packets == 0)
|
if (received_packets == 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
first = &g_array_index (twcc->recv_packets, RecvPacket, 0);
|
first = &g_array_index (twcc->recv_packets, RecvPacket, 0);
|
||||||
packet_count = seqnum - first->seqnum + 1;
|
packet_count = seqnum - first->seqnum + 1;
|
||||||
/* packet-count larger than recevied-packets means we have lost packets */
|
|
||||||
if (packet_count >= 30 && packet_count > received_packets)
|
/* check if we lost half of the threshold */
|
||||||
|
lost_packets = packet_count - received_packets;
|
||||||
|
if (received_packets >= 30 && lost_packets >= 60)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* we have lost the marker bit for some and lost some */
|
||||||
|
if (twcc->packet_count_no_marker >= 10 && lost_packets >= 60)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -621,6 +650,17 @@ rtp_twcc_manager_recv_packet (RTPTWCCManager * twcc,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (twcc->recv_packets->len > 0) {
|
||||||
|
RecvPacket *last = &g_array_index (twcc->recv_packets, RecvPacket,
|
||||||
|
twcc->recv_packets->len - 1);
|
||||||
|
|
||||||
|
diff = gst_rtp_buffer_compare_seqnum (last->seqnum, seqnum);
|
||||||
|
if (diff == 0) {
|
||||||
|
GST_INFO ("Received duplicate packet (%u), dropping", seqnum);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* store the packet for Transport-wide RTCP feedback message */
|
/* store the packet for Transport-wide RTCP feedback message */
|
||||||
recv_packet_init (&packet, seqnum, pinfo);
|
recv_packet_init (&packet, seqnum, pinfo);
|
||||||
g_array_append_val (twcc->recv_packets, packet);
|
g_array_append_val (twcc->recv_packets, packet);
|
||||||
|
@ -628,6 +668,9 @@ rtp_twcc_manager_recv_packet (RTPTWCCManager * twcc,
|
||||||
GST_LOG ("Receive: twcc-seqnum: %u, marker: %d, ts: %" GST_TIME_FORMAT,
|
GST_LOG ("Receive: twcc-seqnum: %u, marker: %d, ts: %" GST_TIME_FORMAT,
|
||||||
seqnum, pinfo->marker, GST_TIME_ARGS (pinfo->running_time));
|
seqnum, pinfo->marker, GST_TIME_ARGS (pinfo->running_time));
|
||||||
|
|
||||||
|
if (!pinfo->marker)
|
||||||
|
twcc->packet_count_no_marker++;
|
||||||
|
|
||||||
/* are we sending on an interval, or based on marker bit */
|
/* are we sending on an interval, or based on marker bit */
|
||||||
if (GST_CLOCK_TIME_IS_VALID (twcc->feedback_interval)) {
|
if (GST_CLOCK_TIME_IS_VALID (twcc->feedback_interval)) {
|
||||||
if (!GST_CLOCK_TIME_IS_VALID (twcc->next_feedback_send_time))
|
if (!GST_CLOCK_TIME_IS_VALID (twcc->next_feedback_send_time))
|
||||||
|
@ -644,6 +687,8 @@ rtp_twcc_manager_recv_packet (RTPTWCCManager * twcc,
|
||||||
} else if (pinfo->marker || _many_packets_some_lost (twcc, seqnum)) {
|
} else if (pinfo->marker || _many_packets_some_lost (twcc, seqnum)) {
|
||||||
rtp_twcc_manager_create_feedback (twcc);
|
rtp_twcc_manager_create_feedback (twcc);
|
||||||
send_feedback = TRUE;
|
send_feedback = TRUE;
|
||||||
|
|
||||||
|
twcc->packet_count_no_marker = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return send_feedback;
|
return send_feedback;
|
||||||
|
|
|
@ -2688,7 +2688,7 @@ typedef struct
|
||||||
GstClockTime duration;
|
GstClockTime duration;
|
||||||
} TWCCTestData;
|
} TWCCTestData;
|
||||||
|
|
||||||
static TWCCTestData twcc_header_and_run_lenght_test_data[] = {
|
static TWCCTestData twcc_header_and_run_length_test_data[] = {
|
||||||
{0, 10, 0, 33 * GST_MSECOND},
|
{0, 10, 0, 33 * GST_MSECOND},
|
||||||
{65530, 12, 37 * 64 * GST_MSECOND, 10 * GST_MSECOND}, /* seqnum wrap */
|
{65530, 12, 37 * 64 * GST_MSECOND, 10 * GST_MSECOND}, /* seqnum wrap */
|
||||||
{99, 200, 1024 * 64 * GST_MSECOND, 10 * GST_MSECOND}, /* many packets */
|
{99, 200, 1024 * 64 * GST_MSECOND, 10 * GST_MSECOND}, /* many packets */
|
||||||
|
@ -2707,7 +2707,7 @@ GST_START_TEST (test_twcc_header_and_run_length)
|
||||||
guint8 *fci_data;
|
guint8 *fci_data;
|
||||||
guint16 run_length;
|
guint16 run_length;
|
||||||
|
|
||||||
TWCCTestData *td = &twcc_header_and_run_lenght_test_data[__i__];
|
TWCCTestData *td = &twcc_header_and_run_length_test_data[__i__];
|
||||||
|
|
||||||
/* enable twcc */
|
/* enable twcc */
|
||||||
session_harness_set_twcc_recv_ext_id (h, TEST_TWCC_EXT_ID);
|
session_harness_set_twcc_recv_ext_id (h, TEST_TWCC_EXT_ID);
|
||||||
|
@ -2775,6 +2775,16 @@ typedef struct
|
||||||
gboolean marker;
|
gboolean marker;
|
||||||
} TWCCPacket;
|
} TWCCPacket;
|
||||||
|
|
||||||
|
#define TWCC_DELTA_UNIT (250 * GST_USECOND)
|
||||||
|
|
||||||
|
static void
|
||||||
|
fail_unless_equals_twcc_clocktime (GstClockTime twcc_packet_ts,
|
||||||
|
GstClockTime pkt_ts)
|
||||||
|
{
|
||||||
|
fail_unless_equals_clocktime (
|
||||||
|
(twcc_packet_ts / TWCC_DELTA_UNIT) * TWCC_DELTA_UNIT, pkt_ts);
|
||||||
|
}
|
||||||
|
|
||||||
#define twcc_push_packets(h, packets) \
|
#define twcc_push_packets(h, packets) \
|
||||||
G_STMT_START { \
|
G_STMT_START { \
|
||||||
guint i; \
|
guint i; \
|
||||||
|
@ -2806,6 +2816,7 @@ G_STMT_START { \
|
||||||
gst_rtcp_packet_fb_get_type (&packet)); \
|
gst_rtcp_packet_fb_get_type (&packet)); \
|
||||||
fci_data = gst_rtcp_packet_fb_get_fci (&packet); \
|
fci_data = gst_rtcp_packet_fb_get_fci (&packet); \
|
||||||
fci_length = gst_rtcp_packet_fb_get_fci_length (&packet) * sizeof (guint32); \
|
fci_length = gst_rtcp_packet_fb_get_fci_length (&packet) * sizeof (guint32); \
|
||||||
|
GST_MEMDUMP ("fci:", fci_data, fci_length); \
|
||||||
fail_unless_equals_int (fci_length, sizeof (exp_fci)); \
|
fail_unless_equals_int (fci_length, sizeof (exp_fci)); \
|
||||||
fail_unless_equals_int (0, memcmp (fci_data, (exp_fci), fci_length)); \
|
fail_unless_equals_int (0, memcmp (fci_data, (exp_fci), fci_length)); \
|
||||||
gst_rtcp_buffer_unmap (&rtcp); \
|
gst_rtcp_buffer_unmap (&rtcp); \
|
||||||
|
@ -2840,7 +2851,7 @@ G_STMT_START { \
|
||||||
fail_unless (gst_structure_get_uint (pkt_s, "seqnum", &seqnum)); \
|
fail_unless (gst_structure_get_uint (pkt_s, "seqnum", &seqnum)); \
|
||||||
twcc_pkt = &(packets)[j++]; \
|
twcc_pkt = &(packets)[j++]; \
|
||||||
fail_unless_equals_int (twcc_pkt->seqnum, seqnum); \
|
fail_unless_equals_int (twcc_pkt->seqnum, seqnum); \
|
||||||
fail_unless_equals_clocktime (twcc_pkt->timestamp, ts); \
|
fail_unless_equals_twcc_clocktime (twcc_pkt->timestamp, ts); \
|
||||||
} \
|
} \
|
||||||
gst_event_unref (event); \
|
gst_event_unref (event); \
|
||||||
} G_STMT_END
|
} G_STMT_END
|
||||||
|
@ -2903,6 +2914,58 @@ GST_START_TEST (test_twcc_1_bit_status_vector)
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
|
||||||
|
GST_START_TEST (test_twcc_status_vector_split_large_delta)
|
||||||
|
{
|
||||||
|
SessionHarness *h0 = session_harness_new ();
|
||||||
|
SessionHarness *h1 = session_harness_new ();
|
||||||
|
|
||||||
|
TWCCPacket packets[] = {
|
||||||
|
{1, 1 * 60 * GST_MSECOND, FALSE},
|
||||||
|
{2, 2 * 60 * GST_MSECOND, FALSE},
|
||||||
|
{3, 3 * 60 * GST_MSECOND, FALSE},
|
||||||
|
{4, 4 * 60 * GST_MSECOND, FALSE},
|
||||||
|
{5, 5 * 60 * GST_MSECOND, FALSE},
|
||||||
|
{6, 6 * 60 * GST_MSECOND, FALSE},
|
||||||
|
{7, 7 * 60 * GST_MSECOND, FALSE},
|
||||||
|
{8, 8 * 60 * GST_MSECOND, FALSE},
|
||||||
|
{9, 9 * 60 * GST_MSECOND, FALSE},
|
||||||
|
{10, 10 * 60 * GST_MSECOND, FALSE},
|
||||||
|
{11, 11 * 60 * GST_MSECOND, FALSE},
|
||||||
|
{12, 12 * 60 * GST_MSECOND, FALSE},
|
||||||
|
{13, 13 * 60 * GST_MSECOND, FALSE},
|
||||||
|
{14, 14 * 60 * GST_MSECOND, FALSE},
|
||||||
|
|
||||||
|
{15, 60 * 60 * GST_MSECOND, TRUE},
|
||||||
|
};
|
||||||
|
|
||||||
|
guint8 exp_fci[] = {
|
||||||
|
0x00, 0x01, /* base sequence number: 1 */
|
||||||
|
0x00, 0x0f, /* packet status count: 15 */
|
||||||
|
0x00, 0x00, 0x00, /* reference time: 0 */
|
||||||
|
0x00, /* feedback packet count: 0 */
|
||||||
|
0x20, 0x0e, /* run-length chunk with small delta for #1 to #14: 0 0 1 0 0 0 0 0 | 0 0 0 0 1 1 1 0 */
|
||||||
|
0x40, 0x01, /* rung-length with large delta for #15: 0 1 0 0 0 0 0 0 | 0 0 0 0 0 0 0 1 */
|
||||||
|
|
||||||
|
/* recv deltas: */
|
||||||
|
0xf0, 0xf0, /* 14 small deltas : +0:00:00.060000000 */
|
||||||
|
0xf0, 0xf0,
|
||||||
|
0xf0, 0xf0,
|
||||||
|
0xf0, 0xf0,
|
||||||
|
0xf0, 0xf0,
|
||||||
|
0xf0, 0xf0,
|
||||||
|
0xf0, 0xf0,
|
||||||
|
0x2b, 0x20, /* large delta: +0:00:02.760000000 */
|
||||||
|
};
|
||||||
|
|
||||||
|
twcc_verify_packets_to_fci (h0, packets, exp_fci);
|
||||||
|
twcc_verify_packets_to_packets (h1, h1, packets);
|
||||||
|
|
||||||
|
session_harness_free (h0);
|
||||||
|
session_harness_free (h1);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_END_TEST;
|
||||||
|
|
||||||
GST_START_TEST (test_twcc_2_bit_status_vector)
|
GST_START_TEST (test_twcc_2_bit_status_vector)
|
||||||
{
|
{
|
||||||
SessionHarness *h0 = session_harness_new ();
|
SessionHarness *h0 = session_harness_new ();
|
||||||
|
@ -2939,6 +3002,178 @@ GST_START_TEST (test_twcc_2_bit_status_vector)
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
|
||||||
|
GST_START_TEST (test_twcc_2_bit_over_capacity)
|
||||||
|
{
|
||||||
|
SessionHarness *h = session_harness_new ();
|
||||||
|
|
||||||
|
TWCCPacket packets[] = {
|
||||||
|
{0, 0 * GST_MSECOND, FALSE},
|
||||||
|
{6, 250 * 250 + 250 * GST_MSECOND, TRUE},
|
||||||
|
};
|
||||||
|
|
||||||
|
guint8 exp_fci[] = {
|
||||||
|
0x00, 0x00, /* base sequence number: 0 */
|
||||||
|
0x00, 0x07, /* packet status count: 7 */
|
||||||
|
0x00, 0x00, 0x00, /* reference time: 0 */
|
||||||
|
0x00, /* feedback packet count: 0 */
|
||||||
|
0xd0, 0x02, /* packet chunk: 1 1 0 1 0 0 0 0 | 0 0 0 0 0 0 1 0 */
|
||||||
|
0x00, /* recv delta: +0:00:00.000000000 */
|
||||||
|
0x03, 0xe8, /* recv delta: +0:00:00.000000000 */
|
||||||
|
0x00, 0x00, 0x00, /* padding */
|
||||||
|
};
|
||||||
|
|
||||||
|
twcc_verify_packets_to_fci (h, packets, exp_fci);
|
||||||
|
|
||||||
|
session_harness_free (h);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_END_TEST;
|
||||||
|
|
||||||
|
GST_START_TEST (test_twcc_status_vector_split_with_gap)
|
||||||
|
{
|
||||||
|
SessionHarness *h0 = session_harness_new ();
|
||||||
|
SessionHarness *h1 = session_harness_new ();
|
||||||
|
|
||||||
|
TWCCPacket packets[] = {
|
||||||
|
{0, 0 * GST_MSECOND, FALSE},
|
||||||
|
{7, (250 * 250) + 250 * GST_MSECOND, TRUE},
|
||||||
|
};
|
||||||
|
|
||||||
|
guint8 exp_fci[] = {
|
||||||
|
0x00, 0x00, /* base sequence number: 0 */
|
||||||
|
0x00, 0x08, /* packet status count: 8 */
|
||||||
|
0x00, 0x00, 0x00, /* reference time: 0 */
|
||||||
|
0x00, /* feedback packet count: 0 */
|
||||||
|
0xd0, 0x00, /* packet chunk: 1 1 0 1 0 0 0 0 | 0 0 0 0 0 0 0 0 */
|
||||||
|
0xe0, 0x00, /* packet chunk: 1 1 1 0 0 0 0 0 | 0 0 0 0 0 0 1 0 */
|
||||||
|
0x00, /* recv delta: +0:00:00.000000000 */
|
||||||
|
0x03, 0xe8, /* recv delta: +0:00:00.250000000 */
|
||||||
|
0x00, /* padding */
|
||||||
|
};
|
||||||
|
|
||||||
|
twcc_verify_packets_to_fci (h0, packets, exp_fci);
|
||||||
|
twcc_verify_packets_to_packets (h1, h1, packets);
|
||||||
|
|
||||||
|
session_harness_free (h0);
|
||||||
|
session_harness_free (h1);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_END_TEST;
|
||||||
|
|
||||||
|
GST_START_TEST (test_twcc_status_vector_split_into_three)
|
||||||
|
{
|
||||||
|
SessionHarness *h0 = session_harness_new ();
|
||||||
|
SessionHarness *h1 = session_harness_new ();
|
||||||
|
|
||||||
|
TWCCPacket packets[] = {
|
||||||
|
/* 7 packets with small deltas */
|
||||||
|
{0, 0 * 250 * GST_USECOND, FALSE},
|
||||||
|
{1, 1 * 250 * GST_USECOND, FALSE},
|
||||||
|
{2, 2 * 250 * GST_USECOND, FALSE},
|
||||||
|
{3, 3 * 250 * GST_USECOND, FALSE},
|
||||||
|
{4, 4 * 250 * GST_USECOND, FALSE},
|
||||||
|
{5, 5 * 250 * GST_USECOND, FALSE},
|
||||||
|
{6, 6 * 250 * GST_USECOND, FALSE},
|
||||||
|
|
||||||
|
/* 2 large delta, #8 will present a negative delta */
|
||||||
|
{7, 7 * 250 * GST_MSECOND, FALSE},
|
||||||
|
{8, 8 * 250 * GST_USECOND, FALSE},
|
||||||
|
|
||||||
|
/* 13 packets with small deltas */
|
||||||
|
{9, 9 * 250 * GST_USECOND, FALSE},
|
||||||
|
{10, 10 * 250 * GST_USECOND, FALSE},
|
||||||
|
{11, 11 * 250 * GST_USECOND, FALSE},
|
||||||
|
{12, 12 * 250 * GST_USECOND, FALSE},
|
||||||
|
{13, 13 * 250 * GST_USECOND, FALSE},
|
||||||
|
{14, 14 * 250 * GST_USECOND, FALSE},
|
||||||
|
{15, 15 * 250 * GST_USECOND, FALSE},
|
||||||
|
{16, 16 * 250 * GST_USECOND, FALSE},
|
||||||
|
{17, 17 * 250 * GST_USECOND, FALSE},
|
||||||
|
{18, 18 * 250 * GST_USECOND, FALSE},
|
||||||
|
{19, 19 * 250 * GST_USECOND, FALSE},
|
||||||
|
{20, 20 * 250 * GST_USECOND, FALSE},
|
||||||
|
{21, 21 * 250 * GST_USECOND, TRUE},
|
||||||
|
};
|
||||||
|
|
||||||
|
guint8 exp_fci[] = {
|
||||||
|
0x00, 0x00, /* base sequence number: 0 */
|
||||||
|
0x00, 0x16, /* packet status count: 22 */
|
||||||
|
0x00, 0x00, 0x00, /* reference time: 0 */
|
||||||
|
0x00, /* feedback packet count: 0 */
|
||||||
|
0x20, 0x07, /* run-length chunk (small deltas) for #0 to #6: 0 0 1 0 0 0 0 0 | 0 0 0 0 0 1 1 1 */
|
||||||
|
0x40, 0x02, /* run-length chunk (large deltas) for #7 and #8 0 1 0 0 0 0 0 0 | 0 0 0 0 0 0 1 0 */
|
||||||
|
0x20, 0x0d, /* run-length chunk (small deltas) for #9 and #21 0 1 0 0 0 0 0 0 | 0 0 0 0 1 1 0 1 */
|
||||||
|
|
||||||
|
0x00, /* recv delta: +0:00:00.000000000 */
|
||||||
|
0x01, /* recv delta: +0:00:00.000250000 */
|
||||||
|
0x01, /* recv delta: +0:00:00.000250000 */
|
||||||
|
0x01, /* recv delta: +0:00:00.000250000 */
|
||||||
|
0x01, /* recv delta: +0:00:00.000250000 */
|
||||||
|
0x01, /* recv delta: +0:00:00.000250000 */
|
||||||
|
0x01, /* recv delta: +0:00:00.000250000 */
|
||||||
|
|
||||||
|
0x1b, 0x52, /* recv delta: +0:00:01.748500000 */
|
||||||
|
0xe4, 0xb0, /* recv delta: -0:00:01.748000000 */
|
||||||
|
|
||||||
|
0x01, /* recv delta: +0:00:00.000250000 */
|
||||||
|
0x01, /* recv delta: +0:00:00.000250000 */
|
||||||
|
0x01, /* recv delta: +0:00:00.000250000 */
|
||||||
|
0x01, /* recv delta: +0:00:00.000250000 */
|
||||||
|
0x01, /* recv delta: +0:00:00.000250000 */
|
||||||
|
0x01, /* recv delta: +0:00:00.000250000 */
|
||||||
|
0x01, /* recv delta: +0:00:00.000250000 */
|
||||||
|
0x01, /* recv delta: +0:00:00.000250000 */
|
||||||
|
0x01, /* recv delta: +0:00:00.000250000 */
|
||||||
|
0x01, /* recv delta: +0:00:00.000250000 */
|
||||||
|
0x01, /* recv delta: +0:00:00.000250000 */
|
||||||
|
0x01, /* recv delta: +0:00:00.000250000 */
|
||||||
|
0x01, /* recv delta: +0:00:00.000250000 */
|
||||||
|
|
||||||
|
0x00, 0x00, /* padding */
|
||||||
|
};
|
||||||
|
|
||||||
|
twcc_verify_packets_to_fci (h0, packets, exp_fci);
|
||||||
|
twcc_verify_packets_to_packets (h1, h1, packets);
|
||||||
|
|
||||||
|
session_harness_free (h0);
|
||||||
|
session_harness_free (h1);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_END_TEST;
|
||||||
|
|
||||||
|
GST_START_TEST (test_twcc_2_bit_full_status_vector)
|
||||||
|
{
|
||||||
|
SessionHarness *h0 = session_harness_new ();
|
||||||
|
SessionHarness *h1 = session_harness_new ();
|
||||||
|
|
||||||
|
TWCCPacket packets[] = {
|
||||||
|
{1, 1 * 64 * GST_MSECOND, FALSE},
|
||||||
|
{2, 2 * 64 * GST_MSECOND, FALSE},
|
||||||
|
{6, 6 * 64 * GST_MSECOND, FALSE},
|
||||||
|
{7, 7 * 64 * GST_MSECOND, TRUE},
|
||||||
|
};
|
||||||
|
|
||||||
|
guint8 exp_fci[] = {
|
||||||
|
0x00, 0x01, /* base sequence number: 1 */
|
||||||
|
0x00, 0x07, /* packet status count: 7 */
|
||||||
|
0x00, 0x00, 0x01, /* reference time: 1 */
|
||||||
|
0x00, /* feedback packet count: 0 */
|
||||||
|
0xd8, 0x0a, /* packet chunk: 1 1 0 1 1 0 0 0 | 0 0 0 0 1 0 1 0 */
|
||||||
|
0x00, 0x01, /* recv delta: +0:00:00.064000000 */
|
||||||
|
0x00, 0x04, /* recv delta: +0:00:00.256000000 */
|
||||||
|
0x00, 0x01, /* recv delta: +0:00:00.064000000 */
|
||||||
|
0x00, 0x00, 0x00, 0x00, /* padding */
|
||||||
|
};
|
||||||
|
|
||||||
|
twcc_verify_packets_to_fci (h0, packets, exp_fci);
|
||||||
|
twcc_verify_packets_to_packets (h1, h1, packets);
|
||||||
|
|
||||||
|
session_harness_free (h0);
|
||||||
|
session_harness_free (h1);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_END_TEST;
|
||||||
|
|
||||||
GST_START_TEST (test_twcc_various_gaps)
|
GST_START_TEST (test_twcc_various_gaps)
|
||||||
{
|
{
|
||||||
SessionHarness *h = session_harness_new ();
|
SessionHarness *h = session_harness_new ();
|
||||||
|
@ -3017,7 +3252,6 @@ GST_START_TEST (test_twcc_seqnum_wrap)
|
||||||
};
|
};
|
||||||
|
|
||||||
twcc_verify_packets_to_fci (h0, packets, exp_fci);
|
twcc_verify_packets_to_fci (h0, packets, exp_fci);
|
||||||
|
|
||||||
twcc_verify_packets_to_packets (h1, h1, packets);
|
twcc_verify_packets_to_packets (h1, h1, packets);
|
||||||
|
|
||||||
session_harness_free (h0);
|
session_harness_free (h0);
|
||||||
|
@ -3026,7 +3260,6 @@ GST_START_TEST (test_twcc_seqnum_wrap)
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
|
||||||
|
|
||||||
GST_START_TEST (test_twcc_seqnum_wrap_with_loss)
|
GST_START_TEST (test_twcc_seqnum_wrap_with_loss)
|
||||||
{
|
{
|
||||||
SessionHarness *h = session_harness_new ();
|
SessionHarness *h = session_harness_new ();
|
||||||
|
@ -3039,10 +3272,10 @@ GST_START_TEST (test_twcc_seqnum_wrap_with_loss)
|
||||||
|
|
||||||
guint8 exp_fci0[] = {
|
guint8 exp_fci0[] = {
|
||||||
0xff, 0xfe, /* base sequence number: 65534 */
|
0xff, 0xfe, /* base sequence number: 65534 */
|
||||||
0x00, 0x01, /* packet status count: 2 */
|
0x00, 0x01, /* packet status count: 1 */
|
||||||
0x00, 0x00, 0x00, /* reference time: 0 */
|
0x00, 0x00, 0x00, /* reference time: 0 */
|
||||||
0x00, /* feedback packet count: 0 */
|
0x00, /* feedback packet count: 0 */
|
||||||
0x20, 0x01, /* packet chunk */
|
0x20, 0x01, /* packet chunk: 0 0 1 0 0 0 0 0 | 0 0 0 0 0 0 0 1 */
|
||||||
0x00, /* recv delta: +0:00:00.000000000 */
|
0x00, /* recv delta: +0:00:00.000000000 */
|
||||||
0x00, /* padding */
|
0x00, /* padding */
|
||||||
};
|
};
|
||||||
|
@ -3052,7 +3285,7 @@ GST_START_TEST (test_twcc_seqnum_wrap_with_loss)
|
||||||
0x00, 0x01, /* packet status count: 1 */
|
0x00, 0x01, /* packet status count: 1 */
|
||||||
0x00, 0x00, 0x00, /* reference time: 0 */
|
0x00, 0x00, 0x00, /* reference time: 0 */
|
||||||
0x01, /* feedback packet count: 1 */
|
0x01, /* feedback packet count: 1 */
|
||||||
0x20, 0x01, /* packet chunk */
|
0x20, 0x01, /* packet chunk: 0 0 1 0 0 0 0 0 | 0 0 0 0 0 0 0 1 */
|
||||||
0x03, /* recv delta: +0:00:00.000750000 */
|
0x03, /* recv delta: +0:00:00.000750000 */
|
||||||
0x00, /* padding */
|
0x00, /* padding */
|
||||||
};
|
};
|
||||||
|
@ -3072,7 +3305,6 @@ GST_START_TEST (test_twcc_seqnum_wrap_with_loss)
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
|
||||||
|
|
||||||
GST_START_TEST (test_twcc_double_packets)
|
GST_START_TEST (test_twcc_double_packets)
|
||||||
{
|
{
|
||||||
SessionHarness *h = session_harness_new ();
|
SessionHarness *h = session_harness_new ();
|
||||||
|
@ -3090,7 +3322,7 @@ GST_START_TEST (test_twcc_double_packets)
|
||||||
|
|
||||||
guint8 exp_fci0[] = {
|
guint8 exp_fci0[] = {
|
||||||
0x00, 0x0b, /* base sequence number: 11 */
|
0x00, 0x0b, /* base sequence number: 11 */
|
||||||
0x00, 0x02, /* packet status count: 14 */
|
0x00, 0x02, /* packet status count: 2 */
|
||||||
0x00, 0x00, 0x00, /* reference time: 0 */
|
0x00, 0x00, 0x00, /* reference time: 0 */
|
||||||
0x00, /* feedback packet count: 0 */
|
0x00, /* feedback packet count: 0 */
|
||||||
0x20, 0x02, /* packet chunk: 0 0 1 0 0 0 0 0 | 0 0 0 0 0 0 1 0 */
|
0x20, 0x02, /* packet chunk: 0 0 1 0 0 0 0 0 | 0 0 0 0 0 0 1 0 */
|
||||||
|
@ -3117,8 +3349,8 @@ GST_END_TEST;
|
||||||
|
|
||||||
GST_START_TEST (test_twcc_huge_seqnum_gap)
|
GST_START_TEST (test_twcc_huge_seqnum_gap)
|
||||||
{
|
{
|
||||||
SessionHarness *h = session_harness_new ();
|
SessionHarness *h0 = session_harness_new ();
|
||||||
GstBuffer *buf;
|
SessionHarness *h1 = session_harness_new ();
|
||||||
|
|
||||||
TWCCPacket packets[] = {
|
TWCCPacket packets[] = {
|
||||||
{9, 4 * 32 * GST_MSECOND, FALSE},
|
{9, 4 * 32 * GST_MSECOND, FALSE},
|
||||||
|
@ -3128,37 +3360,13 @@ GST_START_TEST (test_twcc_huge_seqnum_gap)
|
||||||
{30013, 8 * 32 * GST_MSECOND, TRUE},
|
{30013, 8 * 32 * GST_MSECOND, TRUE},
|
||||||
};
|
};
|
||||||
|
|
||||||
guint8 exp_fci0[] = {
|
|
||||||
0x00, 0x09, /* base sequence number: 9 */
|
|
||||||
0x00, 0x02, /* packet status count: 2 */
|
|
||||||
0x00, 0x00, 0x02, /* reference time: 2 * 64ms */
|
|
||||||
0x00, /* feedback packet count: 0 */
|
|
||||||
/* packet chunks: */
|
|
||||||
0x20, 0x02, /* 0 0 1 0 0 0 0 0 | 0 0 0 0 0 0 1 0 */
|
|
||||||
0x00, 0x80, /* recv deltas, +0, +32ms */
|
|
||||||
};
|
|
||||||
|
|
||||||
guint8 exp_fci1[] = {
|
|
||||||
0x75, 0x3b, /* base sequence number: 300011 */
|
|
||||||
0x00, 0x03, /* packet status count: 3 */
|
|
||||||
0x00, 0x00, 0x03, /* reference time: 3 * 64ms */
|
|
||||||
0x01, /* feedback packet count: 1 */
|
|
||||||
/* packet chunks: */
|
|
||||||
0x20, 0x03, /* 0 0 1 0 0 0 0 0 | 0 0 0 0 0 0 1 1 */
|
|
||||||
0x00, 0x80, 0x80, /* recv deltas, +4, +32ms, +32ms */
|
|
||||||
0x00, 0x00, 0x00, /* padding */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The sequence-number does a huge leap. Instead of encoding this as
|
|
||||||
a massive run-lenght sequence, like so */
|
|
||||||
#if 0
|
|
||||||
guint8 exp_fci[] = {
|
guint8 exp_fci[] = {
|
||||||
0x00, 0x09, /* base sequence number: 9 */
|
0x00, 0x09, /* base sequence number: 9 */
|
||||||
0x75, 0x35, /* packet status count: 30005 */
|
0x75, 0x35, /* packet status count: 30005 */
|
||||||
0x00, 0x00, 0x02, /* reference time: 2 */
|
0x00, 0x00, 0x02, /* reference time: 2 */
|
||||||
0x00, /* feedback packet count: 0 */
|
0x00, /* feedback packet count: 0 */
|
||||||
/* packet chunks: */
|
/* packet chunks: */
|
||||||
0xb0, 0x00, /* 1 bit 2 there, 12 lost: 1 0 1 1 0 0 0 0 | 0 0 0 0 0 0 0 0 */
|
0xb0, 0x00, /* run-length: 1 bit 2 there, 12 lost: 1 0 1 1 0 0 0 0 | 0 0 0 0 0 0 0 0 */
|
||||||
0x1f, 0xff, /* run-length: 8191 lost: 0 0 0 1 1 1 1 1 | 1 1 1 1 1 1 1 1 */
|
0x1f, 0xff, /* run-length: 8191 lost: 0 0 0 1 1 1 1 1 | 1 1 1 1 1 1 1 1 */
|
||||||
0x1f, 0xff, /* run-length: 8191 lost: 0 0 0 1 1 1 1 1 | 1 1 1 1 1 1 1 1 */
|
0x1f, 0xff, /* run-length: 8191 lost: 0 0 0 1 1 1 1 1 | 1 1 1 1 1 1 1 1 */
|
||||||
0x1f, 0xff, /* run-length: 8191 lost: 0 0 0 1 1 1 1 1 | 1 1 1 1 1 1 1 1 */
|
0x1f, 0xff, /* run-length: 8191 lost: 0 0 0 1 1 1 1 1 | 1 1 1 1 1 1 1 1 */
|
||||||
|
@ -3169,21 +3377,14 @@ GST_START_TEST (test_twcc_huge_seqnum_gap)
|
||||||
0x00, 0x80, 0x80, 0x80, 0x80, /* recv deltas */
|
0x00, 0x80, 0x80, 0x80, 0x80, /* recv deltas */
|
||||||
0x00, 0x00, 0x00, /* padding */
|
0x00, 0x00, 0x00, /* padding */
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ...just send two feedback-packets, with
|
twcc_push_packets (h0, packets);
|
||||||
the second one starting from the new sequence-number. */
|
|
||||||
twcc_push_packets (h, packets);
|
|
||||||
|
|
||||||
buf = session_harness_produce_twcc (h);
|
twcc_verify_packets_to_fci (h0, packets, exp_fci);
|
||||||
twcc_verify_fci (buf, exp_fci0);
|
twcc_verify_packets_to_packets (h1, h1, packets);
|
||||||
gst_buffer_unref (buf);
|
|
||||||
|
|
||||||
buf = session_harness_produce_twcc (h);
|
session_harness_free (h0);
|
||||||
twcc_verify_fci (buf, exp_fci1);
|
session_harness_free (h1);
|
||||||
gst_buffer_unref (buf);
|
|
||||||
|
|
||||||
session_harness_free (h);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
@ -3203,35 +3404,22 @@ GST_START_TEST (test_twcc_duplicate_seqnums)
|
||||||
{3, 7 * 32 * GST_MSECOND, TRUE},
|
{3, 7 * 32 * GST_MSECOND, TRUE},
|
||||||
};
|
};
|
||||||
|
|
||||||
guint8 exp_fci0[] = {
|
guint8 exp_fci[] = {
|
||||||
0x00, 0x01, /* base sequence number: 1 */
|
0x00, 0x01, /* base sequence number: 1 */
|
||||||
0x00, 0x02, /* packet status count: 2 */
|
0x00, 0x03, /* packet status count: 2 */
|
||||||
0x00, 0x00, 0x02, /* reference time: 2 * 64ms */
|
0x00, 0x00, 0x02, /* reference time: 2 * 64ms */
|
||||||
0x00, /* feedback packet count: 0 */
|
0x00, /* feedback packet count: 0 */
|
||||||
/* packet chunks: */
|
/* packet chunks: */
|
||||||
0x20, 0x02, /* 0 0 1 0 0 0 0 0 | 0 0 0 0 0 0 1 0 */
|
0xd6, 0x00, /* 1 1 0 1 0 1 1 0 | 0 0 0 0 0 0 0 0 */
|
||||||
0x00, 0x80, /* recv deltas: +0, +32ms */
|
0x00, 0x80, /* recv deltas: +0, +32ms, + 64ms */
|
||||||
};
|
0x01, 0x00,
|
||||||
|
0x00, 0x00, /* padding */
|
||||||
guint8 exp_fci1[] = {
|
|
||||||
0x00, 0x03, /* base sequence number: 3 */
|
|
||||||
0x00, 0x01, /* packet status count: 1 */
|
|
||||||
0x00, 0x00, 0x03, /* reference time: 3 * 64ms */
|
|
||||||
0x01, /* feedback packet count: 1 */
|
|
||||||
/* packet chunks: */
|
|
||||||
0x20, 0x01, /* 0 0 1 0 0 0 0 0 | 0 0 0 0 0 0 0 1 */
|
|
||||||
0x80, /* recv deltas: +32ms */
|
|
||||||
0x00, /* padding */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
twcc_push_packets (h, packets);
|
twcc_push_packets (h, packets);
|
||||||
|
|
||||||
buf = session_harness_produce_twcc (h);
|
buf = session_harness_produce_twcc (h);
|
||||||
twcc_verify_fci (buf, exp_fci0);
|
twcc_verify_fci (buf, exp_fci);
|
||||||
gst_buffer_unref (buf);
|
|
||||||
|
|
||||||
buf = session_harness_produce_twcc (h);
|
|
||||||
twcc_verify_fci (buf, exp_fci1);
|
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
|
|
||||||
session_harness_free (h);
|
session_harness_free (h);
|
||||||
|
@ -3239,6 +3427,7 @@ GST_START_TEST (test_twcc_duplicate_seqnums)
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
|
||||||
|
|
||||||
GST_START_TEST (test_twcc_multiple_markers)
|
GST_START_TEST (test_twcc_multiple_markers)
|
||||||
{
|
{
|
||||||
SessionHarness *h = session_harness_new ();
|
SessionHarness *h = session_harness_new ();
|
||||||
|
@ -3320,7 +3509,7 @@ GST_START_TEST (test_twcc_no_marker_and_gaps)
|
||||||
|
|
||||||
/* Push packets with gaps and no marker bit. This should not prevent
|
/* Push packets with gaps and no marker bit. This should not prevent
|
||||||
the feedback packets from being sent at all. */
|
the feedback packets from being sent at all. */
|
||||||
for (i = 0; i < 80; i += 10) {
|
for (i = 0; i < 100; i += 10) {
|
||||||
TWCCPacket packets[] = { {i, i * 250 * GST_USECOND, FALSE}
|
TWCCPacket packets[] = { {i, i * 250 * GST_USECOND, FALSE}
|
||||||
};
|
};
|
||||||
twcc_push_packets (h, packets);
|
twcc_push_packets (h, packets);
|
||||||
|
@ -3730,7 +3919,6 @@ GST_START_TEST (test_twcc_no_exthdr_in_buffer)
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
|
||||||
|
|
||||||
GST_START_TEST (test_twcc_send_and_recv)
|
GST_START_TEST (test_twcc_send_and_recv)
|
||||||
{
|
{
|
||||||
SessionHarness *h_send = session_harness_new ();
|
SessionHarness *h_send = session_harness_new ();
|
||||||
|
@ -3949,6 +4137,76 @@ GST_START_TEST (test_twcc_feedback_old_seqnum)
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
|
||||||
|
GST_START_TEST (test_twcc_run_length_max)
|
||||||
|
{
|
||||||
|
SessionHarness *h0 = session_harness_new ();
|
||||||
|
SessionHarness *h1 = session_harness_new ();
|
||||||
|
|
||||||
|
TWCCPacket packets[] = {
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
{0, 1000 * GST_USECOND, FALSE},
|
||||||
|
{8205, 2000 * GST_USECOND, TRUE},
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
};
|
||||||
|
|
||||||
|
guint8 exp_fci[] = {
|
||||||
|
0x00, 0x00, /* base sequence number: 0 */
|
||||||
|
0x20, 0x0e, /* packet status count: 8206 */
|
||||||
|
0x00, 0x00, 0x00, /* reference time: 0 */
|
||||||
|
0x00, /* feedback packet count: 0 */
|
||||||
|
|
||||||
|
0xa0, 0x00, /* 1bit status for #0 received: 1 0 1 0 0 0 0 0 | 0 0 0 0 0 0 0 0 */
|
||||||
|
0x1f, 0xff, /* run-length with max length is reported as not received: 0 0 0 1 1 1 1 1 | 1 1 1 1 1 1 1 1 */
|
||||||
|
0xa0, 0x00, /* 1bit status for #8205 received: 1 0 1 0 0 0 0 0 | 0 0 0 0 0 0 0 0 */
|
||||||
|
|
||||||
|
0x04, /* recv delta: +0:00:00.001000000 */
|
||||||
|
0x04, /* recv delta: +0:00:00.001000000 */
|
||||||
|
};
|
||||||
|
|
||||||
|
twcc_verify_packets_to_fci (h0, packets, exp_fci);
|
||||||
|
twcc_verify_packets_to_packets (h1, h1, packets);
|
||||||
|
|
||||||
|
session_harness_free (h0);
|
||||||
|
session_harness_free (h1);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_END_TEST;
|
||||||
|
|
||||||
|
GST_START_TEST (test_twcc_run_length_min)
|
||||||
|
{
|
||||||
|
SessionHarness *h0 = session_harness_new ();
|
||||||
|
SessionHarness *h1 = session_harness_new ();
|
||||||
|
|
||||||
|
TWCCPacket packets[] = {
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
{0, 1000 * GST_USECOND, FALSE},
|
||||||
|
{29, 2000 * GST_USECOND, TRUE},
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
};
|
||||||
|
|
||||||
|
guint8 exp_fci[] = {
|
||||||
|
0x00, 0x00, /* base sequence number: 0 */
|
||||||
|
0x00, 0x1e, /* packet status count: 30 */
|
||||||
|
0x00, 0x00, 0x00, /* reference time: 0 */
|
||||||
|
0x00, /* feedback packet count: 0 */
|
||||||
|
|
||||||
|
0xa0, 0x00, /* 1bit status for #0 received: 1 0 1 0 0 0 0 0 | 0 0 0 0 0 0 0 0 */
|
||||||
|
0x00, 0x0f, /* run-length with length of 15, all not received: 0 0 0 0 0 0 0 0 | 0 0 0 0 1 1 1 1 */
|
||||||
|
0xa0, 0x00, /* 1bit status for #29 received: 1 0 1 0 0 0 0 0 | 0 0 0 0 0 0 0 0 */
|
||||||
|
|
||||||
|
0x04, /* recv delta: +0:00:00.001000000 */
|
||||||
|
0x04, /* recv delta: +0:00:00.001000000 */
|
||||||
|
};
|
||||||
|
|
||||||
|
twcc_verify_packets_to_fci (h0, packets, exp_fci);
|
||||||
|
twcc_verify_packets_to_packets (h1, h1, packets);
|
||||||
|
|
||||||
|
session_harness_free (h0);
|
||||||
|
session_harness_free (h1);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_END_TEST;
|
||||||
|
|
||||||
|
|
||||||
static Suite *
|
static Suite *
|
||||||
rtpsession_suite (void)
|
rtpsession_suite (void)
|
||||||
|
@ -3996,9 +4254,16 @@ rtpsession_suite (void)
|
||||||
|
|
||||||
/* twcc */
|
/* twcc */
|
||||||
tcase_add_loop_test (tc_chain, test_twcc_header_and_run_length,
|
tcase_add_loop_test (tc_chain, test_twcc_header_and_run_length,
|
||||||
0, G_N_ELEMENTS (twcc_header_and_run_lenght_test_data));
|
0, G_N_ELEMENTS (twcc_header_and_run_length_test_data));
|
||||||
|
tcase_add_test (tc_chain, test_twcc_run_length_max);
|
||||||
|
tcase_add_test (tc_chain, test_twcc_run_length_min);
|
||||||
tcase_add_test (tc_chain, test_twcc_1_bit_status_vector);
|
tcase_add_test (tc_chain, test_twcc_1_bit_status_vector);
|
||||||
tcase_add_test (tc_chain, test_twcc_2_bit_status_vector);
|
tcase_add_test (tc_chain, test_twcc_2_bit_status_vector);
|
||||||
|
tcase_add_test (tc_chain, test_twcc_2_bit_over_capacity);
|
||||||
|
tcase_add_test (tc_chain, test_twcc_2_bit_full_status_vector);
|
||||||
|
tcase_add_test (tc_chain, test_twcc_status_vector_split_large_delta);
|
||||||
|
tcase_add_test (tc_chain, test_twcc_status_vector_split_with_gap);
|
||||||
|
tcase_add_test (tc_chain, test_twcc_status_vector_split_into_three);
|
||||||
tcase_add_loop_test (tc_chain, test_twcc_various_gaps, 0, 50);
|
tcase_add_loop_test (tc_chain, test_twcc_various_gaps, 0, 50);
|
||||||
tcase_add_test (tc_chain, test_twcc_negative_delta);
|
tcase_add_test (tc_chain, test_twcc_negative_delta);
|
||||||
tcase_add_test (tc_chain, test_twcc_seqnum_wrap);
|
tcase_add_test (tc_chain, test_twcc_seqnum_wrap);
|
||||||
|
@ -4021,7 +4286,6 @@ rtpsession_suite (void)
|
||||||
tcase_add_test (tc_chain, test_twcc_feedback_count_wrap);
|
tcase_add_test (tc_chain, test_twcc_feedback_count_wrap);
|
||||||
tcase_add_test (tc_chain, test_twcc_feedback_old_seqnum);
|
tcase_add_test (tc_chain, test_twcc_feedback_old_seqnum);
|
||||||
|
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue