您当前的位置: 首页 > 

qianbo_insist

暂无认证

  • 1浏览

    0关注

    399博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

RTP 发送PS流零拷贝方案

qianbo_insist 发布时间:2022-06-29 23:25:59 ,浏览量:1

代码依然在gitee上,逐步修改 https://gitee.com/guanzhi0319/rtp

数据达到发送RTP

数据收集到后,编码h264,或者h265,发送ps流或者h264裸流到指定服务器。

void LiveRTPUdpEncoder::OnCaptureVideoBuffer(uint8_t *data, int len, unsigned int timestamp, bool isKeyframe)
{
#define D(x) *(data+x)
	if (SimpleThread::IsStop()) return;

#if 0
	char buffer[32];
	sprintf_s(buffer, "QB:%02x %02x %02x %02x %02x %02x",
		D(0), D(1), D(2), D(3), D(4), D(5));
	OutputDebugStringA(buffer);
	return;
#endif
    uint8_t* odata = NULL;
    int olen = 0;
    uint8_t n = D(4) & 0x1f;
    int isIFrame = n == 0x07;
    switch (v_stream_type)
    {
    case en_rtp:
        odata = data;
        olen = len;
        break;
    case en_ps_over_rtp:
        uint8_t* odata;
        int olen;
        v_ps.packagingPs(isIFrame, timestamp, data, len, &odata, &olen);
        break;
    }

	//timestamp = GetTimestamp();
    {
        Lock lock(this);
               if(v_stream_type == en_ps_over_rtp)
        {
            uint8_t* ps = odata + RTP_UDP_HEAD_LEN;
            olen = olen - RTP_UDP_HEAD_LEN;
            v_rtp.send_video_ps(ps, olen, convertToRTPTimestamp(), isKeyframe);
            delete[]odata;

        }
        else if (v_stream_type == en_rtp)
        {
            v_rtp.send_video(odata, olen, convertToRTPTimestamp(), isKeyframe);
        }

        if (!gVideoBegin)
            gVideoBegin = true;
    }
}
发送RTP ps

在ps流的前面留空12字节,每次1400字节发送的时候,修改前面12字节RTP包,注意也就是修改了数据包,不复用,并且发送一定是同步的才能正确,好处是避免了数据拷贝。 避免数据拷贝的方式有两种, 1、一种是同步缓冲区,但是异步发送 2、同步发送 3、使用协程,同步发送。 这里是客户端,发送时只有一路,使用了UDP,直接同步发送就行。申请ps内存的时候为了不拷贝数据,前面留空了12字节作为RTP UDP的头部。那么在发送每隔包的时候,在发送的数据往前倒推12字节,避免拷贝,但是这样修改了缓冲区里的数据,如果想复用,每次在覆盖的时候先把12字节赋值,发送完毕,再把字节恢复。

int c_rtp::send_video_ps(uint8_t* data, int len, uint32_t timestamp, bool iskeyframe)
{
	//data 前面有12 字节为空,构造 ps 流时留空
	uint8_t* x = data;
	int num = (len - 1) / 1400 + 1;
	for (int i = 0; i payload = H264;  //负载类型号,
		rtp_hdr->version = 2;  //版本号,此版本固定为2
		rtp_hdr->marker = 0;   //标志位,由具体协议规定其值。
		rtp_hdr->ssrc = little2big(1111);
		rtp_hdr->timestamp = little2big(timestamp);
		if (i             
关注
打赏
1663161521
查看更多评论
0.1964s