Skip to content

Commit 2ed9d06

Browse files
committed
avformat/whip: properly handle encrypted SRTCP NACK pakcet
decrypt the SRTCP pakcet, get the right pid and blp data add more comments Signed-off-by: Jack Lau <jacklau1222@qq.com>
1 parent 734463e commit 2ed9d06

File tree

1 file changed

+33
-9
lines changed

1 file changed

+33
-9
lines changed

libavformat/whip.c

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@
154154
/**
155155
* Retransmission / NACK support
156156
*/
157-
#define HISTORY_SIZE_DEFAULT 512
157+
#define HISTORY_SIZE_DEFAULT 1024
158158

159159
/* Calculate the elapsed time from starttime to endtime in milliseconds. */
160160
#define ELAPSED(starttime, endtime) ((int)(endtime - starttime) / 1000)
@@ -1913,29 +1913,53 @@ static int whip_write_packet(AVFormatContext *s, AVPacket *pkt)
19131913
goto end;
19141914
}
19151915
}
1916-
/* Handle RTCP NACK ( RTPFB / FMT=1 ) */
1916+
/**
1917+
* Handle RTCP NACK
1918+
* Refer to RFC 4585, Section 6.2.1
1919+
* The Generic NACK message is identified by PT=RTPFB and FMT=1.
1920+
*/
19171921
if (media_is_rtcp(whip->buf, ret)) {
19181922
int ptr = 0;
19191923
while (ptr + 4 <= ret) {
19201924
uint8_t pt = whip->buf[ptr + 1];
1925+
/**
1926+
* Refer to RFC 3550, Section 6.4.1.
1927+
* The length of this RTCP packet in 32-bit words minus one,
1928+
* including the header and any padding.
1929+
*/
19211930
int len = (AV_RB16(&whip->buf[ptr + 2]) + 1) * 4;
19221931
if (ptr + len > ret) break;
19231932

1924-
if (pt == 205) { /* RTPFB */
1933+
if (pt == 205) { /* PT=RTPFB */
19251934
uint8_t fmt = (whip->buf[ptr] & 0x1f);
1926-
if (fmt == 1 && len >= 12) {
1927-
uint16_t pid = AV_RB16(&whip->buf[ptr + 12 - 4]);
1928-
uint16_t blp = AV_RB16(&whip->buf[ptr + 14 - 4]);
1935+
if (fmt == 1 && len >= 12) { /* FMT=1 */
1936+
/* SRTCP index(4 bytes) + HMAC (SRTP_AES128_CM_SHA1_80 10bytes) */
1937+
int srtcp_len = len + 4 + 10;
1938+
int ret = ff_srtp_decrypt(&whip->srtp_recv, whip->buf, &srtcp_len);
1939+
if (ret < 0) {
1940+
av_log(whip, AV_LOG_ERROR, "WHIP: SRTCP decrypt failed: %d\n", ret);
1941+
// packet is invalid or authentication failed
1942+
break;
1943+
}
1944+
/**
1945+
* See https://datatracker.ietf.org/doc/html/rfc4585#section-6.1
1946+
* TODO: Handle multi NACK in boudary packets.
1947+
*/
1948+
uint16_t pid = AV_RB16(&whip->buf[ptr + 12]);
1949+
uint16_t blp = AV_RB16(&whip->buf[ptr + 14]);
19291950

19301951
/* retransmit pid + any bit set in blp */
19311952
for (int bit = -1; bit < 16; bit++) {
19321953
uint16_t seq = (bit < 0) ? pid : pid + bit + 1;
19331954
if (bit >= 0 && !(blp & (1 << bit)))
19341955
continue;
19351956

1936-
const RtpHistoryItem * it = rtp_history_find(whip, seq);
1937-
if (it)
1938-
send_rtx_packet(s, it->pkt, it->size);
1957+
const RtpHistoryItem * it = rtp_history_find(whip, seq);
1958+
if (it) {
1959+
send_rtx_packet(s, it->pkt, it->size);
1960+
av_log(whip, AV_LOG_INFO, "WHIP: NACK packet found: size: %d, seq=%d, blp=%d\n", it->size, seq, blp);
1961+
} else
1962+
av_log(whip, AV_LOG_INFO, "WHIP: NACK packet, seq=%d, blp=%d, not found\n", seq, blp);
19391963
}
19401964
}
19411965
}

0 commit comments

Comments
 (0)