static GF_ObjectDescriptor *RP_GetChannelOD(RTPStream *ch, u32 ch_idx) { GF_ESD *esd; GF_ObjectDescriptor *od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG); if (!ch->ES_ID) ch->ES_ID = ch_idx + 1; od->objectDescriptorID = ch->OD_ID ? ch->OD_ID : ch->ES_ID; esd = gf_odf_desc_esd_new(0); esd->slConfig->timestampResolution = gf_rtp_get_clockrate(ch->rtp_ch); esd->slConfig->useRandomAccessPointFlag = 1; esd->slConfig->useTimestampsFlag = 1; esd->ESID = ch->ES_ID; esd->OCRESID = 0; esd->decoderConfig->streamType = ch->depacketizer->sl_map.StreamType; esd->decoderConfig->objectTypeIndication = ch->depacketizer->sl_map.ObjectTypeIndication; if (ch->depacketizer->sl_map.config) { esd->decoderConfig->decoderSpecificInfo->data = (char*)gf_malloc(sizeof(char) * ch->depacketizer->sl_map.configSize); memcpy(esd->decoderConfig->decoderSpecificInfo->data, ch->depacketizer->sl_map.config, sizeof(char) * ch->depacketizer->sl_map.configSize); esd->decoderConfig->decoderSpecificInfo->dataLength = ch->depacketizer->sl_map.configSize; } if (ch->depacketizer->sl_map.rvc_predef) { esd->decoderConfig->predefined_rvc_config = ch->depacketizer->sl_map.rvc_predef; } else if (ch->depacketizer->sl_map.rvc_config) { esd->decoderConfig->rvc_config = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG); esd->decoderConfig->rvc_config->data = ch->depacketizer->sl_map.rvc_config; esd->decoderConfig->rvc_config->dataLength = ch->depacketizer->sl_map.rvc_config_size; ch->depacketizer->sl_map.rvc_config = NULL; ch->depacketizer->sl_map.rvc_config_size = 0; } gf_list_add(od->ESDescriptors, esd); return od; }
static GF_ESD *RP_GetChannelESD(RTPStream *ch, u32 ch_idx) { GF_ESD *esd; if (!ch->ES_ID) ch->ES_ID = ch_idx + 1; esd = gf_odf_desc_esd_new(0); esd->slConfig->timestampResolution = gf_rtp_get_clockrate(ch->rtp_ch); esd->slConfig->useRandomAccessPointFlag = 1; esd->slConfig->useTimestampsFlag = 1; esd->slConfig->no_dts_signaling = ch->depacketizer->sl_map.DTSDeltaLength ? 0 : 1; esd->ESID = ch->ES_ID; esd->OCRESID = 0; if (ch->mid) esd->has_ref_base = 1; esd->decoderConfig->streamType = ch->depacketizer->sl_map.StreamType; esd->decoderConfig->objectTypeIndication = ch->depacketizer->sl_map.ObjectTypeIndication; if (ch->depacketizer->sl_map.config) { esd->decoderConfig->decoderSpecificInfo->data = (char*)gf_malloc(sizeof(char) * ch->depacketizer->sl_map.configSize); memcpy(esd->decoderConfig->decoderSpecificInfo->data, ch->depacketizer->sl_map.config, sizeof(char) * ch->depacketizer->sl_map.configSize); esd->decoderConfig->decoderSpecificInfo->dataLength = ch->depacketizer->sl_map.configSize; } if (ch->depacketizer->sl_map.rvc_predef) { esd->decoderConfig->predefined_rvc_config = ch->depacketizer->sl_map.rvc_predef; } else if (ch->depacketizer->sl_map.rvc_config) { esd->decoderConfig->rvc_config = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG); esd->decoderConfig->rvc_config->data = ch->depacketizer->sl_map.rvc_config; esd->decoderConfig->rvc_config->dataLength = ch->depacketizer->sl_map.rvc_config_size; ch->depacketizer->sl_map.rvc_config = NULL; ch->depacketizer->sl_map.rvc_config_size = 0; } return esd; }
void RP_ProcessRTP(RTPStream *ch, char *pck, u32 size) { GF_NetworkCommand com; GF_Err e; GF_RTPHeader hdr; u32 PayloadStart; ch->rtp_bytes += size; /*first decode RTP*/ e = gf_rtp_decode_rtp(ch->rtp_ch, pck, size, &hdr, &PayloadStart); /*corrupted or NULL data*/ if (e || (PayloadStart >= size)) { //gf_term_on_sl_packet(ch->owner->service, ch->channel, NULL, 0, NULL, GF_CORRUPTED_DATA); return; } /*if we must notify some timing, do it now. If the channel has no range, this should NEVER be called*/ if (ch->check_rtp_time /*&& gf_rtp_is_active(ch->rtp_ch)*/) { Double ch_time; /*it may happen that we still receive packets from a previous "play" request. If this is the case, filter until we reach the indicated rtptime*/ if (ch->rtp_ch->rtp_time && (ch->rtp_ch->rtp_first_SN > hdr.SequenceNumber) && (ch->rtp_ch->rtp_time < hdr.TimeStamp) ) { GF_LOG(GF_LOG_WARNING, GF_LOG_RTP, ("[RTP] Rejecting too early packet (TS %d vs signaled rtp time %d - diff %d ms)\n", hdr.TimeStamp, ch->rtp_ch->rtp_time, ((hdr.TimeStamp - ch->rtp_ch->rtp_time)*1000) / ch->rtp_ch->TimeScale)); return; } ch_time = gf_rtp_get_current_time(ch->rtp_ch); /*this is the first packet on the channel (no PAUSE)*/ if (ch->check_rtp_time == RTP_SET_TIME_RTP) { /*Note: in a SEEK with RTSP, the rtp-info time given by the server is the rtp time of the desired range. But the server may (and should) send from the previous I frame on video, so the time of the first rtp packet after a SEEK can actually be less than CurrentStart. We don't drop these packets in order to see the maximum video. We could drop it, this would mean wait for next RAP...*/ memset(&com, 0, sizeof(com)); com.command_type = GF_NET_CHAN_MAP_TIME; com.base.on_channel = ch->channel; if (ch->rtsp) { com.map_time.media_time = ch->current_start + ch_time; } else { com.map_time.media_time = 0; } com.map_time.timestamp = hdr.TimeStamp; com.map_time.reset_buffers = 0; gf_term_on_command(ch->owner->service, &com, GF_OK); GF_LOG(GF_LOG_INFO, GF_LOG_RTP, ("[RTP] Mapping RTP Time seq %d TS %d Media Time %g - rtp info seq %d TS %d\n", hdr.SequenceNumber, hdr.TimeStamp, com.map_time.media_time, ch->rtp_ch->rtp_first_SN, ch->rtp_ch->rtp_time )); /*skip RTCP clock init when RTSP is used*/ if (ch->rtsp) ch->rtcp_init = 1; // if (ch->depacketizer->payt==GF_RTP_PAYT_H264_AVC) ch->depacketizer->flags |= GF_RTP_AVC_WAIT_RAP; } /*this is RESUME on channel, filter packet based on time (darwin seems to send couple of packet before) do not fetch if we're below 10 ms or <0, because this means we already have this packet - as the PAUSE is issued with the RTP currentTime*/ else if (ch_time <= 0.021) { return; } ch->check_rtp_time = RTP_SET_TIME_NONE; } gf_rtp_depacketizer_process(ch->depacketizer, &hdr, pck + PayloadStart, size - PayloadStart); /*last check: signal EOS if we're close to end range in case the server do not send RTCP BYE*/ if ((ch->flags & RTP_HAS_RANGE) && !(ch->flags & RTP_EOS) ) { /*also check last CTS*/ Double ts = (Double) ((u32) ch->depacketizer->sl_hdr.compositionTimeStamp - hdr.TimeStamp); ts /= gf_rtp_get_clockrate(ch->rtp_ch); if (ABSDIFF(ch->range_end, (ts + ch->current_start + gf_rtp_get_current_time(ch->rtp_ch)) ) < 0.2) { ch->flags |= RTP_EOS; ch->stat_stop_time = gf_sys_clock(); gf_term_on_sl_packet(ch->owner->service, ch->channel, NULL, 0, NULL, GF_EOS); } } }