ortp大数据链传输问题

peacool 2013-12-11 02:49:27
小弟学生一枚,最近做了一个无线投影系统,主要思想描述如下:客户端通过截取PC机的屏幕得到YUV格式的图片,通过X264编码得到码流,再通过ORTP发送到服务端;服务端用FFMPEG解码264,并用SDL显示。
吗,目前遇到个问题,希望大家多多讨论,解决这个问题。
问题描述:
当客户端PC机分辨率很大时,如1680*1050,在发送每张图片上时的第一帧就出现丢失,ORTP发送端提示错误:
ortp-warning-Error sending rtp packet: Error code : 10040 ; socket=340
经过反复的测试,发现是这个数据包的数据过大,编码的nal_t[i].i_payload会达到20几万,请问这个这么大的数据这个能传输过去,或者有没有设置X264的编码参数,从而减少这个数据的大小。
发送端的代码如下:
int sendH264Stream(void *nal,int nalCount)
{
int i = 0;
x264_nal_t *nal_t = (x264_nal_t *)nal;
if (nal_t == NULL)
{
return 0;
}
for (i = 0;i < nalCount;i ++)
{
if (nal_t[i].i_type==NAL_SPS || nal_t[i].i_type==NAL_PPS || nal_t[i].i_type==NAL_SEI ||
nal_t[i].i_type==NAL_SLICE || nal_t[i].i_type==NAL_SLICE_IDR)//NAL_SEI)//获取SPS数据,PPS数据,SEI数据;
{
//rtpSend(nal_t[i].p_payload,nal_t[i].i_payload);
rtpSend1(nal_t[i].p_payload,nal_t[i].i_payload);
#if 0
if (f264 != NULL)
{
fwrite(nal_t[i].p_payload,1,nal_t[i].i_payload,f264);
}
#endif
}
}
return 1;
}
接收端代码:
unsigned int __stdcall recvThreadBody(void *param)
{
int err;
int havemore;
for (;;)
{
err = rtp_session_recv_with_ts(rtp_session_mgr.rtp_session,
(uint8_t *)recv_buf, recv_bufsize,
rtp_session_mgr.timestamp, &havemore);

if (err > 0)
{
printf("receive data is %d\n", err);
#if 1
if (f264 != NULL)
{
fwrite(recv_buf,1,err,f264);
}
#endif
}

rtp_session_mgr.timestamp += timestamp_inc;
Sleep(10);
}

end:
printf("==>Over!\n");
return 1;
}
X264编码参数:
int h264_init(int m_nWidth, int m_nHeight)
{
int m_width=m_nWidth;
int m_height=m_nHeight;
#if 1
x264_param_default_preset(&g_param,"veryfast", "zerolatency"); //实时编码不缓存;
g_param.i_threads = X264_SYNC_LOOKAHEAD_AUTO;
g_param.i_width=m_width;
g_param.i_height=m_height;
g_param.i_frame_total = 0;
g_param.i_keyint_max = 10;

//* 流参数;
g_param.i_bframe = 5;
g_param.b_open_gop = 0;
g_param.i_bframe_pyramid = 0;
g_param.i_bframe_adaptive = X264_B_ADAPT_TRELLIS;
//* Log参数,不需要打印编码信息时直接注释掉就行;
g_param.i_log_level = X264_LOG_DEBUG;
//* 速率控制参数;
g_param.rc.i_bitrate = 1024 * 10;//* 码率(比特率,单位Kbps);
//* muxing parameters ;
g_param.i_fps_den = 1; //* 帧率分母;
g_param.i_fps_num = 10;//* 帧率分子;
g_param.i_timebase_den = g_param.i_fps_num;
g_param.i_timebase_num = g_param.i_fps_den;
//* 设置Profile.使用Baseline profile;
x264_param_apply_profile(&g_param, x264_profile_names[0]);
#endif

g_x264Handle=x264_encoder_open(&g_param);
if (g_x264Handle == NULL)
{
return 0;
}
x264_picture_init(&g_picout);
x264_picture_alloc(&g_picin,X264_CSP_I420,m_width,m_height);

printf("------------------------------\n");
printf("%s\n","[h264_init] H264 Init Over!");
return 1;
}
...全文
245 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
LinuxInEmbedded 2013-12-30
  • 打赏
  • 举报
回复
数据包过大,没有分包吗?
peacool 2013-12-11
  • 打赏
  • 举报
回复
程序中设置了接收空间的大小的,并且能够保证值大于发送空间的值,如下: 发送端: int rtpSend(unsigned char *send_buffer, int frame_len) { int sended_bytes; sended_bytes = rtp_session_send_with_ts(rtp_session_mgr.rtp_session, (uint8_t *)send_buffer, frame_len, rtp_session_mgr.cur_timestamp); //printf("------Send msg len : %d %d\n",frame_len,sended_bytes); rtp_session_mgr.cur_timestamp += rtp_session_mgr.timestamp_inc; return sended_bytes; } 接收端的设置: void rtpInit(RtpSessionMgr *rtp_session_mgr) { WSADATA wsaData; if ( WSAStartup(MAKEWORD(2,2), &wsaData) != 0) { fprintf(stderr, "WAStartup failed!\n"); return ; } ortp_init(); ortp_scheduler_init(); rtp_session_mgr->rtp_session = rtp_session_new(RTP_SESSION_RECVONLY); rtp_session_set_scheduling_mode(rtp_session_mgr->rtp_session, 1); rtp_session_set_blocking_mode(rtp_session_mgr->rtp_session, 1); //rtp_session_set_blocking_mode(rtp_session_mgr->rtp_session, 0); rtp_session_set_local_addr(rtp_session_mgr->rtp_session, recv_ip, recv_port); rtp_session_enable_adaptive_jitter_compensation(rtp_session_mgr->rtp_session, TRUE); rtp_session_set_jitter_compensation(rtp_session_mgr->rtp_session, 40); rtp_session_set_payload_type(rtp_session_mgr->rtp_session, 34); rtp_session_set_recv_buf_size(rtp_session_mgr->rtp_session, recv_bufsize); rtp_session_mgr->timestamp = timestamp_inc; } 似乎好像是当数据大于65535时,还是要自己分片?
max_min_ 2013-12-11
  • 打赏
  • 举报
回复
在ortp中win_receive中还需要显示调用:
rtp_session_set_recv_buf_size(rtp_session_mgr .rtp_session , recv_bufsize);
这里的recv_bufsize必须要比win_sender中
sended_bytes = rtp_session_send_with_ts (rtp_session_mgr .rtp_session ,
                          ( uint8_t *) send_buffer,
                           wrapLen,
                          rtp_session_mgr.cur_timestamp );
的wrapLen要大
peacool 2013-12-11
  • 打赏
  • 举报
回复
能够用TCP自己下个发送方案,自己实现大数据分片和组片,由于传输的距离用无线,并且距离不远,不知是否可行?

70,037

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧