/*buffering scene protected by a mutex because it may be triggered by composition memory (audio or visual threads)*/ void gf_clock_buffer_on(GF_Clock *ck) { gf_mx_p(ck->mx); if (!ck->Buffering) gf_clock_pause(ck); ck->Buffering += 1; gf_mx_v(ck->mx); }
/*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); } } }
/*special handling of decoders not using ESM*/ static GF_Err PrivateScene_Process(GF_Codec *codec, u32 TimeAvailable) { Bool resume_clock; u32 now; GF_Channel *ch; GF_Scene *scene_locked; GF_SceneDecoder *sdec = (GF_SceneDecoder *)codec->decio; GF_Err e = GF_OK; /*muting systems codec means we don't decode until mute is off - likely there will be visible however there is no other way to decode system AUs without modifying the content, which is what mute is about on visual...*/ if (codec->Muted) return GF_OK; if (codec->Status == GF_ESM_CODEC_EOS) { gf_term_stop_codec(codec); return GF_OK; } scene_locked = codec->odm->subscene ? codec->odm->subscene : codec->odm->parentscene; ch = (GF_Channel*)gf_list_get(codec->inChannels, 0); if (!ch) return GF_OK; resume_clock = 0; /*init channel clock*/ if (!ch->IsClockInit) { Bool started; /*signal seek*/ if (!gf_mx_try_lock(scene_locked->root_od->term->compositor->mx)) return GF_OK; gf_es_init_dummy(ch); sdec->ProcessData(sdec, NULL, 0, ch->esd->ESID, -1, GF_CODEC_LEVEL_NORMAL); gf_mx_v(scene_locked->root_od->term->compositor->mx); started = gf_clock_is_started(ch->clock); /*let's be nice to the scene loader (that usually involves quite some parsing), pause clock while parsing*/ gf_clock_pause(ch->clock); codec->last_unit_dts = 0; if (!started) return GF_OK; } codec->odm->current_time = codec->last_unit_cts = gf_clock_time(codec->ck); /*lock scene*/ GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[PrivateDec] Codec %s Processing at %d\n", sdec->module_name , codec->odm->current_time)); if (!gf_mx_try_lock(scene_locked->root_od->term->compositor->mx)) return GF_OK; now = gf_term_get_time(codec->odm->term); e = sdec->ProcessData(sdec, NULL, 0, ch->esd->ESID, codec->odm->current_time, GF_CODEC_LEVEL_NORMAL); now = gf_term_get_time(codec->odm->term) - now; codec->last_unit_dts ++; /*resume on error*/ if (e && (codec->last_unit_dts<2) ) { gf_clock_resume(ch->clock); codec->last_unit_dts = 2; } /*resume clock on 2nd decode (we assume parsing is done in 2 steps, one for first frame display, one for complete parse)*/ else if (codec->last_unit_dts==2) { gf_clock_resume(ch->clock); } codec_update_stats(codec, 0, now); gf_mx_v(scene_locked->root_od->term->compositor->mx); if (e==GF_EOS) { /*first end of stream, evaluate duration*/ //if (!codec->odm->duration) gf_odm_set_duration(codec->odm, ch, codec->odm->current_time); gf_es_on_eos(ch); return GF_OK; } return e; }