/*pause all objects*/ void MC_SetSpeed(GF_ObjectManager *odm, Fixed speed) { u32 i; GF_ObjectManager *ctrl_od; GF_Scene *in_scene; GF_Clock *ck; if (odm->flags & GF_ODM_NO_TIME_CTRL) return; /*locate all objects sharing the clock*/ ck = gf_odm_get_media_clock(odm); if (!ck) return; in_scene = odm->parentscene; if (odm->subscene) { assert(odm->subscene->root_od==odm); // assert( gf_odm_shares_clock(odm, ck) ); gf_odm_set_speed(odm, speed, GF_TRUE); in_scene = odm->subscene; } i=0; while ((ctrl_od = (GF_ObjectManager*)gf_list_enum(in_scene->resources, &i))) { if (!gf_odm_shares_clock(ctrl_od, ck)) continue; gf_odm_set_speed(ctrl_od, speed, GF_TRUE); } }
/*pause all objects*/ void mediacontrol_pause(GF_ObjectManager *odm) { u32 i; GF_ObjectManager *ctrl_od; GF_Scene *in_scene; GF_Clock *ck; if (odm->flags & GF_ODM_NO_TIME_CTRL) return; /*otherwise locate all objects sharing the clock*/ ck = gf_odm_get_media_clock(odm); if (!ck) { odm->flags |= GF_ODM_PAUSE_QUEUED; return; } in_scene = odm->parentscene; if (odm->subscene) { assert(odm->subscene->root_od==odm); assert(odm->subscene->is_dynamic_scene || gf_odm_shares_clock(odm, ck) ); /*pause root*/ gf_odm_pause(odm); in_scene = odm->subscene; } i=0; while ((ctrl_od = (GF_ObjectManager*)gf_list_enum(in_scene->resources, &i))) { if (!odm->subscene && !gf_odm_shares_clock(ctrl_od, ck)) continue; if (ctrl_od->addon && (ctrl_od->addon->addon_type==GF_ADDON_TYPE_MAIN)) { gf_clock_pause(ck); gf_scene_select_main_addon(in_scene, ctrl_od, GF_TRUE, gf_clock_time(ck) ); } if (ctrl_od->subscene) { mediacontrol_pause(ctrl_od); } else { gf_odm_pause(ctrl_od); } } }
/*pause all objects*/ void mediacontrol_set_speed(GF_ObjectManager *odm, Fixed speed) { u32 i; GF_ObjectManager *ctrl_od; GF_Scene *in_scene; GF_Clock *ck; if (odm->flags & GF_ODM_NO_TIME_CTRL) return; /*locate all objects sharing the clock*/ ck = gf_odm_get_media_clock(odm); if (!ck) return; in_scene = odm->parentscene; if (odm->subscene) { assert(odm->subscene->root_od==odm); in_scene = odm->subscene; //dynamic scene with speed direction, we need to re-start everything to issue new PLAY requests if (in_scene->is_dynamic_scene && (gf_mulfix(ck->speed, speed) < 0)) { u32 time = gf_clock_time(ck); gf_clock_set_speed(ck, speed); //enable main addon if (speed<0) { i=0; while ((ctrl_od = (GF_ObjectManager*)gf_list_enum(in_scene->resources, &i))) { if (ctrl_od->addon && (ctrl_od->addon->addon_type==GF_ADDON_TYPE_MAIN)) { gf_scene_select_main_addon(in_scene, ctrl_od, GF_TRUE, gf_clock_time(ck) ); break; } } } gf_scene_restart_dynamic(in_scene, time, 0, 1); return; } gf_clock_set_speed(ck, speed); gf_odm_set_speed(odm, speed, GF_TRUE); } i=0; while ((ctrl_od = (GF_ObjectManager*)gf_list_enum(in_scene->resources, &i))) { if (!gf_odm_shares_clock(ctrl_od, ck)) continue; if (ctrl_od->subscene) { mediacontrol_set_speed(ctrl_od, speed); } else { gf_odm_set_speed(ctrl_od, speed, GF_TRUE); } } }
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); }