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

📄 smil_timing.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 2 页
字号:
#endifBool gf_smil_notify_timed_elements(GF_SceneGraph *sg){	SMIL_Timing_RTI *rti;	u32 active_count = 0, i = 0;	s32 ret;	if (!sg) return 0;	sg->update_smil_timing = 0;	while((rti = (SMIL_Timing_RTI *)gf_list_enum(sg->smil_timed_elements, &i))) {		//scene_time = rti->timed_elt->sgprivate->scenegraph->GetSceneTime(rti->timed_elt->sgprivate->scenegraph->userpriv);		ret = gf_smil_timing_notify_time(rti, gf_node_get_scene_time((GF_Node*)rti->timed_elt));		if (ret == -1) {			/* special case for discard element */			i--;		} else if (ret == -2) {			/* special return value, -2 means that the tested timed element is waiting to begin			   Assuming that the timed elements are sorted by begin order, 			   the next ones don't need to be checked */			break;		} else {			active_count += ret;		}	}	/*in case an anim triggers another one previously inactivated...	TODO FIXME: it would be much better to stack anim as active/inactive*/	while (sg->update_smil_timing) {		sg->update_smil_timing = 0;		i = 0;		while((rti = (SMIL_Timing_RTI *)gf_list_enum(sg->smil_timed_elements, &i))) {			/*this means the anim has been, modified, re-evaluate it*/			if (rti->scene_time==-1) {				ret = gf_smil_timing_notify_time(rti, gf_node_get_scene_time((GF_Node*)rti->timed_elt) );				if (ret == -1) {					/* special case for discard element */					i--;				} else if (ret == -2) {					/* special return value, -2 means that the tested timed element is waiting to begin					   Assuming that the timed elements are sorted by begin order, 					   the next ones don't need to be checked */					break;				} else {					active_count += ret;				}			}		}	}	return (active_count>0);}static Bool gf_smil_discard(SMIL_Timing_RTI *rti, Fixed scene_time){	u32 nb_inst;	SMIL_Time *begin;	SMILTimingAttributesPointers *timingp = rti->timingp;	GF_Node *target;	u32 tag = gf_node_get_tag(rti->timed_elt);	if (!timingp) return 0;		if ((tag>=GF_NODE_RANGE_FIRST_SVG) && (tag<=GF_NODE_RANGE_LAST_SVG)) {		target = ((SVGTimedAnimBaseElement *)rti->timed_elt)->xlinkp->href->target;	} #ifdef GPAC_ENABLE_SVG_SA	else if ((tag>=GF_NODE_RANGE_FIRST_SVG_SA) && (tag<=GF_NODE_RANGE_LAST_SVG_SA)) {		target = ((SVG_SA_Element *)rti->timed_elt)->xlinkp->href->target;	} #endif#ifdef GPAC_ENABLE_SVG_SANI	else if ((tag>=GF_NODE_RANGE_FIRST_SVG_SANI) && (tag<=GF_NODE_RANGE_LAST_SVG_SANI)) {		target = ((SVG_SANI_Element *)rti->timed_elt)->xlinkp->href->target;	}#endif	else {		return 0;	}		begin = (timingp->begin ? (SMIL_Time *)gf_list_get(*timingp->begin, 0) : NULL);	if (!begin) return 0;	if (!GF_SMIL_TIME_IS_CLOCK(begin->type) ) return 0;	if (!target) return 0;	if (begin->clock > scene_time) return 0;	GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[SVG Composer] discarding element %s at time %f\n", gf_node_get_name(target), scene_time));		/*this takes care of cases where discard is a child of its target*/	gf_node_register(rti->timed_elt, NULL);	nb_inst = gf_node_get_num_instances(rti->timed_elt);	gf_node_replace(target, NULL, 0);	if (nb_inst == gf_node_get_num_instances(rti->timed_elt)) {		gf_node_unregister(rti->timed_elt, NULL);		/*after this the stack may be free'd*/		gf_node_replace(rti->timed_elt, NULL, 0);	} else {		gf_node_unregister(rti->timed_elt, NULL);	}	return 1;}/*Animations are applied in their begin order. Whenever an anim (re)starts, it is placed at the end of the queue (potentially after frozen animations)*/static void gf_smil_reorder_anim(SMIL_Timing_RTI *rti){	SMIL_Anim_RTI *rai = (SMIL_Anim_RTI *) gf_smil_anim_get_anim_runtime_from_timing(rti);	if (rai) {		gf_list_del_item(rai->owner->anims, rai);		gf_list_add(rai->owner->anims, rai);		gf_smil_anim_reset_variables(rai);	}}/* Returns:	0 if no rendering traversal is required, 	1 if a rendering traversal is required!!!,   -1 if the time node is a discard which has been deleted!! */s32 gf_smil_timing_notify_time(SMIL_Timing_RTI *rti, Double scene_time){	Fixed simple_time;	s32 ret = 0;	GF_DOM_Event evt;	SMILTimingAttributesPointers *timingp = rti->timingp;	if (!timingp) return 0;		if (rti->scene_time == scene_time) return 0;	rti->scene_time = scene_time;	rti->cycle_number++;	/* for fraction events, we indicate that the scene needs redraw */	if (rti->evaluate_status == SMIL_TIMING_EVAL_FRACTION) 		return 1;	if (rti->evaluate_status == SMIL_TIMING_EVAL_DISCARD) {		/* TODO: FIX ME discarding should send a begin event ? */		/* -1 is a special case when the discard is evaluated */		if (gf_smil_discard(rti, FLT2FIX(rti->scene_time))) return -1;		else return 0;	}	gf_node_register(rti->timed_elt, NULL);waiting_to_begin:	if (rti->status == SMIL_STATUS_WAITING_TO_BEGIN) {		if (rti->current_interval && scene_time >= rti->current_interval->begin) {						GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[SMIL Timing   ] Time %f - Timed element %s - Activating\n", gf_node_get_scene_time((GF_Node *)rti->timed_elt), gf_node_get_name((GF_Node *)rti->timed_elt)));			rti->status = SMIL_STATUS_ACTIVE;			memset(&evt, 0, sizeof(evt));			evt.type = GF_EVENT_BEGIN_EVENT;			evt.smil_event_time = rti->current_interval->begin;			gf_dom_event_fire((GF_Node *)rti->timed_elt, NULL, &evt);			if (rti->timed_elt->sgprivate->tag==TAG_SVG_conditional) {				SVG_Element *e = (SVG_Element *)rti->timed_elt;				/*activate conditional*/				if (e->children) gf_node_render(e->children->node, NULL);				rti->status = SMIL_STATUS_DONE;			} else {				gf_smil_reorder_anim(rti);			}		} else {			GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[SMIL Timing   ] Time %f - Timed element %s - Evaluating (Not starting)\n", gf_node_get_scene_time((GF_Node *)rti->timed_elt), gf_node_get_name((GF_Node *)rti->timed_elt)));			ret = -2;			goto exit;		}	}	if (rti->status == SMIL_STATUS_ACTIVE) {		u32 cur_id;		if (rti->current_interval->active_duration >= 0 			&& scene_time >= (rti->current_interval->begin + rti->current_interval->active_duration)) {			GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[SMIL Timing   ] Time %f - Timed element %s - Stopping \n", gf_node_get_scene_time((GF_Node *)rti->timed_elt), gf_node_get_name((GF_Node *)rti->timed_elt)));			memset(&evt, 0, sizeof(evt));			evt.type = GF_EVENT_END_EVENT;			evt.smil_event_time = rti->current_interval->begin + rti->current_interval->active_duration;			gf_dom_event_fire((GF_Node *)rti->timed_elt, NULL, &evt);			ret = rti->postpone;			if (timingp->fill && *timingp->fill == SMIL_FILL_FREEZE) {				rti->status = SMIL_STATUS_FROZEN;				rti->first_frozen = rti->cycle_number;				rti->evaluate_status = SMIL_TIMING_EVAL_FREEZE;				if (!rti->postpone) {					Fixed simple_time = gf_smil_timing_get_normalized_simple_time(rti, scene_time);					rti->evaluate(rti, simple_time, rti->evaluate_status);				}			} else {				rti->status = SMIL_STATUS_DONE;				rti->first_frozen = rti->cycle_number;				rti->evaluate_status = SMIL_TIMING_EVAL_REMOVE;				if (!rti->postpone) {					Fixed simple_time = gf_smil_timing_get_normalized_simple_time(rti, scene_time);					rti->evaluate(rti, simple_time, rti->evaluate_status);				}			}		}		/*special case for unspecified simpleDur with animations (not with media timed elements)*/		else if (0 && rti->postpone 			&& (rti->current_interval->simple_duration==-1) 			&& (rti->current_interval->active_duration<=0) 		) {			ret = 1;			rti->status = SMIL_STATUS_FROZEN;			rti->first_frozen = rti->cycle_number;			rti->evaluate_status = SMIL_TIMING_EVAL_FREEZE;		} else { // the animation is still active 			if (!timingp->restart || *timingp->restart == SMIL_RESTART_ALWAYS) {				s32 interval_index;				interval_index = gf_smil_timing_find_interval_index(rti, scene_time);								if (interval_index >= 0 &&					interval_index != rti->current_interval_index) {					/* intervals are different, use the new one */					rti->current_interval_index = interval_index;					rti->current_interval = (SMIL_Interval*)gf_list_get(rti->intervals, rti->current_interval_index);										/* reinserting the new timed elements at its proper place in the list					  of timed elements in the scenegraph */					gf_smil_reorder_timing(rti);					/* if this is animation, reinserting the animation in the list of animations 				       that targets this attribute, so that it is the last one */					gf_smil_reorder_anim(rti);					memset(&evt, 0, sizeof(evt));					evt.type = GF_EVENT_BEGIN_EVENT;					evt.smil_event_time = rti->current_interval->begin;					gf_dom_event_fire((GF_Node *)rti->timed_elt, NULL, &evt);								} 			}			ret = rti->postpone;						cur_id = rti->current_interval->nb_iterations;			simple_time = gf_smil_timing_get_normalized_simple_time(rti, scene_time);			if (cur_id < rti->current_interval->nb_iterations) {				memset(&evt, 0, sizeof(evt));				evt.type = GF_EVENT_REPEAT_EVENT;				evt.smil_event_time = rti->current_interval->begin + rti->current_interval->nb_iterations*rti->current_interval->simple_duration;				evt.detail = rti->current_interval->nb_iterations;				gf_dom_event_fire((GF_Node *)rti->timed_elt, NULL, &evt);				GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[SMIL Timing   ] Time %f - Timed element %s - Repeating\n", gf_node_get_scene_time((GF_Node *)rti->timed_elt), gf_node_get_name((GF_Node *)rti->timed_elt)));				rti->evaluate_status = SMIL_TIMING_EVAL_REPEAT;					} else {				GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[SMIL Timing   ] Time %f - Timed element %s - Updating\n", gf_node_get_scene_time((GF_Node *)rti->timed_elt), gf_node_get_name((GF_Node *)rti->timed_elt)));				rti->evaluate_status = SMIL_TIMING_EVAL_UPDATE;			}			if (!rti->postpone) {				rti->evaluate(rti, simple_time, rti->evaluate_status);			}			}	}	if ((rti->status == SMIL_STATUS_DONE) || (rti->status == SMIL_STATUS_FROZEN)) {		if (!timingp->restart || *timingp->restart != SMIL_RESTART_NEVER) { 			/* Check changes in begin or end attributes */			s32 interval_index;			GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[SMIL Timing   ] Time %f - Timed element %s - Checking for restart\n", gf_node_get_scene_time((GF_Node *)rti->timed_elt), gf_node_get_name((GF_Node *)rti->timed_elt)));			interval_index = gf_smil_timing_find_interval_index(rti, scene_time);			if (interval_index >= 0 && interval_index != rti->current_interval_index) {				/* intervals are different, use the new one */				rti->current_interval_index = interval_index;				rti->current_interval = (SMIL_Interval*)gf_list_get(rti->intervals, rti->current_interval_index);				/* reinserting the new timed elements at its proper place in the list				  of timed elements in the scenegraph */				gf_smil_reorder_timing(rti);				rti->status = SMIL_STATUS_WAITING_TO_BEGIN;				rti->evaluate_status = SMIL_TIMING_EVAL_NONE;				goto waiting_to_begin;			} 		} else if ((rti->status == SMIL_STATUS_DONE) && 			        timingp->restart && (*timingp->restart == SMIL_RESTART_NEVER)) {			/* the timed element is done and cannot restart, we don't need to evaluate it anymore */			GF_SceneGraph * sg = rti->timed_elt->sgprivate->scenegraph;			while (sg->parent_scene) sg = sg->parent_scene;			gf_list_del_item(sg->smil_timed_elements, rti);		}	}exit:	gf_node_unregister(rti->timed_elt, NULL);	return ret;}Fixed gf_smil_timing_get_normalized_simple_time(SMIL_Timing_RTI *rti, Double scene_time) {	Double activeTime;	Double simpleTime;	Fixed normalizedSimpleTime;	if (!rti->current_interval) return 0;	activeTime			 = scene_time - rti->current_interval->begin;	if (rti->current_interval->active_duration != -1 && activeTime > rti->current_interval->active_duration) return FIX_ONE;	if (rti->current_interval->simple_duration>0) {		rti->current_interval->nb_iterations = (u32)floor(activeTime / rti->current_interval->simple_duration);	} else {		rti->current_interval->nb_iterations = 0;	}		simpleTime			 = activeTime - rti->current_interval->simple_duration * rti->current_interval->nb_iterations;	/* to be sure clamp simpleTime */	simpleTime = MAX(0, simpleTime);	simpleTime = MIN(rti->current_interval->simple_duration, simpleTime);	normalizedSimpleTime = FLT2FIX(simpleTime / rti->current_interval->simple_duration);	return normalizedSimpleTime;}void gf_smil_timing_modified(GF_Node *node, GF_FieldInfo *field){	GF_SceneGraph *sg;	SMILTimingAttributesPointers *timingp = NULL;	SMIL_Timing_RTI *rti;	u32 tag = gf_node_get_tag(node);		if ((tag>=GF_NODE_RANGE_FIRST_SVG) && (tag<=GF_NODE_RANGE_LAST_SVG)) {		timingp = ((SVGTimedAnimBaseElement *)node)->timingp;	} #ifdef GPAC_ENABLE_SVG_SA	else if ((tag>=GF_NODE_RANGE_FIRST_SVG_SA) && (tag<=GF_NODE_RANGE_LAST_SVG_SA)) {		timingp = ((SVG_SA_Element *)node)->timingp;	}#endif#ifdef GPAC_ENABLE_SVG_SANI	else if ((tag>=GF_NODE_RANGE_FIRST_SVG_SANI) && (tag<=GF_NODE_RANGE_LAST_SVG_SANI)) {		timingp = ((SVG_SANI_Element *)node)->timingp;	}#endif	else {		return;	}		if (!timingp) return;	rti = timingp->runtime;	if (!rti) return;	/*recompute interval list*/	rti->scene_time = -1;	sg = node->sgprivate->scenegraph;	while (sg->parent_scene) sg = sg->parent_scene;	sg->update_smil_timing = 1;	gf_smil_timing_refresh_interval_list(rti);	if (!rti->current_interval) {		s32 interval_index;		interval_index = gf_smil_timing_find_interval_index(rti, GF_MAX_DOUBLE);		if (interval_index >= 0) {			rti->current_interval_index = interval_index;			rti->current_interval = (SMIL_Interval*)gf_list_get(rti->intervals, rti->current_interval_index);		} 	}	gf_smil_timing_add_to_sg(sg, rti);}Bool gf_svg_resolve_smil_times(GF_SceneGraph *sg, void *anim_parent, 							GF_List *smil_times, Bool is_end, const char *node_name){	u32 i, done, count;	done = 0;	count = gf_list_count(smil_times);	for (i=0; i<count; i++) {		SMIL_Time *t = (SMIL_Time *)gf_list_get(smil_times, i);		/*not an event*/		if (t->type != GF_SMIL_TIME_EVENT) {			done++;			continue;		}		if (!t->element_id) {			/*event source is anim parent*/			if (!t->element) t->element = (GF_Node *)anim_parent;			done++;			continue;		}		if (node_name && strcmp(node_name, t->element_id)) continue;			t->element = gf_sg_find_node_by_name(sg, t->element_id);		if (t->element) {			free(t->element_id);			t->element_id = NULL;			done++;		}	}	if (done!=count) return 0;	return 1;}GF_EXPORTvoid gf_smil_timing_insert_clock(GF_Node *elt, Bool is_end, Double clock){	u32 i, count, found;	SVGTimedAnimBaseElement *set = (SVGTimedAnimBaseElement*)elt;	SMIL_Time *begin;	GF_List *l;	GF_SAFEALLOC(begin, SMIL_Time);	begin->type = GF_SMIL_TIME_EVENT_RESOLVED;	begin->clock = clock;	l = is_end ? *set->timingp->end : *set->timingp->begin;	found = 0;	count = gf_list_count(l);	for (i=0; i<count; i++) {		SMIL_Time *first = (SMIL_Time *)gf_list_get(l, i);		/*remove past instanciations*/		if ((first->type==GF_SMIL_TIME_EVENT_RESOLVED) && (first->clock < begin->clock)) {			gf_list_rem(l, i);			free(first);			i--;			count--;			continue;		}		if ( (first->type == GF_SMIL_TIME_INDEFINITE) 			|| ( (first->type == GF_SMIL_TIME_CLOCK) && (first->clock > begin->clock) ) 		) {			gf_list_insert(l, begin, i);			found = 1;			break;		}	}	if (!found) gf_list_add(l, begin);	gf_node_changed(elt, NULL);}

⌨️ 快捷键说明

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