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);
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);
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;
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;
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();
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)
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;
218
218
cap.CapCode = GF_CODEC_WIDTH;
301
308
Bool gf_mo_get_audio_info(GF_MediaObject *mo, u32 *sample_rate, u32 *bits_per_sample, u32 *num_channels, u32 *channel_config)
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;
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;
306
320
if (sample_rate) {
307
321
cap.CapCode = GF_CODEC_SAMPLERATE;
308
322
gf_codec_get_capability(mo->odm->codec, &cap);
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)
351
Bool force_decode = 0;
366
Bool force_decode = GF_FALSE;
356
if (!gf_odm_lock_mo(mo)) return NULL;
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;
380
if (!gf_odm_lock_mo(mo))
358
383
if (!mo->odm->codec || !mo->odm->codec->CB) {
359
384
gf_odm_lock(mo->odm, 0);
363
389
/*if frame locked return it*/
364
390
if (mo->nb_fetch) {
366
*timestamp = mo->timestamp;
367
*size = mo->framesize;
369
392
gf_odm_lock(mo->odm, 0);
370
393
return mo->frame;
395
codec = mo->odm->codec;
373
397
/*end of stream */
374
*eos = gf_cm_is_eos(mo->odm->codec->CB);
398
*eos = gf_cm_is_eos(codec->CB);
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);
381
if (! *eos && (mo->odm->codec->ck->speed > FIX_ONE))
406
bench_mode = mo->odm->term->bench_mode;
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;
419
/*fast forward, force decode if no data is available*/
420
if (! *eos && (codec->ck->speed > FIX_ONE))
421
force_decode = GF_TRUE;
384
423
if (force_decode) {
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);
390
if (!gf_odm_lock_mo(mo)) return NULL;
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);
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));
437
if (!gf_odm_lock_mo(mo))
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);
396
444
if (!CU || (CU->RenderedLength == CU->dataLength)) {
397
445
gf_odm_lock(mo->odm, 0);
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);
404
if (mo->odm->codec->CB->UnitCount==1) resync = 0;
450
//assert(CU->TS >= codec->CB->LastRenderedTS);
452
if (codec->CB->UnitCount==1) 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);
465
obj_time = gf_clock_time(codec->ck);
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);
419
477
gf_odm_lock(mo->odm, 1);
420
478
if (!CU->next->dataLength)
426
484
/*figure out closest time*/
427
485
if (CU->next->TS > obj_time) {
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));
437
495
CU->RenderedLength = CU->dataLength = 0;
438
gf_cm_drop_output(mo->odm->codec->CB);
496
gf_cm_drop_output(codec->CB);
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);
446
504
mo->framesize = CU->dataLength - CU->RenderedLength;
447
505
mo->frame = CU->data + CU->RenderedLength;
507
if (CU->next->dataLength) {
508
diff = (s32) (CU->next->TS) - (s32) obj_time;
509
mo->ms_until_next = FIX2INT(diff * mo->speed);
511
mo->ms_until_next = 1;
513
diff = (s32) (CU->TS) - (s32) obj_time;
514
mo->ms_until_pres = FIX2INT(diff * mo->speed);
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);
453
521
if (mo->odm->parentscene->is_dynamic_scene)
454
522
mo->odm->parentscene->root_od->current_time = mo->odm->current_time;
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*/
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 ));
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;
535
// mo->timestamp = gf_clock_time(codec->ck);
536
mo->ms_until_pres = -1;
537
mo->ms_until_next = 1;
466
542
*timestamp = mo->timestamp;
467
543
*size = mo->framesize;
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);
469
548
gf_odm_lock(mo->odm, 0);
549
if (codec->direct_vout) return codec->CB->pY;
470
550
return mo->frame;
554
GF_Err gf_mo_get_raw_image_planes(GF_MediaObject *mo, u8 **pY_or_RGB, u8 **pU, u8 **pV)
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;
474
564
void gf_mo_release_data(GF_MediaObject *mo, u32 nb_bytes, s32 forceDrop)
571
661
if (!mo->num_open && mo->odm) {
663
Bool is_restart = GF_FALSE;
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);
580
670
if (mo->odm->action_type!=GF_ODM_ACTION_PLAY) {
581
671
mo->odm->action_type = GF_ODM_ACTION_PLAY;
672
is_restart = GF_FALSE;
628
718
Bool gf_mo_stop(GF_MediaObject *mo)
631
if (!mo || !mo->num_open) return 0;
721
if (!mo || !mo->num_open) return GF_FALSE;
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;
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);
740
830
Bool gf_mo_is_same_url(GF_MediaObject *obj, MFURL *an_url, Bool *keep_fragment, u32 obj_hint_type)
742
Bool include_sub_url = 0;
832
Bool include_sub_url = GF_FALSE;
744
834
char szURL1[GF_MAX_PATH], szURL2[GF_MAX_PATH], *ext;
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);
750
840
strcpy(szURL1, obj->URLs.vals[0].url);
762
852
char *frag = strrchr(an_url->vals[i].url, '#');
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;
767
857
/*fragment is a media segment, same URL*/
859
Bool same_res = GF_FALSE;
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;
774
864
/*if we're talking about the same resource, check if the fragment can be matched*/
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) )
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))
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)) {
879
*keep_fragment = GF_TRUE;
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;
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;
892
if (keep_fragment) *keep_fragment = GF_TRUE;
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;
818
908
Bool gf_mo_url_changed(GF_MediaObject *mo, MFURL *url)
822
if (!mo) return (url ? 1 : 0);
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);
827
ret = (mo->OD_ID == od_id) ? 0 : 1;
917
ret = (mo->OD_ID == od_id) ? GF_FALSE : GF_TRUE;
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);
945
1035
Bool gf_mo_should_deactivate(GF_MediaObject *mo)
1037
Bool res = GF_FALSE;
948
1038
#ifndef GPAC_DISABLE_VRML
949
1039
MediaControlStack *ctrl;
952
if (!gf_odm_lock_mo(mo)) return 0;
1042
if (!gf_odm_lock_mo(mo)) return GF_FALSE;
954
1044
if (!mo->odm->state) {
955
1045
gf_odm_lock(mo->odm, 0);
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);
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*/
972
1062
gf_odm_lock(mo->odm, 0);
989
1079
Bool gf_mo_is_done(GF_MediaObject *mo)
1081
Bool res = GF_FALSE;
992
1082
GF_Codec *codec;
994
if (!gf_odm_lock_mo(mo)) return 0;
1084
if (!gf_odm_lock_mo(mo)) return GF_FALSE;
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;
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;
1006
1096
codec = mo->odm->subscene->scene_codec;
1007
1097
dur = mo->odm->subscene->duration;
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;
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;
1157
e = dec->Control(dec, GF_FALSE, src, dst);
1158
if (e==GF_BUFFER_TOO_SMALL) return GF_TRUE;
1163
Bool gf_mo_is_raw_memory(GF_MediaObject *mo)
1165
if (!mo->odm || !mo->odm->codec) return GF_FALSE;
1166
return mo->odm->codec->direct_vout;
1112
1209
return mo->odm->subscene->graph;
1214
GF_DOMEventTarget *gf_mo_event_target_add_node(GF_MediaObject *mo, GF_Node *n)
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);
1223
GF_Err gf_mo_event_target_remove(GF_MediaObject *mo, GF_DOMEventTarget *target)
1225
if (!mo || !target) return GF_BAD_PARAM;
1226
gf_list_del_item(mo->evt_targets, target);
1230
GF_Err gf_mo_event_target_remove_by_index(GF_MediaObject *mo, u32 i)
1232
if (!mo) return GF_BAD_PARAM;
1233
gf_list_rem(mo->evt_targets, i);
1237
GF_Node *gf_mo_event_target_enum_node(GF_MediaObject *mo, u32 *i)
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;
1247
s32 gf_mo_event_target_find_by_node(GF_MediaObject *mo, GF_Node *node)
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) {
1261
GF_Err gf_mo_event_target_remove_by_node(GF_MediaObject *mo, GF_Node *node)
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);
1272
return GF_BAD_PARAM;
1276
GF_Node *gf_event_target_get_node(GF_DOMEventTarget *target)
1278
if (target && (target->ptr_type == GF_DOM_EVENT_TARGET_HTML_MEDIA)) {
1279
return (GF_Node *)target->ptr;
1285
GF_DOMEventTarget *gf_mo_event_target_get(GF_MediaObject *mo, u32 i)
1287
GF_DOMEventTarget *target = (GF_DOMEventTarget *)gf_list_get(mo->evt_targets, i);
1291
void gf_mo_event_target_reset(GF_MediaObject *mo)
1293
if (mo->evt_targets) gf_list_reset(mo->evt_targets);
1296
u32 gf_mo_event_target_count(GF_MediaObject *mo)
1299
return gf_list_count(mo->evt_targets);
1302
void gf_mo_del(GF_MediaObject *mo)
1304
assert(gf_list_count(mo->evt_targets) == 0);
1305
gf_list_del(mo->evt_targets);