无法从 RTP 数据包中提取 RTP 负载
can't extraxt RTP Payload from RTP Packet
您好,我想像 udpxy 一样将多播视频代理到单播:http://www.udpxy.com,但在 C# 中
因为我找不到任何我可以使用的合适的 RTP 库(它们太复杂或者我不明白如何使用它们),我决定移植一个 udpxy 使用的 rtp.c: https://github.com/pcherenkov/udpxy/blob/master/chipmunk/rtp.c
一切顺利(几乎,因为我不想使用指针),直到我想将 RTP_Process 翻译成 C#
RTP_Process 在 C
RTP_process( void** pbuf, size_t* len, int verify, FILE* log )
{
int rtp_padding = -1;
size_t front_skip = 0, back_skip = 0, pad_len = 0;
char* buf = NULL;
size_t pkt_len = 0;
assert( pbuf && len && log );
buf = *pbuf;
pkt_len = *len;
if( verify && !RTP_verify( buf, pkt_len, log ) )
return -1;
if( 0 != RTP_hdrlen( buf, pkt_len, &front_skip, log ) )
return -1;
rtp_padding = buf[0] & 0x20;
if( rtp_padding ) {
pad_len = buf[ pkt_len - 1 ];
}
back_skip += pad_len;
if( verify && (pkt_len < (front_skip + back_skip)) ) {
(void) tmfprintf( log, "RTP_process: invalid header "
"(skip [%lu] exceeds packet length [%lu])\n",
(u_long)(front_skip + back_skip), (u_long)pkt_len );
return -1;
}
/* adjust buffer/length to skip heading and padding */
/*
TRACE( (void)tmfprintf( log, "In: RTP buf=[%p] of [%lu] bytes, "
"fskip=[%ld], bskip=[%lu]\n",
(void*)buf, (u_long)pkt_len,
(u_long)front_skip, (u_long)back_skip ) );
*/
buf += front_skip;
pkt_len -= (front_skip + back_skip);
/*
TRACE( (void)tmfprintf( log, "Out RTP buf=[%p] of [%lu] bytes\n",
(void*)buf, (u_long)pkt_len ) );
*/
*pbuf = buf;
*len = pkt_len;
return 0;
}
RTP_Process 在 C#
public byte[] RTP_process(int verify)
{
/* process RTP package to retrieve the payload: set
* pbuf to the start of the payload area; set len to
* be equal payload's length
*
* @param pbuf address of pointer to beginning of RTP packet
* @param len pointer to RTP packet's length
* @param verify verify that it is an RTP packet if != 0
* @param log log file
*
* @return 0 if there was no error, -1 otherwise;
* set pbuf to point to beginning of payload and len
* be payload size in bytes
*/
int rtp_padding = -1;
int front_skip = 0, back_skip = 0, pad_len = 0;
int pkt_len = 0;
//assert(pbuf && len && log);
//buf = *pbuf;
pbuf = buf;
//pkt_len = *len;
len = pkt_len;
/*
if (verify != 1 && RTP_verify() != 1)
RTPOK = - 1;
if (0 != RTP_hdrlen(buf, pkt_len, front_skip)) //?????
RTPOK = - 1;
*/
rtp_padding = buf[0] & 0x20;
if (rtp_padding != -1) //???????
{
pad_len = buf[pkt_len - 1];
}
back_skip += pad_len;
if ((verify != -1) && (pkt_len < (front_skip + back_skip))) //???????
{
Console.WriteLine("RTP_process: invalid header (skip {0} exceeds packet length {1})\n", (long)(front_skip + back_skip), (long)pkt_len);
RTPOK = - 1;
}
/* adjust buffer/length to skip heading and padding */
/*
TRACE( (void)tmfprintf( log, "In: RTP buf=[%p] of [%lu] bytes, "
"fskip=[%ld], bskip=[%lu]\n",
(void*)buf, (u_long)pkt_len,
(u_long)front_skip, (u_long)back_skip ) );
*/
//buf += front_skip;
//pkt_len -= (front_skip + back_skip);
/*
TRACE( (void)tmfprintf( log, "Out RTP buf=[%p] of [%lu] bytes\n",
(void*)buf, (u_long)pkt_len ) );
*/
pbuf = buf;
len = pkt_len;
RTPOK = 0;
return pbuf;
}
问题从这里开始
1. buf += front_skip;
抱怨 operator += 不能应用于 byte[] 和 int 类型的操作数
那么为什么它在 C 中的 RTP_Process 中工作,什么是 C# 等价物
2. 在
if (rtp_padding != -1) //???????
{
pad_len = buf[pkt_len - 1]; //There is an exeption trown: System.IndexOutOfRangeException: Index was outside the bounds of the array.
很明显我以错误的方式解释和翻译了一些东西,但我唯一想做的就是从 RTP 流中获取 MPEG-TS 帧,然后将其转发到 TCP 套接字,所以如果有人可以建议更好的方法我很想听听
感谢您的回答和最诚挚的问候
}
首先,我建议仔细阅读RFC-3550, it has all information about RTP-packet structure (mostly you need Section #5: RTP Fixed Header and extensions).
然后你必须执行RTP_hdrlen来计算RTP header大小,它必须return front_skip值作为RTP header大小包括扩展。因此,您不必使用 buf += front_skip;
,RTP 负载从字节 buf[front_skip]
.
开始
你这里的数据包长度参数有误:int pkt_len = 0;
,所以这里抛出异常pad_len = buf[pkt_len - 1];
.
您好,我想像 udpxy 一样将多播视频代理到单播:http://www.udpxy.com,但在 C# 中 因为我找不到任何我可以使用的合适的 RTP 库(它们太复杂或者我不明白如何使用它们),我决定移植一个 udpxy 使用的 rtp.c: https://github.com/pcherenkov/udpxy/blob/master/chipmunk/rtp.c
一切顺利(几乎,因为我不想使用指针),直到我想将 RTP_Process 翻译成 C#
RTP_Process 在 C
RTP_process( void** pbuf, size_t* len, int verify, FILE* log )
{
int rtp_padding = -1;
size_t front_skip = 0, back_skip = 0, pad_len = 0;
char* buf = NULL;
size_t pkt_len = 0;
assert( pbuf && len && log );
buf = *pbuf;
pkt_len = *len;
if( verify && !RTP_verify( buf, pkt_len, log ) )
return -1;
if( 0 != RTP_hdrlen( buf, pkt_len, &front_skip, log ) )
return -1;
rtp_padding = buf[0] & 0x20;
if( rtp_padding ) {
pad_len = buf[ pkt_len - 1 ];
}
back_skip += pad_len;
if( verify && (pkt_len < (front_skip + back_skip)) ) {
(void) tmfprintf( log, "RTP_process: invalid header "
"(skip [%lu] exceeds packet length [%lu])\n",
(u_long)(front_skip + back_skip), (u_long)pkt_len );
return -1;
}
/* adjust buffer/length to skip heading and padding */
/*
TRACE( (void)tmfprintf( log, "In: RTP buf=[%p] of [%lu] bytes, "
"fskip=[%ld], bskip=[%lu]\n",
(void*)buf, (u_long)pkt_len,
(u_long)front_skip, (u_long)back_skip ) );
*/
buf += front_skip;
pkt_len -= (front_skip + back_skip);
/*
TRACE( (void)tmfprintf( log, "Out RTP buf=[%p] of [%lu] bytes\n",
(void*)buf, (u_long)pkt_len ) );
*/
*pbuf = buf;
*len = pkt_len;
return 0;
}
RTP_Process 在 C#
public byte[] RTP_process(int verify)
{
/* process RTP package to retrieve the payload: set
* pbuf to the start of the payload area; set len to
* be equal payload's length
*
* @param pbuf address of pointer to beginning of RTP packet
* @param len pointer to RTP packet's length
* @param verify verify that it is an RTP packet if != 0
* @param log log file
*
* @return 0 if there was no error, -1 otherwise;
* set pbuf to point to beginning of payload and len
* be payload size in bytes
*/
int rtp_padding = -1;
int front_skip = 0, back_skip = 0, pad_len = 0;
int pkt_len = 0;
//assert(pbuf && len && log);
//buf = *pbuf;
pbuf = buf;
//pkt_len = *len;
len = pkt_len;
/*
if (verify != 1 && RTP_verify() != 1)
RTPOK = - 1;
if (0 != RTP_hdrlen(buf, pkt_len, front_skip)) //?????
RTPOK = - 1;
*/
rtp_padding = buf[0] & 0x20;
if (rtp_padding != -1) //???????
{
pad_len = buf[pkt_len - 1];
}
back_skip += pad_len;
if ((verify != -1) && (pkt_len < (front_skip + back_skip))) //???????
{
Console.WriteLine("RTP_process: invalid header (skip {0} exceeds packet length {1})\n", (long)(front_skip + back_skip), (long)pkt_len);
RTPOK = - 1;
}
/* adjust buffer/length to skip heading and padding */
/*
TRACE( (void)tmfprintf( log, "In: RTP buf=[%p] of [%lu] bytes, "
"fskip=[%ld], bskip=[%lu]\n",
(void*)buf, (u_long)pkt_len,
(u_long)front_skip, (u_long)back_skip ) );
*/
//buf += front_skip;
//pkt_len -= (front_skip + back_skip);
/*
TRACE( (void)tmfprintf( log, "Out RTP buf=[%p] of [%lu] bytes\n",
(void*)buf, (u_long)pkt_len ) );
*/
pbuf = buf;
len = pkt_len;
RTPOK = 0;
return pbuf;
}
问题从这里开始
1. buf += front_skip;
抱怨 operator += 不能应用于 byte[] 和 int 类型的操作数
那么为什么它在 C 中的 RTP_Process 中工作,什么是 C# 等价物
2. 在
if (rtp_padding != -1) //???????
{
pad_len = buf[pkt_len - 1]; //There is an exeption trown: System.IndexOutOfRangeException: Index was outside the bounds of the array.
很明显我以错误的方式解释和翻译了一些东西,但我唯一想做的就是从 RTP 流中获取 MPEG-TS 帧,然后将其转发到 TCP 套接字,所以如果有人可以建议更好的方法我很想听听
感谢您的回答和最诚挚的问候 }
首先,我建议仔细阅读RFC-3550, it has all information about RTP-packet structure (mostly you need Section #5: RTP Fixed Header and extensions).
然后你必须执行RTP_hdrlen来计算RTP header大小,它必须return front_skip值作为RTP header大小包括扩展。因此,您不必使用
开始buf += front_skip;
,RTP 负载从字节buf[front_skip]
.你这里的数据包长度参数有误:
int pkt_len = 0;
,所以这里抛出异常pad_len = buf[pkt_len - 1];
.