GF_EXPORT GF_RTPStreamer *gf_rtp_streamer_new(u32 streamType, u32 oti, u32 timeScale, const char *ip_dest, u16 port, u32 MTU, u8 TTL, const char *ifce_addr, u32 flags, char *dsi, u32 dsi_len) { return gf_rtp_streamer_new_extended(streamType, oti, timeScale, ip_dest, port, MTU, TTL, ifce_addr, flags, dsi, dsi_len, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); }
static void live_session_setup(LiveSession *livesess, char *ip, u16 port, u32 path_mtu, u32 ttl, char *ifce_addr, char *sdp_name) { RTPChannel *rtpch; u32 count = gf_seng_get_stream_count(livesess->seng); u32 i; char *iod64 = gf_seng_get_base64_iod(livesess->seng); char *sdp = gf_rtp_streamer_format_sdp_header("GPACSceneStreamer", ip, NULL, iod64); if (iod64) gf_free(iod64); for (i=0; i<count; i++) { u16 ESID; u32 st, oti, ts; char *config = NULL; u32 config_len; gf_seng_get_stream_config(livesess->seng, i, &ESID, &config, &config_len, &st, &oti, &ts); GF_SAFEALLOC(rtpch, RTPChannel); rtpch->timescale = ts; rtpch->init_time = gf_sys_clock(); switch (st) { case GF_STREAM_OD: case GF_STREAM_SCENE: rtpch->rtp = gf_rtp_streamer_new_extended(st, oti, ts, ip, port, path_mtu, ttl, ifce_addr, GP_RTP_PCK_SYSTEMS_CAROUSEL, (char *) config, config_len, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4); if (rtpch->rtp) { gf_rtp_streamer_disable_auto_rtcp(rtpch->rtp); rtpch->manual_rtcp = 1; } break; default: rtpch->rtp = gf_rtp_streamer_new(st, oti, ts, ip, port, path_mtu, ttl, ifce_addr, GP_RTP_PCK_SIGNAL_RAP, (char *) config, config_len); break; } rtpch->ESID = ESID; rtpch->adjust_carousel_time = 1; gf_list_add(livesess->streams, rtpch); gf_rtp_streamer_append_sdp(rtpch->rtp, ESID, (char *) config, config_len, NULL, &sdp); /*fetch initial config of the broadcast*/ gf_seng_get_stream_carousel_info(livesess->seng, ESID, &rtpch->carousel_period, &rtpch->aggregate_on_stream); port += 2; } if (sdp) { FILE *out = gf_f64_open(sdp_name, "wt"); fprintf(out, "%s", sdp); fclose(out); gf_free(sdp); } }
GF_EXPORT GF_ISOMRTPStreamer *gf_isom_streamer_new(const char *file_name, const char *ip_dest, u16 port, Bool loop, Bool force_mpeg4, u32 path_mtu, u32 ttl, char *ifce_addr) { GF_ISOMRTPStreamer *streamer; GF_Err e = GF_OK; const char *opt = NULL; /*GF_Config *configFile = NULL; */ u32 i, max_ptime, au_sn_len; u8 payt; GF_ISOFile *file; GF_RTPTrack *track, *prev_track; u16 first_port; u32 nb_tracks; u32 sess_data_size; if (!ip_dest) ip_dest = "127.0.0.1"; if (!port) port = 7000; if (!path_mtu) path_mtu = 1450; GF_SAFEALLOC(streamer, GF_ISOMRTPStreamer); streamer->dest_ip = gf_strdup(ip_dest); payt = 96; max_ptime = au_sn_len = 0; file = gf_isom_open(file_name, GF_ISOM_OPEN_READ, NULL); if (!file) { GF_LOG(GF_LOG_ERROR, GF_LOG_RTP, ("Error opening file %s: %s\n", opt, gf_error_to_string(gf_isom_last_error(NULL)))); return NULL; } streamer->isom = file; streamer->loop = loop; streamer->force_mpeg4_generic = force_mpeg4; first_port = port; sess_data_size = 0; prev_track = NULL; nb_tracks = gf_isom_get_track_count(streamer->isom); for (i=0; i<nb_tracks; i++) { u32 mediaSize, mediaDuration, flags, MinSize, MaxSize, avgTS, streamType, oti, const_dur, nb_ch, samplerate, maxDTSDelta, TrackMediaSubType, TrackMediaType, bandwidth, IV_length, KI_length, dsi_len; const char *url, *urn; char *dsi; Bool is_crypted; dsi_len = samplerate = streamType = oti = nb_ch = IV_length = KI_length = 0; is_crypted = 0; dsi = NULL; flags = 0; /*we only support self-contained files for hinting*/ gf_isom_get_data_reference(streamer->isom, i+1, 1, &url, &urn); if (url || urn) continue; TrackMediaType = gf_isom_get_media_type(streamer->isom, i+1); TrackMediaSubType = gf_isom_get_media_subtype(streamer->isom, i+1, 1); switch (TrackMediaType) { case GF_ISOM_MEDIA_TEXT: break; case GF_ISOM_MEDIA_VISUAL: case GF_ISOM_MEDIA_AUDIO: case GF_ISOM_MEDIA_SUBT: case GF_ISOM_MEDIA_OD: case GF_ISOM_MEDIA_SCENE: if (gf_isom_get_sample_description_count(streamer->isom, i+1) > 1) continue; break; default: continue; } GF_SAFEALLOC(track, GF_RTPTrack); if (prev_track) prev_track->next = track; else streamer->stream = track; prev_track = track; track->track_num = i+1; track->nb_aus = gf_isom_get_sample_count(streamer->isom, track->track_num); track->timescale = gf_isom_get_media_timescale(streamer->isom, track->track_num); mediaDuration = (u32)(gf_isom_get_media_duration(streamer->isom, track->track_num)*1000/track->timescale); // ms mediaSize = (u32)gf_isom_get_media_data_size(streamer->isom, track->track_num); sess_data_size += mediaSize; if (mediaDuration > streamer->duration_ms) streamer->duration_ms = mediaDuration; track->port = check_next_port(streamer, first_port); first_port = track->port+2; /*init packetizer*/ if (streamer->force_mpeg4_generic) flags = GP_RTP_PCK_SIGNAL_RAP | GP_RTP_PCK_FORCE_MPEG4; switch (TrackMediaSubType) { case GF_ISOM_SUBTYPE_MPEG4_CRYP: is_crypted = 1; case GF_ISOM_SUBTYPE_MPEG4: { GF_ESD *esd = gf_isom_get_esd(streamer->isom, track->track_num, 1); if (esd) { streamType = esd->decoderConfig->streamType; oti = esd->decoderConfig->objectTypeIndication; /*systems streams*/ if (streamType==GF_STREAM_AUDIO) { gf_isom_get_audio_info(streamer->isom, track->track_num, 1, &samplerate, &nb_ch, NULL); } /*systems streams*/ else if (streamType==GF_STREAM_SCENE) { if (gf_isom_has_sync_shadows(streamer->isom, track->track_num) || gf_isom_has_sample_dependency(streamer->isom, track->track_num)) flags |= GP_RTP_PCK_SYSTEMS_CAROUSEL; } if (esd->decoderConfig->decoderSpecificInfo) { dsi = esd->decoderConfig->decoderSpecificInfo->data; dsi_len = esd->decoderConfig->decoderSpecificInfo->dataLength; esd->decoderConfig->decoderSpecificInfo->data = NULL; esd->decoderConfig->decoderSpecificInfo->dataLength = 0; } gf_odf_desc_del((GF_Descriptor*)esd); } } break; case GF_ISOM_SUBTYPE_AVC_H264: case GF_ISOM_SUBTYPE_AVC2_H264: case GF_ISOM_SUBTYPE_SVC_H264: { GF_AVCConfig *avcc = gf_isom_avc_config_get(streamer->isom, track->track_num, 1); track->avc_nalu_size = avcc->nal_unit_size; gf_odf_avc_cfg_del(avcc); streamType = GF_STREAM_VISUAL; oti = GPAC_OTI_VIDEO_AVC; } break; default: streamType = GF_STREAM_4CC; oti = TrackMediaSubType; break; } /*get sample info*/ gf_media_get_sample_average_infos(streamer->isom, track->track_num, &MinSize, &MaxSize, &avgTS, &maxDTSDelta, &const_dur, &bandwidth); if (is_crypted) { Bool use_sel_enc; gf_isom_get_ismacryp_info(streamer->isom, track->track_num, 1, NULL, NULL, NULL, NULL, NULL, &use_sel_enc, &IV_length, &KI_length); if (use_sel_enc) flags |= GP_RTP_PCK_SELECTIVE_ENCRYPTION; } track->rtp = gf_rtp_streamer_new_extended(streamType, oti, track->timescale, (char *) streamer->dest_ip, track->port, path_mtu, ttl, ifce_addr, flags, dsi, dsi_len, payt, samplerate, nb_ch, is_crypted, IV_length, KI_length, MinSize, MaxSize, avgTS, maxDTSDelta, const_dur, bandwidth, max_ptime, au_sn_len); if (!track->rtp) { GF_LOG(GF_LOG_ERROR, GF_LOG_RTP, ("Could not initialize RTP streamer: %s\n", gf_error_to_string(e))); goto exit; } payt++; track->microsec_ts_scale = 1000000; track->microsec_ts_scale /= gf_isom_get_media_timescale(streamer->isom, track->track_num); } return streamer; exit: gf_free(streamer); return NULL; }