路由器rtsp协议如何设置

路由器rtsp协议如何设置,第1张

支持持久连接或无连接的客户端可能给其请求排队。服务器必须以收到请求的同样顺序发出响应。如果请求不是发送给多播组,接收者就确认请求,如没有确认信息,发送者可在超过一个来回时间(RTT)后重发同一信息。在TCP中RTT估计的初始值为500ms。应用缓存最后所测量的RTT,作为将来连接的初始值。如使用一个可靠传输协议传输RTSP,请求不允许重发,RTSP应用反过来依赖低层传输提供可靠性。如两个低层可靠传输(如TCP和RTSP)应用重发请求,有可能每个包损失导致两次重传。由于传输栈在第一次尝试到达接收者前不会发送应用层重传,接收者也不能充分利用应用层重传。如包损失由阻塞引起,不同层的重发将使阻塞进一步恶化。时标头用来避免重发模糊性问题,避免对圆锥算法的依赖。每个请求在CSeq头中携带一个系列号,每发送一个不同请求,它就加一。如由于没有确认而重发请求,请求必须携带初始系列号。实现RTSP的系统必须支持通过TCP传输RTSP,并支持UDP。对UDP和TCP,RTSP服务器的缺省端口都是554。许多目的一致的RTSP包被打包成单个低层PDU或TCP流。RTSP数据可与RTP和RTCP包交叉。不像HTTP,RTSP信息必须包含一个内容长度头,无论信息何时包含负载。否则,RTSP包以空行结束,后跟最后一个信息头。

1 把视频源当然文件来处理,sample有。不过这种方法用的不多。

2 修改vid_stream.c,在put_frame和get_frame里,换上我们自己的视频源。这种方法使用的最多,很多人在1.x版本里支持视频,就用这种方法。

3 重新构造sdp,自己创建rtp通道。

在sdp上,pjsua_call_make_call这个函数非常方便,直接呼叫对方。不过它在底层做了太多工作,比如启动了声卡。而不用这个函数,直接用比较底层的pjsip_inv_send_msg,自己处理的工作相对比较多(但不难,不过这样就不需要pjsua这个现成的程序了,所以我们继续用pjsua_call_make_call)。

不过还好,pj库提供了大量的回调,其中一个:on_call_sdp_created,就是在创建sdp后回调上来,由我们自己再修改。比如我们自己定义rtp的端口g_local_port。

void on_call_sdp_created(pjsua_call_id call_id,

pjmedia_sdp_session *sdp,

pj_pool_t *pool,

const pjmedia_sdp_session *rem_sdp)

{

int nPort

if (sdp != NULL)

{

pjmedia_sdp_media *m = sdp->media[sdp->media_count-1]

m->desc.port = g_local_port

pjmedia_sdp_conn *c = sdp->conn

char* addr

if (c)

addr= c->addr.ptr

else

{

const pj_str_t *hostname

pj_sockaddr_in tmp_addr

char *addr

hostname = pj_gethostname()

pj_sockaddr_in_init(&tmp_addr, hostname, 0)

addr = pj_inet_ntoa(tmp_addr.sin_addr)

sdp->conn = (pjmedia_sdp_conn *)pj_pool_zalloc (pool, sizeof(pjmedia_sdp_conn))

sdp->conn->net_type = pj_str("IN")

sdp->conn->addr_type = pj_str("IP4")

sdp->conn->addr = pj_str(addr)

}

sdp->origin.addr = *pj_gethostname()

}

}

同样,这里还可以修改payload type等。

这是发起呼叫时的,接收方收到后的回应之后,也会触发这个回调,自己设定RTP端口,payload type就可以了。

2

呼叫成功后,双方建立起连接关系,这时需要传rtp数据了。pjsua把这些工作都放在底层了,不做任何修改,只需要在发送和接收时,自己做一些处理就行。

先说接收方(参考siprtp.c源码):

pj_status_t init_local_rtp()

{

if (m_bInitMedia)

{

destroy_media()

}

//g_local_port = local_port

pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0)

pool = pj_pool_create(&(cp.factory), "test", 1000, 512, NULL)

int status

//status = pjmedia_endpt_create(&cp.factory, pjsip_endpt_get_ioqueue(pjsua_get_pjsip_endpt()), 0, &med_endpt)

status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt)

status = pjmedia_rtp_session_init(&video.out_sess, 97, pj_rand())

status = pjmedia_rtp_session_init(&video.in_sess, 97, 0)

status = pjmedia_transport_udp_create(med_endpt, NULL, g_local_port, 0, &video.transport)

m_bInitMedia = true

video.active = true

return 0

}

这段代码是本地启动rtp一个端口用来接收视频数据。

然后,从sdp得到对方发送的ip和端口,调用pjmedia_transport_attach,建立关联就可以了。

实现了rtp ,rtsp部分,还有rtcp没搞定网上找了下,没发现很好的解释,如图字段,哪位帮忙讲解下:主要是这个:以上是我通过抓包软件根据vlc获取的rtcp部分我想发送rtcp到ipc,发现rtcp包有两个部分rr sd而rr时刻是变化的,sd部分一个特定的IPC是固定的网上貌 是没有关于这个部分的解释,rr变化的规律


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/tougao/11473001.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-16
下一篇 2023-05-16

发表评论

登录后才能评论

评论列表(0条)

保存