Пример #1
0
/* the end value of this interval needs to be initialized before computing the active duration
   the begin value must be >= 0 
   The result can be:
    - a positive value meaning that a resolved and non-indefinite value was found
	- the value -1 meaning indefinite or unresolved
		TODO: we should make a difference between indefinite and unresolved because
		if an interval is created with a value of indefinite, this value should not 
		be replaced by a resolved event. (Not sure ?!!)
	- the value -2 meaning that a valid end value (including indefinite) could not be found
*/ 
static void gf_smil_timing_get_interval_end(SMIL_Timing_RTI *rti, SMIL_Interval *interval)
{
	u32 end_count, j;

	/* we set the value to indicate that this is an illegal end, 
	   if it stays like that after searching through the values, 
	   then the whole interval must be discarded */
	interval->end = -2;

	end_count = (rti->timingp->end ? gf_list_count(*rti->timingp->end) : 0);
	/* trying to find a matching end */
	if (end_count > 0) {
		for (j = 0; j < end_count; j++) {
			SMIL_Time *end = (SMIL_Time*)gf_list_get(*rti->timingp->end, j);
			if ( GF_SMIL_TIME_IS_CLOCK(end->type) )  {
				if( end->clock >= interval->begin) {
					interval->end = end->clock;
					break;
				}
			} else {
				/* an unresolved or indefinite value is always good */
				interval->end = -1;
				break;
			}
		}	
	} else {
		interval->end = -1;
	}					
}
Пример #2
0
static Bool gf_smil_timing_get_next_interval(SMIL_Timing_RTI *rti, Bool current, SMIL_Interval *interval, Double scene_time)
{
	u32 i, count;

	memset(interval, 0, sizeof(SMIL_Interval));
	interval->begin = -1;
	
	count = (rti->timingp->begin ? gf_list_count(*rti->timingp->begin) : 0);
	for (i = 0; i < count; i ++) {
		SMIL_Time *begin = (SMIL_Time*)gf_list_get(*rti->timingp->begin, i);
		if (GF_SMIL_TIME_IS_CLOCK(begin->type)) {
			if (rti->current_interval->begin != -1 && begin->clock <= rti->current_interval->begin) continue;
//			if (rti->current_interval->begin == -1 || begin->clock <= scene_time) {
				interval->begin = begin->clock;
				break;
//			}
		}
	}
	if (interval->begin != -1) {
		gf_smil_timing_get_interval_end(rti, interval);
		if (interval->end == -2) {
			/* this is a wrong interval see first animation in animate-elem-201-t.svg */
			GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, ("[SMIL Timing   ] Time %f - Timed element %s - Wrong Interval\n", gf_node_get_scene_time((GF_Node *)rti->timed_elt), gf_node_get_log_name((GF_Node *)rti->timed_elt)));
			interval->begin = -1;
			interval->end = -1;
			return 0;
		}
		gf_smil_timing_compute_active_duration(rti, interval);
		gf_smil_timing_print_interval(rti, current, interval);
		return 1;
	} else {
		return 0;
	}
}
Пример #3
0
/* assumes that the list of time values is sorted */
static void gf_smil_timing_refresh_interval_list(SMIL_Timing_RTI *rti)
{
	u32 i, count, j, count2;
	SMIL_Time *begin;
	SMILTimingAttributesPointers *timingp = rti->timingp;

	if (!timingp) return;

	count = (timingp->begin ? gf_list_count(*timingp->begin) : 0);
	if (!count) {
		if (rti->current_interval)
			gf_smil_timing_add_new_interval(rti, rti->current_interval, rti->current_interval->begin, 0);
		return;
	}

	for (i = 0; i < count; i ++) {
		SMIL_Interval *existing_interval = NULL;
		begin = (SMIL_Time*)gf_list_get(*timingp->begin, i);
		/* this is not an acceptable value for a begin */
		if (! GF_SMIL_TIME_IS_CLOCK(begin->type) ) continue;

		count2 = gf_list_count(rti->intervals);
		for (j=0; j<count2; j++) {
			existing_interval = (SMIL_Interval *)gf_list_get(rti->intervals, j);
			if (existing_interval->begin==begin->clock) break;
			existing_interval = NULL;
		}
		/* we create an acceptable only if begin is unspecified or defined (clock or wallclock) */
		gf_smil_timing_add_new_interval(rti, existing_interval, begin->clock, i);
	}

}
Пример #4
0
/* assumes that the list of time values is sorted */
static void gf_smil_timing_init_interval_list(SMIL_Timing_RTI *rti)
{
	u32 i, count;
	SMIL_Time *begin;
	SMILTimingAttributesPointers *timingp = rti->timingp;

	if (!timingp) return;

	count = gf_list_count(rti->intervals);
	for (i = 0; i<count; i++) {
		SMIL_Interval *interval = (SMIL_Interval *)gf_list_get(rti->intervals, i);
		free(interval);
	}
	gf_list_reset(rti->intervals);

	count = (timingp->begin ? gf_list_count(*timingp->begin) : 0);
	if (count) {
		for (i = 0; i < count; i ++) {
			begin = (SMIL_Time*)gf_list_get(*timingp->begin, i);
			if (GF_SMIL_TIME_IS_CLOCK(begin->type) ) {
				/* we create an acceptable only if begin is unspecified or defined (clock or wallclock) */
				gf_smil_timing_add_new_interval(rti, NULL, begin->clock, i);
			} else {
				/* this is not an acceptable value for a begin */
			}
		} 
	}
	/*conditional has a default begin value of indefinite*/
	else if (rti->timed_elt->sgprivate->tag != TAG_SVG_conditional) {
		gf_smil_timing_add_new_interval(rti, NULL, 0, 0);
	}
}
Пример #5
0
static void gf_smil_timing_add_new_interval(SMIL_Timing_RTI *rti, SMIL_Interval *interval, Double begin, u32 index)
{
	u32 j, end_count;
	SMIL_Time *end;
	SMILTimingAttributesPointers *timingp = rti->timingp;

	if (!timingp) return;

	if (!interval) {
		GF_SAFEALLOC(interval, SMIL_Interval)
		interval->begin = begin;
		gf_list_add(rti->intervals, interval);
	}

	end_count = (timingp->end ? gf_list_count(*timingp->end) : 0);
	/* trying to find a matching end */
	if (end_count > index) {
		for (j = index; j < end_count; j++) {
			end = (SMIL_Time*)gf_list_get(*timingp->end, j);
			if ( GF_SMIL_TIME_IS_CLOCK(end->type) )  {
				if( end->clock >= interval->begin) {
					interval->end = end->clock;
					break;
				}
			} else {
				/* an unresolved or indefinite value is always good */
				interval->end = -1;
				break;
			}
		}	
	} else {
		interval->end = -1;
	}
	gf_smil_timing_compute_active_duration(rti, interval);
}
Пример #6
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;
}
Пример #7
0
static void gf_smil_timing_get_first_interval(SMIL_Timing_RTI *rti)
{
	u32 i, count;
	memset(rti->current_interval, 0, sizeof(SMIL_Interval));
	rti->current_interval->begin = -1;
	count = (rti->timingp->begin ? gf_list_count(*rti->timingp->begin) : 0);
	for (i = 0; i < count; i ++) {
		SMIL_Time *begin = (SMIL_Time*)gf_list_get(*rti->timingp->begin, i);
		if (GF_SMIL_TIME_IS_CLOCK(begin->type)) {
			rti->current_interval->begin = begin->clock;
			break;
		}
	}
	/*In SVG, if no 'begin' is specified, the default timing of the time container 
	is equivalent to an offset value of '0'.*/
	if (rti->current_interval->begin == -1 && count == 0) {
		/* except for LASeR Conditional element*/
		if (rti->timed_elt->sgprivate->tag != TAG_LSR_conditional) {
			rti->current_interval->begin = 0;
		} else {
			return;
		}
	}
	
	/* this is the first time we check the interval */
	gf_smil_timing_get_interval_end(rti, rti->current_interval);
	if (0 && rti->current_interval->end == -2) {
		/* TODO: check if the interval can be discarded (i.e. if end is specified with an invalid end value (return -2)),
		   probably yes, but next time we call the evaluation of interval, we should call get_first_interval */
		GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, ("[SMIL Timing   ] Time %f - Timed element %s - Wrong Interval\n", gf_node_get_scene_time((GF_Node *)rti->timed_elt), gf_node_get_log_name((GF_Node *)rti->timed_elt)));
		rti->current_interval->begin = -1;
		rti->current_interval->end = -1;
		return;
	}

	gf_smil_timing_compute_active_duration(rti, rti->current_interval);
	gf_smil_timing_print_interval(rti, 1, rti->current_interval);
}
Пример #8
0
/* evaluation function for the discard element 
   returns 1 if the discard was executed
           0 otherwise
*/
static Bool gf_smil_discard(SMIL_Timing_RTI *rti, Fixed scene_time)
{
	u32 nb_inst;
	SMIL_Time *begin;
	SVGTimedAnimBaseElement *tb = (SVGTimedAnimBaseElement *)rti->timed_elt;
	SMILTimingAttributesPointers *timingp = (SMILTimingAttributesPointers *)rti->timingp;
	GF_Node *target;

	if (!timingp) return 0;
	
	target = tb->xlinkp->href ? tb->xlinkp->href->target : NULL;

	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 (begin->clock > scene_time) return 0;

	GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, ("[SVG Composer] discarding element %s at time %f\n", target ? gf_node_get_log_name(target) : "None", scene_time));

	gf_smil_mark_modified(rti, 1);
	
	/*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);
	if (target) 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;
}