📄 mp3_in.c
字号:
/*remote fetch*/ read->is_remote = !mp3_is_local(szURL); if (read->is_remote) { mp3_download_file(plug, (char *) szURL); return GF_OK; } reply = GF_OK; read->stream = fopen(szURL, "rb"); if (!read->stream) { reply = GF_URL_ERROR; } else if (!MP3_ConfigureFromFile(read)) { fclose(read->stream); read->stream = NULL; reply = GF_NOT_SUPPORTED; } gf_term_on_connect(serv, NULL, reply); if (!reply) mp3_setup_object(read); return GF_OK;}static GF_Err MP3_CloseService(GF_InputService *plug){ MP3Reader *read = plug->priv; if (read->stream) fclose(read->stream); read->stream = NULL; if (read->dnload) gf_term_download_del(read->dnload); read->dnload = NULL; if (read->data) free(read->data); read->data = NULL; gf_term_on_disconnect(read->service, NULL, GF_OK); return GF_OK;}static GF_Descriptor *MP3_GetServiceDesc(GF_InputService *plug, u32 expect_type, const char *sub_url){ MP3Reader *read = plug->priv; /*since we don't handle multitrack in mp3, we don't need to check sub_url, only use expected type*/ /*audio object*/ if (expect_type==GF_MEDIA_OBJECT_AUDIO) { GF_ObjectDescriptor *od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG); GF_ESD *esd = MP3_GetESD(read); od->objectDescriptorID = 1; gf_list_add(od->ESDescriptors, esd); return (GF_Descriptor *) od; } read->is_inline = 1; return NULL;}static GF_Err MP3_ConnectChannel(GF_InputService *plug, LPNETCHANNEL channel, const char *url, Bool upstream){ u32 ES_ID; GF_Err e; MP3Reader *read = plug->priv; e = GF_SERVICE_ERROR; if (read->ch==channel) goto exit; e = GF_STREAM_NOT_FOUND; if (strstr(url, "ES_ID")) { sscanf(url, "ES_ID=%d", &ES_ID); } /*URL setup*/ else if (!read->ch && MP3_CanHandleURL(plug, url)) ES_ID = 1; if (ES_ID==1) { read->ch = channel; e = GF_OK; }exit: gf_term_on_connect(read->service, channel, e); return e;}static GF_Err MP3_DisconnectChannel(GF_InputService *plug, LPNETCHANNEL channel){ MP3Reader *read = plug->priv; GF_Err e = GF_STREAM_NOT_FOUND; if (read->ch == channel) { read->ch = NULL; if (read->data) free(read->data); read->data = NULL; e = GF_OK; } gf_term_on_disconnect(read->service, channel, e); return GF_OK;}static GF_Err MP3_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com){ MP3Reader *read = plug->priv; if (com->base.command_type==GF_NET_SERVICE_INFO) { com->info.name = read->icy_track_name ? read->icy_track_name : read->icy_name; com->info.comment = read->icy_genre; return GF_OK; } if (!com->base.on_channel) { /*if live session we may cache*/ if (read->is_live && (com->command_type==GF_NET_IS_CACHABLE)) return GF_OK; return GF_NOT_SUPPORTED; } switch (com->command_type) { case GF_NET_CHAN_SET_PULL: if ((read->ch == com->base.on_channel) && read->is_live) return GF_NOT_SUPPORTED; return GF_OK; case GF_NET_CHAN_INTERACTIVE: if ((read->ch == com->base.on_channel) && read->is_live) return GF_NOT_SUPPORTED; return GF_OK; case GF_NET_CHAN_BUFFER: if ((read->ch == com->base.on_channel) && read->is_live) { if (com->buffer.max<2000) com->buffer.max = 2000; com->buffer.min = com->buffer.max/2; } return GF_OK; case GF_NET_CHAN_SET_PADDING: read->pad_bytes = com->pad.padding_bytes; return GF_OK; case GF_NET_CHAN_DURATION: com->duration.duration = read->duration; com->duration.duration /= read->sample_rate; return GF_OK; case GF_NET_CHAN_PLAY: read->start_range = com->play.start_range; read->end_range = com->play.end_range; read->current_time = 0; if (read->stream) fseek(read->stream, 0, SEEK_SET); if (read->ch == com->base.on_channel) { read->done = 0; /*PLAY after complete download, estimate duration*/ if (!read->is_remote && !read->duration) { MP3_ConfigureFromFile(read); if (read->duration) { GF_NetworkCommand rcfg; rcfg.base.on_channel = read->ch; rcfg.base.command_type = GF_NET_CHAN_DURATION; rcfg.duration.duration = read->duration; rcfg.duration.duration /= read->sample_rate; gf_term_on_command(read->service, &rcfg, GF_OK); } } } return GF_OK; case GF_NET_CHAN_STOP: return GF_OK; default: return GF_OK; }}static GF_Err MP3_ChannelGetSLP(GF_InputService *plug, LPNETCHANNEL channel, char **out_data_ptr, u32 *out_data_size, GF_SLHeader *out_sl_hdr, Bool *sl_compressed, GF_Err *out_reception_status, Bool *is_new_data){ u32 pos, hdr, start_from; MP3Reader *read = plug->priv; if (read->ch != channel) return GF_STREAM_NOT_FOUND; *out_reception_status = GF_OK; *sl_compressed = 0; *is_new_data = 0; memset(&read->sl_hdr, 0, sizeof(GF_SLHeader)); read->sl_hdr.randomAccessPointFlag = 1; read->sl_hdr.compositionTimeStampFlag = 1; /*fetching es data*/ if (read->done) { *out_reception_status = GF_EOS; return GF_OK; } if (!read->data) { if (!read->stream) { *out_data_ptr = NULL; *out_data_size = 0; return GF_OK; } *is_new_data = 1; pos = ftell(read->stream); hdr = gf_mp3_get_next_header(read->stream); if (!hdr) { if (!read->dnload) { *out_reception_status = GF_EOS; read->done = 1; } else { fseek(read->stream, pos, SEEK_SET); *out_reception_status = GF_OK; } return GF_OK; } read->data_size = gf_mp3_frame_size(hdr); if (!read->data_size) { *out_reception_status = GF_EOS; read->done = 1; return GF_OK; } /*we're seeking*/ if (read->start_range && read->duration) { read->current_time = 0; start_from = (u32) (read->start_range * read->sample_rate); fseek(read->stream, 0, SEEK_SET); while (read->current_time<start_from) { hdr = gf_mp3_get_next_header(read->stream); if (!hdr) { read->start_range = 0; *out_reception_status = GF_SERVICE_ERROR; return GF_OK; } read->current_time += gf_mp3_window_size(hdr); read->data_size = gf_mp3_frame_size(hdr); fseek(read->stream, read->data_size-4, SEEK_CUR); } read->start_range = 0; GF_LOG(GF_LOG_DEBUG, GF_LOG_SERVICE, ("[MP3Demux] Seeking to frame size %d - TS %d - file pos %d\n", read->data_size, read->current_time, ftell(read->stream))); } read->sl_hdr.compositionTimeStamp = read->current_time; GF_LOG(GF_LOG_DEBUG, GF_LOG_SERVICE, ("[MP3Demux] Found new frame size %d - TS %d - file pos %d\n", read->data_size, read->current_time, ftell(read->stream))); read->current_time += gf_mp3_window_size(hdr); read->data = malloc(sizeof(char) * (read->data_size+read->pad_bytes)); read->data[0] = (hdr >> 24) & 0xFF; read->data[1] = (hdr >> 16) & 0xFF; read->data[2] = (hdr >> 8) & 0xFF; read->data[3] = (hdr ) & 0xFF; /*end of file*/ if (fread(&read->data[4], 1, read->data_size - 4, read->stream) != read->data_size-4) { free(read->data); read->data = NULL; if (read->is_remote) { fseek(read->stream, pos, SEEK_SET); *out_reception_status = GF_OK; } else { *out_reception_status = GF_EOS; } return GF_OK; } if (read->pad_bytes) memset(read->data + read->data_size, 0, sizeof(char) * read->pad_bytes); } *out_sl_hdr = read->sl_hdr; *out_data_ptr = read->data; *out_data_size = read->data_size; return GF_OK;}static GF_Err MP3_ChannelReleaseSLP(GF_InputService *plug, LPNETCHANNEL channel){ MP3Reader *read = plug->priv; if (read->ch == channel) { if (!read->data) return GF_BAD_PARAM; free(read->data); read->data = NULL; return GF_OK; } return GF_OK;}GF_InputService *MP3_Load(){ MP3Reader *reader; GF_InputService *plug = malloc(sizeof(GF_InputService)); memset(plug, 0, sizeof(GF_InputService)); GF_REGISTER_MODULE_INTERFACE(plug, GF_NET_CLIENT_INTERFACE, "GPAC MP3 Reader", "gpac distribution") plug->CanHandleURL = MP3_CanHandleURL; plug->ConnectService = MP3_ConnectService; plug->CloseService = MP3_CloseService; plug->GetServiceDescriptor = MP3_GetServiceDesc; plug->ConnectChannel = MP3_ConnectChannel; plug->DisconnectChannel = MP3_DisconnectChannel; plug->ServiceCommand = MP3_ServiceCommand; /*we do support pull mode*/ plug->ChannelGetSLP = MP3_ChannelGetSLP; plug->ChannelReleaseSLP = MP3_ChannelReleaseSLP; reader = malloc(sizeof(MP3Reader)); memset(reader, 0, sizeof(MP3Reader)); plug->priv = reader; return plug;}void MP3_Delete(void *ifce){ GF_InputService *plug = (GF_InputService *) ifce; MP3Reader *read = plug->priv; free(read); free(plug);}#ifdef GPAC_HAS_MADGF_BaseDecoder *NewMADDec();void DeleteMADDec(GF_BaseDecoder *ifcg);#endifGF_EXPORTBool QueryInterface(u32 InterfaceType) { if (InterfaceType == GF_NET_CLIENT_INTERFACE) return 1;#ifdef GPAC_HAS_MAD if (InterfaceType == GF_MEDIA_DECODER_INTERFACE) return 1;#endif return 0;}GF_EXPORTGF_BaseInterface *LoadInterface(u32 InterfaceType) { if (InterfaceType == GF_NET_CLIENT_INTERFACE) return (GF_BaseInterface *)MP3_Load();#ifdef GPAC_HAS_MAD if (InterfaceType == GF_MEDIA_DECODER_INTERFACE) return (GF_BaseInterface *)NewMADDec();#endif return NULL;}GF_EXPORTvoid ShutdownInterface(GF_BaseInterface *ifce){ switch (ifce->InterfaceType) {#ifdef GPAC_HAS_MAD case GF_MEDIA_DECODER_INTERFACE: DeleteMADDec((GF_BaseDecoder *) ifce); break;#endif case GF_NET_CLIENT_INTERFACE: MP3_Delete(ifce); break; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -