从多播流中计算 RTP 序列号
Count RTP Sequence number from multicast stream
我正在尝试从多播流中计算 RTP 序列号并确定丢失的包。
请看下面的C代码:
int sock, bytesRead;
char buffer[MAXBUFSIZE];
uint16_t seq = 0;
uint16_t eseq = 0;
struct sockaddr_in saddr;
socklen_t socklen;
for(;;) {
bytesRead = recvfrom(sock, buffer, MAXBUFSIZE, 0,
(struct sockaddr *)&saddr, &socklen);
if (bytesRead) {
seq = (buffer[2] << 8)+buffer[3];
eseq++;
if (seq != eseq) {
std::cerr << " SEQ = " << seq << " ESEC = " << eseq << "\n";
eseq = seq;
}
}
}
我收到了以下结果:
12:47:44 SEQ = 58112 ESEC = 57856
12:47:45 SEQ = 57984 ESEC = 58240
12:47:45 SEQ = 58368 ESEC = 58112
12:47:45 SEQ = 58240 ESEC = 58496
12:47:45 SEQ = 58624 ESEC = 58368
12:47:46 SEQ = 58496 ESEC = 58752
12:47:46 SEQ = 58880 ESEC = 58624
12:47:46 SEQ = 58752 ESEC = 59008
12:47:46 SEQ = 59136 ESEC = 58880
12:47:47 SEQ = 59008 ESEC = 59264
12:47:47 SEQ = 59392 ESEC = 59136
12:47:47 SEQ = 59264 ESEC = 59520
每个 128
RTP 包都出现错误,如您所见 |ESEC - SEQ| = 256
,我还删除了 RTP headers 并将数据写入 file.mpg 并且视频播放正常没有错误和人工制品。
请解释如何正确计算多播流中的 RTP 序列号
由于缓冲区是 signed char
数组,您的转换(左移)发生溢出。这是UB
您可以 test/solve 使用此代码示例:
#include <stdio.h>
#include <stdint.h>
int main()
{
uint16_t seq1;
uint16_t seq2;
uint16_t seq3;
char buffer1[] = {0, 0, 0xE8, 0x80};
unsigned char buffer2[] = {0, 0, 0xE8, 0x80};
seq1 = (buffer1[2] << 8)+buffer1[3];
printf("seq1: %d\n", seq1);
seq2 = (buffer2[2] << 8)+buffer2[3];
printf("seq2: %d\n", seq2);
seq3 = buffer1[2];
seq3 = (seq3 << 8)+buffer2[3];
printf("seq3: %d\n", seq3);
return 0;
}
输出为:
seq1: 59264
seq2: 59520
seq3: 59520
如您所见,使用 signed char
(seq1
) 缓冲区,转换是错误的。
该示例显示了您发布的最后一行结果发生了什么。
我正在尝试从多播流中计算 RTP 序列号并确定丢失的包。
请看下面的C代码:
int sock, bytesRead;
char buffer[MAXBUFSIZE];
uint16_t seq = 0;
uint16_t eseq = 0;
struct sockaddr_in saddr;
socklen_t socklen;
for(;;) {
bytesRead = recvfrom(sock, buffer, MAXBUFSIZE, 0,
(struct sockaddr *)&saddr, &socklen);
if (bytesRead) {
seq = (buffer[2] << 8)+buffer[3];
eseq++;
if (seq != eseq) {
std::cerr << " SEQ = " << seq << " ESEC = " << eseq << "\n";
eseq = seq;
}
}
}
我收到了以下结果:
12:47:44 SEQ = 58112 ESEC = 57856
12:47:45 SEQ = 57984 ESEC = 58240
12:47:45 SEQ = 58368 ESEC = 58112
12:47:45 SEQ = 58240 ESEC = 58496
12:47:45 SEQ = 58624 ESEC = 58368
12:47:46 SEQ = 58496 ESEC = 58752
12:47:46 SEQ = 58880 ESEC = 58624
12:47:46 SEQ = 58752 ESEC = 59008
12:47:46 SEQ = 59136 ESEC = 58880
12:47:47 SEQ = 59008 ESEC = 59264
12:47:47 SEQ = 59392 ESEC = 59136
12:47:47 SEQ = 59264 ESEC = 59520
每个 128
RTP 包都出现错误,如您所见 |ESEC - SEQ| = 256
,我还删除了 RTP headers 并将数据写入 file.mpg 并且视频播放正常没有错误和人工制品。
请解释如何正确计算多播流中的 RTP 序列号
由于缓冲区是 signed char
数组,您的转换(左移)发生溢出。这是UB
您可以 test/solve 使用此代码示例:
#include <stdio.h>
#include <stdint.h>
int main()
{
uint16_t seq1;
uint16_t seq2;
uint16_t seq3;
char buffer1[] = {0, 0, 0xE8, 0x80};
unsigned char buffer2[] = {0, 0, 0xE8, 0x80};
seq1 = (buffer1[2] << 8)+buffer1[3];
printf("seq1: %d\n", seq1);
seq2 = (buffer2[2] << 8)+buffer2[3];
printf("seq2: %d\n", seq2);
seq3 = buffer1[2];
seq3 = (seq3 << 8)+buffer2[3];
printf("seq3: %d\n", seq3);
return 0;
}
输出为:
seq1: 59264
seq2: 59520
seq3: 59520
如您所见,使用 signed char
(seq1
) 缓冲区,转换是错误的。
该示例显示了您发布的最后一行结果发生了什么。