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

📄 object_manager.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 4 页
字号:
	/*send stop command*/	com.command_type = GF_NET_CHAN_STOP;	i=0;	while ((ch = (GF_Channel*)gf_list_enum(odm->channels, &i)) ) {		if (ch->ipmp_tool) {			GF_IPMPEvent evt;			memset(&evt, 0, sizeof(evt));			evt.event_type=GF_IPMP_TOOL_RELEASE_ACCESS;			evt.channel = ch;			ch->ipmp_tool->process(ch->ipmp_tool, &evt);		}				if (ch->service) {			com.base.on_channel = ch;			gf_term_service_command(ch->service, &com);			GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("[ODM%d] CH %d At OTB %d requesting STOP\n", odm->OD->objectDescriptorID, ch->esd->ESID, gf_clock_time(ch->clock)));		}	}	/*stop channels*/	i=0;	while ((ch = (GF_Channel*)gf_list_enum(odm->channels, &i)) ) {		/*stops clock if this is a scene stop*/		if (!(odm->flags & GF_ODM_INHERIT_TIMELINE) && odm->subscene) gf_clock_stop(ch->clock);		gf_es_stop(ch);	}	gf_term_lock_net(odm->term, 0);	odm->state = GF_ODM_STATE_STOP;	odm->current_time = 0;	/*reset media sensor(s)*/	if (force_close!=2) {		i = 0;		while ((media_sens = (MediaSensorStack *)gf_list_enum(odm->ms_stack, &i))){			MS_Stop(media_sens);		}	}	/*reset media control state*/	ctrl = ODM_GetMediaControl(odm);	if (ctrl) ctrl->current_seg = 0;}void gf_odm_on_eos(GF_ObjectManager *odm, GF_Channel *on_channel){	if (gf_odm_check_segment_switch(odm)) return;		if (odm->codec && (on_channel->esd->decoderConfig->streamType==odm->codec->type)) {		gf_codec_set_status(odm->codec, GF_ESM_CODEC_EOS);		return;	} 	if (on_channel->esd->decoderConfig->streamType==GF_STREAM_OCR) {		gf_codec_set_status(odm->ocr_codec, GF_ESM_CODEC_EOS);		return;	}	if (on_channel->esd->decoderConfig->streamType==GF_STREAM_OCI) {		gf_codec_set_status(odm->oci_codec, GF_ESM_CODEC_EOS);		return;	}	if (!odm->subscene) return;	if (odm->subscene->scene_codec && (gf_list_find(odm->subscene->scene_codec->inChannels, on_channel)>=0) ) {		gf_codec_set_status(odm->subscene->scene_codec, GF_ESM_CODEC_EOS);		return;	}	if (on_channel->esd->decoderConfig->streamType==GF_STREAM_OD) {		gf_codec_set_status(odm->subscene->od_codec, GF_ESM_CODEC_EOS);		return;	}}void gf_odm_set_duration(GF_ObjectManager *odm, GF_Channel *ch, u64 stream_duration){	if (odm->codec) {		if (ch->esd->decoderConfig->streamType == odm->codec->type)			if (odm->duration < stream_duration)				odm->duration = stream_duration;	} else if (odm->ocr_codec) {		if (ch->esd->decoderConfig->streamType == odm->ocr_codec->type)			if (odm->duration < stream_duration)				odm->duration = stream_duration;	} else if (odm->subscene && odm->subscene->scene_codec) {		//if (gf_list_find(odm->subscene->scene_codec->inChannels, ch) >= 0) {			if (odm->duration < stream_duration) odm->duration = stream_duration;		//}	}	/*update scene duration*/	gf_is_set_duration(odm->subscene ? odm->subscene : (odm->parentscene ? odm->parentscene : odm->term->root_scene));}GF_Clock *gf_odm_get_media_clock(GF_ObjectManager *odm){	if (odm->codec) return odm->codec->ck;	if (odm->ocr_codec) return odm->ocr_codec->ck;	if (odm->subscene && odm->subscene->scene_codec) return odm->subscene->scene_codec->ck;	if (odm->subscene && odm->subscene->dyn_ck) return odm->subscene->dyn_ck;	return NULL;}void ODM_SetMediaControl(GF_ObjectManager *odm, MediaControlStack *ctrl){	u32 i;	GF_Channel *ch;	/*keep track of it*/	if (ctrl && (gf_list_find(odm->mc_stack, ctrl) < 0)) gf_list_add(odm->mc_stack, ctrl);	if (ctrl && !ctrl->control->enabled) return;	if (odm->subscene && odm->subscene->is_dynamic_scene) {		if (odm->subscene->dyn_ck) {			/*deactivate current control*/			if (ctrl && odm->subscene->dyn_ck->mc) {				odm->subscene->dyn_ck->mc->control->enabled = 0;				gf_node_event_out_str((GF_Node *)odm->subscene->dyn_ck->mc->control, "enabled");			}			odm->subscene->dyn_ck->mc = ctrl;		}	} else {		/*for each clock in the controled OD*/		i=0;		while ((ch = (GF_Channel*)gf_list_enum(odm->channels, &i))) {			if (ch->clock->mc != ctrl) {				/*deactivate current control*/				if (ctrl && ch->clock->mc) {					ch->clock->mc->control->enabled = 0;					gf_node_event_out_str((GF_Node *)ch->clock->mc->control, "enabled");				}				/*and attach this control to the clock*/				ch->clock->mc = ctrl;			}		}	}	/*store active control on media*/	odm->media_ctrl = ODM_GetMediaControl(odm);}MediaControlStack *ODM_GetMediaControl(GF_ObjectManager *odm){	GF_Clock *ck;	ck = gf_odm_get_media_clock(odm);	if (!ck) return NULL;	return ck->mc;}MediaControlStack *ODM_GetObjectMediaControl(GF_ObjectManager *odm){	MediaControlStack *ctrl;	ctrl = ODM_GetMediaControl(odm);	if (!ctrl) return NULL;	/*inline scene control*/	if (odm->subscene && (ctrl->stream->odm == odm->subscene->root_od) ) return ctrl;	if (ctrl->stream->OD_ID != odm->OD->objectDescriptorID) return NULL;	return ctrl;}void ODM_RemoveMediaControl(GF_ObjectManager *odm, MediaControlStack *ctrl){	gf_list_del_item(odm->mc_stack, ctrl);	/*removed. Note the spec doesn't say what to do in this case...*/	if (odm->media_ctrl == ctrl) ODM_SetMediaControl(odm, NULL);}Bool ODM_SwitchMediaControl(GF_ObjectManager *odm, MediaControlStack *ctrl){	u32 i;	MediaControlStack *st2;	if (!ctrl->control->enabled) return 0;	/*for all media controls other than this one force enable to false*/	i=0;	while ((st2 = (MediaControlStack *)gf_list_enum(odm->mc_stack, &i))) {		if (st2 == ctrl) continue;		if (st2->control->enabled) {			st2->control->enabled = 0;			gf_node_event_out_str((GF_Node *) st2->control, "enabled");		}		st2->enabled = 0;	}	if (ctrl == odm->media_ctrl) return 0;	ODM_SetMediaControl(odm, ctrl);	return 1;}Bool gf_odm_shares_clock(GF_ObjectManager *odm, GF_Clock *ck){	u32 i = 0;	GF_Channel *ch;	while ((ch = (GF_Channel*)gf_list_enum(odm->channels, &i))) {		if (ch->clock == ck) return 1;	}	return 0;}void gf_odm_pause(GF_ObjectManager *odm){	u32 i;	GF_NetworkCommand com;	MediaSensorStack *media_sens;	GF_Channel *ch;	if (odm->flags & GF_ODM_NO_TIME_CTRL) return;	/*stop codecs, and update status for media codecs*/	if (odm->codec) {		gf_term_stop_codec(odm->codec);		gf_codec_set_status(odm->codec, GF_ESM_CODEC_PAUSE);	} else if (odm->subscene) {		if (odm->subscene->scene_codec) {			gf_codec_set_status(odm->subscene->scene_codec, GF_ESM_CODEC_PAUSE);			gf_term_stop_codec(odm->subscene->scene_codec);		}		if (odm->subscene->od_codec) gf_term_stop_codec(odm->subscene->od_codec);	}	if (odm->ocr_codec) gf_term_stop_codec(odm->ocr_codec);	if (odm->oci_codec) gf_term_stop_codec(odm->oci_codec);	com.command_type = GF_NET_CHAN_PAUSE;	i=0;	while ((ch = (GF_Channel*)gf_list_enum(odm->channels, &i))) {		gf_clock_pause(ch->clock);		com.base.on_channel = ch;		gf_term_service_command(ch->service, &com);	}	/*mediaSensor  shall generate isActive false when paused*/	i=0;	while ((media_sens = (MediaSensorStack *)gf_list_enum(odm->ms_stack, &i)) ) {		if (media_sens && media_sens->sensor->isActive) {			media_sens->sensor->isActive = 0;			gf_node_event_out_str((GF_Node *) media_sens->sensor, "isActive");		}	}}void gf_odm_resume(GF_ObjectManager *odm){	u32 i;	GF_NetworkCommand com;	GF_Channel *ch;	MediaSensorStack *media_sens;	if (odm->flags & GF_ODM_NO_TIME_CTRL) return;	/*start codecs, and update status for media codecs*/	if (odm->codec) {		gf_term_start_codec(odm->codec);		gf_codec_set_status(odm->codec, GF_ESM_CODEC_PLAY);	} else if (odm->subscene) {		if (odm->subscene->scene_codec) {			gf_codec_set_status(odm->subscene->scene_codec, GF_ESM_CODEC_PLAY);			gf_term_start_codec(odm->subscene->scene_codec);		}		if (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);		com.command_type = GF_NET_CHAN_RESUME;	i=0;	while ((ch = (GF_Channel*)gf_list_enum(odm->channels, &i)) ){		gf_clock_resume(ch->clock);		com.base.on_channel = ch;		gf_term_service_command(ch->service, &com);	}	/*mediaSensor shall generate isActive TRUE when resumed*/	i=0;	while ((media_sens = (MediaSensorStack *)gf_list_enum(odm->ms_stack, &i)) ){		if (media_sens && !media_sens->sensor->isActive) {			media_sens->sensor->isActive = 1;			gf_node_event_out_str((GF_Node *) media_sens->sensor, "isActive");		}	}}void gf_odm_set_speed(GF_ObjectManager *odm, Fixed speed){	u32 i;	GF_NetworkCommand com;	GF_Channel *ch;	if (odm->flags & GF_ODM_NO_TIME_CTRL) return;	com.command_type = GF_NET_CHAN_SET_SPEED;	com.play.speed = FIX2FLT(speed);	i=0;	while ((ch = (GF_Channel*)gf_list_enum(odm->channels, &i)) ) {		gf_clock_set_speed(ch->clock, speed);		com.play.on_channel = ch;		gf_term_service_command(ch->service, &com);	}}GF_Segment *gf_odm_find_segment(GF_ObjectManager *odm, char *descName){	GF_Segment *desc;	u32 i = 0;	while ( (desc = (GF_Segment *)gf_list_enum(odm->OD->OCIDescriptors, &i)) ){		if (desc->tag != GF_ODF_SEGMENT_TAG) continue;		if (!stricmp(desc->SegmentName, descName)) return desc;	}	return NULL;}static void gf_odm_insert_segment(GF_ObjectManager *odm, GF_Segment *seg, GF_List *list){	/*this reorders segments when inserting into list - I believe this is not compliant*/#if 0	GF_Segment *desc;	u32 i = 0;	while ((desc = gf_list_enum(list, &i))) {		if (desc == seg) return;		if (seg->startTime + seg->Duration <= desc->startTime) {			gf_list_insert(list, seg, i);			return;		}	}#endif	gf_list_add(list, seg);}/*add segment descriptor and sort them*/void gf_odm_init_segments(GF_ObjectManager *odm, GF_List *list, MFURL *url){	char *str, *sep;	char seg1[1024], seg2[1024], seg_url[4096];	GF_Segment *first_seg, *last_seg, *seg;	u32 i, j;	/*browse all URLs*/	for (i=0; i<url->count; i++) {		if (!url->vals[i].url) continue;		str = strstr(url->vals[i].url, "#");		if (!str) continue;		str++;		strcpy(seg_url, str);		/*segment closed range*/		if ((sep = strstr(seg_url, "-")) ) {			strcpy(seg2, sep+1);			sep[0] = 0;			strcpy(seg1, seg_url);			first_seg = gf_odm_find_segment(odm, seg1);			if (!first_seg) continue;			last_seg = gf_odm_find_segment(odm, seg2);		} 		/*segment open range*/		else if ((sep = strstr(seg_url, "+")) ) {			sep[0] = 0;			strcpy(seg1, seg_url);			first_seg = gf_odm_find_segment(odm, seg_url);			if (!first_seg) continue;			last_seg = NULL;		} 		/*single segment*/		else {			first_seg = gf_odm_find_segment(odm, seg_url);			if (!first_seg) continue;			gf_odm_insert_segment(odm, first_seg, list);			continue;		}		/*segment range process*/		gf_odm_insert_segment(odm, first_seg, list);		j=0;		while ( (seg = (GF_Segment *)gf_list_enum(odm->OD->OCIDescriptors, &j)) ) {			if (seg->tag != GF_ODF_SEGMENT_TAG) continue;			if (seg==first_seg) continue;			if (seg->startTime + seg->Duration <= first_seg->startTime) continue;			/*this also includes last_seg insertion !!*/			if (last_seg && (seg->startTime + seg->Duration > last_seg->startTime + last_seg->Duration) ) continue;			gf_odm_insert_segment(odm, seg, list);		}	}}Bool gf_odm_check_segment_switch(GF_ObjectManager *odm){	u32 count, i;	GF_Segment *cur, *next;	MediaControlStack *ctrl = ODM_GetMediaControl(odm);	/*if no control or control not on this object ignore segment switch*/	if (!ctrl || (ctrl->stream->odm != odm)) return 0;	count = gf_list_count(ctrl->seg);	/*reached end of controled stream (no more segments)*/	if (ctrl->current_seg>=count) return 0;	/*synth media, trigger if end of segment run-time*/	if (!odm->codec || ((odm->codec->type!=GF_STREAM_VISUAL) && (odm->codec->type!=GF_STREAM_AUDIO))) {		GF_Clock *ck = gf_odm_get_media_clock(odm);		u32 now = gf_clock_time(ck);		u64 dur = odm->subscene ? odm->subscene->duration : odm->duration;		cur = (GF_Segment *)gf_list_get(ctrl->seg, ctrl->current_seg);		if (odm->subscene && odm->subscene->needs_restart) return 0;		if (cur) dur = (u32) ((cur->Duration+cur->startTime)*1000);		if (now<=dur) return 0;	} else {		/*FIXME - for natural media with scalability, we should only process when all streams of the object are done*/	}	/*get current segment and move to next one*/	cur = (GF_Segment *)gf_list_get(ctrl->seg, ctrl->current_seg);	ctrl->current_seg ++;	/*resync in case we have been issuing a play range over several segments*/	for (i=ctrl->current_seg; i<count; i++) {		next = (GF_Segment *)gf_list_get(ctrl->seg, i);		if (			/*if next seg start is after cur seg start*/			(cur->startTime < next->startTime) 			/*if next seg start is before cur seg end*/			&& (cur->startTime + cur->Duration > next->startTime) 			/*if next seg start is already passed*/			&& (1000*next->startTime < odm->current_time)			/*then next segment was taken into account when requesting play*/			) {			cur = next;			ctrl->current_seg ++;		}	}	/*if last segment in ctrl is done, end of stream*/	if (ctrl->current_seg >= count) return 0;	next = (GF_Segment *)gf_list_get(ctrl->seg, ctrl->current_seg);	/*if next seg start is not in current seg, media needs restart*/	if ((next->startTime < cur->startTime) || (cur->startTime + cur->Duration < next->startTime))		MC_Restart(odm);	return 1;}

⌨️ 快捷键说明

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