📄 saf_in.c
字号:
fseek(read->stream, 0, SEEK_SET); read->saf_size=0; read->run_state = 1; while (read->run_state && !feof(read->stream) ) { par.size = fread(data, 1, 1024, read->stream); if (!par.size) break; SAF_NetIO(read, &par); } read->run_state = 2; return 0;}static void SAF_DownloadFile(GF_InputService *plug, char *url){ SAFIn *read = (SAFIn*) plug->priv; read->dnload = gf_term_download_new(read->service, url, 0, SAF_NetIO, read); if (!read->dnload) { read->needs_connection = 0; gf_term_on_connect(read->service, NULL, GF_NOT_SUPPORTED); } /*service confirm is done once fetched*/}typedef struct{ u32 stream_id; u32 ts_res;} StreamInfo;static void SAF_CheckFile(SAFIn *read){ u32 nb_streams, i, cts, au_size, au_type, stream_id, ts_res; GF_BitStream *bs; StreamInfo si[1024]; fseek(read->stream, 0, SEEK_SET); bs = gf_bs_from_file(read->stream, GF_BITSTREAM_READ); nb_streams=0; while (gf_bs_available(bs)) { gf_bs_read_u16(bs); gf_bs_read_int(bs, 2); cts = gf_bs_read_int(bs, 30); au_size = gf_bs_read_int(bs, 16); au_type = gf_bs_read_int(bs, 4); stream_id = gf_bs_read_int(bs, 12); au_size-=2; ts_res = 0; for (i=0; i<nb_streams; i++) { if (si[i].stream_id==stream_id) ts_res = si[i].ts_res; } if (!ts_res) { if ((au_type==1) || (au_type==2) || (au_type==7)) { gf_bs_read_u16(bs); ts_res = gf_bs_read_u24(bs); au_size -= 5; si[nb_streams].stream_id = stream_id; si[nb_streams].ts_res = ts_res; nb_streams++; } } if (ts_res && (au_type==4)) { Double ts = cts; ts /= ts_res; if (ts>read->duration) read->duration = ts; } gf_bs_skip_bytes(bs, au_size); } gf_bs_del(bs); fseek(read->stream, 0, SEEK_SET);}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_term_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 = fopen(szURL, "rb"); if (!read->stream) { gf_term_on_connect(serv, NULL, GF_URL_ERROR); return GF_OK; } SAF_CheckFile(read); read->th = gf_th_new(); /*start playing for tune-in*/ gf_th_run(read->th, SAF_Run, read); return GF_OK;}static GF_Err SAF_CloseService(GF_InputService *plug){ SAFIn *read = (SAFIn *)plug->priv; if (read->th) { if (read->run_state == 1) { read->run_state=0; while (read->run_state!=2) gf_sleep(0); } gf_th_del(read->th); read->th = NULL; } if (read->stream) fclose(read->stream); read->stream = NULL; if (read->dnload) gf_term_download_del(read->dnload); read->dnload = NULL; gf_term_on_disconnect(read->service, NULL, GF_OK); return GF_OK;}static GF_Descriptor *SAF_GetServiceDesc(GF_InputService *plug, u32 expect_type, const char *sub_url){ u32 i=0; SAFChannel *root; SAFIn *read = (SAFIn *)plug->priv; GF_ObjectDescriptor *od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_IOD_TAG); od->objectDescriptorID = 1; while ( (root = (SAFChannel *)gf_list_enum(read->channels, &i))) { if (root->esd && (root->esd->decoderConfig->streamType==GF_STREAM_SCENE)) break; } if (!root) return NULL; /*inline scene*/ gf_list_add(od->ESDescriptors, root->esd); root->esd = NULL; return (GF_Descriptor *) od;}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_term_on_connect(read->service, channel, e); return e;}static GF_Err SAF_DisconnectChannel(GF_InputService *plug, LPNETCHANNEL channel){ SAFChannel *ch; SAFIn *read = (SAFIn *)plug->priv; GF_Err e = GF_STREAM_NOT_FOUND; ch = saf_get_channel(read, 0, channel); if (ch) { gf_list_del_item(read->channels, ch); if (ch->esd) gf_odf_desc_del((GF_Descriptor*)ch->esd); free(ch); e = GF_OK; } gf_term_on_disconnect(read->service, channel, e); return GF_OK;}static GF_Err SAF_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com){ SAFIn *read = (SAFIn *)plug->priv; if (!com->base.on_channel) return GF_NOT_SUPPORTED; switch (com->command_type) { case GF_NET_CHAN_SET_PULL: return GF_NOT_SUPPORTED; case GF_NET_CHAN_INTERACTIVE: return GF_OK; case GF_NET_CHAN_BUFFER: return GF_OK; case GF_NET_CHAN_DURATION: com->duration.duration = read->duration; return GF_OK; case GF_NET_CHAN_PLAY: if (!read->nb_playing) { read->start_range = (u32) (com->play.start_range*1000); read->end_range = (u32) (com->play.end_range*1000); /*start demuxer*/ if ((read->saf_type == SAF_FILE_LOCAL) && (read->run_state!=1)) { gf_th_run(read->th, SAF_Run, read); } } read->nb_playing++; return GF_OK; case GF_NET_CHAN_STOP: assert(read->nb_playing); read->nb_playing--; /*stop demuxer*/ if (!read->nb_playing && (read->run_state==1)) { read->run_state=0; while (read->run_state!=2) gf_sleep(2); } return GF_OK; default: return GF_OK; }}GF_InputService *NewSAFReader(){ SAFIn *reader; GF_InputService *plug; GF_SAFEALLOC(plug, GF_InputService); GF_REGISTER_MODULE_INTERFACE(plug, GF_NET_CLIENT_INTERFACE, "GPAC SAF Reader", "gpac distribution") plug->CanHandleURL = SAF_CanHandleURL; plug->ConnectService = SAF_ConnectService; plug->CloseService = SAF_CloseService; plug->GetServiceDescriptor = SAF_GetServiceDesc; plug->ConnectChannel = SAF_ConnectChannel; plug->DisconnectChannel = SAF_DisconnectChannel; plug->ServiceCommand = SAF_ServiceCommand; GF_SAFEALLOC(reader, SAFIn); reader->channels = gf_list_new(); plug->priv = reader; return plug;}void DeleteSAFReader(void *ifce){ GF_InputService *plug = (GF_InputService *) ifce; SAFIn *read = (SAFIn *)plug->priv; while (gf_list_count(read->channels)) { SAFChannel *ch = (SAFChannel *)gf_list_last(read->channels); gf_list_rem_last(read->channels); if (ch->esd) gf_odf_desc_del((GF_Descriptor *) ch->esd); free(ch); } gf_list_del(read->channels); if (read->saf_data) free(read->saf_data); free(read); free(plug);}GF_EXPORTBool QueryInterface(u32 InterfaceType){ switch (InterfaceType) { case GF_NET_CLIENT_INTERFACE: return 1; default: return 0; }}GF_EXPORTGF_BaseInterface *LoadInterface(u32 InterfaceType){ switch (InterfaceType) { case GF_NET_CLIENT_INTERFACE: return (GF_BaseInterface *) NewSAFReader(); default: return NULL; }}GF_EXPORTvoid ShutdownInterface(GF_BaseInterface *ifce){ switch (ifce->InterfaceType) { case GF_NET_CLIENT_INTERFACE: DeleteSAFReader(ifce); break; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -