|
154 | 154 | /** |
155 | 155 | * Retransmission / NACK support |
156 | 156 | */ |
157 | | -#define HISTORY_SIZE_DEFAULT 512 |
| 157 | +#define HISTORY_SIZE_DEFAULT 1024 |
158 | 158 |
|
159 | 159 | /* Calculate the elapsed time from starttime to endtime in milliseconds. */ |
160 | 160 | #define ELAPSED(starttime, endtime) ((int)(endtime - starttime) / 1000) |
@@ -1913,29 +1913,53 @@ static int whip_write_packet(AVFormatContext *s, AVPacket *pkt) |
1913 | 1913 | goto end; |
1914 | 1914 | } |
1915 | 1915 | } |
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 | + */ |
1917 | 1921 | if (media_is_rtcp(whip->buf, ret)) { |
1918 | 1922 | int ptr = 0; |
1919 | 1923 | while (ptr + 4 <= ret) { |
1920 | 1924 | 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 | + */ |
1921 | 1930 | int len = (AV_RB16(&whip->buf[ptr + 2]) + 1) * 4; |
1922 | 1931 | if (ptr + len > ret) break; |
1923 | 1932 |
|
1924 | | - if (pt == 205) { /* RTPFB */ |
| 1933 | + if (pt == 205) { /* PT=RTPFB */ |
1925 | 1934 | 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]); |
1929 | 1950 |
|
1930 | 1951 | /* retransmit pid + any bit set in blp */ |
1931 | 1952 | for (int bit = -1; bit < 16; bit++) { |
1932 | 1953 | uint16_t seq = (bit < 0) ? pid : pid + bit + 1; |
1933 | 1954 | if (bit >= 0 && !(blp & (1 << bit))) |
1934 | 1955 | continue; |
1935 | 1956 |
|
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); |
1939 | 1963 | } |
1940 | 1964 | } |
1941 | 1965 | } |
|
0 commit comments