static void animationstream_check_url(AnimationStreamStack *stack, M_AnimationStream *as) { if (!stack->stream) { gf_sg_vrml_mf_reset(&stack->current_url, GF_SG_VRML_MFURL); gf_sg_vrml_field_copy(&stack->current_url, &as->url, GF_SG_VRML_MFURL); stack->stream = gf_mo_register((GF_Node *)as, &as->url, 0, 0); gf_sc_invalidate(stack->compositor, NULL); /*if changed while playing trigger*/ if (as->isActive) { gf_mo_play(stack->stream, 0, -1, 0); gf_mo_set_speed(stack->stream, as->speed); } return; } /*check change*/ if (gf_mo_url_changed(stack->stream, &as->url)) { gf_sg_vrml_mf_reset(&stack->current_url, GF_SG_VRML_MFURL); gf_sg_vrml_field_copy(&stack->current_url, &as->url, GF_SG_VRML_MFURL); /*if changed while playing stop old source*/ if (as->isActive) { gf_mo_set_flag(stack->stream, GF_MO_DISPLAY_REMOVE, 1); gf_mo_stop(stack->stream); } gf_mo_unregister((GF_Node *)as, stack->stream); stack->stream = gf_mo_register((GF_Node *)as, &as->url, 0, 0); /*if changed while playing play new source*/ if (as->isActive) { gf_mo_play(stack->stream, 0, -1, 0); gf_mo_set_speed(stack->stream, as->speed); } gf_sc_invalidate(stack->compositor, NULL); } }
GF_EXPORT GF_Err gf_sc_audio_open(GF_AudioInput *ai, MFURL *url, Double clipBegin, Double clipEnd, Bool lock_timeline) { u32 i; if (ai->is_open) return GF_BAD_PARAM; /*get media object*/ ai->stream = gf_mo_register(ai->owner, url, lock_timeline, 0); /*bad URL*/ if (!ai->stream) return GF_NOT_SUPPORTED; /*request play*/ gf_mo_play(ai->stream, clipBegin, clipEnd, 0); ai->stream_finished = 0; ai->is_open = 1; gf_mo_set_flag(ai->stream, GF_MO_IS_INIT, 0); if (ai->filter) gf_af_del(ai->filter); ai->filter = NULL; for (i=0; i<url->count; i++) { if (url->vals[i].url && !strnicmp(url->vals[i].url, "#filter=", 8)) { ai->filter = gf_af_new(ai->compositor, &ai->input_ifce, url->vals[i].url+8); if (ai->filter) break; } } return GF_OK; }
static void svg_traverse_updates(GF_Node *node, void *rs, Bool is_destroy) { /*video stack is just an extension of image stack, type-casting is OK*/ SVG_updates_stack *stack = (SVG_updates_stack*)gf_node_get_private(node); GF_TraverseState *tr_state = (GF_TraverseState *)rs; SVGAllAttributes all_atts; SVGPropertiesPointers backup_props; u32 backup_flags, dirty_flags; if (is_destroy) { if (stack->resource) { if (stack->is_open) { gf_mo_set_flag(stack->resource, GF_MO_DISPLAY_REMOVE, GF_TRUE); gf_mo_stop(stack->resource); } gf_mo_unregister(node, stack->resource); } gf_free(stack); return; } if (tr_state->traversing_mode!=TRAVERSE_SORT) return; /*flatten attributes and apply animations + inheritance*/ gf_svg_flatten_attributes((SVG_Element *)node, &all_atts); if (!compositor_svg_traverse_base(node, &all_atts, (GF_TraverseState *)rs, &backup_props, &backup_flags)) return; dirty_flags = gf_node_dirty_get(node); if (dirty_flags) { stack->clipBegin = all_atts.clipBegin ? *all_atts.clipBegin : 0; stack->clipEnd = all_atts.clipEnd ? *all_atts.clipEnd : -1; if (dirty_flags & GF_SG_SVG_XLINK_HREF_DIRTY) { GF_MediaObject *new_res; MFURL url; Bool lock_timeline=GF_FALSE; url.vals = NULL; url.count = 0; if (all_atts.syncBehavior) lock_timeline = (*all_atts.syncBehavior == SMIL_SYNCBEHAVIOR_LOCKED) ? GF_TRUE : GF_FALSE; gf_term_get_mfurl_from_xlink(node, &url); new_res = gf_mo_register(node, &url, lock_timeline, GF_FALSE); gf_sg_mfurl_del(url); if (stack->resource!=new_res) { if (stack->resource) { gf_mo_stop(stack->resource); gf_mo_unregister(node, stack->resource); } stack->resource = new_res; if (stack->resource && stack->is_open) gf_mo_play(stack->resource, stack->clipBegin, stack->clipEnd, GF_FALSE); } } gf_node_dirty_clear(node, 0); } memcpy(tr_state->svg_props, &backup_props, sizeof(SVGPropertiesPointers)); tr_state->svg_flags = backup_flags; }
static void IS_Register(GF_Node *n) { GF_ObjectManager *odm; ISPriv *is_dec; u32 i; ISStack *st = (ISStack *)gf_node_get_private(n); odm = st->mo->odm; if (!odm) return; assert(odm->codec && (odm->codec->type == GF_STREAM_INTERACT)); /*get IS dec*/ is_dec = (ISPriv*)odm->codec->decio->privateStack; if ( gf_list_find(is_dec->is_nodes, st) == -1 ) gf_list_add(is_dec->is_nodes, st); /*start stream*/ gf_mo_play(st->mo, 0, -1, 0); gf_term_unqueue_node_traverse(odm->term, n); /*we want at least one sensor enabled*/ i=0; while ((st = gf_list_enum(is_dec->is_nodes, &i))) { if (st->is->enabled) { st->registered = 1; if (is_dec->io_dev && is_dec->io_dev->Start) is_dec->io_dev->Start(is_dec->io_dev); break; } } }
static void svg_updates_smil_evaluate(SMIL_Timing_RTI *rti, Fixed normalized_scene_time, u32 status) { SVG_updates_stack *stack = (SVG_updates_stack *)gf_node_get_private(gf_smil_get_element(rti)); switch (status) { case SMIL_TIMING_EVAL_UPDATE: if (!stack->is_open) { if (stack->resource ) gf_mo_play(stack->resource, stack->clipBegin, stack->clipEnd, GF_FALSE); stack->is_open = GF_TRUE; } else if (gf_mo_is_done(stack->resource) && (gf_smil_get_media_duration(rti)<0) ) { Double dur = gf_mo_get_duration(stack->resource); gf_smil_set_media_duration(rti, dur); } break; case SMIL_TIMING_EVAL_FREEZE: case SMIL_TIMING_EVAL_REMOVE: stack->is_open = GF_FALSE; gf_mo_set_flag(stack->resource, GF_MO_DISPLAY_REMOVE, GF_TRUE); gf_mo_stop(stack->resource); break; case SMIL_TIMING_EVAL_REPEAT: gf_mo_restart(stack->resource); break; } }
static void svg_animation_smil_update(GF_Node *node, SVGlinkStack *stack, Fixed normalized_scene_time) { if (stack->init_vis_state == 3) { stack->init_vis_state = 4; gf_mo_resume(stack->resource); } else if (stack->needs_play || (gf_node_dirty_get(node) & GF_SG_SVG_XLINK_HREF_DIRTY )) { SVGAllAttributes all_atts; Double clipBegin, clipEnd; GF_MediaObject *new_res; gf_svg_flatten_attributes((SVG_Element *)node, &all_atts); clipBegin = all_atts.clipBegin ? *all_atts.clipBegin : 0; clipEnd = all_atts.clipEnd ? *all_atts.clipEnd : -1; if (stack->needs_play) { gf_mo_play(stack->resource, clipBegin, clipEnd, 0); stack->needs_play = 0; } else { Bool primary = all_atts.gpac_useAsPrimary ? *all_atts.gpac_useAsPrimary : 1; new_res = gf_mo_load_xlink_resource(node, primary, clipBegin, clipEnd); if (new_res != stack->resource) { if (stack->resource) gf_mo_unload_xlink_resource(node, stack->resource); if (all_atts.xlink_href) all_atts.xlink_href->target = NULL; stack->resource = new_res; stack->fragment_id = NULL; stack->inline_sg = NULL; } gf_node_dirty_clear(node, 0); } } }
static void animationstream_activate(AnimationStreamStack *stack, M_AnimationStream *as) { animationstream_check_url(stack, as); as->isActive = 1; gf_node_event_out((GF_Node*)as, 6/*"isActive"*/); gf_mo_play(stack->stream, 0, -1, 0); gf_mo_set_speed(stack->stream, as->speed); }
static void AS_Activate(AnimationStreamStack *stack, M_AnimationStream *as) { AS_CheckURL(stack, as); as->isActive = 1; gf_node_event_out_str((GF_Node*)as, "isActive"); gf_mo_play(stack->stream, 0, -1, 0); gf_mo_set_speed(stack->stream, as->speed); }
GF_EXPORT GF_Err gf_sc_texture_play_from_to(GF_TextureHandler *txh, MFURL *url, Double start_offset, Double end_offset, Bool can_loop, Bool lock_scene_timeline) { if (!txh->stream) { GF_Err e; e = gf_sc_texture_open(txh, url, lock_scene_timeline); if (e != GF_OK) return e; } /*request play*/ gf_mo_play(txh->stream, start_offset, end_offset, can_loop); txh->last_frame_time = (u32) (-1); //gf_sc_invalidate(txh->compositor, NULL); txh->is_open = 1; /*request play*/ txh->raw_memory = gf_mo_is_raw_memory(txh->stream); return GF_OK; }
GF_EXPORT GF_Err gf_sc_texture_play_from_to(GF_TextureHandler *txh, MFURL *url, Double start_offset, Double end_offset, Bool can_loop, Bool lock_scene_timeline) { if (txh->is_open) return GF_BAD_PARAM; /*if existing texture in cache destroy it - we don't destroy it on stop to handle MovieTexture*/ if (txh->tx_io) gf_sc_texture_release(txh); /*get media object*/ txh->stream = gf_mo_register(txh->owner, url, lock_scene_timeline, 0); /*bad/Empty URL*/ if (!txh->stream) return GF_NOT_SUPPORTED; /*request play*/ gf_mo_play(txh->stream, start_offset, end_offset, can_loop); txh->last_frame_time = (u32) (-1); //gf_sc_invalidate(txh->compositor, NULL); txh->is_open = 1; return GF_OK; }
static Bool gf_inline_set_scene(M_Inline *root) { GF_MediaObject *mo; GF_Scene *parent; GF_SceneGraph *graph = gf_node_get_graph((GF_Node *) root); parent = (GF_Scene *)gf_sg_get_private(graph); if (!parent) return 0; mo = gf_scene_get_media_object_ex(parent, &root->url, GF_MEDIA_OBJECT_SCENE, 0, NULL, 0, (GF_Node*)root); if (!mo || !mo->odm) return 0; if (!mo->odm->subscene) { gf_term_invalidate_compositor(parent->root_od->term); return 0; } /*assign inline scene as private stack of inline node, and remember inline node for event propagation*/ gf_node_set_private((GF_Node *)root, mo->odm->subscene); /*play*/ gf_mo_play(mo, 0, -1, 0); return 1; }
static void IS_Register(GF_Node *n) { GF_ObjectManager *odm; ISPriv *is_dec; ISStack *st = (ISStack *)gf_node_get_private(n); odm = st->mo->odm; if (!odm) return; assert(odm->codec && (odm->codec->type == GF_STREAM_INTERACT)); /*get IS dec*/ is_dec = (ISPriv*)odm->codec->decio->privateStack; gf_list_add(is_dec->is_nodes, st); st->registered = 1; #if GPAC_HTK_DEMO StartHTK(is_dec); #endif /*start stream*/ gf_mo_play(st->mo, 0, -1, 0); gf_term_rem_render_node(odm->term, n); }
GF_MediaObject *gf_mo_load_xlink_resource(GF_Node *node, Bool primary_resource, Double clipBegin, Double clipEnd) { GF_Scene *new_resource; SVGAllAttributes all_atts; XLinkAttributesPointers xlinkp; SMILSyncAttributesPointers syncp; GF_Scene *scene = gf_sg_get_private(gf_node_get_graph(node)); if (!scene) return NULL; gf_svg_flatten_attributes((SVG_Element *)node, &all_atts); xlinkp.actuate = all_atts.xlink_actuate; xlinkp.arcrole = all_atts.xlink_arcrole; xlinkp.href = all_atts.xlink_href; xlinkp.role = all_atts.xlink_role; xlinkp.show = all_atts.xlink_show; xlinkp.title = all_atts.xlink_title; xlinkp.type = all_atts.xlink_type; syncp.syncBehavior = all_atts.syncBehavior; syncp.syncBehaviorDefault = all_atts.syncBehaviorDefault; syncp.syncMaster = all_atts.syncMaster; syncp.syncReference = all_atts.syncReference; syncp.syncTolerance = all_atts.syncTolerance; syncp.syncToleranceDefault = all_atts.syncToleranceDefault; if (!xlinkp.href) return NULL; if (xlinkp.href->type == XMLRI_ELEMENTID) return NULL; // else if (xlinkp.href->string && (xlinkp.href->string[0]=='#')) return NULL; new_resource = gf_svg_get_subscene(node, &xlinkp, &syncp, primary_resource ? 1 : 0, primary_resource); if (!new_resource) return NULL; /*play*/ gf_mo_play(new_resource->root_od->mo, 0, -1, 0); return new_resource->root_od->mo; }
GF_SceneGraph *gf_inline_get_proto_lib(void *_is, MFURL *lib_url) { GF_ProtoLink *pl; u32 i; GF_Scene *scene = (GF_Scene *) _is; if (!scene || !lib_url->count) return NULL; if (gf_inline_is_hardcoded_proto(lib_url, scene->root_od->term->user->config)) return GF_SG_INTERNAL_PROTO; i=0; while ((pl = (GF_ProtoLink*)gf_list_enum(scene->extern_protos, &i))) { if (!pl->mo) continue; if (gf_mo_get_od_id(pl->url) != GF_MEDIA_EXTERNAL_ID) { if (gf_mo_get_od_id(pl->url) == gf_mo_get_od_id(lib_url)) { if (!pl->mo->odm || !pl->mo->odm->subscene) return NULL; return pl->mo->odm->subscene->graph; } } } /*for string URL based protos, recursively check until top if the proto lib is not already present*/ if (lib_url->vals[0].url) { GF_Scene *check_scene = scene; while (check_scene) { i=0; while ((pl = (GF_ProtoLink*)gf_list_enum(check_scene->extern_protos, &i))) { char *url1, *url2; Bool ok; if (!pl->mo) continue; if (gf_mo_get_od_id(pl->url) != GF_MEDIA_EXTERNAL_ID) continue; /*not the same url*/ if (!gf_mo_is_same_url(pl->mo, lib_url, NULL, 0)) continue; /*check the url path is the same*/ url1 = gf_url_concatenate(pl->mo->odm->net_service->url, lib_url->vals[0].url); url2 = gf_url_concatenate(scene->root_od->net_service->url, lib_url->vals[0].url); ok = 0; if (url1 && url2 && !strcmp(url1, url2)) ok=1; if (url1) gf_free(url1); if (url2) gf_free(url2); if (!ok) continue; if (!pl->mo->odm || !pl->mo->odm->subscene) return NULL; return pl->mo->odm->subscene->graph; } check_scene = check_scene->root_od->parentscene; } } /*not found, let's try to load it*/ if (!lib_url || !lib_url->count) return NULL; /*internal, don't waste ressources*/ if (gf_inline_is_hardcoded_proto(lib_url, scene->root_od->term->user->config)) return NULL; i=0; while ((pl = (GF_ProtoLink*)gf_list_enum(scene->extern_protos, &i)) ) { if (pl->url == lib_url) return NULL; if (pl->url->vals[0].OD_ID && (pl->url->vals[0].OD_ID == lib_url->vals[0].OD_ID)) return NULL; if (pl->url->vals[0].url && lib_url->vals[0].url && !stricmp(pl->url->vals[0].url, lib_url->vals[0].url) ) return NULL; } pl = (GF_ProtoLink*)gf_malloc(sizeof(GF_ProtoLink)); pl->url = lib_url; gf_list_add(scene->extern_protos, pl); pl->mo = gf_scene_get_media_object(scene, lib_url, GF_MEDIA_OBJECT_SCENE, 0); /*this may already be destroyed*/ if (pl->mo) gf_mo_play(pl->mo, 0, -1, 0); /*and return NULL*/ return NULL; }