pjsip中添加视频

来源:互联网 发布:大连生态科技城 知乎 编辑:程序博客网 时间:2024/05/18 00:04
  1. 在sdp中添加视频信息
    1. 在Invite消息的sdp中添加视频信息
    2. sdp信息中视频的rtp端口的生成
  2. 视频处理模块的添加
  3. 视频收发以及回放
    1. rtp发送
    2. Rtp接收
    3. 远端视频回放
    4. 本地视频回放
  4. 视频工作线程
    1. 发送线程
    2. 接收以及回放线程

1.                   在sdp中添加视频信息

添加sdp信息中的视频部分主要通过下面两个步骤处理。

1.1               在Invite消息的sdp中添加视频信息

主要在endpoint.c的pjmedia_endpt_create_sdp()函数中添加。具体的可以看其中的代码,以及代码中的注释。

注意pjmedia_endpt_create_sdppjmedia_endpt *endpt,

                          pj_pool_t *pool,

                          unsigned stream_cnt,

                          const pjmedia_sock_info sock_info[2],

                          pjmedia_sdp_session **p_sdp )函数的第三个参数stream_cnt,第四个参数sock_info在使用pjsua_media_channel_create_sdp()调用时,重新调整了输入的参数值。

1.2               sdp信息中视频的rtp端口的生成

在pjus_media.c文件中的pjsua_media_subsys_start()函数使用pjsua_media_transports_create添加创建rtp要使用的transport端口(也就是socket端口)。这样在1中的sdp信息中就可以获取到视频通讯的本地创建的rtp端口。

2.                   视频处理模块的添加

视频处理模块主要完成视频的采集、编码、解码、回放、以及将数据送给rtp或者从rtp获取到数据的功能。其工程为pjmedia-videodev。

CCameraMgr主要实现摄像头的管理功能。如果移植mobile可以考虑修改这部分。

CCodecVideo主要实现视频编解码的功能。如果添加H.263、H.264编解码可以直接修改这部分代码。

CCodecDataChannel主要实现整个视频模块的管理功能。视频的采集、编码、解码、回放、以及将数据送给rtp或者从rtp获取到数据的功能。

Videodev主要实现pjmedia-videodev对Pjsip的外部接口功能。这些接口可以根据需要继续添加。目前应该够用。具体实现见注释。

注意这部分跟rtp交互的接口主要通过两个函数实现。Rtp模块通过pjmedia_video_query_frame_attach接口将回调设置到Pjmedia-videdev模块。Pjmedia-videodev模块,在获取到编码数据后,通过put_frame_video_data将数据送给pjmedia的rtp层,进行rtp打包传输。

3.                   视频收发以及回放

3.1               rtp发送

在stream.c中pjmedia_stream_create_video处理过程中通过调用pjmedia_video_query_frame_attach将回调函数设置给pjmedia-videodev模块。这样,在启动视频工作线程后,就可以通过put_frame_video_data源源不断的将编码后的数据送给stream.c的rtp的put_frame_video接口进行视频的rtp发送。注意这里对于视频包需要拆包处理。

3.2               Rtp接收

对于从rtp接收到的数据。都在stream.c的on_rx_rtp回调来处理。这里处理了视频和音频以及dtmf数据。我们对于解析后pt类型为34(H.263)、31(H.261)的数据直接进行视频处理on_rx_video_rtp。通过on_rx_video_rtp将接收到的视频数据写入pjmedia-videodev的Jitterbuffer(NetPool)中,这样就完成了rtp数据接收视频数据源源不断的输入到pjmedia-videodev模块。

3.3               远端视频回放

对于接收到的视频数据,已经放入netpool中。我们通过启动本地线程不断地从缓冲中获取到数据(视频数据需要重新组赈,然后解码回放),这个通过CCocecDataChnanel:: ShowRemoteVideo来实现。

3.4               本地视频回放

这个简单,也就是直接获取到摄像头的数据,在本地显示的过程。主要通过CCodecDataChannl:: ShowLocalVideo来实现。

4.                   视频工作线程

4.1               发送线程

worker_proc_video主要完成对pjmedia-videdev的pjmedia_video_get_frame_and_send接口的调用。完成视频采集编码并将数据送给rtp的过程。这里注意,对于在pjsip工程中的线程,必须使用pj_thread_create创建,例如:

//add with lianhy in 20090902 创建视频工作线程

    status = pj_thread_createendpt->pool"video", &worker_proc_video,

        endpt, 0, 0, &endpt->thread_video);

4.2               接收以及回放线程

主要通过Pjmedia-vidodev的接口pjmedia_video_query_frame_start来启动。当然对应的停止应该是pjmedia_video_query_frame_stop。

 

 

对于以上说的线程以及socket、session、mediapoint的创建,注意一定要释放(销毁)。