~ubuntu-branches/debian/experimental/gpac/experimental

« back to all changes in this revision

Viewing changes to src/terminal/media_object.c

  • Committer: Package Import Robot
  • Author(s): Reinhard Tartler
  • Date: 2014-02-22 18:15:00 UTC
  • mfrom: (1.2.2) (3.1.6 sid)
  • Revision ID: package-import@ubuntu.com-20140222181500-b4phupo05gjpmopa
Tags: 0.5.0+svn5104~dfsg1-1
* New  upstream version 0.5.0+svn5104~dfsg1:
  - src/utils/sha1.c is relicensed under LGPLv2.1, Closes: #730759
* Don't install modules in multi-arch directories, Closes: #730497
* Add libusb-1.0.0-dev headers because libfreenect requires this
* Fix install rule
* Follow upstream soname bump
  - Drop the symbols file for now until it has been revised thourougly
* Let binaries produce the correct svn revision
* Refresh patches
* Patch and build against libav10, Closes: #739321
* Bump standards version, no changes necessary

Show diffs side-by-side

added added

removed removed

Lines of Context:
48
48
        } else if (!iri->string) {
49
49
                return NULL;
50
50
        } else {
51
 
                if (iri->target) ref = iri->target;
 
51
                if (iri->target) ref = (GF_Node *)iri->target;
52
52
                else if (iri->string[0]=='#') ref = gf_sg_find_node_by_name(scene->graph, iri->string+1);
53
53
                else ref = gf_sg_find_node_by_name(scene->graph, iri->string);
54
54
 
60
60
                        switch (ref->sgprivate->tag) {
61
61
                        case TAG_SVG_audio:
62
62
                                o_type = GF_MEDIA_OBJECT_AUDIO; 
63
 
                                if (gf_node_get_attribute_by_tag(ref, TAG_XLINK_ATT_href, 0, 0, &info)==GF_OK) {
64
 
                                        return get_sync_reference(scene, info.far_ptr, o_type, orig_ref ? orig_ref : ref, post_pone);
 
63
                                if (gf_node_get_attribute_by_tag(ref, TAG_XLINK_ATT_href, GF_FALSE, GF_FALSE, &info)==GF_OK) {
 
64
                                        return get_sync_reference(scene, (XMLRI *)info.far_ptr, o_type, orig_ref ? orig_ref : ref, post_pone);
65
65
                                }
66
66
                                return NULL;
67
67
                        case TAG_SVG_video:
68
68
                                o_type = GF_MEDIA_OBJECT_VIDEO; 
69
 
                                if (gf_node_get_attribute_by_tag(ref, TAG_XLINK_ATT_href, 0, 0, &info)==GF_OK) {
70
 
                                        return get_sync_reference(scene, info.far_ptr, o_type, orig_ref ? orig_ref : ref, post_pone);
 
69
                                if (gf_node_get_attribute_by_tag(ref, TAG_XLINK_ATT_href, GF_FALSE, GF_FALSE, &info)==GF_OK) {
 
70
                                        return get_sync_reference(scene, (XMLRI *)info.far_ptr, o_type, orig_ref ? orig_ref : ref, post_pone);
71
71
                                }
72
72
                                return NULL;
73
73
                        default:
75
75
                        }
76
76
                }
77
77
        }
78
 
        *post_pone = 0;
 
78
        *post_pone = GF_FALSE;
79
79
        mfurl.count = 1;
80
80
        mfurl.vals = &sfurl;
81
81
        mfurl.vals[0].OD_ID = stream_id;
82
82
        mfurl.vals[0].url = iri->string;
83
83
 
84
 
        res = gf_scene_get_media_object(scene, &mfurl, o_type, 0);
85
 
        if (!res) *post_pone = 1;
 
84
        res = gf_scene_get_media_object(scene, &mfurl, o_type, GF_FALSE);
 
85
        if (!res) *post_pone = GF_TRUE;
86
86
        return res;
87
87
}
88
88
#endif
150
150
#ifndef GPAC_DISABLE_SVG
151
151
        case TAG_SVG_audio: 
152
152
                obj_type = GF_MEDIA_OBJECT_AUDIO; 
153
 
                if (gf_node_get_attribute_by_tag(node, TAG_SVG_ATT_syncReference, 0, 0, &info)==GF_OK) {
154
 
                        syncRef = get_sync_reference(scene, info.far_ptr, GF_MEDIA_OBJECT_UNDEF, node, &post_pone);
 
153
                if (gf_node_get_attribute_by_tag(node, TAG_SVG_ATT_syncReference, GF_FALSE, GF_FALSE, &info)==GF_OK) {
 
154
                        syncRef = get_sync_reference(scene, (XMLRI *)info.far_ptr, GF_MEDIA_OBJECT_UNDEF, node, &post_pone);
155
155
                        /*syncRef is specified but doesn't exist yet, post-pone*/
156
156
                        if (post_pone) return NULL;
157
157
                }
158
158
                break;
159
159
        case TAG_SVG_video: 
160
160
                obj_type = GF_MEDIA_OBJECT_VIDEO; 
161
 
                if (gf_node_get_attribute_by_tag(node, TAG_SVG_ATT_syncReference, 0, 0, &info)==GF_OK) {
162
 
                        syncRef = get_sync_reference(scene, info.far_ptr, GF_MEDIA_OBJECT_UNDEF, node, &post_pone);
 
161
                if (gf_node_get_attribute_by_tag(node, TAG_SVG_ATT_syncReference, GF_FALSE, GF_FALSE, &info)==GF_OK) {
 
162
                        syncRef = get_sync_reference(scene, (XMLRI *)info.far_ptr, GF_MEDIA_OBJECT_UNDEF, node, &post_pone);
163
163
                        /*syncRef is specified but doesn't exist yet, post-pone*/
164
164
                        if (post_pone) return NULL;
165
165
                }
191
191
void gf_mo_unregister(GF_Node *node, GF_MediaObject *mo)
192
192
{
193
193
        if (mo && node) {
194
 
                gf_list_del_item(mo->nodes, node);
 
194
                gf_mo_event_target_remove_by_node(mo, node);
195
195
        }
196
196
}
197
197
 
203
203
        mo->speed = FIX_ONE;
204
204
        mo->URLs.count = 0;
205
205
        mo->URLs.vals = NULL;
206
 
        mo->nodes = gf_list_new();
 
206
        mo->evt_targets = gf_list_new();
207
207
        return mo;
208
208
}
209
209
 
210
210
 
211
211
GF_EXPORT
212
 
Bool gf_mo_get_visual_info(GF_MediaObject *mo, u32 *width, u32 *height, u32 *stride, u32 *pixel_ar, u32 *pixelFormat)
 
212
Bool gf_mo_get_visual_info(GF_MediaObject *mo, u32 *width, u32 *height, u32 *stride, u32 *pixel_ar, u32 *pixelFormat, Bool *is_flipped)
213
213
{
214
214
        GF_CodecCapability cap;
215
 
        if ((mo->type != GF_MEDIA_OBJECT_VIDEO) && (mo->type!=GF_MEDIA_OBJECT_TEXT)) return 0;
 
215
        if ((mo->type != GF_MEDIA_OBJECT_VIDEO) && (mo->type!=GF_MEDIA_OBJECT_TEXT)) return GF_FALSE;
216
216
 
217
217
        if (width) {
218
218
                cap.CapCode = GF_CODEC_WIDTH;
224
224
                gf_codec_get_capability(mo->odm->codec, &cap);
225
225
                *height = cap.cap.valueInt;
226
226
        }
227
 
        if (mo->type==GF_MEDIA_OBJECT_TEXT) return 1;
 
227
        if (mo->type==GF_MEDIA_OBJECT_TEXT) return GF_TRUE;
 
228
    
 
229
    if (is_flipped) {
 
230
        cap.CapCode = GF_CODEC_FLIP;
 
231
        cap.cap.valueInt = 0;
 
232
                gf_codec_get_capability(mo->odm->codec, &cap);
 
233
                *is_flipped = cap.cap.valueInt ? GF_TRUE : GF_FALSE;
 
234
    }
228
235
 
229
236
        if (stride) {
230
237
                cap.CapCode = GF_CODEC_STRIDE;
237
244
                *pixelFormat = cap.cap.valueInt;
238
245
 
239
246
                if (mo->odm && mo->odm->parentscene->is_dynamic_scene) {
240
 
                        const char *name = gf_node_get_name(gf_list_get(mo->nodes, 0));
 
247
                        const char *name = gf_node_get_name(gf_event_target_get_node(gf_mo_event_target_get(mo, 0)));
241
248
                        if (name && !strcmp(name, "DYN_VIDEO")) {
242
249
                                const char *opt;
243
250
                                u32 r, g, b, a;
258
265
                                                back->backColor.blue = INT2FIX(b)/255;
259
266
                                                break;
260
267
                                        default:
261
 
                                                back->backColor.red = back->backColor.green = back->backColor.blue = FIX_ONE;
 
268
                                                back->backColor.red = back->backColor.green = back->backColor.blue = 0;
262
269
                                                break;
263
270
                                        }
264
 
                                        gf_node_dirty_set((GF_Node *)back, 0, 1);
 
271
                                        gf_node_dirty_set((GF_Node *)back, 0, GF_TRUE);
265
272
                                }
266
273
                        }
267
274
                }
279
286
                        GF_Channel *ch;
280
287
                        GF_NetworkCommand com;
281
288
                        com.base.command_type = GF_NET_CHAN_GET_PIXEL_AR;
282
 
                        ch = gf_list_get(mo->odm->channels, 0);
283
 
                        if (!ch) return 0;
 
289
                        ch = (GF_Channel *)gf_list_get(mo->odm->channels, 0);
 
290
                        if (!ch) return GF_FALSE;
284
291
 
285
292
                        com.base.on_channel = ch;
286
293
                        com.par.hSpacing = com.par.vSpacing = 0;
294
301
                        }
295
302
                }
296
303
        }
297
 
        return 1;
 
304
        return GF_TRUE;
298
305
}
299
306
 
300
307
GF_EXPORT
301
308
Bool gf_mo_get_audio_info(GF_MediaObject *mo, u32 *sample_rate, u32 *bits_per_sample, u32 *num_channels, u32 *channel_config)
302
309
{
303
310
        GF_CodecCapability cap;
304
 
        if (!mo->odm || !mo->odm->codec || (mo->type != GF_MEDIA_OBJECT_AUDIO)) return 0;
 
311
        if (!mo->odm || !mo->odm->codec || (mo->type != GF_MEDIA_OBJECT_AUDIO)) return GF_FALSE;
305
312
 
 
313
        if (mo->odm->term->bench_mode==2) {
 
314
                if (sample_rate) *sample_rate = 44100;
 
315
                if (bits_per_sample) *bits_per_sample = 16;
 
316
                if (num_channels) *num_channels = 2;
 
317
                if (channel_config) *channel_config = 0;
 
318
                return GF_TRUE;
 
319
        }
306
320
        if (sample_rate) {
307
321
                cap.CapCode = GF_CODEC_SAMPLERATE;
308
322
                gf_codec_get_capability(mo->odm->codec, &cap);
323
337
                gf_codec_get_capability(mo->odm->codec, &cap);
324
338
                *channel_config = cap.cap.valueInt;
325
339
        }
326
 
        return 1;
 
340
        return GF_TRUE;
327
341
}
328
342
 
329
343
void gf_mo_update_caps(GF_MediaObject *mo)
346
360
}
347
361
 
348
362
GF_EXPORT
349
 
char *gf_mo_fetch_data(GF_MediaObject *mo, Bool resync, Bool *eos, u32 *timestamp, u32 *size)
 
363
char *gf_mo_fetch_data(GF_MediaObject *mo, Bool resync, Bool *eos, u32 *timestamp, u32 *size, s32 *ms_until_pres, u32 *ms_until_next)
350
364
{
351
 
        Bool force_decode = 0;
 
365
        GF_Codec *codec;
 
366
        Bool force_decode = GF_FALSE;
352
367
        u32 obj_time;
353
368
        GF_CMUnit *CU;
354
 
        *eos = 0;
355
 
 
356
 
        if (!gf_odm_lock_mo(mo)) return NULL;
 
369
        s32 diff;
 
370
        Bool bench_mode;
 
371
 
 
372
 
 
373
        *eos = GF_FALSE;
 
374
        *eos = GF_FALSE;
 
375
        *timestamp = mo->timestamp;
 
376
        *size = mo->framesize;
 
377
        if (ms_until_pres) *ms_until_pres = mo->ms_until_pres;
 
378
        if (ms_until_next) *ms_until_next = mo->ms_until_next;
 
379
 
 
380
        if (!gf_odm_lock_mo(mo)) 
 
381
                return NULL;
357
382
 
358
383
        if (!mo->odm->codec || !mo->odm->codec->CB) {
359
384
                gf_odm_lock(mo->odm, 0);
360
385
                return NULL;
361
386
        }
362
387
 
 
388
 
363
389
        /*if frame locked return it*/
364
390
        if (mo->nb_fetch) {
365
 
                *eos = 0;
366
 
                *timestamp = mo->timestamp;
367
 
                *size = mo->framesize;
368
391
                mo->nb_fetch ++;
369
392
                gf_odm_lock(mo->odm, 0);
370
393
                return mo->frame;
371
394
        }
 
395
        codec = mo->odm->codec;
372
396
 
373
397
        /*end of stream */
374
 
        *eos = gf_cm_is_eos(mo->odm->codec->CB);
 
398
        *eos = gf_cm_is_eos(codec->CB);
375
399
 
376
400
        /*not running and no resync (ie audio)*/
377
 
        if (!resync && !gf_cm_is_running(mo->odm->codec->CB)) {
 
401
        if (!resync && !gf_cm_is_running(codec->CB)) {
378
402
                gf_odm_lock(mo->odm, 0);
379
403
                return NULL;
380
404
        }
381
 
        if (! *eos && (mo->odm->codec->ck->speed > FIX_ONE))
382
 
                force_decode = 1;
 
405
 
 
406
        bench_mode = mo->odm->term->bench_mode;
 
407
 
 
408
        /*resize requested - if last frame destroy CB and force a decode*/
 
409
        if (codec->force_cb_resize && (codec->CB->UnitCount<=1)) {
 
410
                CU = gf_cm_get_output(codec->CB);
 
411
                if (!CU || (CU->TS==mo->timestamp)) {
 
412
                        GF_LOG(GF_LOG_INFO, GF_LOG_CODEC, ("[%s] ODM%d: Resizing output buffer %d -> %d\n", codec->decio->module_name, codec->odm->OD->objectDescriptorID, codec->CB->UnitSize, codec->force_cb_resize));
 
413
                        gf_codec_resize_composition_buffer(codec, codec->force_cb_resize);
 
414
                        codec->force_cb_resize=0;
 
415
                        force_decode = GF_TRUE;
 
416
                }
 
417
        }
 
418
 
 
419
        /*fast forward, force decode if no data is available*/
 
420
        if (! *eos && (codec->ck->speed > FIX_ONE))
 
421
                force_decode = GF_TRUE;
383
422
 
384
423
        if (force_decode) {
 
424
                u32 retry=100;
385
425
                gf_odm_lock(mo->odm, 0);
386
 
                if (gf_term_lock_codec(mo->odm->codec, 1)) {
387
 
                        gf_codec_process(mo->odm->codec, 1);
388
 
                        gf_term_lock_codec(mo->odm->codec, 0);
389
 
                }
390
 
                if (!gf_odm_lock_mo(mo)) return NULL;
 
426
                while (retry) {
 
427
                        if (gf_term_lock_codec(codec, GF_TRUE, GF_TRUE)) {
 
428
                                gf_codec_process(codec, 1);
 
429
                                gf_term_lock_codec(codec, GF_FALSE, GF_TRUE);
 
430
                                break;
 
431
                        }
 
432
                        retry--;
 
433
                }
 
434
                if (!retry) {
 
435
                        GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("[ODM%d] At %d could not resize and decode next frame in one pass - blank frame after TS %d\n", mo->odm->OD->objectDescriptorID, gf_clock_time(codec->ck), mo->timestamp));
 
436
                }
 
437
                if (!gf_odm_lock_mo(mo))
 
438
                        return NULL;
391
439
        }
392
440
 
393
441
        /*new frame to fetch, lock*/
394
 
        CU = gf_cm_get_output(mo->odm->codec->CB);
 
442
        CU = gf_cm_get_output(codec->CB);
395
443
        /*no output*/
396
444
        if (!CU || (CU->RenderedLength == CU->dataLength)) {
397
445
                gf_odm_lock(mo->odm, 0);
399
447
        }
400
448
 
401
449
        /*note this assert is NOT true when recomputing DTS from CTS on the fly (MPEG1/2 RTP and H264/AVC RTP)*/
402
 
        //assert(CU->TS >= mo->odm->codec->CB->LastRenderedTS);
403
 
 
404
 
        if (mo->odm->codec->CB->UnitCount==1) resync = 0;
 
450
        //assert(CU->TS >= codec->CB->LastRenderedTS);
 
451
 
 
452
        if (codec->CB->UnitCount==1) resync = GF_FALSE;
 
453
 
 
454
        if (bench_mode) {
 
455
                resync = GF_FALSE;
 
456
                if (mo->timestamp == CU->TS) {
 
457
                        if (CU->next->dataLength) {
 
458
                                gf_cm_drop_output(codec->CB);
 
459
                                CU = gf_cm_get_output(codec->CB);
 
460
                        }
 
461
                }
 
462
        }
405
463
 
406
464
        /*resync*/
 
465
        obj_time = gf_clock_time(codec->ck);
407
466
        if (resync) {
408
467
                u32 nb_droped = 0;
409
 
                obj_time = gf_clock_time(mo->odm->codec->ck);
410
468
                while (CU->TS < obj_time) {
411
469
                        if (!CU->next->dataLength) {
412
470
                                if (force_decode) {
413
 
                                        obj_time = gf_clock_time(mo->odm->codec->ck);
 
471
                                        obj_time = gf_clock_time(codec->ck);
414
472
                                        gf_odm_lock(mo->odm, 0);
415
 
                                        if (gf_term_lock_codec(mo->odm->codec, 1)) {
416
 
                                                gf_codec_process(mo->odm->codec, 1);
417
 
                                                gf_term_lock_codec(mo->odm->codec, 0);
 
473
                                        if (gf_term_lock_codec(codec, GF_TRUE, GF_TRUE)) {
 
474
                                                gf_codec_process(codec, 1);
 
475
                                                gf_term_lock_codec(codec, GF_FALSE, GF_TRUE);
418
476
                                        }
419
477
                                        gf_odm_lock(mo->odm, 1);
420
478
                                        if (!CU->next->dataLength) 
425
483
                        }
426
484
                        /*figure out closest time*/
427
485
                        if (CU->next->TS > obj_time) {
428
 
                                *eos = 0;
 
486
                                *eos = GF_FALSE;
429
487
                                break;
430
488
                        }
431
489
                        nb_droped ++;
432
490
                        if (nb_droped>1) {
433
 
                                GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("[ODM%d] At OTB %d dropped frame TS %d\n", mo->odm->OD->objectDescriptorID, obj_time, CU->TS));
434
 
                                mo->odm->codec->nb_droped++;
 
491
                                GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("[ODM%d] At OTB %u dropped frame TS %u\n", mo->odm->OD->objectDescriptorID, obj_time, CU->TS));
 
492
                                codec->nb_droped++;
435
493
                        }
436
494
                        /*discard*/
437
495
                        CU->RenderedLength = CU->dataLength = 0;
438
 
                        gf_cm_drop_output(mo->odm->codec->CB);
 
496
                        gf_cm_drop_output(codec->CB);
439
497
 
440
498
                        /*get next*/
441
 
                        CU = gf_cm_get_output(mo->odm->codec->CB);
442
 
                        *eos = gf_cm_is_eos(mo->odm->codec->CB);
 
499
                        CU = gf_cm_get_output(codec->CB);
 
500
                        *eos = gf_cm_is_eos(codec->CB);
443
501
                }
444
502
        }       
445
503
 
446
504
        mo->framesize = CU->dataLength - CU->RenderedLength;
447
505
        mo->frame = CU->data + CU->RenderedLength;
 
506
 
 
507
        if (CU->next->dataLength) {
 
508
                diff = (s32) (CU->next->TS) - (s32) obj_time;
 
509
                mo->ms_until_next = FIX2INT(diff * mo->speed);
 
510
        } else  {
 
511
                mo->ms_until_next = 1;
 
512
        }
 
513
        diff = (s32) (CU->TS) - (s32) obj_time;
 
514
        mo->ms_until_pres = FIX2INT(diff * mo->speed);
 
515
 
448
516
        if (mo->timestamp != CU->TS) {
449
517
#ifndef GPAC_DISABLE_VRML
450
 
                mediasensor_update_timing(mo->odm, mo->odm->codec->CB->HasSeenEOS);
 
518
                mediasensor_update_timing(mo->odm, codec->CB->HasSeenEOS);
451
519
#endif
452
520
        
453
521
                if (mo->odm->parentscene->is_dynamic_scene)
454
522
                        mo->odm->parentscene->root_od->current_time = mo->odm->current_time;
455
523
 
456
524
                mo->timestamp = CU->TS;
457
 
                GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[ODM%d] At OTB %d fetch frame TS %d size %d - %d unit in CB\n", mo->odm->OD->objectDescriptorID, gf_clock_time(mo->odm->codec->ck), mo->timestamp, mo->framesize, mo->odm->codec->CB->UnitCount));
458
525
                /*signal EOS after rendering last frame, not while rendering it*/
459
 
                *eos = 0;
 
526
                *eos = GF_FALSE;
 
527
 
 
528
                GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[ODM%d] At OTB %u fetch frame TS %u size %d (previous TS %d) - %d unit in CB - UTC "LLU" ms - %d ms until CTS is due - %d ms until next frame\n", mo->odm->OD->objectDescriptorID, gf_clock_time(codec->ck), CU->TS, mo->framesize, mo->timestamp, codec->CB->UnitCount, gf_net_get_utc(), mo->ms_until_pres, mo->ms_until_next ));
460
529
        }
461
530
 
462
531
        /*also adjust CU time based on consummed bytes in input, since some codecs output very large audio chunks*/
463
 
        if (mo->odm->codec->bytes_per_sec) mo->timestamp += CU->RenderedLength * 1000 / mo->odm->codec->bytes_per_sec;
 
532
        if (codec->bytes_per_sec) mo->timestamp += CU->RenderedLength * 1000 / codec->bytes_per_sec;
 
533
 
 
534
        if (bench_mode) {
 
535
//              mo->timestamp = gf_clock_time(codec->ck);
 
536
                mo->ms_until_pres = -1;
 
537
                mo->ms_until_next = 1;
 
538
        } 
 
539
 
464
540
 
465
541
        mo->nb_fetch ++;
466
542
        *timestamp = mo->timestamp;
467
543
        *size = mo->framesize;
468
 
 
 
544
        if (ms_until_pres) *ms_until_pres = mo->ms_until_pres;
 
545
        if (ms_until_next) *ms_until_next = mo->ms_until_next;
 
546
        gf_term_service_media_event(mo->odm, GF_EVENT_MEDIA_TIME_UPDATE);
 
547
                        
469
548
        gf_odm_lock(mo->odm, 0);
 
549
        if (codec->direct_vout) return codec->CB->pY;
470
550
        return mo->frame;
471
551
}
472
552
 
473
553
GF_EXPORT
 
554
GF_Err gf_mo_get_raw_image_planes(GF_MediaObject *mo, u8 **pY_or_RGB, u8 **pU, u8 **pV)
 
555
{
 
556
        if (!mo || !mo->odm || !mo->odm->codec) return GF_BAD_PARAM;
 
557
        *pY_or_RGB = mo->odm->codec->CB->pY;
 
558
        *pU = mo->odm->codec->CB->pU;
 
559
        *pV = mo->odm->codec->CB->pV;
 
560
        return GF_OK;
 
561
}
 
562
 
 
563
GF_EXPORT
474
564
void gf_mo_release_data(GF_MediaObject *mo, u32 nb_bytes, s32 forceDrop)
475
565
{
476
566
#if 0
570
660
 
571
661
        if (!mo->num_open && mo->odm) {
572
662
                s32 res;
573
 
                Bool is_restart = 0;
 
663
                Bool is_restart = GF_FALSE;
574
664
 
575
665
                /*remove object from media queue*/
576
 
                gf_term_lock_media_queue(mo->odm->term, 1);
 
666
                gf_term_lock_media_queue(mo->odm->term, GF_TRUE);
577
667
                res = gf_list_del_item(mo->odm->term->media_queue, mo->odm);
578
 
                gf_term_lock_media_queue(mo->odm->term, 0);
 
668
                gf_term_lock_media_queue(mo->odm->term, GF_FALSE);
579
669
 
580
670
                if (mo->odm->action_type!=GF_ODM_ACTION_PLAY) {
581
671
                        mo->odm->action_type = GF_ODM_ACTION_PLAY;
582
 
                        is_restart = 0;
 
672
                        is_restart = GF_FALSE;
583
673
                        res = -1;
584
674
                }
585
675
 
627
717
GF_EXPORT
628
718
Bool gf_mo_stop(GF_MediaObject *mo)
629
719
{
630
 
        Bool ret = 0;
631
 
        if (!mo || !mo->num_open) return 0;
 
720
        Bool ret = GF_FALSE;
 
721
        if (!mo || !mo->num_open) return GF_FALSE;
632
722
 
633
723
        mo->num_open--;
634
724
        if (!mo->num_open && mo->odm) {
635
 
                if (mo->odm->flags & GF_ODM_DESTROYED) return 1;
 
725
                if (mo->odm->flags & GF_ODM_DESTROYED) return GF_TRUE;
636
726
 
637
727
                /*do not stop directly, this can delete channel data currently being decoded (BIFS anim & co)*/
638
 
                gf_term_lock_media_queue(mo->odm->term, 1);
 
728
                gf_term_lock_media_queue(mo->odm->term, GF_TRUE);
639
729
                /*if object not in media queue, add it*/
640
730
                if (gf_list_find(mo->odm->term->media_queue, mo->odm)<0) {
641
731
                        gf_list_add(mo->odm->term->media_queue, mo->odm);
644
734
                /*signal STOP request*/
645
735
                if ((mo->OD_ID==GF_MEDIA_EXTERNAL_ID) || (mo->odm && mo->odm->OD && (mo->odm->OD->objectDescriptorID==GF_MEDIA_EXTERNAL_ID))) {
646
736
                        mo->odm->action_type = GF_ODM_ACTION_DELETE;
647
 
                        ret = 1;
 
737
                        ret = GF_TRUE;
648
738
                }
649
739
                else 
650
740
                        mo->odm->action_type = GF_ODM_ACTION_STOP;
651
741
 
652
 
                gf_term_lock_media_queue(mo->odm->term, 0);
 
742
                gf_term_lock_media_queue(mo->odm->term, GF_FALSE);
653
743
        } else {
654
744
                if (!mo->num_to_restart) {
655
745
                        mo->num_restart = mo->num_to_restart = mo->num_open + 1;
739
829
 
740
830
Bool gf_mo_is_same_url(GF_MediaObject *obj, MFURL *an_url, Bool *keep_fragment, u32 obj_hint_type)
741
831
{
742
 
        Bool include_sub_url = 0;
 
832
        Bool include_sub_url = GF_FALSE;
743
833
        u32 i;
744
834
        char szURL1[GF_MAX_PATH], szURL2[GF_MAX_PATH], *ext;
745
835
 
746
836
        if (!obj->URLs.count) {
747
 
                if (!obj->odm) return 0;
 
837
                if (!obj->odm) return GF_FALSE;
748
838
                strcpy(szURL1, obj->odm->net_service->url);
749
839
        } else {
750
840
                strcpy(szURL1, obj->URLs.vals[0].url);
752
842
 
753
843
        /*don't analyse audio/video to locate segments or viewports*/
754
844
        if ((obj->type==GF_MEDIA_OBJECT_AUDIO) || (obj->type==GF_MEDIA_OBJECT_VIDEO)) {
755
 
                if (keep_fragment) *keep_fragment = 0;
756
 
                include_sub_url = 1;
 
845
                if (keep_fragment) *keep_fragment = GF_FALSE;
 
846
                include_sub_url = GF_TRUE;
757
847
        } else if ((obj->type==GF_MEDIA_OBJECT_SCENE) && keep_fragment && obj->odm) {
758
848
                GF_ClientService *ns;
759
849
                u32 j;
762
852
                        char *frag = strrchr(an_url->vals[i].url, '#');
763
853
                        j=0;
764
854
                        /*this is the same object (may need some refinement)*/
765
 
                        if (!stricmp(szURL1, an_url->vals[i].url)) return 1;
 
855
                        if (!stricmp(szURL1, an_url->vals[i].url)) return GF_TRUE;
766
856
 
767
857
                        /*fragment is a media segment, same URL*/
768
858
                        if (frag ) {
769
 
                                Bool same_res = 0;
 
859
                                Bool same_res = GF_FALSE;
770
860
                                frag[0] = 0;
771
 
                                same_res = !strncmp(an_url->vals[i].url, szURL1, strlen(an_url->vals[i].url)) ? 1 : 0;
 
861
                                same_res = !strncmp(an_url->vals[i].url, szURL1, strlen(an_url->vals[i].url)) ? GF_TRUE : GF_FALSE;
772
862
                                frag[0] = '#';
773
863
 
774
864
                                /*if we're talking about the same resource, check if the fragment can be matched*/
775
865
                                if (same_res) {
776
866
                                        /*if the fragment is a node which can be found, this is the same resource*/
777
867
                                        if (obj->odm->subscene && (gf_sg_find_node_by_name(obj->odm->subscene->graph, frag+1)!=NULL) )
778
 
                                                return 1;
 
868
                                                return GF_TRUE;
779
869
                                
780
870
                                        /*if the expected type is an existing segment (undefined media type), this is the same resource*/
781
871
                                        if (!obj_hint_type && gf_odm_find_segment(obj->odm, frag+1))
782
 
                                                return 1;
 
872
                                                return GF_TRUE;
783
873
                                }
784
874
                        }
785
875
 
786
876
                        while ( (ns = (GF_ClientService*)gf_list_enum(obj->odm->term->net_services, &j)) ) {
787
877
                                /*sub-service of an existing service - don't touch any fragment*/
788
878
                                if (gf_term_service_can_handle_url(ns, an_url->vals[i].url)) {
789
 
                                        *keep_fragment = 1;
790
 
                                        return 0;
 
879
                                        *keep_fragment = GF_TRUE;
 
880
                                        return GF_FALSE;
791
881
                                }
792
882
                        }
793
883
                }
796
886
        /*check on full URL without removing fragment IDs*/
797
887
        if (include_sub_url) {
798
888
                for (i=0; i<an_url->count; i++) {
799
 
                        if (an_url->vals[i].url && !stricmp(szURL1, an_url->vals[i].url)) return 1;
 
889
                        if (an_url->vals[i].url && !stricmp(szURL1, an_url->vals[i].url)) return GF_TRUE;
800
890
                }
801
891
                /*not same resource, we will have to check fragment as URL might point to a sub-service or single stream of a mux*/
802
 
                if (keep_fragment) *keep_fragment = 1;
803
 
                return 0;
 
892
                if (keep_fragment) *keep_fragment = GF_TRUE;
 
893
                return GF_FALSE;
804
894
        }
805
895
        ext = strrchr(szURL1, '#');
806
896
        if (ext) ext[0] = 0;
807
897
        for (i=0; i<an_url->count; i++) {
808
 
                if (!an_url->vals[i].url) return 0;
 
898
                if (!an_url->vals[i].url) return GF_FALSE;
809
899
                strcpy(szURL2, an_url->vals[i].url);
810
900
                ext = strrchr(szURL2, '#');
811
901
                if (ext) ext[0] = 0;
812
 
                if (!stricmp(szURL1, szURL2)) return 1;
 
902
                if (!stricmp(szURL1, szURL2)) return GF_TRUE;
813
903
        }
814
 
        return 0;
 
904
        return GF_FALSE;
815
905
}
816
906
 
817
907
GF_EXPORT
818
908
Bool gf_mo_url_changed(GF_MediaObject *mo, MFURL *url)
819
909
{
820
910
        u32 od_id;
821
 
        Bool ret = 0;
822
 
        if (!mo) return (url ? 1 : 0);
 
911
        Bool ret = GF_FALSE;
 
912
        if (!mo) return (url ? GF_TRUE : GF_FALSE);
823
913
        od_id = gf_mo_get_od_id(url);
824
914
        if ( (mo->OD_ID == GF_MEDIA_EXTERNAL_ID) && (od_id == GF_MEDIA_EXTERNAL_ID)) {
825
915
                ret = !gf_mo_is_same_url(mo, url, NULL, 0);
826
916
        } else {
827
 
                ret = (mo->OD_ID == od_id) ? 0 : 1;
 
917
                ret = (mo->OD_ID == od_id) ? GF_FALSE : GF_TRUE;
828
918
        }
829
919
        /*special case for 3GPP text: if not playing and user node changed, force removing it*/
830
920
        if (ret && mo->odm && !mo->num_open && (mo->type == GF_MEDIA_OBJECT_TEXT)) {
831
921
                mo->flags |= GF_MO_DISPLAY_REMOVE;
832
 
                gf_term_stop_codec(mo->odm->codec, 0);
 
922
                gf_term_stop_codec(mo->odm->codec, GF_FALSE);
833
923
        }
834
924
        return ret;
835
925
}
919
1009
        /*otherwise looping is only accepted if not sharing parent scene clock*/
920
1010
        ck = gf_odm_get_media_clock(mo->odm->parentscene->root_od);
921
1011
        if (gf_odm_shares_clock(mo->odm, ck)) {
922
 
                in_loop = 0;
 
1012
                in_loop = GF_FALSE;
923
1013
#ifndef GPAC_DISABLE_VRML
924
1014
/*
925
1015
        if (ctrl && ctrl->stream->odm && ctrl->stream->odm->subscene)
944
1034
GF_EXPORT
945
1035
Bool gf_mo_should_deactivate(GF_MediaObject *mo)
946
1036
{
947
 
        Bool res = 0;
 
1037
        Bool res = GF_FALSE;
948
1038
#ifndef GPAC_DISABLE_VRML
949
1039
        MediaControlStack *ctrl;
950
1040
#endif
951
1041
 
952
 
        if (!gf_odm_lock_mo(mo)) return 0;
 
1042
        if (!gf_odm_lock_mo(mo)) return GF_FALSE;
953
1043
        
954
1044
        if (!mo->odm->state) {
955
1045
                gf_odm_lock(mo->odm, 0);
956
 
                return 0;
 
1046
                return GF_FALSE;
957
1047
        }
958
1048
 
959
1049
#ifndef GPAC_DISABLE_VRML
960
1050
        /*get media control and see if object owning control is running*/
961
1051
        ctrl = gf_odm_get_mediacontrol(mo->odm);
962
 
        if (!ctrl) res = 1;
 
1052
        if (!ctrl) res = GF_TRUE;
963
1053
        /*if ctrl and ctrl not ruling this mediaObject, deny deactivation*/
964
 
        else if (ctrl->stream->odm != mo->odm) res = 0;
 
1054
        else if (ctrl->stream->odm != mo->odm) res = GF_FALSE;
965
1055
        /*this is currently under discussion in MPEG. for now we deny deactivation as soon as a mediaControl is here*/
966
 
        else if (ctrl->stream->odm->state) res = 0;
 
1056
        else if (ctrl->stream->odm->state) res = GF_FALSE;
967
1057
        /*otherwise allow*/     
968
1058
        else 
969
1059
#endif
970
 
                res = 1;
 
1060
                res = GF_TRUE;
971
1061
 
972
1062
        gf_odm_lock(mo->odm, 0);
973
1063
        return res;
976
1066
GF_EXPORT
977
1067
Bool gf_mo_is_muted(GF_MediaObject *mo)
978
1068
{
979
 
        Bool res = 0;
 
1069
        Bool res = GF_FALSE;
980
1070
#ifndef GPAC_DISABLE_VRML
981
 
        if (!gf_odm_lock_mo(mo)) return 0;
982
 
        res = mo->odm->media_ctrl ? mo->odm->media_ctrl->control->mute : 0;
 
1071
        if (!gf_odm_lock_mo(mo)) return GF_FALSE;
 
1072
        res = mo->odm->media_ctrl ? mo->odm->media_ctrl->control->mute : GF_FALSE;
983
1073
        gf_odm_lock(mo->odm, 0);
984
1074
#endif
985
1075
        return res;
988
1078
GF_EXPORT
989
1079
Bool gf_mo_is_done(GF_MediaObject *mo)
990
1080
{
991
 
        Bool res = 0;
 
1081
        Bool res = GF_FALSE;
992
1082
        GF_Codec *codec;
993
1083
        u64 dur;
994
 
        if (!gf_odm_lock_mo(mo)) return 0;
 
1084
        if (!gf_odm_lock_mo(mo)) return GF_FALSE;
995
1085
 
996
1086
        if (mo->odm->codec && mo->odm->codec->CB) {
997
1087
                /*for natural media use composition buffer*/
998
 
                res = (mo->odm->codec->CB->Status==CB_STOP) ? 1 : 0;
 
1088
                res = (mo->odm->codec->CB->Status==CB_STOP) ? GF_TRUE : GF_FALSE;
999
1089
        } else {
1000
1090
                /*otherwise check EOS and time*/
1001
1091
                codec = mo->odm->codec;
1002
1092
                dur = mo->odm->duration;
1003
1093
                if (!mo->odm->codec) {
1004
 
                        if (!mo->odm->subscene) res = 0;
 
1094
                        if (!mo->odm->subscene) res = GF_FALSE;
1005
1095
                        else {
1006
1096
                                codec = mo->odm->subscene->scene_codec;
1007
1097
                                dur = mo->odm->subscene->duration;
1010
1100
                if (codec && (codec->Status==GF_ESM_CODEC_STOP)) {
1011
1101
                        /*codec is done, check by duration*/
1012
1102
                        GF_Clock *ck = gf_odm_get_media_clock(mo->odm);
1013
 
                        if (gf_clock_time(ck) > dur) res = 1;
 
1103
                        if (gf_clock_time(ck) > dur) res = GF_TRUE;
1014
1104
                }
1015
1105
        }
1016
1106
        gf_odm_lock(mo->odm, 0);
1052
1142
GF_EXPORT
1053
1143
Bool gf_mo_is_private_media(GF_MediaObject *mo)
1054
1144
{
1055
 
        if (mo->odm && mo->odm->codec && mo->odm->codec->decio && (mo->odm->codec->decio->InterfaceType==GF_PRIVATE_MEDIA_DECODER_INTERFACE)) return 1;
1056
 
        return 0;
 
1145
        if (mo->odm && mo->odm->codec && mo->odm->codec->decio && (mo->odm->codec->decio->InterfaceType==GF_PRIVATE_MEDIA_DECODER_INTERFACE)) return GF_TRUE;
 
1146
        return GF_FALSE;
1057
1147
}
1058
1148
 
1059
1149
GF_EXPORT
1061
1151
{
1062
1152
        GF_Err e;
1063
1153
        GF_PrivateMediaDecoder *dec;
1064
 
        if (!mo->odm || !mo->odm->codec || !mo->odm->codec->decio || (mo->odm->codec->decio->InterfaceType!=GF_PRIVATE_MEDIA_DECODER_INTERFACE)) return 0;
 
1154
        if (!mo->odm || !mo->odm->codec || !mo->odm->codec->decio || (mo->odm->codec->decio->InterfaceType!=GF_PRIVATE_MEDIA_DECODER_INTERFACE)) return GF_FALSE;
1065
1155
 
1066
1156
        dec = (GF_PrivateMediaDecoder*)mo->odm->codec->decio;
1067
 
        e = dec->Control(dec, 0, src, dst);
1068
 
        if (e==GF_BUFFER_TOO_SMALL) return 1;
1069
 
        return 0;
 
1157
        e = dec->Control(dec, GF_FALSE, src, dst);
 
1158
        if (e==GF_BUFFER_TOO_SMALL) return GF_TRUE;
 
1159
        return GF_FALSE;
 
1160
}
 
1161
 
 
1162
GF_EXPORT
 
1163
Bool gf_mo_is_raw_memory(GF_MediaObject *mo)
 
1164
{
 
1165
        if (!mo->odm || !mo->odm->codec) return GF_FALSE;
 
1166
        return mo->odm->codec->direct_vout;
1070
1167
}
1071
1168
 
1072
1169
GF_EXPORT
1085
1182
        scene = mo->odm->parentscene;
1086
1183
        sub_url = strchr(ns->url, '#');
1087
1184
        for (i=0; i<gf_list_count(scene->resources); i++) {
1088
 
                GF_ObjectManager *odm = gf_list_get(scene->resources, i);
 
1185
                GF_ObjectManager *odm = (GF_ObjectManager *)gf_list_get(scene->resources, i);
1089
1186
                if (odm->net_service != ns) continue;
1090
1187
                if (!odm->mo) continue;
1091
1188
 
1112
1209
        return mo->odm->subscene->graph;
1113
1210
}
1114
1211
 
 
1212
 
 
1213
GF_EXPORT
 
1214
GF_DOMEventTarget *gf_mo_event_target_add_node(GF_MediaObject *mo, GF_Node *n)
 
1215
{
 
1216
    GF_DOMEventTarget *target = NULL;
 
1217
    if (!mo ||!n) return NULL;
 
1218
        target = gf_html_media_get_event_target_from_node(n);
 
1219
        gf_list_add(mo->evt_targets, target);
 
1220
        return target;
 
1221
}
 
1222
 
 
1223
GF_Err gf_mo_event_target_remove(GF_MediaObject *mo, GF_DOMEventTarget *target)
 
1224
{
 
1225
    if (!mo || !target) return GF_BAD_PARAM;
 
1226
    gf_list_del_item(mo->evt_targets, target);
 
1227
    return GF_OK;
 
1228
}
 
1229
 
 
1230
GF_Err gf_mo_event_target_remove_by_index(GF_MediaObject *mo, u32 i)
 
1231
{
 
1232
    if (!mo) return GF_BAD_PARAM;
 
1233
    gf_list_rem(mo->evt_targets, i);
 
1234
    return GF_OK;
 
1235
}
 
1236
 
 
1237
GF_Node *gf_mo_event_target_enum_node(GF_MediaObject *mo, u32 *i)
 
1238
{
 
1239
    GF_DOMEventTarget *target;
 
1240
    if (!mo || !i) return NULL;
 
1241
    target = (GF_DOMEventTarget *)gf_list_enum(mo->evt_targets, i);
 
1242
    if (!target) return NULL;
 
1243
        //if (target->ptr_type != GF_DOM_EVENT_TARGET_NODE) return NULL;
 
1244
    return (GF_Node *)target->ptr;
 
1245
}
 
1246
 
 
1247
s32 gf_mo_event_target_find_by_node(GF_MediaObject *mo, GF_Node *node)
 
1248
{
 
1249
    u32 i, count;
 
1250
    count = gf_list_count(mo->evt_targets);
 
1251
    for (i = 0; i < count; i++) {
 
1252
        GF_DOMEventTarget *target = (GF_DOMEventTarget *)gf_list_get(mo->evt_targets, i);
 
1253
        if (target->ptr == node) {
 
1254
            return i;
 
1255
        }
 
1256
    }
 
1257
    return -1;
 
1258
}
 
1259
 
 
1260
GF_EXPORT
 
1261
GF_Err gf_mo_event_target_remove_by_node(GF_MediaObject *mo, GF_Node *node)
 
1262
{
 
1263
    u32 i, count;
 
1264
    count = gf_list_count(mo->evt_targets);
 
1265
    for (i = 0; i < count; i++) {
 
1266
        GF_DOMEventTarget *target = (GF_DOMEventTarget *)gf_list_get(mo->evt_targets, i);
 
1267
        if (target->ptr == node) {
 
1268
            gf_list_del_item(mo->evt_targets, target);
 
1269
            return GF_OK;
 
1270
        }
 
1271
    }
 
1272
    return GF_BAD_PARAM;
 
1273
}
 
1274
 
 
1275
GF_EXPORT
 
1276
GF_Node *gf_event_target_get_node(GF_DOMEventTarget *target)
 
1277
{
 
1278
    if (target && (target->ptr_type == GF_DOM_EVENT_TARGET_HTML_MEDIA)) {
 
1279
        return (GF_Node *)target->ptr;
 
1280
    }
 
1281
    return NULL;
 
1282
}
 
1283
 
 
1284
GF_EXPORT
 
1285
GF_DOMEventTarget *gf_mo_event_target_get(GF_MediaObject *mo, u32 i)
 
1286
{
 
1287
    GF_DOMEventTarget *target = (GF_DOMEventTarget *)gf_list_get(mo->evt_targets, i);
 
1288
    return target;
 
1289
}
 
1290
 
 
1291
void gf_mo_event_target_reset(GF_MediaObject *mo)
 
1292
{
 
1293
    if (mo->evt_targets) gf_list_reset(mo->evt_targets);
 
1294
}
 
1295
 
 
1296
u32 gf_mo_event_target_count(GF_MediaObject *mo)
 
1297
{
 
1298
    if (!mo) return 0;
 
1299
    return gf_list_count(mo->evt_targets);
 
1300
}
 
1301
 
 
1302
void gf_mo_del(GF_MediaObject *mo)
 
1303
{
 
1304
        assert(gf_list_count(mo->evt_targets) == 0);
 
1305
    gf_list_del(mo->evt_targets);
 
1306
    gf_free(mo);
 
1307
}
 
1308