static GF_MediaObject *get_sync_reference(GF_Scene *scene, XMLRI *iri, u32 o_type, GF_Node *orig_ref, Bool *post_pone) { MFURL mfurl; SFURL sfurl; GF_MediaObject *res; GF_Node *ref = NULL; u32 stream_id = 0; if (iri->type==XMLRI_STREAMID) { stream_id = iri->lsr_stream_id; } else if (!iri->string) { return NULL; } else { if (iri->target) ref = iri->target; else if (iri->string[0]=='#') ref = gf_sg_find_node_by_name(scene->graph, iri->string+1); else ref = gf_sg_find_node_by_name(scene->graph, iri->string); if (ref) { #ifndef GPAC_DISABLE_SVG GF_FieldInfo info; #endif /*safety check, break cyclic references*/ if (ref==orig_ref) return NULL; switch (ref->sgprivate->tag) { #ifndef GPAC_DISABLE_SVG case TAG_SVG_audio: o_type = GF_MEDIA_OBJECT_AUDIO; if (gf_node_get_attribute_by_tag(ref, TAG_XLINK_ATT_href, 0, 0, &info)==GF_OK) { return get_sync_reference(scene, info.far_ptr, o_type, orig_ref ? orig_ref : ref, post_pone); } return NULL; case TAG_SVG_video: o_type = GF_MEDIA_OBJECT_VIDEO; if (gf_node_get_attribute_by_tag(ref, TAG_XLINK_ATT_href, 0, 0, &info)==GF_OK) { return get_sync_reference(scene, info.far_ptr, o_type, orig_ref ? orig_ref : ref, post_pone); } return NULL; #endif default: return NULL; } } } *post_pone = 0; mfurl.count = 1; mfurl.vals = &sfurl; mfurl.vals[0].OD_ID = stream_id; mfurl.vals[0].url = iri->string; res = gf_scene_get_media_object(scene, &mfurl, o_type, 0); if (!res) *post_pone = 1; return res; }
GF_EXPORT GF_MediaObject *gf_mo_register(GF_Node *node, MFURL *url, Bool lock_timelines, Bool force_new_res) { u32 obj_type; #ifndef GPAC_DISABLE_SVG Bool post_pone; GF_FieldInfo info; #endif GF_Scene *scene; GF_MediaObject *res, *syncRef; GF_SceneGraph *sg = gf_node_get_graph(node); if (!sg) return NULL; scene = (GF_Scene*)gf_sg_get_private(sg); if (!scene) return NULL; syncRef = NULL; /*keep track of the kind of object expected if URL is not using OD scheme*/ switch (gf_node_get_tag(node)) { #ifndef GPAC_DISABLE_VRML /*MPEG-4 / VRML / X3D only*/ case TAG_MPEG4_AudioClip: case TAG_MPEG4_AudioSource: #ifndef GPAC_DISABLE_X3D case TAG_X3D_AudioClip: #endif obj_type = GF_MEDIA_OBJECT_AUDIO; break; case TAG_MPEG4_SBVCAnimation: case TAG_MPEG4_AnimationStream: obj_type = GF_MEDIA_OBJECT_UPDATES; break; case TAG_MPEG4_BitWrapper: obj_type = GF_MEDIA_OBJECT_SCENE; break; case TAG_MPEG4_InputSensor: obj_type = GF_MEDIA_OBJECT_INTERACT; break; case TAG_MPEG4_Background2D: case TAG_MPEG4_Background: case TAG_MPEG4_ImageTexture: case TAG_MPEG4_CacheTexture: case TAG_MPEG4_MovieTexture: #ifndef GPAC_DISABLE_X3D case TAG_X3D_Background: case TAG_X3D_ImageTexture: case TAG_X3D_MovieTexture: #endif obj_type = GF_MEDIA_OBJECT_VIDEO; break; case TAG_MPEG4_Inline: #ifndef GPAC_DISABLE_X3D case TAG_X3D_Inline: #endif obj_type = GF_MEDIA_OBJECT_SCENE; break; #endif /*GPAC_DISABLE_VRML*/ /*SVG*/ #ifndef GPAC_DISABLE_SVG case TAG_SVG_audio: obj_type = GF_MEDIA_OBJECT_AUDIO; if (gf_node_get_attribute_by_tag(node, TAG_SVG_ATT_syncReference, GF_FALSE, GF_FALSE, &info)==GF_OK) { syncRef = get_sync_reference(scene, (XMLRI *)info.far_ptr, GF_MEDIA_OBJECT_UNDEF, node, &post_pone); /*syncRef is specified but doesn't exist yet, post-pone*/ if (post_pone) return NULL; } break; case TAG_SVG_video: obj_type = GF_MEDIA_OBJECT_VIDEO; if (gf_node_get_attribute_by_tag(node, TAG_SVG_ATT_syncReference, GF_FALSE, GF_FALSE, &info)==GF_OK) { syncRef = get_sync_reference(scene, (XMLRI *)info.far_ptr, GF_MEDIA_OBJECT_UNDEF, node, &post_pone); /*syncRef is specified but doesn't exist yet, post-pone*/ if (post_pone) return NULL; } break; case TAG_SVG_image: obj_type = GF_MEDIA_OBJECT_VIDEO; break; case TAG_SVG_foreignObject: case TAG_SVG_animation: obj_type = GF_MEDIA_OBJECT_SCENE; break; case TAG_LSR_updates: obj_type = GF_MEDIA_OBJECT_UPDATES; break; #endif default: obj_type = GF_MEDIA_OBJECT_UNDEF; break; } /*move to primary resource handler*/ while (scene->secondary_resource && scene->root_od->parentscene) scene = scene->root_od->parentscene; res = gf_scene_get_media_object_ex(scene, url, obj_type, lock_timelines, syncRef, force_new_res, node); return res; }