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

📄 object_manager.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 4 页
字号:
		setting up the channel...*/		cs = (GF_ChannelSetup*)malloc(sizeof(GF_ChannelSetup));		cs->ch = ch;		cs->dec = dec;		/*HACK: special case when OD resources are statically described in the ESD itself (ISMA streaming)*/		if ((ch->esd->decoderConfig->streamType==GF_STREAM_OD) && strstr(ch->esd->URLString, "data:application/mpeg4-od-au;") ) 			dec->flags |= GF_ESM_CODEC_IS_STATIC_OD;		gf_term_lock_net(odm->term, 1);		gf_list_add(odm->term->channels_pending, cs);		e = gf_term_connect_remote_channel(odm->term, ch, esd->URLString);		if (e) {			s32 i = gf_list_find(odm->term->channels_pending, cs);			if (i>=0) {				gf_list_rem(odm->term->channels_pending, (u32) i);				free(cs);				odm->pending_channels--;				ODM_CheckChannelService(ch);				gf_es_del(ch);			}		}		gf_term_lock_net(odm->term, 0);		if (ch->service->owner) {			gf_list_del_item(odm->term->channels_pending, cs);			free(cs);			return gf_odm_post_es_setup(ch, dec, GF_OK);		}		return e;	}	/*regular setup*/	return gf_odm_post_es_setup(ch, dec, GF_OK);}GF_Err gf_odm_post_es_setup(GF_Channel *ch, GF_Codec *dec, GF_Err had_err){	char szURL[2048];	GF_Err e;	GF_NetworkCommand com;	e = had_err;	if (e) {		ch->odm->pending_channels--;		goto err_exit;	}	/*insert channel*/	if (dec) gf_list_insert(ch->odm->channels, ch, 0);	if (ch->service) {		ch->es_state = GF_ESM_ES_WAIT_FOR_ACK;		if (ch->esd->URLString) {			strcpy(szURL, ch->esd->URLString);		} else {			sprintf(szURL, "ES_ID=%d", ch->esd->ESID);		}		/*connect before setup: this is needed in case the decoder cfg is wrong, we may need to get it from		network config...*/		e = ch->service->ifce->ConnectChannel(ch->service->ifce, ch, szURL, ch->esd->decoderConfig->upstream);		/*special case (not really specified in specs ...): if the stream is not found and is an Interaction 		one (ie, used by an InputSensor), consider this means the stream shall be generated by the IS device*/		if ((e==GF_STREAM_NOT_FOUND) && (ch->esd->decoderConfig->streamType==GF_STREAM_INTERACT)) e = GF_OK;	} else {		ch->es_state = GF_ESM_ES_CONNECTED;		ch->odm->pending_channels--;	}	if (e) {		if (dec) gf_list_rem(ch->odm->channels, 0);		goto err_exit;	}	/*add to decoder*/	if (dec) {		e = gf_codec_add_channel(dec, ch);		if (e) {			switch (ch->esd->decoderConfig->streamType) {			case GF_STREAM_VISUAL:				gf_term_message(ch->odm->term, ch->service->url, "Video Setup failed", e);				break;			case GF_STREAM_AUDIO:				gf_term_message(ch->odm->term, ch->service->url, "Audio Setup failed", e);				break;			}			gf_list_rem(ch->odm->channels, 0);			/*disconnect*/			ch->service->ifce->DisconnectChannel(ch->service->ifce, ch); 			if (ch->esd->URLString) ch->service->nb_ch_users--;			goto err_exit;		}	}	/*in case a channel is inserted in a running OD, open and play if not in queue*/	if ( (ch->odm->state==GF_ODM_STATE_PLAY) 		/*HACK: special case when OD resources are statically described in the ESD itself (ISMA streaming)*///		|| 	(dec && (dec->flags & GF_ESM_CODEC_IS_STATIC_OD)) 	) {		gf_term_lock_net(ch->odm->term, 1);		gf_list_del_item(ch->odm->term->media_queue, ch->odm);		gf_es_start(ch);		com.command_type = GF_NET_CHAN_PLAY;		com.base.on_channel = ch;		com.play.speed = FIX2FLT(ch->clock->speed);		com.play.start_range = gf_clock_time(ch->clock);		com.play.start_range /= 1000;		com.play.end_range = -1.0;		gf_term_service_command(ch->service, &com);		if (dec && (dec->Status!=GF_ESM_CODEC_PLAY)) gf_term_start_codec(dec);		gf_term_lock_net(ch->odm->term, 0);	}	return GF_OK;err_exit:	ODM_CheckChannelService(ch);	gf_es_del(ch);	return e;}/*confirmation of channel delete from net*/void ODM_DeleteChannel(GF_ObjectManager *odm, GF_Channel *ch){	u32 i, count, ch_pos;	GF_Channel *ch2;	GF_Clock *ck;	if (!ch) return;	//find a clock with this stream ES_ID	ck = gf_clock_find(odm->net_service->Clocks, ch->esd->ESID, 0);	count = gf_list_count(odm->channels);	ch_pos = count+1;	for (i=0; i<count; i++) {		ch2 = (GF_Channel*)gf_list_get(odm->channels, i);		if (ch2 == ch) {			ch_pos = i;				if (ck) continue;			break;		}		//note that when a stream is added, we need to update clocks info ...		if (ck && ch->clock && (ch2->clock->clockID == ck->clockID)) gf_es_stop(ch2);	}	/*remove channel*/	if (ch_pos != count+1) gf_list_rem(odm->channels, ch_pos);	/*remove from the codec*/	count = 0;	if (!count && odm->codec) 		count = gf_codec_remove_channel(odm->codec, ch);	if (!count && odm->ocr_codec)		count = gf_codec_remove_channel(odm->ocr_codec, ch);	if (!count && odm->oci_codec)		count = gf_codec_remove_channel(odm->oci_codec, ch);	if (!count && odm->subscene) {		if (odm->subscene->scene_codec) count = gf_codec_remove_channel(odm->subscene->scene_codec, ch);		if (!count) count = gf_codec_remove_channel(odm->subscene->od_codec, ch);	}	assert(count);		if (ch->service) {		ch->service->ifce->DisconnectChannel(ch->service->ifce, ch); 		if (ch->esd->URLString) ch->service->nb_ch_users--;		ODM_CheckChannelService(ch);	}	//and delete	gf_es_del(ch);}GF_EXPORTvoid gf_odm_remove_es(GF_ObjectManager *odm, u16 ES_ID){	GF_ESD *esd;	GF_Channel *ch;	u32 i = 0;	while ((esd = (GF_ESD *)gf_list_enum(odm->OD->ESDescriptors, &i)) ) {		if (esd->ESID==ES_ID) goto esd_found;	}	return;esd_found:	/*remove esd*/	gf_list_rem(odm->OD->ESDescriptors, i-1);	/*locate channel*/	ch = NULL;	i=0;	while ((ch = (GF_Channel*)gf_list_enum(odm->channels, &i)) ) {		if (ch->esd->ESID == ES_ID) break;		ch = NULL;	}	/*destroy ESD*/	gf_odf_desc_del((GF_Descriptor *) esd);	/*remove channel*/	if (ch) ODM_DeleteChannel(odm, ch);}/*this is the tricky part: make sure the net is locked before doing anything since an async service reply could destroy the object we're queuing for play*/void gf_odm_start(GF_ObjectManager *odm){	gf_term_lock_net(odm->term, 1);	/*only if not open & ready (not waiting for ACK on channel setup)*/	if (!odm->state && !odm->pending_channels) {		GF_Channel *ch;		u32 i = 0;		odm->state = GF_ODM_STATE_PLAY;		/*look for a given segment name to play*/		if (odm->subscene) {			char *url, *frag;			assert(odm->subscene->root_od==odm);			url = (odm->mo && odm->mo->URLs.count) ? odm->mo->URLs.vals[0].url : odm->net_service->url;			frag = strrchr(url, '#');			if (frag) {				GF_Segment *seg = gf_odm_find_segment(odm, frag+1);				if (seg) {					odm->media_start_time = (u64) ((s64) seg->startTime*1000);					odm->media_stop_time =  (u64) ((s64) (seg->startTime + seg->Duration)*1000);				}			}		}		/*start all channels and postpone play - this assures that all channels of a multiplexed are setup		before one starts playing*/		while ( (ch = (GF_Channel*)gf_list_enum(odm->channels, &i)) ) {			gf_es_start(ch);			GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("[ODM%d] CH%d: At OTB %d starting channel\n", odm->OD->objectDescriptorID, ch->esd->ESID, gf_clock_time(ch->clock)));		}		if (gf_list_find(odm->term->media_queue, odm)<0) gf_list_add(odm->term->media_queue, odm);	}	gf_term_lock_net(odm->term, 0);}void gf_odm_play(GF_ObjectManager *odm){	GF_Channel *ch;	u32 i;	u32 nb_failure;	u64 range_end;	Bool skip_od_st;	GF_NetworkCommand com;	MediaControlStack *ctrl;	GF_Clock *parent_ck = NULL;	if (odm->parentscene) {		parent_ck = gf_odm_get_media_clock(odm->parentscene->root_od);		if (!gf_odm_shares_clock(odm, parent_ck)) parent_ck = NULL;	}	skip_od_st = (odm->subscene && odm->subscene->static_media_ressources) ? 1 : 0;	range_end = odm->media_stop_time;//	odm->media_stop_time = 0;	nb_failure = gf_list_count(odm->channels);	/*send play command*/	com.command_type = GF_NET_CHAN_PLAY;	i=0;	while ( (ch = (GF_Channel*)gf_list_enum(odm->channels, &i)) ) {		Double ck_time;		if (ch->ipmp_tool) {			GF_IPMPEvent evt;			GF_Err e;			memset(&evt, 0, sizeof(evt));			evt.event_type=GF_IPMP_TOOL_GRANT_ACCESS;			evt.channel = ch;			e = ch->ipmp_tool->process(ch->ipmp_tool, &evt);			if (e) {				gf_term_message(odm->term, NULL, "PLAY access is not granted on channel - please check your license", e);				gf_es_stop(ch);				continue;			}		}		nb_failure --;		com.base.on_channel = ch;		com.play.speed = 1.0;		/*play from requested time (seeking or non-mpeg4 media control)*/		if (odm->media_start_time && !ch->clock->clock_init) {			ck_time = (Double) (s64) odm->media_start_time;			ck_time /= 1000;		}		/*play from current time*/		else {			ck_time = gf_clock_time(ch->clock);			ck_time /= 1000;			/*handle initial start - MPEG-4 is a bit annoying here, streams are not started through OD but through			scene nodes. If the stream runs on the BIFS/OD clock, the clock is already started at this point and we're 			sure to get at least a one-frame delay in PLAY, so just remove it - note we're generous but this shouldn't hurt*/			if (ck_time<=0.5) ck_time = 0;		}		com.play.start_range = ck_time;		if (range_end) {			com.play.end_range = (s64) range_end / 1000.0;		} else {			if (!odm->subscene && gf_odm_shares_clock(odm->parentscene->root_od, ch->clock)				&& (odm->parentscene->root_od->media_stop_time != odm->parentscene->root_od->duration)			) {				com.play.end_range = (s64) odm->parentscene->root_od->media_stop_time / 1000.0;			} else {				com.play.end_range = -1;			}		}		/*if object shares parent scene clock, do not use media control*/		ctrl = parent_ck ? NULL : ODM_GetMediaControl(odm);		/*override range and speed with MC*/		if (ctrl) {			MC_GetRange(ctrl, &com.play.start_range, &com.play.end_range);			com.play.speed = FIX2FLT(ctrl->control->mediaSpeed);			/*if the channel doesn't control the clock, jump to current time in the controled range, not just the begining*/			if ((ch->esd->ESID!=ch->clock->clockID) && (ck_time>com.play.start_range) && (com.play.end_range>com.play.start_range) && (ck_time<com.play.end_range)) {				com.play.start_range = ck_time;			}			gf_clock_set_speed(ch->clock, ctrl->control->mediaSpeed);			/*if requested seek time AND media control, adjust start range to current play time*/			if (odm->media_start_time) {				if ((com.play.start_range>=0) && (com.play.end_range>com.play.start_range)) {					if (ctrl->control->loop) {						Double active_dur = com.play.end_range - com.play.start_range;						while (ck_time>active_dur) ck_time -= active_dur;					} else {						ck_time = 0;						//com.play.start_range = com.play.end_range;					}				}				com.play.start_range += ck_time;			}		}		/*full object playback*/		if (com.play.end_range<=0) {			odm->media_stop_time = odm->subscene ? 0 : odm->duration;		} else {			/*segment playback - since our timing is in ms whereas segment ranges are double precision, 			make sure we have a LARGER range in ms, otherwise media sensors won't deactivate properly*/			odm->media_stop_time = (u64) ceil(1000 * com.play.end_range);		}		/*don't replay OD channel, only init clock if needed*/		if (!ch->service || (skip_od_st && (ch->esd->decoderConfig->streamType==GF_STREAM_OD))) {			Bool gf_es_owns_clock(GF_Channel *ch);			if (gf_es_owns_clock(ch) ) 				gf_clock_set_time(ch->clock, (u32) (com.play.start_range*1000));			ch->IsClockInit = 1;			if (ch->BufferOn) {				ch->BufferOn = 0;				gf_clock_buffer_off(ch->clock);			}		} else {			gf_term_service_command(ch->service, &com);			GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("[ODM%d] CH%d: At OTB %d requesting PLAY from %g to %g (clock init %d)\n", odm->OD->objectDescriptorID, ch->esd->ESID, gf_clock_time(ch->clock), com.play.start_range, com.play.end_range, ch->clock->clock_init));		}	}//	odm->media_start_time = 0;	if (nb_failure) {		odm->state = GF_ODM_STATE_BLOCKED;		return;	}	/*start codecs last (otherwise we end up pulling data from channels not yet connected->pbs when seeking)*/	if (odm->codec) {		/*reset*/		if (odm->codec->CB) {			gf_cm_set_status(odm->codec->CB, CB_STOP);			odm->codec->CB->HasSeenEOS = 0;		}		gf_term_start_codec(odm->codec);	} else if (odm->subscene) {		if (odm->subscene->scene_codec) gf_term_start_codec(odm->subscene->scene_codec);		if (!skip_od_st && odm->subscene->od_codec) gf_term_start_codec(odm->subscene->od_codec);	}	if (odm->ocr_codec) gf_term_start_codec(odm->ocr_codec);	if (odm->oci_codec) gf_term_start_codec(odm->oci_codec);}void gf_odm_stop(GF_ObjectManager *odm, Bool force_close){	GF_Channel *ch;	u32 i;	MediaControlStack *ctrl;	MediaSensorStack *media_sens;	GF_NetworkCommand com;		if (!odm->state) return;#if 0	/*Handle broadcast environment, do not stop the object if no time control and instruction	comes from the scene*/	if (odm->no_time_ctrl && !force_close) {		GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("[ODM%d] - broadcast detected, ignoring Stop from scene\n", odm->OD->objectDescriptorID);		return;	}#endif	gf_term_lock_net(odm->term, 1);	gf_list_del_item(odm->term->media_queue, odm);	gf_term_lock_net(odm->term, 0);	/*little opt for image codecs: don't actually stop the OD*/	if (!force_close && odm->codec && odm->codec->CB) {		if (odm->codec->CB->Capacity==1) return;	}	/*object was not unlocked, decoders were not started*/	if (odm->state==GF_ODM_STATE_BLOCKED) {		odm->current_time = 0;		return;	}	/*stop codecs*/	if (odm->codec) {		gf_term_stop_codec(odm->codec);	} else if (odm->subscene) {		u32 i=0;		GF_ObjectManager *sub_odm;		if (odm->subscene->scene_codec) gf_term_stop_codec(odm->subscene->scene_codec);		if (odm->subscene->od_codec) gf_term_stop_codec(odm->subscene->od_codec);		/*stops all resources of the subscene as well*/		while ((sub_odm=(GF_ObjectManager *)gf_list_enum(odm->subscene->ODlist, &i))) {			gf_odm_stop(sub_odm, force_close);		}	}	if (odm->ocr_codec) gf_term_stop_codec(odm->ocr_codec);	if (odm->oci_codec) gf_term_stop_codec(odm->oci_codec);	gf_term_lock_net(odm->term, 1);

⌨️ 快捷键说明

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