1、在官方SDK的sample中添加rtp传输代码
(1)venc/sample_venc.c中,添加:s32ChnNum = 1;
(2)common/sample_common_venc.c中,改了很多

第一步:添加下面ortp代码

#define ORTP_ENABLE  1

#if ORTP_ENABLE
#include <ortp/ortp.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/time.h>
#include <stdio.h>
#define Y_PLOAD_TYPE 96 //H.264
#define MAX_RTP_PKT_LENGTH 1400
#define DefaultTimestampIncrement 3600 //(90000/25)
uint32_t g_userts=0;
RtpSession *pRtpSession = NULL;

#define LOCAL_HOST_IP "192.168.1.20"

/** 初始化
*
* 主要用于对ortp以及其它参数进行初始化
* @param: char * ipStr 目的端IP地址描述串
* @param: int port 目的端RTP监听端口
* @return: RtpSession * 返回指向RtpSession对象的指针,如果为NULL,则初始化失败
* @note:
*/
RtpSession * rtpInit( char * ipStr, int port)
{
RtpSession *session;
char *ssrc;
printf("********oRTP for H.264 Init********\n");

ortp_init();
ortp_scheduler_init();
ortp_set_log_level_mask(ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR);
session=rtp_session_new(RTP_SESSION_SENDONLY);

rtp_session_set_scheduling_mode(session,1);
rtp_session_set_blocking_mode(session,0);
//rtp_session_set_connected_mode(session,TRUE);
rtp_session_set_remote_addr(session,ipStr,port);
rtp_session_set_payload_type(session,Y_PLOAD_TYPE);

ssrc=getenv("SSRC");
if (ssrc!=NULL) {
printf("using SSRC=%i.\n",atoi(ssrc));
// 设置输出流的SSRC。不做此步的话将会给个随机值
rtp_session_set_ssrc(session,atoi(ssrc));
}
return session;
}
/** 结束ortp的发送,释放资源
*
* @param: RtpSession *session RTP会话对象的指针
* @return: 0表示成功
* @note:
*/
int rtpExit(RtpSession *session)
{
printf("********oRTP for H.264 Exit********\n");
g_userts = 0;

rtp_session_destroy(session);
ortp_exit();
ortp_global_stats_display();

return 0;
}
/** 发送rtp数据包
*
* 主要用于发送rtp数据包
* @param: RtpSession *session RTP会话对象的指针
* @param: const char *buffer 要发送的数据的缓冲区地址
* @param: int len 要发送的数据长度
* @return: int 实际发送的数据包数目
* @note: 如果要发送的数据包长度大于BYTES_PER_COUNT,本函数内部会进行分包处理
*/
int rtpSend(RtpSession *session, char *buffer, int len)
{
int sendBytes = 0;
int status;
uint32_t valid_len=len-4;
unsigned char NALU=buffer[4];

//如果数据小于MAX_RTP_PKT_LENGTH字节,直接发送:单一NAL单元模式
if(valid_len <= MAX_RTP_PKT_LENGTH)
{
sendBytes = rtp_session_send_with_ts(session,
&buffer[4],
valid_len,
g_userts);
}
else if (valid_len > MAX_RTP_PKT_LENGTH)
{
//切分为很多个包发送,每个包前要对头进行处理,如第一个包
valid_len -= 1;
int k=0,l=0;
k=valid_len/MAX_RTP_PKT_LENGTH;
l=valid_len%MAX_RTP_PKT_LENGTH;
int t=0;
int pos=5;
if(l!=0)
{
k=k+1;
}
while(t<k)//||(t==k&&l>0))
{
if(t<(k-1))//(t<k&&l!=0)||(t<(k-1))&&(l==0))//(0==t)||(t<k&&0!=l))
{
buffer[pos-2]=(NALU & 0x60)|28;
buffer[pos-1]=(NALU & 0x1f);
if(0==t)
{
buffer[pos-1]|=0x80;
}
sendBytes = rtp_session_send_with_ts(session,
&buffer[pos-2],
MAX_RTP_PKT_LENGTH+2,
g_userts);
t++;
pos+=MAX_RTP_PKT_LENGTH;
}
else //if((k==t&&l>0)||((t==k-1)&&l==0))
{
int iSendLen;
if(l>0)
{
iSendLen=valid_len-t*MAX_RTP_PKT_LENGTH;
}
else
iSendLen=MAX_RTP_PKT_LENGTH;
buffer[pos-2]=(NALU & 0x60)|28;
buffer[pos-1]=(NALU & 0x1f);
buffer[pos-1]|=0x40;
sendBytes = rtp_session_send_with_ts(session,
&buffer[pos-2],
iSendLen+2,
g_userts);
t++;
}
}
}

g_userts += DefaultTimestampIncrement;//timestamp increase
return len;
}
#endif

第二步:在SAMPLE_COMM_VENC_SaveH264 函数中添加下面的代码

#if ORTP_ENABLE
rtpSend(pRtpSession,pstStream->pstPack[i].pu8Addr, pstStream->pstPack[i].u32Len);
#else


#endif

变为:

8 海思Hi3518E部署ORTP_#define

第三步:在SAMPLE_COMM_VENC_GetVencStreamProc 函数添加下面的代码

#if ORTP_ENABLE
/***rtp init****/
pRtpSession = rtpInit( LOCAL_HOST_IP ,8080);
if (pRtpSession==NULL)
{
printf( "error rtpInit" );
exit(-1);
return 0;
}
#endif

位置:

8 海思Hi3518E部署ORTP_#define_02

2、重新编译sample

(1)复制ortp头文件

8 海思Hi3518E部署ORTP_#define_03

因为我应用ortp库文件是用的:#include <ortp/ortp.h>

(2)修改venc中Makefile,添加libortp的链接支持

添加:-lortp 和 -L/tmp/ortp/lib

8 海思Hi3518E部署ORTP_#define_04
(3)make

3、开发板中部署并运行测试
(1)部署libortp.so到开发板中/usr/lib目录下

8 海思Hi3518E部署ORTP_#define_05

添加动态连接库的路径:

vi /etc/profile 

LD_LIBRARY_PATH="/usr/local/lib:/usr/lib:/mnt/lib"

(2)检查开发板中原有配置是否正确,譬如sensor是否对应实际
(3)在nfs中运行新的sample程序
(4)vlc中打开配置好的sdp文件,看到实时图像就证明整个实验完成了

也可以自己创建VLC文件:

先创建.sdp 的文件

在写入下面的内容

m=video 8080 RTP/AVP 96
a=rtpmap:96 H264
a=framerate:25
c=IN IP4 192.168.1.20