void RP_ReadStream(RTPStream *ch) { u32 size, tot_size; if (!ch->rtp_ch) return; /*NOTE: A weird bug on windows wrt to select(): if both RTP and RTCP are in the same loop there is a hudge packet drop on RTP. We therefore split RTP and RTCP reading, this is not a big deal as the RTCP traffic is far less than RTP, and we should never have more than one RTCP packet reading per RTP reading loop NOTE2: a better implementation would be to use select() to get woken up... */ tot_size = 0; while (1) { size = gf_rtp_read_rtcp(ch->rtp_ch, ch->buffer, RTP_BUFFER_SIZE); if (!size) break; tot_size += size; RP_ProcessRTCP(ch, ch->buffer, size); } while (1) { size = gf_rtp_read_rtp(ch->rtp_ch, ch->buffer, RTP_BUFFER_SIZE); if (!size) break; tot_size += size; RP_ProcessRTP(ch, ch->buffer, size); } /*and send the report*/ if (ch->flags & RTP_ENABLE_RTCP) gf_rtp_send_rtcp_report(ch->rtp_ch, SendTCPData, ch); if (tot_size) ch->owner->udp_time_out = 0; /*detect timeout*/ if (ch->owner->udp_time_out) { if (!ch->last_udp_time) { ch->last_udp_time = gf_sys_clock(); } else if (ch->rtp_ch->net_info.IsUnicast && !(ch->flags & RTP_MOBILEIP) ) { u32 diff = gf_sys_clock() - ch->last_udp_time; if (diff >= ch->owner->udp_time_out) { char szMessage[1024]; GF_LOG(GF_LOG_WARNING, GF_LOG_RTP, ("[RTP] UDP Timeout after %d ms\n", diff)); sprintf(szMessage, "No data received in %d ms", diff); RP_SendMessage(ch->owner->service, GF_IP_UDP_TIMEOUT, szMessage); ch->status = RTP_Unavailable; } } } }
void SDP_NetIO(void *cbk, GF_NETIO_Parameter *param) { GF_Err e; RTPClient *rtp = (RTPClient *)cbk; SDPFetch *sdp = rtp->sdp_temp; gf_service_download_update_stats(rtp->dnload); e = param->error; switch (param->msg_type) { case GF_NETIO_GET_METHOD: if (sdp->original_url) param->name = "POST"; return; case GF_NETIO_GET_CONTENT: if (sdp->original_url) { char szBody[4096], *opt; opt = (char *) gf_modules_get_option((GF_BaseInterface *) gf_service_get_interface(rtp->service), "Network", "MobileIP"); sprintf(szBody, "ipadd\n%s\n\nurl\n%s\n\n", opt, sdp->original_url); param->data = szBody; param->size = (u32) strlen(szBody); } return; case GF_NETIO_DATA_TRANSFERED: if (sdp->original_url) { u32 sdp_size; e = gf_dm_sess_get_stats(rtp->dnload, NULL, NULL, &sdp_size, NULL, NULL, NULL); if (sdp_size) { const char *szFile = gf_dm_sess_get_cache_name(rtp->dnload); if (!szFile) { e = GF_SERVICE_ERROR; } else { e = GF_OK; RP_SDPFromFile(rtp, (char *) szFile, sdp->chan); gf_free(sdp->remote_url); if (sdp->original_url) gf_free(sdp->original_url); gf_free(sdp); rtp->sdp_temp = NULL; return; } } } break; default: if (e == GF_OK) return; } if (sdp->original_url) { char *url = sdp->original_url; gf_free(sdp->remote_url); gf_free(sdp); rtp->sdp_temp = NULL; RP_SendMessage(rtp->service, e, "Error fetching session state - restarting"); RP_ConnectServiceEx(gf_service_get_interface(rtp->service), rtp->service, url, GF_TRUE); gf_free(url); return; } /*error*/ if (sdp->chan) { gf_service_connect_ack(rtp->service, sdp->chan->channel, e); } else { gf_service_connect_ack(rtp->service, NULL, e); rtp->sdp_temp = NULL; } gf_free(sdp->remote_url); if (sdp->original_url) gf_free(sdp->original_url); gf_free(sdp); rtp->sdp_temp = NULL; }
void RP_SendFailure(RTSPSession *sess, GF_RTSPCommand *com, GF_Err e) { char sMsg[1000]; sprintf(sMsg, "Cannot send %s", com->method); RP_SendMessage(sess->owner->service, e, sMsg); }