Esempio n. 1
0
void gf_scene_mpeg4_inline_restart(GF_Scene *scene)
{
	u32 current_seg = 0;

	if (scene->root_od->media_ctrl) current_seg = scene->root_od->media_ctrl->current_seg;

	if (scene->is_dynamic_scene) {
		u32 from = 0;
		if (scene->root_od->media_ctrl) {
			scene->root_od->media_ctrl->current_seg = current_seg;
			from = (u32) (scene->root_od->media_ctrl->media_start * 1000);
		}
		gf_scene_restart_dynamic(scene, from);
	} else {
		/*we cannot use gf_mo_restart since it only sets the needs_restart for inline scenes. 
		The rational is that gf_mo_restart can be called from the parent scene (OK) or from the scene itself, in 
		which case shutting down the graph would crash the compositor. We therefore need two render passes to 
		safely restart an inline scene*/

		/*1- stop main object from playing but don't disconnect channels*/
		gf_odm_stop(scene->root_od, 1);
		/*2- close all ODs inside the scene and reset the graph*/
		gf_scene_disconnect(scene, 0);
		if (scene->root_od->media_ctrl) scene->root_od->media_ctrl->current_seg = current_seg;
		/*3- restart the scene*/
		gf_odm_start(scene->root_od, 0);
	}
}
Esempio n. 2
0
void mediacontrol_restart(GF_ObjectManager *odm)
{
	GF_List *to_restart;
	GF_ObjectManager *ctrl_od;
	GF_Clock *ck, *scene_ck;
	u32 i;
	u32 current_seg;
#ifndef GPAC_DISABLE_VRML
	MediaControlStack *ctrl;
#endif

	if (!odm || (odm->flags & GF_ODM_NO_TIME_CTRL) ) return;

#ifndef GPAC_DISABLE_VRML
	ctrl = gf_odm_get_mediacontrol(odm);
	if (ctrl) {
		/*we have a control - filter calls to only handle objects owning media control*/
		ctrl_od = ctrl->stream->odm;
		/*if media control owns the scene this OD refers to the scene is always restarted - TODO make that an option*/
		if (!ctrl_od->subscene) {
			if (ctrl->stream->odm != odm) return;
		}
		odm = ctrl->stream->odm;

		/*this is inline restart - only possible through media control*/
		if (odm->subscene && odm->subscene->root_od==ctrl->stream->odm) {
			gf_inline_restart(odm->subscene);
			return;
		}
	}
#endif

	/*if clock is main scene clock do nothing*/
	scene_ck = gf_odm_get_media_clock(odm->parentscene->root_od);
	if (gf_odm_shares_clock(odm, scene_ck)) {
		if (odm->parentscene->is_dynamic_scene)
			gf_scene_restart_dynamic(odm->parentscene, 0, 0);
		return;
	}

	/*otherwise locate all objects sharing the clock*/
	ck = gf_odm_get_media_clock(odm);
	if (!ck) return;

	current_seg = 0;
#ifndef GPAC_DISABLE_VRML
	/*store current segment idx*/
	if (ctrl) {
		current_seg = ctrl->current_seg;
		/*if last segment is passed restart*/
		if (gf_list_count(ctrl->seg) == current_seg) current_seg = 0;
	}
#endif

	to_restart = gf_list_new();
	/*do stop/start in 2 pass, it's much cleaner for servers*/
	i=0;
	while ((ctrl_od = (GF_ObjectManager*)gf_list_enum(odm->parentscene->resources, &i))) {
		if (!gf_odm_shares_clock(ctrl_od, ck)) continue;
		/*if running, stop and collect for restart*/
		if (ctrl_od->state) {
			gf_odm_stop(ctrl_od, 1);
			gf_list_add(to_restart, ctrl_od);
		}
	}
	/*force clock reset since we don't know how OD ordering is done*/
	gf_clock_reset(ck);
#ifndef GPAC_DISABLE_VRML
	if (ctrl) ctrl->current_seg = current_seg;
#endif

	/*play on all ODs collected for restart*/
	i=0;
	while ((ctrl_od = (GF_ObjectManager*)gf_list_enum(to_restart, &i))) {
		gf_odm_start(ctrl_od, 0);
	}
	gf_list_del(to_restart);
}