~ubuntu-branches/ubuntu/intrepid/gpac/intrepid-proposed

« back to all changes in this revision

Viewing changes to modules/ctx_load/ctx_load.c

  • Committer: Bazaar Package Importer
  • Author(s): John Dong
  • Date: 2007-01-24 23:34:57 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20070124233457-zzlls8afkt0nyakj
Tags: 0.4.2~rc2-0ubuntu1
* New upstream release
  * Most notably MP4 tagging support via MP4Box -itags
* debian/patches/01_64bits.dpatch: dropped; included upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
#include <gpac/scene_manager.h>
27
27
#include <gpac/constants.h>
28
28
#include <gpac/network.h>
 
29
#include <gpac/nodes_mpeg4.h>
29
30
 
30
31
 
31
32
typedef struct 
33
34
        GF_InlineScene *inline_scene;
34
35
        GF_Terminal *app;
35
36
        GF_SceneManager *ctx;
36
 
        char *fileName;
 
37
        GF_SceneLoader load;
 
38
        char *file_name;
 
39
        u32 file_size;
37
40
        u32 load_flags;
38
41
        u32 nb_streams;
39
42
        u32 base_stream_id;
 
43
        u32 last_check_time, last_check_size;
40
44
        /*mp3 import from flash*/
41
45
        GF_List *files_to_delete;
42
 
        GF_SceneLoader load;
 
46
        /*progressive loading support for XMT X3D*/
 
47
        FILE *src;
 
48
        u32 file_pos, sax_max_duration;
 
49
        Bool progressive_support;
43
50
} CTXLoadPriv;
44
51
 
45
52
 
99
106
        CTXLoadPriv *priv = (CTXLoadPriv *) gf_node_get_private(node);
100
107
        M_Conditional*c = (M_Conditional*)node;
101
108
        /*always apply in parent graph to handle protos correctly*/
102
 
        if (!c->reverseActivate) gf_sg_command_apply_list(gf_node_get_graph(node), c->buffer.commandList, gf_is_get_time(priv->inline_scene));
 
109
        if (!c->reverseActivate) 
 
110
                gf_sg_command_apply_list(gf_node_get_graph(node), c->buffer.commandList, gf_is_get_time(priv->inline_scene));
103
111
}
104
112
 
105
113
void CTXLoad_NodeInit(void *cbk, GF_Node *node)
106
114
{
107
115
        CTXLoadPriv *priv = (CTXLoadPriv *) cbk;
108
116
        if (gf_node_get_tag(node) == TAG_MPEG4_Conditional) {
109
 
                ((M_Conditional*)node)->on_activate = CTXLoad_OnActivate;
110
 
                ((M_Conditional*)node)->on_reverseActivate = CTXLoad_OnReverseActivate;
 
117
                M_Conditional*c = (M_Conditional*)node;
 
118
                c->on_activate = CTXLoad_OnActivate;
 
119
                c->on_reverseActivate = CTXLoad_OnReverseActivate;
111
120
                gf_node_set_private(node, priv);
112
121
        } else {
113
122
                gf_term_on_node_init(priv->inline_scene, node);
114
123
        }
115
124
}
116
125
 
117
 
static GF_Err CTXLoad_AttachScene(GF_SceneDecoder *plug, GF_InlineScene *scene, Bool is_scene_decoder)
 
126
static Bool CTXLoad_CheckDownload(CTXLoadPriv *priv)
 
127
{
 
128
        u32 size;
 
129
        FILE *f;
 
130
        u32 now = gf_sys_clock();
 
131
 
 
132
        if (!priv->file_size && (now - priv->last_check_time < 1000) ) return 0;
 
133
 
 
134
        f = fopen(priv->file_name, "rt");
 
135
        fseek(f, 0, SEEK_END);
 
136
        size = ftell(f);
 
137
        fclose(f);
 
138
 
 
139
        /*we MUST have a complete file for now ...*/
 
140
        if (!priv->file_size) {
 
141
                if (priv->last_check_size == size) return 1;
 
142
                priv->last_check_size = size;
 
143
                priv->last_check_time = now;
 
144
        } else {
 
145
                if (size==priv->file_size) return 1;
 
146
        }
 
147
        return 0;
 
148
}
 
149
 
 
150
static void CTXLoad_OnMessage(void *cbk, char *szMsg, GF_Err e)
 
151
{
 
152
        CTXLoadPriv *priv = (CTXLoadPriv *)cbk;
 
153
        gf_term_message(priv->inline_scene->root_od->term, priv->inline_scene->root_od->net_service->url, szMsg, e);
 
154
}
 
155
 
 
156
static void CTXLoad_OnProgress(void *cbk, u32 done, u32 tot)
 
157
{
 
158
        GF_Event evt;
 
159
        CTXLoadPriv *priv = (CTXLoadPriv *)cbk;
 
160
        evt.type = GF_EVT_PROGRESS;
 
161
        evt.progress.progress_type = 2;
 
162
        evt.progress.done = done;
 
163
        evt.progress.total = tot;
 
164
        evt.progress.service = priv->inline_scene->root_od->net_service->url;
 
165
        GF_USER_SENDEVENT(priv->inline_scene->root_od->term->user, &evt);
 
166
}
 
167
 
 
168
 
 
169
static GF_Err CTXLoad_Setup(GF_BaseDecoder *plug)
118
170
{
119
171
        CTXLoadPriv *priv = plug->privateStack;
120
 
        if (priv->ctx) return GF_BAD_PARAM;
121
 
 
122
 
        priv->inline_scene = scene;
123
 
        priv->app = scene->root_od->term;
124
 
 
125
 
        gf_sg_set_init_callback(scene->graph, CTXLoad_NodeInit, priv);
126
 
        return GF_OK;
127
 
}
128
 
 
129
 
static GF_Err CTXLoad_ReleaseScene(GF_SceneDecoder *plug)
130
 
{
131
 
        CTXLoad_Reset((CTXLoadPriv *) plug->privateStack);
 
172
        if (!priv->file_name) return GF_BAD_PARAM;
 
173
 
 
174
        priv->ctx = gf_sm_new(priv->inline_scene->graph);
 
175
        memset(&priv->load, 0, sizeof(GF_SceneLoader));
 
176
        priv->load.ctx = priv->ctx;
 
177
        priv->load.cbk = priv;
 
178
        priv->load.scene_graph = priv->inline_scene->graph;
 
179
        priv->load.fileName = priv->file_name;
 
180
        priv->load.OnMessage = CTXLoad_OnMessage;
 
181
        priv->load.OnProgress = CTXLoad_OnProgress;
 
182
        priv->load.flags = GF_SM_LOAD_FOR_PLAYBACK;
 
183
        priv->load.localPath = gf_modules_get_option((GF_BaseInterface *)plug, "General", "CacheDirectory");
 
184
        priv->load.swf_import_flags = GF_SM_SWF_STATIC_DICT | GF_SM_SWF_QUAD_CURVE | GF_SM_SWF_SCALABLE_LINE;
132
185
        return GF_OK;
133
186
}
134
187
 
140
193
                                                                         u32 objectTypeIndication, 
141
194
                                                                         Bool Upstream)
142
195
{
 
196
        const char *ext;
 
197
        GF_BitStream *bs;
143
198
        CTXLoadPriv *priv = plug->privateStack;
144
199
        if (Upstream) return GF_NOT_SUPPORTED;
145
200
 
146
201
        /*animation stream like*/
147
202
        if (priv->ctx) {
148
 
                u32 i;
149
 
                for (i=0; i<gf_list_count(priv->ctx->streams); i++) {
150
 
                        GF_StreamContext *sc = gf_list_get(priv->ctx->streams, i);
 
203
                GF_StreamContext *sc;
 
204
                u32 i = 0;
 
205
                while ((sc = gf_list_enum(priv->ctx->streams, &i))) {
151
206
                        if (ES_ID == sc->ESID) {
152
207
                                priv->nb_streams++;
153
208
                                return GF_OK;
156
211
                return GF_NON_COMPLIANT_BITSTREAM;
157
212
        }
158
213
        /*main dummy stream we need a dsi*/
159
 
        if (!decSpecInfo) return GF_NON_COMPLIANT_BITSTREAM;
160
 
 
161
 
        priv->fileName = strdup(decSpecInfo);
 
214
        if (!decSpecInfo) 
 
215
                return GF_NON_COMPLIANT_BITSTREAM;
 
216
        bs = gf_bs_new(decSpecInfo, decSpecInfoSize, GF_BITSTREAM_READ);
 
217
        priv->file_size = gf_bs_read_u32(bs);
 
218
        gf_bs_del(bs);
 
219
        GF_SAFEALLOC(priv->file_name, sizeof(char)*(1 + decSpecInfoSize - sizeof(u32)) );
 
220
        memcpy(priv->file_name, decSpecInfo + sizeof(u32),  sizeof(char)*(decSpecInfoSize - sizeof(u32)) );
162
221
        priv->nb_streams = 1;
163
222
        priv->load_flags = 0;
164
223
        priv->base_stream_id = ES_ID;
 
224
 
 
225
        
 
226
        CTXLoad_Setup(plug);
 
227
 
 
228
        priv->progressive_support = 0;
 
229
        priv->sax_max_duration = 0;
 
230
 
 
231
        ext = strrchr(priv->file_name, '.');
 
232
        if (!ext) return GF_OK;
 
233
 
 
234
        ext++;
 
235
        if (!stricmp(ext, "xmt") || !stricmp(ext, "xmtz") || !stricmp(ext, "xmta") 
 
236
                || !stricmp(ext, "x3d") || !stricmp(ext, "x3dz")
 
237
        ) {
 
238
                ext = gf_modules_get_option((GF_BaseInterface *)plug, "SAXLoader", "Progressive");
 
239
                priv->progressive_support = (ext && !stricmp(ext, "yes")) ? 1 : 0;
 
240
        }
 
241
        if (priv->progressive_support) {
 
242
                ext = gf_modules_get_option((GF_BaseInterface *)plug, "SAXLoader", "MaxDuration");
 
243
                if (ext) priv->sax_max_duration = atoi(ext);
 
244
        }
165
245
        return GF_OK;
166
246
}
167
247
 
172
252
        return GF_OK;
173
253
}
174
254
 
 
255
static GF_Err CTXLoad_AttachScene(GF_SceneDecoder *plug, GF_InlineScene *scene, Bool is_scene_decoder)
 
256
{
 
257
        CTXLoadPriv *priv = plug->privateStack;
 
258
        if (priv->ctx) return GF_BAD_PARAM;
 
259
 
 
260
        priv->inline_scene = scene;
 
261
        priv->app = scene->root_od->term;
 
262
 
 
263
        gf_sg_set_init_callback(scene->graph, CTXLoad_NodeInit, priv);
 
264
 
 
265
        return GF_OK;
 
266
}
 
267
 
 
268
static GF_Err CTXLoad_ReleaseScene(GF_SceneDecoder *plug)
 
269
{
 
270
        CTXLoad_Reset((CTXLoadPriv *) plug->privateStack);
 
271
        return GF_OK;
 
272
}
 
273
 
175
274
static Bool CTXLoad_StreamInRootOD(GF_ObjectDescriptor *od, u32 ESID)
176
275
{
177
276
        u32 i, count;
187
286
        return 0;
188
287
}
189
288
 
190
 
static void CTXLoad_OnMessage(void *cbk, char *szMsg, GF_Err e)
191
 
{
192
 
        CTXLoadPriv *priv = (CTXLoadPriv *)cbk;
193
 
        gf_term_message(priv->inline_scene->root_od->term, priv->inline_scene->root_od->net_service->url, szMsg, e);
194
 
}
195
 
 
196
 
static void CTXLoad_OnProgress(void *cbk, u32 done, u32 tot)
197
 
{
198
 
        GF_Event evt;
199
 
        CTXLoadPriv *priv = (CTXLoadPriv *)cbk;
200
 
        evt.type = GF_EVT_PROGRESS;
201
 
        evt.progress.progress_type = 2;
202
 
        evt.progress.done = done;
203
 
        evt.progress.total = tot;
204
 
        evt.progress.service = priv->inline_scene->root_od->net_service->url;
205
 
        GF_USER_SENDEVENT(priv->inline_scene->root_od->term->user, &evt);
206
 
}
207
289
 
208
290
static GF_SceneGraph *CTXLoad_GetProtoLib(void *cbk, MFURL *lib_url)
209
291
{
222
304
        return res;
223
305
}
224
306
 
 
307
static void CTXLoad_CheckStreams(CTXLoadPriv *priv )
 
308
{
 
309
        u32 i, j, max_dur;
 
310
        GF_AUContext *au;
 
311
        GF_StreamContext *sc;
 
312
        max_dur = 0;
 
313
        i=0;
 
314
        while ((sc = gf_list_enum(priv->ctx->streams, &i))) {
 
315
                /*all streams in root OD are handled with ESID 0 to differentiate with any animation streams*/
 
316
                if (CTXLoad_StreamInRootOD(priv->ctx->root_od, sc->ESID)) sc->ESID = 0;
 
317
                if (!sc->timeScale) sc->timeScale = 1000;
 
318
 
 
319
                j=0;
 
320
                while ((au = gf_list_enum(sc->AUs, &j))) {
 
321
                        if (!au->timing) au->timing = (u64) (sc->timeScale*au->timing_sec);
 
322
                }
 
323
                if (au && !sc->ESID && (au->timing>max_dur)) max_dur = (u32) (au->timing * 1000 / sc->timeScale);
 
324
        }
 
325
        if (max_dur) {
 
326
                priv->inline_scene->root_od->duration = max_dur;
 
327
                gf_is_set_duration(priv->inline_scene);
 
328
        }
 
329
}
225
330
 
226
331
static GF_Err CTXLoad_ProcessData(GF_SceneDecoder *plug, unsigned char *inBuffer, u32 inBufferLength, 
227
332
                                                                u16 ES_ID, u32 stream_time, u32 mmlevel)
228
333
{
229
334
        GF_Err e = GF_OK;
230
 
        u32 i, j, k, nb_updates, max_dur;
 
335
        u32 i, j, k, nb_updates;
231
336
        GF_AUContext *au;
232
337
        Bool can_delete_com;
233
338
        GF_StreamContext *sc;
238
343
 
239
344
        /*this signals main scene deconnection, destroy the context if needed*/
240
345
        assert(ES_ID);
 
346
        if (!priv->ctx) {
 
347
                e = CTXLoad_Setup((GF_BaseDecoder *)plug);
 
348
                if (e) return e;
 
349
        }
241
350
 
242
351
        if (priv->load_flags != 2) {
 
352
 
 
353
                if (priv->progressive_support) {
 
354
                        u32 entry_time;
 
355
                        char file_buf[4096+1];
 
356
                        if (!priv->src) {
 
357
                                priv->src = fopen(priv->file_name, "rb");
 
358
                                if (!priv->src) return GF_URL_ERROR;
 
359
                                priv->file_pos = 0;
 
360
                        }
 
361
                        priv->load.type = GF_SM_LOAD_XMTA;
 
362
                        e = GF_OK;
 
363
                        entry_time = gf_sys_clock();
 
364
                        fseek(priv->src, priv->file_pos, SEEK_SET);
 
365
                        while (1) {
 
366
                                u32 diff, nb_read;
 
367
                                nb_read = fread(file_buf, 1, 4096, priv->src);
 
368
                                file_buf[nb_read] = 0;
 
369
                                if (!nb_read) {
 
370
                                        if (priv->file_pos==priv->file_size) {
 
371
                                                CTXLoad_OnProgress(priv, priv->file_pos, priv->file_size);
 
372
                                                fclose(priv->src);
 
373
                                                priv->src = NULL;
 
374
                                                priv->load_flags = 2;
 
375
                                                gf_sm_load_done(&priv->load);
 
376
                                                break;
 
377
                                        }
 
378
                                        break;
 
379
                                }
 
380
 
 
381
                                e = gf_sm_load_string(&priv->load, file_buf, 0);
 
382
                                priv->file_pos += nb_read;
 
383
                                if (e) break;
 
384
                                diff = gf_sys_clock() - entry_time;
 
385
                                CTXLoad_OnProgress(priv, priv->file_pos, priv->file_size);
 
386
                                if (diff > priv->sax_max_duration) break;
 
387
                        }
 
388
                        if (!priv->inline_scene->graph_attached) {
 
389
                                gf_sg_set_scene_size_info(priv->inline_scene->graph, priv->ctx->scene_width, priv->ctx->scene_height, priv->ctx->is_pixel_metrics);
 
390
                                gf_is_attach_to_renderer(priv->inline_scene);
 
391
 
 
392
                                CTXLoad_CheckStreams(priv);
 
393
                        }
 
394
                }
243
395
                /*load first frame only*/
244
 
                if (!priv->load_flags) {
 
396
                else if (!priv->load_flags) {
 
397
                        /*we need the whole file*/
 
398
                        if (!CTXLoad_CheckDownload(priv)) return GF_OK;
 
399
 
245
400
                        priv->load_flags = 1;
246
 
                        priv->ctx = gf_sm_new(priv->inline_scene->graph);
247
 
                        memset(&priv->load, 0, sizeof(GF_SceneLoader));
248
 
                        priv->load.ctx = priv->ctx;
249
 
                        priv->load.cbk = priv;
250
 
                        priv->load.scene_graph = priv->inline_scene->graph;
251
 
                        priv->load.fileName = priv->fileName;
252
 
                        priv->load.OnMessage = CTXLoad_OnMessage;
253
 
                        priv->load.OnProgress = CTXLoad_OnProgress;
254
 
                        priv->load.flags = GF_SM_LOAD_FOR_PLAYBACK;
255
 
                        priv->load.swf_import_flags = GF_SM_SWF_STATIC_DICT | GF_SM_SWF_QUAD_CURVE | GF_SM_SWF_SCALABLE_LINE;
256
401
                        e = gf_sm_load_init(&priv->load);
257
402
                        if (!e) {
258
403
                                gf_sg_set_scene_size_info(priv->inline_scene->graph, priv->ctx->scene_width, priv->ctx->scene_height, priv->ctx->is_pixel_metrics);
278
423
                }
279
424
 
280
425
                /*and figure out duration of root scene, and take care of XMT timing*/
281
 
                max_dur = 0;
282
 
                for (i=0; i<gf_list_count(priv->ctx->streams); i++) {
283
 
                        sc = gf_list_get(priv->ctx->streams, i);
284
 
                        /*all streams in root OD are handled with ESID 0 to differentiate with any animation streams*/
285
 
                        if (CTXLoad_StreamInRootOD(priv->ctx->root_od, sc->ESID)) sc->ESID = 0;
286
 
                        if (!sc->timeScale) sc->timeScale = 1000;
287
 
 
288
 
                        au = NULL;
289
 
                        for (j = 0; j<gf_list_count(sc->AUs); j++) {
290
 
                                au = gf_list_get(sc->AUs, j);
291
 
                                if (!au->timing) au->timing = (u32) (sc->timeScale*au->timing_sec);
292
 
                        }
293
 
                        if (au && !sc->ESID && (au->timing>max_dur)) max_dur = au->timing * 1000 / sc->timeScale;
294
 
                }
295
426
                if (priv->load_flags==2) {
296
 
                        if (max_dur) {
297
 
                                priv->inline_scene->root_od->duration = max_dur;
298
 
                                gf_is_set_duration(priv->inline_scene);
 
427
                        CTXLoad_CheckStreams(priv);
 
428
                        if (!gf_list_count(priv->ctx->streams)) {
 
429
                                gf_is_attach_to_renderer(priv->inline_scene);
299
430
                        }
300
431
                }
301
432
        }
302
433
 
303
434
        nb_updates = 0;
304
435
 
305
 
        for (i=0; i<gf_list_count(priv->ctx->streams); i++) {
306
 
                GF_StreamContext *sc = gf_list_get(priv->ctx->streams, i);
 
436
        i=0;
 
437
        while ((sc = gf_list_enum(priv->ctx->streams, &i))) {
307
438
                /*not our stream*/
308
439
                if (sc->ESID && (sc->ESID != ES_ID)) continue;
309
440
                /*not the base stream*/
325
456
                if (!sc->ESID && (priv->load_flags==2)) can_delete_com = 1;
326
457
 
327
458
                /*we're in the right stream, apply update*/
328
 
                for (j=0; j<gf_list_count(sc->AUs); j++) {
329
 
                        GF_AUContext *au = gf_list_get(sc->AUs, j);
330
 
                        u32 au_time = au->timing*1000/sc->timeScale;
 
459
                j=0;
 
460
                while ((au = gf_list_enum(sc->AUs, &j))) {
 
461
                        u32 au_time = (u32) (au->timing*1000/sc->timeScale);
331
462
                        if (au_time + 1 <= sc->last_au_time) {
332
463
                                /*remove first replace command*/
333
 
                                if (!sc->ESID && (sc->streamType==GF_STREAM_SCENE)) {
 
464
                                if (can_delete_com && (sc->streamType==GF_STREAM_SCENE)) {
334
465
                                        while (gf_list_count(au->commands)) {
335
466
                                                GF_Command *com = gf_list_get(au->commands, 0);
336
467
                                                gf_list_rem(au->commands, 0);
337
468
                                                gf_sg_command_del(com);
338
469
                                        }
 
470
                                        j--;
339
471
                                        gf_list_rem(sc->AUs, j);
340
472
                                        gf_list_del(au->commands);
341
473
                                        free(au);
342
 
                                        j--;
343
474
                                }
344
475
                                continue;
345
476
                        }
349
480
                        }
350
481
 
351
482
                        if (sc->streamType == GF_STREAM_SCENE) {
 
483
                                GF_Command *com;
352
484
                                /*apply the commands*/
353
 
                                for (k=0; k<gf_list_count(au->commands); k++) {
354
 
                                        GF_Command *com = gf_list_get(au->commands, k);
 
485
                                k=0;
 
486
                                while ((com = gf_list_enum(au->commands, &k))) {
355
487
                                        e = gf_sg_command_apply(priv->inline_scene->graph, com, 0);
356
488
                                        if (e) break;
357
489
                                        /*remove commands on base layer*/
358
490
                                        if (can_delete_com) {
 
491
                                                k--;
359
492
                                                gf_list_rem(au->commands, k);
360
493
                                                gf_sg_command_del(com);
361
 
                                                k--;
362
494
                                        }
363
495
                                }
364
496
                        } 
397
529
                                                                continue;
398
530
                                                        }
399
531
                                                        /*look for MUX info*/
400
 
                                                        for (k=0; k<gf_list_count(esd->extensionDescriptors); k++) {
401
 
                                                                mux = gf_list_get(esd->extensionDescriptors, k);
 
532
                                                        k=0;
 
533
                                                        while ((mux = gf_list_enum(esd->extensionDescriptors, &k))) {
402
534
                                                                if (mux->tag == GF_ODF_MUXINFO_TAG) break;
403
535
                                                                mux = NULL;
404
536
                                                        }
496
628
 
497
629
                        /*for root streams remove completed AUs (no longer needed)*/
498
630
                        if (!sc->ESID && !gf_list_count(au->commands) ) {
 
631
                                j--;
499
632
                                gf_list_rem(sc->AUs, j);
500
633
                                gf_list_del(au->commands);
501
634
                                free(au);
502
 
                                j--;
503
635
                        }
504
636
                }
505
637
        }
519
651
        case GF_SM_LOAD_XMTA: return "XMT-A Parser";
520
652
        case GF_SM_LOAD_X3D: return "X3D (XML Syntax) Parser";
521
653
        case GF_SM_LOAD_SWF: return "Flash (SWF) Emulator";
 
654
        case GF_SM_LOAD_SVG: return "SVG Loader";
 
655
        case GF_SM_LOAD_XSR: return "LASeRML Loader";
522
656
        case GF_SM_LOAD_MP4: return "MP4 Memory Loader";
 
657
 
523
658
        default: return "Undetermined";
524
659
        }
525
660
}
526
661
 
527
662
Bool CTXLoad_CanHandleStream(GF_BaseDecoder *ifce, u32 StreamType, u32 ObjectType, unsigned char *decSpecInfo, u32 decSpecInfoSize, u32 PL)
528
663
{
529
 
        if ((StreamType==GF_STREAM_PRIVATE_SCENE) && (ObjectType==1)) return 1;
 
664
        if (StreamType==GF_STREAM_PRIVATE_SCENE) {
 
665
                if (ObjectType==1) return 1;
 
666
                /*LASeR ML: we use this plugin since it has command handling*/
 
667
                if (ObjectType==3) return 1;
 
668
        }
 
669
        /*SVG*/
 
670
        //if ((StreamType==GF_STREAM_PRIVATE_SCENE) && (ObjectType==2)) return 1;
530
671
        return 0;
531
672
}
532
673
 
533
674
void DeleteContextLoader(GF_BaseDecoder *plug)
534
675
{
535
676
        CTXLoadPriv *priv = plug->privateStack;
536
 
        if (priv->fileName) free(priv->fileName);
 
677
        if (priv->file_name) free(priv->file_name);
537
678
        assert(!priv->ctx);
538
679
        gf_list_del(priv->files_to_delete);
539
680
        free(priv);