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

📄 read.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 2 页
字号:
			if (expect_type!=GF_MEDIA_OBJECT_VIDEO) {				gf_odf_desc_del((GF_Descriptor*) iod);				return isor_emulate_iod(read);			}			break;		case GF_STREAM_AUDIO:			/*we need a fake scene graph*/			if (expect_type!=GF_MEDIA_OBJECT_AUDIO) {				gf_odf_desc_del((GF_Descriptor*) iod);				return isor_emulate_iod(read);			}			break;		default:			gf_odf_desc_del((GF_Descriptor*) iod);			return NULL;		}	}	/*check IOD is not badly formed (eg mixing audio, video or text streams)*/	nb_st = 0;	for (i=0; i<count; i++) {		esd = (GF_ESD *)gf_list_get(iod->ESDescriptors, i);		switch (esd->decoderConfig->streamType) {		case GF_STREAM_VISUAL: nb_st |= 1; break;		case GF_STREAM_AUDIO: nb_st |= 2; break;		case GF_STREAM_TEXT: nb_st |= 4; break;		}	}	if ( (nb_st & 1) + (nb_st & 2) + (nb_st & 4) > 1) {		gf_odf_desc_del((GF_Descriptor*) iod);		return isor_emulate_iod(read);	}	isor_emulate_chapters(read->mov, iod);	return (GF_Descriptor *) iod;}GF_Err ISOR_ConnectChannel(GF_InputService *plug, LPNETCHANNEL channel, const char *url, Bool upstream){	u32 ESID;	ISOMChannel *ch;	GF_NetworkCommand com;	u32 track;	Bool is_esd_url;	GF_Err e;	ISOMReader *read;	if (!plug || !plug->priv) return GF_SERVICE_ERROR;	read = (ISOMReader *) plug->priv;	track = 0;	ch = NULL;	is_esd_url = 0;	e = GF_OK;	if (upstream) {		e = GF_ISOM_INVALID_FILE;		goto exit;	}	if (!read->mov) return GF_SERVICE_ERROR;	if (strstr(url, "ES_ID")) {		sscanf(url, "ES_ID=%d", &ESID);	} else {		/*handle url like mypath/myfile.mp4#trackID*/		char *track_id = strrchr(url, '.');		if (track_id) {			track_id = strchr(url, '#');			if (track_id) track_id ++;		}		is_esd_url = 1;		ESID = 0;		/*if only one track ok*/		if (gf_isom_get_track_count(read->mov)==1) ESID = gf_isom_get_track_id(read->mov, 1);		else if (track_id) {			ESID = atoi(track_id);			track = gf_isom_get_track_by_id(read->mov, (u32) ESID);			if (!track) ESID = 0;		}	}	if (!ESID) {		e = GF_NOT_SUPPORTED;		goto exit;	}	/*a channel cannot be open twice, it has to be closed before - NOTE a track is NOT a channel and the user can open	several times the same track as long as a dedicated channel is used*/	ch = isor_get_channel(read, channel);	if (ch) {		e = GF_SERVICE_ERROR;		goto exit;	}	track = gf_isom_get_track_by_id(read->mov, (u32) ESID);	if (!track) {		e = GF_STREAM_NOT_FOUND;		goto exit;	}	GF_SAFEALLOC(ch, ISOMChannel);	ch->owner = read;	ch->channel = channel;	gf_list_add(read->channels, ch);	ch->track = track;	switch (gf_isom_get_media_type(ch->owner->mov, ch->track)) {	case GF_ISOM_MEDIA_OCR:		ch->streamType = GF_STREAM_OCR;		break;	case GF_ISOM_MEDIA_SCENE:		ch->streamType = GF_STREAM_SCENE;		break;	}	ch->has_edit_list = gf_isom_get_edit_segment_count(ch->owner->mov, ch->track) ? 1 : 0;	ch->time_scale = gf_isom_get_media_timescale(ch->owner->mov, ch->track);exit:	gf_term_on_connect(read->service, channel, e);	/*if esd url reconfig SL layer*/	if (!e && is_esd_url) {		GF_ESD *esd;		memset(&com, 0, sizeof(GF_NetworkCommand));		com.base.on_channel = channel;		com.command_type = GF_NET_CHAN_RECONFIG;		esd = gf_isom_get_esd(read->mov, ch->track, 1);		if (esd) {			memcpy(&com.cfg.sl_config, esd->slConfig, sizeof(GF_SLConfig));			gf_odf_desc_del((GF_Descriptor *)esd);		} else {			com.cfg.sl_config.tag = GF_ODF_SLC_TAG;			com.cfg.sl_config.timestampLength = 32;			com.cfg.sl_config.timestampResolution = ch->time_scale;			com.cfg.sl_config.useRandomAccessPointFlag = 1;		}		gf_term_on_command(read->service, &com, GF_OK);	}	if (!e && track && gf_isom_is_track_encrypted(read->mov, track)) {		memset(&com, 0, sizeof(GF_NetworkCommand));		com.base.on_channel = channel;		com.command_type = GF_NET_CHAN_DRM_CFG;		ch->is_encrypted = 1;		if (gf_isom_is_ismacryp_media(read->mov, track, 1)) {			gf_isom_get_ismacryp_info(read->mov, track, 1, NULL, &com.drm_cfg.scheme_type, &com.drm_cfg.scheme_version, &com.drm_cfg.scheme_uri, &com.drm_cfg.kms_uri, NULL, NULL, NULL);			gf_term_on_command(read->service, &com, GF_OK);		} else if (gf_isom_is_omadrm_media(read->mov, track, 1)) {			gf_isom_get_omadrm_info(read->mov, track, 1, NULL, &com.drm_cfg.scheme_type, &com.drm_cfg.scheme_version, &com.drm_cfg.contentID, &com.drm_cfg.kms_uri, &com.drm_cfg.oma_drm_textual_headers, &com.drm_cfg.oma_drm_textual_headers_len, NULL, &com.drm_cfg.oma_drm_crypt_type, NULL, NULL, NULL);			gf_media_get_file_hash(gf_isom_get_filename(read->mov), com.drm_cfg.hash);			gf_term_on_command(read->service, &com, GF_OK);		}	}	return e;}GF_Err ISOR_DisconnectChannel(GF_InputService *plug, LPNETCHANNEL channel){	ISOMChannel *ch;	GF_Err e;	ISOMReader *read;	if (!plug || !plug->priv) return GF_SERVICE_ERROR;	read = (ISOMReader *) plug->priv;	if (!read->mov) return GF_SERVICE_ERROR;	e = GF_OK;	ch = isor_get_channel(read, channel);	assert(ch);	if (!ch) {		e = GF_STREAM_NOT_FOUND;		goto exit;	}	/*signal the service is broken but still process the delete*/	isor_delete_channel(read, ch);	assert(!isor_get_channel(read, channel));exit:	gf_term_on_disconnect(read->service, channel, e);	return e;}GF_Err ISOR_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){	ISOMChannel *ch;	ISOMReader *read;	if (!plug || !plug->priv) return GF_SERVICE_ERROR;	/*cannot read native SL-PDUs*/	if (!out_sl_hdr) return GF_NOT_SUPPORTED;	read = (ISOMReader *) plug->priv;	if (!read->mov) return GF_SERVICE_ERROR;	*out_data_ptr = NULL;	*out_data_size = 0;	*sl_compressed = 0;	*out_reception_status = GF_OK;	ch = isor_get_channel(read, channel);	if (!ch) return GF_STREAM_NOT_FOUND;	if (!ch->is_playing) return GF_OK;	*is_new_data = 0;	if (!ch->sample) {		/*get sample*/		isor_reader_get_sample(ch);		*is_new_data = 1;	}	if (ch->sample) {		*out_data_ptr = ch->sample->data;		*out_data_size = ch->sample->dataLength;		*out_sl_hdr = ch->current_slh;	}	*out_reception_status = ch->last_state;	return GF_OK;}GF_Err ISOR_ChannelReleaseSLP(GF_InputService *plug, LPNETCHANNEL channel){	ISOMChannel *ch;	ISOMReader *read;	if (!plug || !plug->priv) return GF_SERVICE_ERROR;	read = (ISOMReader *) plug->priv;	if (!read->mov) return GF_SERVICE_ERROR;	ch = isor_get_channel(read, channel);	if (!ch) return GF_STREAM_NOT_FOUND;	if (!ch->is_playing) return GF_SERVICE_ERROR;	if (ch->sample) {		isor_reader_release_sample(ch);		/*release sample*/	}	return GF_OK;}static u64 check_round(ISOMChannel *ch, u64 val_ts, Double val_range, Bool make_greater){	Double round_check = (Double) (s64) val_ts;	round_check /= ch->time_scale;//	if (round_check != val_range) val_ts += make_greater ? 1 : -1;	return val_ts;}GF_Err ISOR_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com){	Double track_dur, media_dur;	ISOMChannel *ch;	ISOMReader *read;	if (!plug || !plug->priv || !com) return GF_SERVICE_ERROR;	read = (ISOMReader *) plug->priv;	if (com->command_type==GF_NET_SERVICE_INFO) {		u32 tag_len;		const char *tag;		if (gf_isom_apple_get_tag(read->mov, GF_ISOM_ITUNE_NAME, &tag, &tag_len)==GF_OK) com->info.name = tag;		if (gf_isom_apple_get_tag(read->mov, GF_ISOM_ITUNE_ARTIST, &tag, &tag_len)==GF_OK) com->info.artist = tag;		if (gf_isom_apple_get_tag(read->mov, GF_ISOM_ITUNE_ALBUM, &tag, &tag_len)==GF_OK) com->info.album = tag;		if (gf_isom_apple_get_tag(read->mov, GF_ISOM_ITUNE_COMMENT, &tag, &tag_len)==GF_OK) com->info.comment = tag;		if (gf_isom_apple_get_tag(read->mov, GF_ISOM_ITUNE_TRACK, &tag, &tag_len)==GF_OK) {			com->info.track_info = (((tag[2]<<8)|tag[3]) << 16) | ((tag[4]<<8)|tag[5]);		}		if (gf_isom_apple_get_tag(read->mov, GF_ISOM_ITUNE_COMPOSER, &tag, &tag_len)==GF_OK) com->info.composer = tag;		if (gf_isom_apple_get_tag(read->mov, GF_ISOM_ITUNE_WRITER, &tag, &tag_len)==GF_OK) com->info.writer = tag;		if (gf_isom_apple_get_tag(read->mov, GF_ISOM_ITUNE_GENRE, &tag, &tag_len)==GF_OK) {			if (tag[0]) {				com->info.genre = 0;			} else {				com->info.genre = (tag[0]<<8) | tag[1];			}		}		return GF_OK;	}	if (com->command_type==GF_NET_SERVICE_HAS_AUDIO) {		u32 i, count;		count = gf_isom_get_track_count(read->mov);		for (i=0; i<count; i++) {			if (gf_isom_get_media_type(read->mov, i+1) == GF_ISOM_MEDIA_AUDIO) return GF_OK;		}		return GF_NOT_SUPPORTED;	}	if (!com->base.on_channel) return GF_NOT_SUPPORTED;	ch = isor_get_channel(read, com->base.on_channel);	if (!ch) return GF_STREAM_NOT_FOUND;	switch (com->command_type) {	case GF_NET_CHAN_SET_PADDING:		if (!ch->track) return GF_OK;		gf_isom_set_sample_padding(read->mov, ch->track, com->pad.padding_bytes);		return GF_OK;	case GF_NET_CHAN_SET_PULL:		ch->is_pulling = 1;		return GF_OK;	case GF_NET_CHAN_INTERACTIVE:		return GF_OK;	case GF_NET_CHAN_BUFFER:		com->buffer.max = com->buffer.min = 0;		return GF_OK;	case GF_NET_CHAN_DURATION:		if (!ch->track) {			com->duration.duration = 0;			return GF_OK;		}		ch->duration = gf_isom_get_track_duration(read->mov, ch->track);		track_dur = (Double) (s64) ch->duration;		track_dur /= read->time_scale;		if (gf_isom_get_edit_segment_count(read->mov, ch->track)) {			com->duration.duration = (Double) track_dur;			ch->duration = (u32) (track_dur * ch->time_scale);		} else {			/*some file indicate a wrong TrackDuration, get the longest*/			ch->duration = gf_isom_get_media_duration(read->mov, ch->track);			media_dur = (Double) (s64) ch->duration;			media_dur /= ch->time_scale;			com->duration.duration = MAX(track_dur, media_dur);		}		return GF_OK;	case GF_NET_CHAN_PLAY:		if (!ch->is_pulling) return GF_NOT_SUPPORTED;		assert(!ch->is_playing);		isor_reset_reader(ch);		ch->speed = com->play.speed;		ch->start = ch->end = 0;		if (com->play.speed>0) {			if (com->play.start_range>=0) {				ch->start = (u64) (s64) (com->play.start_range * ch->time_scale);				ch->start = check_round(ch, ch->start, com->play.start_range, 1);			}			if (com->play.end_range >= com->play.start_range) {				ch->end = (u64) (s64) (com->play.end_range*ch->time_scale);				ch->end = check_round(ch, ch->end, com->play.end_range, 0);			}		} else if (com->play.speed<0) {			if (com->play.end_range>=com->play.start_range) ch->start = (u64) (s64) (com->play.start_range * ch->time_scale);			if (com->play.end_range >= 0) ch->end = (u64) (s64) (com->play.end_range*ch->time_scale);		}		ch->is_playing = 1;		GF_LOG(GF_LOG_DEBUG, GF_LOG_SERVICE, ("[IsoMedia] Starting channel playback "LLD" to "LLD" (%g to %g)\n", ch->start, ch->end, com->play.start_range, com->play.end_range));		return GF_OK;	case GF_NET_CHAN_STOP:		isor_reset_reader(ch);		return GF_OK;	/*nothing to do on MP4 for channel config*/	case GF_NET_CHAN_CONFIG:		return GF_OK;	case GF_NET_CHAN_GET_DSI:	{		/*it may happen that there are conflicting config when using ESD URLs...*/		GF_DecoderConfig *dcd = gf_isom_get_decoder_config(read->mov, ch->track, 1);		com->get_dsi.dsi = NULL;		com->get_dsi.dsi_len = 0;		if (dcd) {			if (dcd->decoderSpecificInfo) {				com->get_dsi.dsi = dcd->decoderSpecificInfo->data;				com->get_dsi.dsi_len = dcd->decoderSpecificInfo->dataLength;				dcd->decoderSpecificInfo->data = NULL;			}			gf_odf_desc_del((GF_Descriptor *) dcd);		}	}		return GF_OK;	}	return GF_NOT_SUPPORTED;}static Bool ISOR_CanHandleURLInService(GF_InputService *plug, const char *url){	char szURL[2048], *sep;	ISOMReader *read = (ISOMReader *)plug->priv;	const char *this_url = gf_term_get_service_url(read->service);	if (!this_url || !url) return 0;	if (!strcmp(this_url, url)) return 1;	strcpy(szURL, this_url);	sep = strrchr(szURL, '#');	if (sep) sep[0] = 0;	/*direct addressing in service*/	if (url[0] == '#') return 1;	if (strnicmp(szURL, url, sizeof(char)*strlen(szURL))) return 0;	return 1;}GF_InputService *isor_client_load(){	ISOMReader *reader;	GF_InputService *plug;	GF_SAFEALLOC(plug, GF_InputService);	GF_REGISTER_MODULE_INTERFACE(plug, GF_NET_CLIENT_INTERFACE, "GPAC IsoMedia Reader", "gpac distribution")	plug->CanHandleURL = ISOR_CanHandleURL;	plug->ConnectService = ISOR_ConnectService;	plug->CloseService = ISOR_CloseService;	plug->GetServiceDescriptor = ISOR_GetServiceDesc;	plug->ConnectChannel = ISOR_ConnectChannel;	plug->DisconnectChannel = ISOR_DisconnectChannel;	plug->ServiceCommand = ISOR_ServiceCommand;	plug->CanHandleURLInService = ISOR_CanHandleURLInService;	/*we do support pull mode*/	plug->ChannelGetSLP = ISOR_ChannelGetSLP;	plug->ChannelReleaseSLP = ISOR_ChannelReleaseSLP;	GF_SAFEALLOC(reader, ISOMReader);	reader->channels = gf_list_new();	plug->priv = reader;	return plug;}void isor_client_del(GF_BaseInterface *bi){	GF_InputService *plug = (GF_InputService *) bi;	ISOMReader *read = (ISOMReader *)plug->priv;	gf_list_del(read->channels);	free(read);	free(bi);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -