当前位置:文档之家› ortp移植到hi3518eh.264封包rtp发送

ortp移植到hi3518eh.264封包rtp发送

ortp移植到hi3518eh.264封包rtp发送看到ORTP是纯C实现的rtp库,于是移植到3518e试用一下.1.下载源码链接地址里面有个tar res跳转链接跳转入链接地址下载最新的ortp-0.23.0.tar.gz,并解压2.编译./configure --prefix=/work/hi3518/ortp--host=arm-hisiv100nptl-linuxmakemake install配置只需指定安装目录prefix,编译平台host即可,这里host 直接赋值arm-hisiv100nptl-linux-gcc前缀即可,注意不是arm-hisiv100nptl-linux-而是arm-hisiv100nptl-linux。

3.部署到开发板将编译生成的库/work/hi3518/ortp/lib/libortp.so.9复制到开发板/usr/lib中4.添加ortp库到mpp2中在海思SDK mpp2目录下新建rtp目录,将/work/hi3518/ortp/下全部内容复制到该目录下,修改mpp2/sample/Makefile.param,添加:INC_FLAGS += -I$(MPP_PATH)/rtp/include-L$(MPP_PATH)/rtp/lib/ -lortp5.修改代码示例程序venc中有将视频进行264编码并保存为文件(nfs挂载),这里一步步分析sample_venc.c即可找到最终的保存是通过sample_comm_venc.c中的SAMPLE_COMM_VENC_SaveH264函数完成的,这里只要修改该函数为封包发送即可。

下面是sample_comm_venc.c中需要添加的部分:#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;/** 初始化** 主要用于对ortp以及其它参数进行初始化* @param: char * ipStr 目的端IP地址描述串* @param: iint 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_WARNIN G|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];//printf("send len=%d\n",len);//如果数据小于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);return sendBytes;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))&&am p;(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;}elseiSendLen=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 increasereturn len;}在实现调用前需要进行ortp加载初始化,我们在该文件中的函数SAMPLE_COMM_VENC_GetVencStreamProc中添加初始化即可:/***rtp init****/pRtpSession = rtpInit( "129.1.4.196" ,8080);if (pRtpSession==NULL){printf( "error rtpInit" );exit(-1);return 0;}/******************************************step 2: Start to get streams of each channel.******************************************/注:这里为了简便在程序中写死了发送目标为129.1.4.196:8080,这要与下面的cfg.sdp对应. 然后修改SAMPLE_COMM_VENC_SaveH264函数调用rtp发送:/*************************************************** *************************** funciton : save H264 stream*************************************************** ***************************/HI_S32 SAMPLE_COMM_VENC_SaveH264(FILE*fpH264File, VENC_STREAM_S *pstStream){HI_S32 i;for (i = 0; i < pstStream->u32PackCount; i++){#if 0fwrite(pstStream->pstPack[i].pu8Addr[0],pstStream->pstPack[i].u32Len[0], 1,fpH264File);fflush(fpH264File);if (pstStream->pstPack[i].u32Len[1] > 0){fwrite(pstStream->pstPack[i].pu8Addr[1],pstStream->pstPack[i].u32Len[1], 1, fpH264File);fflush(fpH264File);}#elsertpSend(pRtpSession,pstStream->pstPack[i].pu8Addr[0],pstStream->pstPack[i].u32Len[0]);if (pstStream->pstPack[i].u32Len[1] > 0){rtpSend(pRtpSession,pstStream->pstPack[i].pu8Addr[1],pstStream->pstPack[i].u32Len[1]);}#endif}return HI_SUCCESS;}这样编译获得sample_venc.6.运行将sample_venc加载到开发板并运行,#./sample_venc 0please press twice ENTER to exit this sample********oRTP for H.264 Init********Av profile add H.264ortp-message-Setting random local addresses.ortp-message-rtp session [0x1c95758] set to rtp[129.1.4.196:8080] rtcp [129.1.4.196:8081]ortp-message-Using permissive algorithmortp-message-Sending RTCP SR compound message on session [0x1c95758].ortp-message-Sending RTCP SR compound message on session [0x1c95758].......7.VLC播放PC端使用VLC来播放,编写cfg.sdp如下:m=video 8080 RTP/A VP 96a=rtpmap:96 H264/90000;a=decode_buf=300;a=framerate:25c=IN IP4 129.1.4.196这里129.1.4.196即为PC的IP,Port8080为监控rtp使用端口,payloadtype为96,即h.264.VLC能够正常播放,但有延时。

相关主题