void RP_SDPFromFile(RTPClient *rtp, char *file_name, RTPStream *stream) { FILE *_sdp; char *sdp_buf; u32 sdp_size; sdp_buf = NULL; if (file_name && strstr(file_name, "file://")) file_name += strlen("file://"); if (!file_name || !(_sdp = gf_fopen(file_name, "rt")) ) { gf_service_connect_ack(rtp->service, NULL, GF_URL_ERROR); return; } gf_fseek(_sdp, 0, SEEK_END); sdp_size = (u32) gf_ftell(_sdp); gf_fseek(_sdp, 0, SEEK_SET); sdp_buf = (char*)gf_malloc(sdp_size); if (1 > fread(sdp_buf, 1, sdp_size, _sdp)) { gf_service_connect_ack(rtp->service, NULL, GF_URL_ERROR); } else { RP_LoadSDP(rtp, sdp_buf, sdp_size, stream); } gf_fclose(_sdp); gf_free(sdp_buf); }
GF_Err LIBPLAYER_ConnectChannel(GF_InputService *plug, LPNETCHANNEL channel, const char *url, Bool upstream) { u32 ESID; LibPlayerIn *read = (LibPlayerIn *) plug->priv; sscanf(url, "ES_ID=%ud", &ESID); GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[LibPlayerIN] instance %d connect channel %d\n", read->player_id, ESID)); if (ESID != 1+read->player_id) { gf_service_connect_ack(read->service, channel, GF_STREAM_NOT_FOUND); } else { gf_service_connect_ack(read->service, channel, GF_OK); } return GF_OK; }
static GF_Err AC3_ConnectService(GF_InputService *plug, GF_ClientService *serv, const char *url) { char szURL[2048]; char *ext; GF_Err reply; AC3Reader *read = plug->priv; read->service = serv; if (read->dnload) gf_service_download_del(read->dnload); read->dnload = NULL; strcpy(szURL, url); ext = strrchr(szURL, '#'); if (ext) ext[0] = 0; /*remote fetch*/ read->is_remote = !ac3_is_local(szURL); if (read->is_remote) { ac3_download_file(plug, (char *) szURL); return GF_OK; } reply = GF_OK; read->stream = gf_f64_open(szURL, "rb"); if (!read->stream) { reply = GF_URL_ERROR; } else if (!AC3_ConfigureFromFile(read)) { fclose(read->stream); read->stream = NULL; reply = GF_NOT_SUPPORTED; } gf_service_connect_ack(serv, NULL, reply); if (!reply && read->is_inline ) AC3_SetupObject(read); return GF_OK; }
static GF_Err IMG_ConnectService(GF_InputService *plug, GF_ClientService *serv, const char *url) { char *sExt; IMGLoader *read = (IMGLoader *)plug->priv; read->service = serv; if (!url) return GF_BAD_PARAM; sExt = strrchr(url, '.'); if (!stricmp(sExt, ".jpeg") || !stricmp(sExt, ".jpg")) read->img_type = IMG_JPEG; else if (!stricmp(sExt, ".png")) read->img_type = IMG_PNG; else if (!stricmp(sExt, ".pngd")) read->img_type = IMG_PNGD; else if (!stricmp(sExt, ".pngds")) read->img_type = IMG_PNGDS; else if (!stricmp(sExt, ".pngs")) read->img_type = IMG_PNGS; else if (!stricmp(sExt, ".bmp")) read->img_type = IMG_BMP; if (read->dnload) gf_service_download_del(read->dnload); read->dnload = NULL; /*remote fetch*/ if (!jp_is_local(url)) { jp_download_file(plug, url); return GF_OK; } read->stream = fopen(url, "rb"); if (read->stream) { gf_f64_seek(read->stream, 0, SEEK_END); read->data_size = (u32) gf_f64_tell(read->stream); gf_f64_seek(read->stream, 0, SEEK_SET); } gf_service_connect_ack(serv, NULL, read->stream ? GF_OK : GF_URL_ERROR); if (read->stream && read->is_inline) IMG_SetupObject(read); return GF_OK; }
void RP_ConfirmChannelConnect(RTPStream *ch, GF_Err e) { GF_NetworkCommand com; /*in case the channel has been disconnected while SETUP was issued&processed. We also could clean up the command stack*/ if (!ch->channel) return; gf_service_connect_ack(ch->owner->service, ch->channel, e); if (e != GF_OK || !ch->rtp_ch) return; /*success, overwrite SL config*/ memset(&com, 0, sizeof(GF_NetworkCommand)); com.command_type = GF_NET_CHAN_RECONFIG; com.base.on_channel = ch->channel; gf_rtp_depacketizer_get_slconfig(ch->depacketizer, &com.cfg.sl_config); /*reconfig*/ gf_service_command(ch->owner->service, &com, GF_OK); /*ISMACryp config*/ if (ch->depacketizer->flags & GF_RTP_HAS_ISMACRYP) { memset(&com, 0, sizeof(GF_NetworkCommand)); com.base.on_channel = ch->channel; com.command_type = GF_NET_CHAN_DRM_CFG; com.drm_cfg.scheme_type = ch->depacketizer->isma_scheme; com.drm_cfg.scheme_version = 1; /*not transported in SDP!!!*/ com.drm_cfg.scheme_uri = NULL; com.drm_cfg.kms_uri = ch->depacketizer->key; gf_service_command(ch->owner->service, &com, GF_OK); } }
void IMG_NetIO(void *cbk, GF_NETIO_Parameter *param) { GF_Err e; const char *szCache; IMGLoader *read = (IMGLoader *) cbk; if (!read->dnload) return; /*handle service message*/ gf_service_download_update_stats(read->dnload); e = param->error; /*wait to get the whole file*/ if (!e && (param->msg_type!=GF_NETIO_DATA_TRANSFERED)) return; if ((e==GF_EOS) && (param->msg_type==GF_NETIO_DATA_EXCHANGE)) return; if (param->msg_type==GF_NETIO_DATA_TRANSFERED) { szCache = gf_dm_sess_get_cache_name(read->dnload); if (!szCache) e = GF_IO_ERR; else { if (read->stream) gf_fclose(read->stream); read->stream = gf_fopen((char *) szCache, "rb"); if (!read->stream) e = GF_SERVICE_ERROR; else { e = GF_OK; gf_fseek(read->stream, 0, SEEK_END); read->data_size = (u32) gf_ftell(read->stream); gf_fseek(read->stream, 0, SEEK_SET); } } } /*OK confirm*/ gf_service_connect_ack(read->service, NULL, e); if (!e) IMG_SetupObject(read); }
void VTT_NetIO(void *cbk, GF_NETIO_Parameter *param) { GF_Err e; const char *szCache; GF_InputService *plug = (GF_InputService *)cbk; VTTIn *vttin = (VTTIn *) plug->priv; if (!vttin) return; gf_service_download_update_stats(vttin->dnload); e = param->error; /*done*/ if (param->msg_type==GF_NETIO_DATA_TRANSFERED) { szCache = gf_dm_sess_get_cache_name(vttin->dnload); if (!szCache) e = GF_IO_ERR; else { //e = TTIn_LoadFile(plug, szCache, 1); } } else if (param->msg_type==GF_NETIO_DATA_EXCHANGE) { return; } /*OK confirm*/ if (vttin->needs_connection) { vttin->needs_connection = GF_FALSE; gf_service_connect_ack(vttin->service, NULL, e); //if (!e && !vttin->od_done) tti_setup_object(vttin); } }
static GF_Err IMG_ConnectChannel(GF_InputService *plug, LPNETCHANNEL channel, const char *url, Bool upstream) { u32 ES_ID=0; GF_Err e; IMGLoader *read; if (!plug) return GF_OK; read = (IMGLoader *)plug->priv; e = GF_SERVICE_ERROR; if (read->ch==channel) goto exit; if (!url) goto exit; e = GF_STREAM_NOT_FOUND; if (strstr(url, "ES_ID")) { sscanf(url, "ES_ID=%ud", &ES_ID); } /*URL setup*/ else if (!read->ch && IMG_CanHandleURL(plug, url)) ES_ID = 1; if (ES_ID==1) { read->ch = channel; e = GF_OK; } exit: gf_service_connect_ack(read->service, channel, e); return e; }
static void AC3_OnLiveData(AC3Reader *read, const char *data, u32 data_size) { u64 pos; Bool sync; GF_BitStream *bs; GF_AC3Header hdr; memset(&hdr, 0, sizeof(GF_AC3Header)); read->data = gf_realloc(read->data, sizeof(char)*(read->data_size+data_size) ); memcpy(read->data + read->data_size, data, sizeof(char)*data_size); read->data_size += data_size; if (read->needs_connection) { read->needs_connection = 0; bs = gf_bs_new((char *) read->data, read->data_size, GF_BITSTREAM_READ); sync = gf_ac3_parser_bs(bs, &hdr, GF_TRUE); gf_bs_del(bs); if (!sync) return; read->nb_ch = hdr.channels; read->sample_rate = hdr.sample_rate; read->is_live = 1; memset(&read->sl_hdr, 0, sizeof(GF_SLHeader)); gf_service_connect_ack(read->service, NULL, GF_OK); AC3_SetupObject(read); } if (!read->ch) return; /*need a full ac3 header*/ if (read->data_size<=7) return; bs = gf_bs_new((char *) read->data, read->data_size, GF_BITSTREAM_READ); hdr.framesize = 0; pos = 0; while (gf_ac3_parser_bs(bs, &hdr, GF_FALSE)) { pos = gf_bs_get_position(bs); read->sl_hdr.accessUnitStartFlag = 1; read->sl_hdr.accessUnitEndFlag = 1; read->sl_hdr.AU_sequenceNumber++; read->sl_hdr.compositionTimeStampFlag = 1; read->sl_hdr.compositionTimeStamp += 1536; gf_service_send_packet(read->service, read->ch, (char *) read->data + pos, hdr.framesize, &read->sl_hdr, GF_OK); gf_bs_skip_bytes(bs, hdr.framesize); } pos = gf_bs_get_position(bs); gf_bs_del(bs); if (pos) { u8 *d; read->data_size -= (u32) pos; d = gf_malloc(sizeof(char) * read->data_size); memcpy(d, read->data + pos, sizeof(char) * read->data_size); gf_free(read->data); read->data = d; } AC3_RegulateDataRate(read); }
GF_Err DC_ConnectChannel(GF_InputService *plug, LPNETCHANNEL channel, const char *url, Bool upstream) { u32 ESID; DCReader *read = (DCReader *) plug->priv; sscanf(url, "ES_ID=%ud", &ESID); if (!ESID) { gf_service_connect_ack(read->service, channel, GF_STREAM_NOT_FOUND); } else { DummyChannel *dc; GF_SAFEALLOC(dc, DummyChannel); dc->ch = channel; dc->ESID = ESID; gf_list_add(read->channels, dc); gf_service_connect_ack(read->service, channel, GF_OK); } return GF_OK; }
void DC_DownloadFile(GF_InputService *plug, char *url) { DCReader *read = (DCReader *) plug->priv; read->dnload = gf_service_download_new(read->service, url, 0, DC_NetIO, read); if (!read->dnload) { gf_service_connect_ack(read->service, NULL, GF_NOT_SUPPORTED); } else { /*start our download (threaded)*/ gf_dm_sess_process(read->dnload); } }
u32 RP_Thread(void *param) { u32 i; GF_NetworkCommand com; RTSPSession *sess; RTPStream *ch; RTPClient *rtp = (RTPClient *)param; rtp->th_state = 1; com.command_type = GF_NET_CHAN_BUFFER_QUERY; while (rtp->th_state) { gf_mx_p(rtp->mx); /*fecth data on udp*/ i=0; while ((ch = (RTPStream *)gf_list_enum(rtp->channels, &i))) { if ((ch->flags & RTP_EOS) || (ch->status!=RTP_Running) ) continue; /*for interleaved channels don't read too fast, query the buffer occupancy*/ if (ch->flags & RTP_INTERLEAVED) { com.base.on_channel = ch->channel; gf_service_command(rtp->service, &com, GF_OK); /*if no buffering, use a default value (3 sec of data should do it)*/ if (!com.buffer.max) com.buffer.max = 3000; if (com.buffer.occupancy <= com.buffer.max) ch->rtsp->flags |= RTSP_TCP_FLUSH; } else { RP_ReadStream(ch); } } /*and process commands / flush TCP*/ i=0; while ((sess = (RTSPSession *)gf_list_enum(rtp->sessions, &i))) { RP_ProcessCommands(sess); if (sess->connect_error) { gf_service_connect_ack(sess->owner->service, NULL, sess->connect_error); sess->connect_error = 0; } } gf_mx_v(rtp->mx); gf_sleep(1); } if (rtp->dnload) gf_service_download_del(rtp->dnload); rtp->dnload = NULL; rtp->th_state = 2; return 0; }
void jp_download_file(GF_InputService *plug, const char *url) { IMGLoader *read = (IMGLoader *) plug->priv; read->dnload = gf_service_download_new(read->service, url, 0, IMG_NetIO, read); if (!read->dnload) { gf_service_connect_ack(read->service, NULL, GF_NOT_SUPPORTED); } else { /*start our download (threaded)*/ gf_dm_sess_process(read->dnload); } /*service confirm is done once fetched*/ }
static void SAF_DownloadFile(GF_InputService *plug, char *url) { SAFIn *read = (SAFIn*) plug->priv; read->dnload = gf_service_download_new(read->service, url, 0, SAF_NetIO, read); if (!read->dnload) { read->needs_connection = 0; gf_service_connect_ack(read->service, NULL, GF_NOT_SUPPORTED); } else { /*start our download (threaded)*/ gf_dm_sess_process(read->dnload); } /*service confirm is done once fetched*/ }
void isor_setup_download(GF_InputService *plug, const char *url) { ISOMReader *read = (ISOMReader *) plug->priv; read->dnload = gf_service_download_new(read->service, url, 0, isor_net_io, read); if (!read->dnload) { if (read->input->query_proxy && read->input->proxy_udta && read->input->proxy_type) { send_proxy_command(read, GF_FALSE, GF_FALSE, GF_NOT_SUPPORTED, NULL, NULL); } else { gf_service_connect_ack(read->service, NULL, GF_NOT_SUPPORTED); } } else { /*start our download (threaded)*/ gf_dm_sess_process(read->dnload); } /*service confirm is done once IOD can be fetched*/ }
void VTT_download_file(GF_InputService *plug, const char *url) { VTTIn *vttin = (VTTIn *) plug->priv; if (!plug || !url) return; vttin->needs_connection = GF_TRUE; vttin->dnload = gf_service_download_new(vttin->service, url, 0, VTT_NetIO, plug); if (!vttin->dnload) { vttin->needs_connection = GF_FALSE; gf_service_connect_ack(vttin->service, NULL, GF_NOT_SUPPORTED); } else { /*start our download (threaded)*/ gf_dm_sess_process(vttin->dnload); } /*service confirm is done once fetched*/ }
void ac3_download_file(GF_InputService *plug, char *url) { AC3Reader *read = (AC3Reader*) plug->priv; read->needs_connection = GF_TRUE; read->dnload = gf_service_download_new(read->service, url, 0, AC3_NetIO, read); if (!read->dnload ) { read->needs_connection = GF_FALSE; gf_service_connect_ack(read->service, NULL, GF_NOT_SUPPORTED); } else { /*start our download (threaded)*/ gf_dm_sess_process(read->dnload); } /*service confirm is done once fetched*/ }
void RP_SDPFromData(RTPClient *rtp, char *s_url, RTPStream *stream) { char *url; char buf[2000]; u32 size; url = strstr(s_url, ","); if (!url) { gf_service_connect_ack(rtp->service, NULL, GF_URL_ERROR); return; } url += 1; if (strstr(url, ";base64")) { //decode size = gf_base64_decode(url, (u32) strlen(url), buf, 2000); buf[size] = 0; url = buf; } RP_LoadSDP(rtp, url, (u32) strlen(url), stream); }
static GF_Err VTT_ConnectChannel(GF_InputService *plug, LPNETCHANNEL channel, const char *url, Bool upstream) { u32 ES_ID; GF_Err e; VTTIn *vttin = (VTTIn *)plug->priv; if (!vttin) return GF_BAD_PARAM; e = GF_SERVICE_ERROR; if (!vttin || vttin->channel==channel) goto exit; e = GF_STREAM_NOT_FOUND; ES_ID = 0; if (strstr(url, "ES_ID")) sscanf(url, "ES_ID=%ud", &ES_ID); if (ES_ID==1) { vttin->channel = channel; e = GF_OK; } exit: gf_service_connect_ack(vttin->service, channel, e); return e; }
static GF_Err FFD_ConnectChannel(GF_InputService *plug, LPNETCHANNEL channel, const char *url, Bool upstream) { GF_Err e; u32 ESID; FFDemux *ffd = plug->priv; e = GF_STREAM_NOT_FOUND; if (upstream) { e = GF_ISOM_INVALID_FILE; goto exit; } if (!strstr(url, "ES_ID=")) { e = GF_NOT_SUPPORTED; goto exit; } sscanf(url, "ES_ID=%u", &ESID); if ((s32) ESID == 1 + ffd->audio_st) { if (ffd->audio_ch) { e = GF_SERVICE_ERROR; goto exit; } ffd->audio_ch = channel; e = GF_OK; } else if ((s32) ESID == 1 + ffd->video_st) { if (ffd->video_ch) { e = GF_SERVICE_ERROR; goto exit; } ffd->video_ch = channel; e = GF_OK; } exit: gf_service_connect_ack(ffd->service, channel, e); return GF_OK; }
void DC_NetIO(void *cbk, GF_NETIO_Parameter *param) { GF_Err e; DCReader *read = (DCReader *) cbk; /*handle service message*/ gf_service_download_update_stats(read->dnload); e = param->error; if (param->msg_type==GF_NETIO_DATA_TRANSFERED) { } else if (param->msg_type==GF_NETIO_PARSE_HEADER) { if (!strcmp(param->name, "Content-Type")) { if (strstr(param->value, "application/x-bt")) read->oti = GPAC_OTI_PRIVATE_SCENE_GENERIC; if (strstr(param->value, "application/x-xmt")) read->oti = GPAC_OTI_PRIVATE_SCENE_GENERIC; if (strstr(param->value, "model/vrml")) read->oti = GPAC_OTI_PRIVATE_SCENE_GENERIC; if (strstr(param->value, "model/x3d+vrml")) read->oti = GPAC_OTI_PRIVATE_SCENE_GENERIC; if (strstr(param->value, "application/x-shockwave-flash")) read->oti = GPAC_OTI_PRIVATE_SCENE_GENERIC; if (strstr(param->value, "image/svg+xml")) read->oti = GPAC_OTI_PRIVATE_SCENE_SVG; if (strstr(param->value, "image/x-svgm")) read->oti = GPAC_OTI_PRIVATE_SCENE_SVG; if (strstr(param->value, "application/x-LASeR+xml")) read->oti = GPAC_OTI_PRIVATE_SCENE_GENERIC; if (strstr(param->value, "application/widget")) read->oti = GPAC_OTI_PRIVATE_SCENE_WGT; if (strstr(param->value, "application/x-mpegu-widget")) read->oti = GPAC_OTI_PRIVATE_SCENE_WGT; } return; } else if (!e && (param->msg_type!=GF_NETIO_DATA_EXCHANGE)) return; if (!e && !read->oti) return; /*OK confirm*/ if (!read->is_service_connected) { if (!gf_dm_sess_get_cache_name(read->dnload)) e = GF_IO_ERR; if (e>0) e = GF_OK; gf_service_connect_ack(read->service, NULL, e); read->is_service_connected = GF_TRUE; } }
static GF_Err VTT_ConnectService(GF_InputService *plug, GF_ClientService *serv, const char *url) { GF_Err e; VTTIn *vttin = (VTTIn *)plug->priv; if (!plug || !url) return GF_BAD_PARAM; vttin->service = serv; if (vttin->dnload) gf_service_download_del(vttin->dnload); vttin->dnload = NULL; /*remote fetch*/ if (!VTT_is_local(url)) { VTT_download_file(plug, url); return GF_OK; } else { e = GF_OK; //e = TTIn_LoadFile(plug, url, 0); gf_service_connect_ack(serv, NULL, e); //if (!e && !vttin->od_done) tti_setup_object(vttin); } return GF_OK; }
void RP_FetchSDP(RTPClient *rtp, char *url, RTPStream *stream, char *original_url) { SDPFetch *sdp; /*if local URL get file*/ if (strstr(url, "data:application/sdp")) { RP_SDPFromData(rtp, url, stream); return; } if (!strnicmp(url, "file://", 7) || !strstr(url, "://")) { RP_SDPFromFile(rtp, url, stream); return; } sdp = (SDPFetch*)gf_malloc(sizeof(SDPFetch)); memset(sdp, 0, sizeof(SDPFetch)); sdp->client = rtp; sdp->remote_url = gf_strdup(url); sdp->chan = stream; if (original_url) { sdp->original_url = gf_strdup(original_url); } /*otherwise setup download*/ if (rtp->dnload) gf_service_download_del(rtp->dnload); rtp->dnload = NULL; rtp->sdp_temp = sdp; rtp->dnload = gf_service_download_new(rtp->service, url, 0, SDP_NetIO, rtp); if (!rtp->dnload) { gf_service_connect_ack(rtp->service, NULL, GF_NOT_SUPPORTED); } else { /*start our download (threaded)*/ gf_dm_sess_process(rtp->dnload); } /*service confirm is done once fetched*/ }
static GF_Err SAF_ConnectService(GF_InputService *plug, GF_ClientService *serv, const char *url) { char szURL[2048]; char *ext; SAFIn *read = (SAFIn *)plug->priv; read->service = serv; if (read->dnload) gf_service_download_del(read->dnload); read->dnload = NULL; strcpy(szURL, url); ext = strrchr(szURL, '#'); if (ext) ext[0] = 0; read->needs_connection = 1; read->duration = 0; read->saf_type = SAF_FILE_LOCAL; /*remote fetch*/ if (strnicmp(url, "file://", 7) && strstr(url, "://")) { read->saf_type = SAF_FILE_REMOTE; SAF_DownloadFile(plug, (char *) szURL); return GF_OK; } read->stream = gf_f64_open(szURL, "rb"); if (!read->stream) { gf_service_connect_ack(serv, NULL, GF_URL_ERROR); return GF_OK; } SAF_CheckFile(read); read->th = gf_th_new("SAFDemux"); /*start playing for tune-in*/ gf_th_run(read->th, SAF_Run, read); return GF_OK; }
static GF_Err SAF_ConnectChannel(GF_InputService *plug, LPNETCHANNEL channel, const char *url, Bool upstream) { u32 ES_ID; SAFChannel *ch; GF_Err e; SAFIn *read = (SAFIn *)plug->priv; ch = saf_get_channel(read, 0, channel); if (ch) e = GF_SERVICE_ERROR; e = GF_STREAM_NOT_FOUND; if (strstr(url, "ES_ID")) { sscanf(url, "ES_ID=%d", &ES_ID); ch = saf_get_channel(read, ES_ID, NULL); if (ch && !ch->ch) { ch->ch = channel; e = GF_OK; } } gf_service_connect_ack(read->service, channel, e); return e; }
/* Callback functions used by a media parser when parsing events happens */ GF_Err gf_mse_proxy(GF_InputService *parser, GF_NetworkCommand *command) { if (!parser || !command || !parser->proxy_udta) { return GF_BAD_PARAM; } else { GF_HTML_SourceBuffer *sb = (GF_HTML_SourceBuffer *)parser->proxy_udta; switch (command->command_type) { case GF_NET_SERVICE_QUERY_INIT_RANGE: break; case GF_NET_SERVICE_QUERY_NEXT: /* The parser is asking for the next media segment in the buffer, check for the media time and give the right one */ { GF_HTML_ArrayBuffer *buffer; /* The input buffer should not be modified by append operations at the same time, no need to protect access */ buffer = (GF_HTML_ArrayBuffer *)gf_list_get(sb->input_buffer, 0); if (buffer) { command->url_query.discontinuity_type = 0; command->url_query.current_download = GF_FALSE; command->url_query.start_range = 0; command->url_query.end_range = 0; command->url_query.switch_start_range = 0; command->url_query.switch_end_range = 0; command->url_query.next_url_init_or_switch_segment = NULL; if (buffer->is_init) { GF_HTML_ArrayBuffer *next = (GF_HTML_ArrayBuffer *)gf_list_get(sb->input_buffer, 1); command->url_query.discontinuity_type = 1; if (next) { GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MSE] Next segment to parse %s with init \n", next->url, buffer->url)); command->url_query.next_url = next->url; command->url_query.next_url_init_or_switch_segment = buffer->url; gf_list_rem(sb->input_buffer, 0); gf_list_rem(sb->input_buffer, 0); } else { GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MSE] Only one init segment to parse %s, need to wait\n", buffer->url)); command->url_query.next_url = NULL; } } else { GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MSE] Next segment to parse %s\n", buffer->url)); command->url_query.next_url = buffer->url; gf_list_rem(sb->input_buffer, 0); } sb->prev_buffer = buffer; } else { command->url_query.next_url = NULL; command->url_query.discontinuity_type = 0; } } break; case GF_NET_SERVICE_STATUS_PROXY: /* The parser is informing the proxy about its status changes: - new track found - all tracks parsed - connect/disconnect - */ if (command->status.is_add_media) { if (command->status.desc) { gf_mse_source_buffer_store_track_desc(sb, (GF_ObjectDescriptor *)command->status.desc); } else { /* this is the last add media, we can switch updating to false */ /* the first init segment was correctly processed */ gf_mse_source_buffer_set_update(sb, GF_FALSE); /* TODO: set active tracks and send addsourcebuffer event */ /* TODO: send media loadedmetadata event */ } gf_service_declare_media(sb->mediasource->service, command->status.desc, (command->status.desc ? GF_TRUE : GF_FALSE)); } /* general connection/disconnection messages from the media parser (not track related) */ else if (!command->status.channel) { /* connection message */ if (!command->status.is_disconnect) { if (command->status.e == GF_OK) { /* nothing needs to be done. Setup is done with final add media */ sb->parser_connected = GF_TRUE; sb->mediasource->durationType = DURATION_INFINITY; gf_mse_source_buffer_setup_tracks(sb); } else { /* wrong first init segment */ /* TODO: fire an error event */ } gf_service_connect_ack(sb->mediasource->service, command->status.channel, command->status.e); } else { gf_service_disconnect_ack(sb->mediasource->service, command->status.channel, command->status.e); } } /* channel (track related) specific connection/disconnection messages from the media parser */ else { if (!command->status.is_disconnect) { gf_service_connect_ack(sb->mediasource->service, command->status.channel, command->status.e); } else { gf_service_disconnect_ack(sb->mediasource->service, command->status.channel, command->status.e); } } break; default: gf_service_command(sb->mediasource->service, command, GF_OK); break; } return GF_OK; } }
GF_Err DC_ConnectService(GF_InputService *plug, GF_ClientService *serv, const char *url) { DCReader *read = (DCReader *) plug->priv; FILE *test; char *tmp, *ext; if (!read || !serv || !url) return GF_BAD_PARAM; if (read->dnload) gf_service_download_del(read->dnload); read->dnload = NULL; read->url = gf_strdup(url); ext = strchr(read->url, '#'); if (ext) { char *anext; ext[0] = 0; anext = strrchr(read->url, '.'); ext[0] = '#'; ext = anext; } else { ext = strrchr(read->url, '.'); } if (ext && !stricmp(ext, ".gz")) { char *anext; ext[0] = 0; anext = strrchr(read->url, '.'); ext[0] = '.'; ext = anext; } read->service = serv; if (!strnicmp(url, "views://", 8)) { read->is_views_url = GF_TRUE; gf_service_connect_ack(serv, NULL, GF_OK); read->is_service_connected = GF_TRUE; return GF_OK; } if (ext) { char *cgi_par = NULL; ext += 1; if (ext) { tmp = strchr(ext, '#'); if (tmp) tmp[0] = 0; /* Warning the '?' sign should not be present in local files but it is convenient to have it to test web content locally */ cgi_par = strchr(ext, '?'); if (cgi_par) cgi_par[0] = 0; } if (!stricmp(ext, "bt") || !stricmp(ext, "btz") || !stricmp(ext, "bt.gz") || !stricmp(ext, "xmta") || !stricmp(ext, "xmt") || !stricmp(ext, "xmt.gz") || !stricmp(ext, "xmtz") || !stricmp(ext, "wrl") || !stricmp(ext, "wrl.gz") || !stricmp(ext, "x3d") || !stricmp(ext, "x3d.gz") || !stricmp(ext, "x3dz") || !stricmp(ext, "x3dv") || !stricmp(ext, "x3dv.gz") || !stricmp(ext, "x3dvz") || !stricmp(ext, "swf") ) read->oti = GPAC_OTI_PRIVATE_SCENE_GENERIC; else if (!stricmp(ext, "svg") || !stricmp(ext, "svgz") || !stricmp(ext, "svg.gz")) { read->oti = GPAC_OTI_PRIVATE_SCENE_SVG; } /*XML LASeR*/ else if (!stricmp(ext, "xsr")) read->oti = GPAC_OTI_PRIVATE_SCENE_LASER; else if (!stricmp(ext, "xbl")) read->oti = GPAC_OTI_PRIVATE_SCENE_XBL; else if (!stricmp(ext, "wgt") || !stricmp(ext, "mgt")) read->oti = GPAC_OTI_PRIVATE_SCENE_WGT; if (cgi_par) cgi_par[0] = '?'; } if (!read->oti && (!strnicmp(url, "file://", 7) || !strstr(url, "://"))) { char *rtype = gf_xml_get_root_type(url, NULL); if (rtype) { if (!strcmp(rtype, "SAFSession")) read->oti = GPAC_OTI_PRIVATE_SCENE_LASER; else if (!strcmp(rtype, "svg")) read->oti = GPAC_OTI_PRIVATE_SCENE_SVG; else if (!strcmp(rtype, "XMT-A")) read->oti = GPAC_OTI_PRIVATE_SCENE_GENERIC; else if (!strcmp(rtype, "X3D")) read->oti = GPAC_OTI_PRIVATE_SCENE_GENERIC; else if (!strcmp(rtype, "bindings")) read->oti = GPAC_OTI_PRIVATE_SCENE_XBL; else if (!strcmp(rtype, "widget")) read->oti = GPAC_OTI_PRIVATE_SCENE_WGT; gf_free(rtype); } } /*remote fetch*/ if (!strnicmp(url, "file://", 7)) { url += 7; } else if (strstr(url, "://")) { DC_DownloadFile(plug, read->url); return GF_OK; } test = gf_fopen(read->url, "rt"); if (!test) { gf_service_connect_ack(serv, NULL, GF_URL_ERROR); return GF_OK; } gf_fclose(test); if (!read->is_service_connected) { gf_service_connect_ack(serv, NULL, GF_OK); read->is_service_connected = GF_TRUE; } return GF_OK; }
static GF_Err FFD_ConnectService(GF_InputService *plug, GF_ClientService *serv, const char *url) { GF_Err e; s64 last_aud_pts; u32 i; s32 res; Bool is_local; const char *sOpt; char *ext, szName[1024]; FFDemux *ffd = plug->priv; AVInputFormat *av_in = NULL; char szExt[20]; if (ffd->ctx) return GF_SERVICE_ERROR; assert( url && strlen(url) < 1024); strcpy(szName, url); ext = strrchr(szName, '#'); ffd->service_type = 0; e = GF_NOT_SUPPORTED; ffd->service = serv; if (ext) { if (!stricmp(&ext[1], "video")) ffd->service_type = 1; else if (!stricmp(&ext[1], "audio")) ffd->service_type = 2; ext[0] = 0; } /*some extensions not supported by ffmpeg, overload input format*/ ext = strrchr(szName, '.'); strcpy(szExt, ext ? ext+1 : ""); strlwr(szExt); if (!strcmp(szExt, "cmp")) av_in = av_find_input_format("m4v"); is_local = (strnicmp(url, "file://", 7) && strstr(url, "://")) ? 0 : 1; GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[FFMPEG] opening file %s - local %d - av_in %08x\n", url, is_local, av_in)); if (!is_local) { AVProbeData pd; /*setup wraper for FFMPEG I/O*/ ffd->buffer_size = 8192; sOpt = gf_modules_get_option((GF_BaseInterface *)plug, "FFMPEG", "IOBufferSize"); if (sOpt) ffd->buffer_size = atoi(sOpt); ffd->buffer = gf_malloc(sizeof(char)*ffd->buffer_size); #ifdef FFMPEG_DUMP_REMOTE ffd->outdbg = gf_f64_open("ffdeb.raw", "wb"); #endif #ifdef USE_PRE_0_7 init_put_byte(&ffd->io, ffd->buffer, ffd->buffer_size, 0, ffd, ff_url_read, NULL, NULL); ffd->io.is_streamed = 1; #else ffd->io.seekable = 1; #endif ffd->dnload = gf_service_download_new(ffd->service, url, GF_NETIO_SESSION_NOT_THREADED | GF_NETIO_SESSION_NOT_CACHED, NULL, ffd); if (!ffd->dnload) return GF_URL_ERROR; while (1) { u32 read; e = gf_dm_sess_fetch_data(ffd->dnload, ffd->buffer + ffd->buffer_used, ffd->buffer_size - ffd->buffer_used, &read); if (e==GF_EOS) break; /*we're sync!!*/ if (e==GF_IP_NETWORK_EMPTY) continue; if (e) goto err_exit; ffd->buffer_used += read; if (ffd->buffer_used == ffd->buffer_size) break; } if (e==GF_EOS) { const char *cache_file = gf_dm_sess_get_cache_name(ffd->dnload); res = open_file(&ffd->ctx, cache_file, av_in); } else { pd.filename = szName; pd.buf_size = ffd->buffer_used; pd.buf = (u8 *) ffd->buffer; av_in = av_probe_input_format(&pd, 1); if (!av_in) { GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[FFMPEG] error probing file %s - probe start with %c %c %c %c\n", url, ffd->buffer[0], ffd->buffer[1], ffd->buffer[2], ffd->buffer[3])); return GF_NOT_SUPPORTED; } /*setup downloader*/ av_in->flags |= AVFMT_NOFILE; #ifdef USE_AVFORMAT_OPEN_INPUT /*commit ffmpeg 603b8bc2a109978c8499b06d2556f1433306eca7*/ res = avformat_open_input(&ffd->ctx, szName, av_in, NULL); #else res = av_open_input_stream(&ffd->ctx, &ffd->io, szName, av_in, NULL); #endif } } else { res = open_file(&ffd->ctx, szName, av_in); } switch (res) { #ifndef _WIN32_WCE case 0: e = GF_OK; break; case AVERROR_IO: e = GF_URL_ERROR; goto err_exit; case AVERROR_INVALIDDATA: e = GF_NON_COMPLIANT_BITSTREAM; goto err_exit; case AVERROR_NOMEM: e = GF_OUT_OF_MEM; goto err_exit; case AVERROR_NOFMT: e = GF_NOT_SUPPORTED; goto err_exit; #endif default: e = GF_SERVICE_ERROR; goto err_exit; } GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[FFMPEG] looking for streams in %s - %d streams - type %s\n", ffd->ctx->filename, ffd->ctx->nb_streams, ffd->ctx->iformat->name)); res = av_find_stream_info(ffd->ctx); if (res <0) { GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[FFMPEG] cannot locate streams - error %d\n", res)); e = GF_NOT_SUPPORTED; goto err_exit; } GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[FFMPEG] file %s opened - %d streams\n", url, ffd->ctx->nb_streams)); /*figure out if we can use codecs or not*/ ffd->audio_st = ffd->video_st = -1; for (i = 0; i < ffd->ctx->nb_streams; i++) { AVCodecContext *enc = ffd->ctx->streams[i]->codec; switch(enc->codec_type) { case AVMEDIA_TYPE_AUDIO: if ((ffd->audio_st<0) && (ffd->service_type!=1)) { ffd->audio_st = i; ffd->audio_tscale = ffd->ctx->streams[i]->time_base; } break; case AVMEDIA_TYPE_VIDEO: if ((ffd->video_st<0) && (ffd->service_type!=2)) { ffd->video_st = i; ffd->video_tscale = ffd->ctx->streams[i]->time_base; } break; default: break; } } if ((ffd->service_type==1) && (ffd->video_st<0)) goto err_exit; if ((ffd->service_type==2) && (ffd->audio_st<0)) goto err_exit; if ((ffd->video_st<0) && (ffd->audio_st<0)) { GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[FFMPEG] No supported streams in file\n")); goto err_exit; } sOpt = gf_modules_get_option((GF_BaseInterface *)plug, "FFMPEG", "DataBufferMS"); ffd->data_buffer_ms = 0; if (sOpt) ffd->data_buffer_ms = atoi(sOpt); if (!ffd->data_buffer_ms) ffd->data_buffer_ms = FFD_DATA_BUFFER; /*build seek*/ if (is_local) { /*check we do have increasing pts. If not we can't rely on pts, we must skip SL we assume video pts is always present*/ if (ffd->audio_st>=0) { last_aud_pts = 0; for (i=0; i<20; i++) { AVPacket pkt; pkt.stream_index = -1; if (av_read_frame(ffd->ctx, &pkt) <0) break; if (pkt.pts == AV_NOPTS_VALUE) pkt.pts = pkt.dts; if (pkt.stream_index==ffd->audio_st) last_aud_pts = pkt.pts; } if (last_aud_pts*ffd->audio_tscale.den<10*ffd->audio_tscale.num) ffd->unreliable_audio_timing = 1; } ffd->seekable = (av_seek_frame(ffd->ctx, -1, 0, AVSEEK_FLAG_BACKWARD)<0) ? 0 : 1; if (!ffd->seekable) { #ifndef FF_API_CLOSE_INPUT_FILE av_close_input_file(ffd->ctx); #else avformat_close_input(&ffd->ctx); #endif ffd->ctx = NULL; open_file(&ffd->ctx, szName, av_in); av_find_stream_info(ffd->ctx); } } /*let's go*/ gf_service_connect_ack(serv, NULL, GF_OK); /*if (!ffd->service_type)*/ FFD_SetupObjects(ffd); ffd->service_type = 0; return GF_OK; err_exit: GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[FFMPEG] Error opening file %s: %s\n", url, gf_error_to_string(e))); #ifndef FF_API_CLOSE_INPUT_FILE if (ffd->ctx) av_close_input_file(ffd->ctx); #else if (ffd->ctx) avformat_close_input(&ffd->ctx); #endif ffd->ctx = NULL; gf_service_connect_ack(serv, NULL, e); return GF_OK; }
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 AC3_NetIO(void *cbk, GF_NETIO_Parameter *param) { GF_Err e; const char *szCache; u32 total_size, bytes_done; AC3Reader *read = (AC3Reader *) cbk; e = param->error; /*done*/ if (param->msg_type==GF_NETIO_DATA_TRANSFERED) { if (read->stream) { read->is_remote = 0; e = GF_EOS; } else if (!read->needs_connection) { return; } } else if (param->msg_type==GF_NETIO_PARSE_HEADER) { if (!strcmp(param->name, "icy-name")) { if (read->icy_name) gf_free(read->icy_name); read->icy_name = gf_strdup(param->value); } if (!strcmp(param->name, "icy-genre")) { if (read->icy_genre) gf_free(read->icy_genre); read->icy_genre = gf_strdup(param->value); } if (!strcmp(param->name, "icy-meta")) { GF_NetworkCommand com; char *meta; if (read->icy_track_name) gf_free(read->icy_track_name); read->icy_track_name = NULL; meta = param->value; while (meta && meta[0]) { char *sep = strchr(meta, ';'); if (sep) sep[0] = 0; if (!strnicmp(meta, "StreamTitle=", 12)) { read->icy_track_name = gf_strdup(meta+12); } if (!sep) break; sep[0] = ';'; meta = sep+1; } com.base.command_type = GF_NET_SERVICE_INFO; gf_service_command(read->service, &com, GF_OK); } return; } else { /*handle service message*/ gf_service_download_update_stats(read->dnload); if (param->msg_type!=GF_NETIO_DATA_EXCHANGE) return; } /*data fetching or EOS*/ if (e >= GF_OK) { if (read->needs_connection) { gf_dm_sess_get_stats(read->dnload, NULL, NULL, &total_size, NULL, NULL, NULL); if (!total_size) read->is_live = 1; } if (read->is_live) { if (!e) AC3_OnLiveData(read, param->data, param->size); return; } if (read->stream) return; /*open service*/ szCache = gf_dm_sess_get_cache_name(read->dnload); if (!szCache) e = GF_IO_ERR; else { read->stream = gf_f64_open((char *) szCache, "rb"); if (!read->stream) e = GF_SERVICE_ERROR; else { /*if full file at once (in cache) parse duration*/ if (e==GF_EOS) read->is_remote = 0; e = GF_OK; /*not enough data*/ if (!AC3_ConfigureFromFile(read)) { /*get amount downloaded and check*/ gf_dm_sess_get_stats(read->dnload, NULL, NULL, NULL, &bytes_done, NULL, NULL); if (bytes_done>10*1024) { e = GF_CORRUPTED_DATA; } else { fclose(read->stream); read->stream = NULL; return; } } } } } /*OK confirm*/ if (read->needs_connection) { read->needs_connection = 0; gf_service_connect_ack(read->service, NULL, e); if (!e) AC3_SetupObject(read); } }