⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mp3_in.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 2 页
字号:
	/*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 + -