Line data Source code
1 : /*
2 : * GPAC - Multimedia Framework C SDK
3 : *
4 : * Authors: Cyril Concolato - Jean le Feuvre
5 : * Copyright (c) Telecom ParisTech 2005-2017
6 : * All rights reserved
7 : *
8 : * This file is part of GPAC / Scene Compositor sub-project
9 : *
10 : * GPAC is free software; you can redistribute it and/or modify
11 : * it under the terms of the GNU Lesser General Public License as published by
12 : * the Free Software Foundation; either version 2, or (at your option)
13 : * any later version.
14 : *
15 : * GPAC is distributed in the hope that it will be useful,
16 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : * GNU Lesser General Public License for more details.
19 : *
20 : * You should have received a copy of the GNU Lesser General Public
21 : * License along with this library; see the file COPYING. If not, write to
22 : * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23 : *
24 : */
25 :
26 : #include <gpac/constants.h>
27 : #include <gpac/mediaobject.h>
28 :
29 : #ifndef GPAC_DISABLE_SVG
30 :
31 : #include <gpac/internal/scenegraph_dev.h>
32 : #include <gpac/internal/compositor_dev.h>
33 : #include <gpac/nodes_svg.h>
34 : #include <gpac/compositor.h>
35 : #include <gpac/network.h>
36 :
37 : GF_EXPORT
38 29 : GF_Err gf_sc_get_mfurl_from_xlink(GF_Node *node, MFURL *mfurl)
39 : {
40 : u32 stream_id = 0;
41 : GF_Err e = GF_OK;
42 : SFURL *sfurl = NULL;
43 : GF_FieldInfo info;
44 : XMLRI *iri;
45 29 : GF_Scene *scene = gf_sg_get_private(gf_node_get_graph(node));
46 29 : if (!scene) return GF_BAD_PARAM;
47 :
48 29 : gf_sg_vrml_mf_reset(mfurl, GF_SG_VRML_MFURL);
49 :
50 29 : e = gf_node_get_attribute_by_tag(node, TAG_XLINK_ATT_href, 0, 0, &info);
51 29 : if (e) return e;
52 :
53 15 : iri = (XMLRI*)info.far_ptr;
54 :
55 15 : if (iri->type==XMLRI_STREAMID) {
56 1 : stream_id = iri->lsr_stream_id;
57 14 : } else if (!iri->string) return GF_OK;
58 :
59 15 : mfurl->count = 1;
60 15 : GF_SAFEALLOC(mfurl->vals, SFURL)
61 15 : if (!mfurl->vals) return GF_BAD_PARAM;
62 : sfurl = mfurl->vals;
63 15 : sfurl->OD_ID = stream_id;
64 15 : if (stream_id) return GF_OK;
65 :
66 14 : if (!strncmp(iri->string, "data:", 5)) {
67 0 : const char *cache_dir = gf_opts_get_key("core", "cache");
68 0 : e = gf_node_store_embedded_data(iri, cache_dir, "embedded_");
69 0 : if (e) return e;
70 0 : sfurl->url = gf_strdup(iri->string);
71 0 : return GF_OK;
72 : }
73 14 : sfurl->url = gf_scene_resolve_xlink(node, iri->string);
74 14 : return e;
75 : }
76 :
77 :
78 : /* Creates a subscene from the xlink:href */
79 9 : static GF_Scene *gf_svg_get_subscene(GF_Node *elt, XLinkAttributesPointers *xlinkp, SMILSyncAttributesPointers *syncp, Bool use_sync, Bool primary_resource)
80 : {
81 : MFURL url;
82 : Bool lock_timelines = 0;
83 : GF_MediaObject *mo;
84 9 : GF_SceneGraph *graph = gf_node_get_graph(elt);
85 9 : GF_Scene *scene = (GF_Scene *)gf_sg_get_private(graph);
86 9 : if (!scene) return NULL;
87 :
88 9 : if (use_sync && syncp) {
89 7 : switch ((syncp->syncBehavior?*syncp->syncBehavior:SMIL_SYNCBEHAVIOR_DEFAULT)) {
90 0 : case SMIL_SYNCBEHAVIOR_LOCKED:
91 : case SMIL_SYNCBEHAVIOR_CANSLIP:
92 : lock_timelines = 1;
93 : break;
94 : case SMIL_SYNCBEHAVIOR_DEFAULT:
95 : {
96 : #if 0
97 : if (svg && syncp) {
98 : switch ((syncp->syncBehaviorDefault ? *syncp->syncBehaviorDefault : SMIL_SYNCBEHAVIOR_LOCKED)) {
99 : case SMIL_SYNCBEHAVIOR_LOCKED:
100 : case SMIL_SYNCBEHAVIOR_CANSLIP:
101 : lock_timelines = 1;
102 : break;
103 : default:
104 : break;
105 : }
106 : }
107 : #endif
108 : }
109 : default:
110 : break;
111 : }
112 : }
113 : memset(&url, 0, sizeof(MFURL));
114 9 : if (!xlinkp->href) return NULL;
115 :
116 9 : gf_sc_get_mfurl_from_xlink(elt, &url);
117 :
118 9 : while (scene->secondary_resource && scene->root_od->parentscene)
119 : scene = scene->root_od->parentscene;
120 :
121 9 : mo = gf_scene_get_media_object_ex(scene, &url, GF_MEDIA_OBJECT_SCENE, lock_timelines, NULL, primary_resource, elt);
122 9 : gf_sg_vrml_mf_reset(&url, GF_SG_VRML_MFURL);
123 :
124 9 : if (!mo || !mo->odm) return NULL;
125 9 : mo->odm->subscene->secondary_resource = primary_resource ? 0 : 1;
126 9 : return mo->odm->subscene;
127 : }
128 :
129 : GF_EXPORT
130 10 : GF_MediaObject *gf_mo_load_xlink_resource(GF_Node *node, Bool primary_resource, Double clipBegin, Double clipEnd)
131 : {
132 : GF_Scene *new_resource;
133 : SVGAllAttributes all_atts;
134 : XLinkAttributesPointers xlinkp;
135 : SMILSyncAttributesPointers syncp;
136 10 : GF_Scene *scene = gf_sg_get_private(gf_node_get_graph(node));
137 10 : if (!scene) return NULL;
138 :
139 10 : gf_svg_flatten_attributes((SVG_Element *)node, &all_atts);
140 10 : xlinkp.actuate = all_atts.xlink_actuate;
141 10 : xlinkp.arcrole = all_atts.xlink_arcrole;
142 10 : xlinkp.href = all_atts.xlink_href;
143 10 : xlinkp.role = all_atts.xlink_role;
144 10 : xlinkp.show = all_atts.xlink_show;
145 10 : xlinkp.title = all_atts.xlink_title;
146 10 : xlinkp.type = all_atts.xlink_type;
147 10 : syncp.syncBehavior = all_atts.syncBehavior;
148 10 : syncp.syncBehaviorDefault = all_atts.syncBehaviorDefault;
149 10 : syncp.syncMaster = all_atts.syncMaster;
150 10 : syncp.syncReference = all_atts.syncReference;
151 10 : syncp.syncTolerance = all_atts.syncTolerance;
152 10 : syncp.syncToleranceDefault = all_atts.syncToleranceDefault;
153 :
154 10 : if (!xlinkp.href) return NULL;
155 :
156 10 : if (xlinkp.href->type == XMLRI_ELEMENTID) return NULL;
157 : // else if (xlinkp.href->string && (xlinkp.href->string[0]=='#')) return NULL;
158 :
159 9 : new_resource = gf_svg_get_subscene(node, &xlinkp, &syncp, primary_resource ? 1 : 0, primary_resource);
160 9 : if (!new_resource) return NULL;
161 :
162 : /*play*/
163 9 : gf_mo_play(new_resource->root_od->mo, 0, -1, 0);
164 :
165 9 : return new_resource->root_od->mo;
166 : }
167 :
168 : GF_EXPORT
169 9 : void gf_mo_unload_xlink_resource(GF_Node *node, GF_MediaObject *mo)
170 : {
171 9 : if (!mo || !mo->odm || !mo->odm->subscene) {
172 : return;
173 : }
174 :
175 8 : if (mo->num_open) {
176 8 : mo->num_open--;
177 8 : if (!mo->num_open) {
178 : /*do we simply stop the associated document or unload it??? to check*/
179 : // gf_mo_stop(&mo);
180 7 : gf_odm_disconnect(mo->odm, 2);
181 7 : return;
182 : }
183 : }
184 : }
185 :
186 : #endif //GPAC_DISABLE_SVG
187 :
|