54
54
void gf_odm_del(GF_ObjectManager *odm)
57
count = gf_list_count(odm->ms_stack);
58
for (i = 0; i<count; i++) {
59
MediaSensorStack *media_sens = gf_list_get(odm->ms_stack, i);
57
MediaSensorStack *media_sens;
59
while ((media_sens = gf_list_enum(odm->ms_stack, &i))) {
60
60
MS_Stop(media_sens);
61
61
/*and detach from stream object*/
62
62
media_sens->is_init = 0;
91
91
if (!do_remove) return;
93
/*then delete all the OD channels associated with this service*/
93
/*unload the decoders before deleting the channels to prevent any access fault*/
94
if (odm->codec) gf_mm_remove_codec(odm->term->mediaman, odm->codec);
95
if (odm->ocr_codec) gf_mm_remove_codec(odm->term->mediaman, odm->ocr_codec);
96
if (odm->oci_codec) gf_mm_remove_codec(odm->term->mediaman, odm->oci_codec);
98
/*then delete all the channels in this OD */
94
99
while (gf_list_count(odm->channels)) {
95
100
ch = gf_list_get(odm->channels, 0);
102
if (ch->clock->mc && ch->clock->mc->stream && ch->clock->mc->stream->odm==odm) {
103
ch->clock->mc->stream = NULL;
104
ch->clock->mc = NULL;
96
107
ODM_DeleteChannel(odm, ch);
110
/*delete the decoders*/
111
if (odm->codec) gf_codec_del(odm->codec);
112
if (odm->ocr_codec) gf_codec_del(odm->ocr_codec);
113
if (odm->oci_codec) gf_codec_del(odm->oci_codec);
115
/*then detach from network service*/
99
116
if (odm->net_service) {
100
117
if (odm->net_service->owner == odm) {
101
118
if (odm->net_service->nb_odm_users) odm->net_service->nb_odm_users--;
103
120
odm->net_service->owner = NULL;
104
121
/*try to assign a new root in case this is not scene shutdown*/
105
122
if (odm->net_service->nb_odm_users && odm->parentscene) {
107
for (i=0; i<gf_list_count(odm->parentscene->ODlist); i++) {
108
GF_ObjectManager *new_root = gf_list_get(odm->parentscene->ODlist, i);
123
GF_ObjectManager *new_root;
125
while ((new_root = gf_list_enum(odm->parentscene->ODlist, &i)) ) {
126
while (new_root->remote_OD) new_root = new_root->remote_OD;
109
127
if (new_root == odm) continue;
110
while (new_root->remote_OD) new_root = new_root->remote_OD;
111
128
if (new_root->net_service != odm->net_service) continue;
112
129
new_root->net_service->owner = new_root;
118
135
odm->net_service = NULL;
121
/*last thing to do, unload the decoders if no channels associated*/
123
assert(!gf_list_count(odm->codec->inChannels));
124
gf_mm_remove_codec(odm->term->mediaman, odm->codec);
125
gf_codec_del(odm->codec);
127
if (odm->ocr_codec) {
128
assert(!gf_list_count(odm->ocr_codec->inChannels));
129
gf_mm_remove_codec(odm->term->mediaman, odm->ocr_codec);
130
gf_codec_del(odm->ocr_codec);
132
if (odm->oci_codec) {
133
assert(!gf_list_count(odm->oci_codec->inChannels));
134
gf_mm_remove_codec(odm->term->mediaman, odm->oci_codec);
135
gf_codec_del(odm->oci_codec);
138
138
/*delete from the parent scene.*/
139
139
if (odm->parentscene) {
140
gf_is_remove_object(odm->parentscene, odm);
140
gf_is_remove_object(odm->parentscene, odm, do_remove);
141
141
if (odm->subscene) gf_is_del(odm->subscene);
142
142
if (odm->parent_OD) odm->parent_OD->remote_OD = NULL;
164
164
/*setup service for OD (extract IOD and go)*/
165
void gf_odm_setup_entry_point(GF_ObjectManager *odm, const char *sub_url)
165
void gf_odm_setup_entry_point(GF_ObjectManager *odm, const char *service_sub_url)
168
char *sub_url = (char *) service_sub_url;
168
169
GF_ObjectManager *par;
169
170
GF_Terminal *term;
170
171
GF_Descriptor *desc;
173
174
assert(odm->OD==NULL);
175
176
odm->net_service->nb_odm_users++;
176
od_type = GF_MEDIA_OBJECT_UNDEF;
177
if (odm->subscene) od_type = GF_MEDIA_OBJECT_SCENE;
178
else od_type = GF_MEDIA_OBJECT_UNDEF;
178
180
/*for remote ODs, get expected OD type in case the service needs to generate the IOD on the fly*/
180
182
while (par->parent_OD) par = par->parent_OD;
181
183
if (par->parentscene && par->OD && par->OD->URLString) {
182
184
GF_MediaObject *mo;
183
186
mo = gf_is_find_object(par->parentscene, par->OD->objectDescriptorID, par->OD->URLString);
184
187
if (mo) od_type = mo->type;
188
ext = strchr(par->OD->URLString, '#');
189
if (ext) sub_url = ext;
187
192
desc = odm->net_service->ifce->GetServiceDescriptor(odm->net_service->ifce, od_type, sub_url);
189
gf_term_message(odm->term, odm->net_service->url, "Service Entry Point not found", GF_SERVICE_ERROR);
194
/*create empty service descriptor, this will automatically create a dynamic scene*/
195
if (!desc) desc = gf_odf_desc_new(GF_ODF_OD_TAG);
197
if (!gf_list_count( ((GF_ObjectDescriptor*)desc)->ESDescriptors)) {
199
if (!odm->subscene) {
200
assert(odm->parentscene);
201
odm->subscene = gf_is_new(odm->parentscene);
202
odm->subscene->root_od = odm;
203
gf_sg_set_javascript_api(odm->subscene->graph, &odm->term->js_ifce);
223
237
Bool ipmp_failed = 0;
225
for (i=0; i<gf_list_count(toolList->ipmp_tools); i++) {
226
GF_IPMP_Tool *ipmpt = gf_list_get(toolList->ipmp_tools, i);
241
while ((ipmpt = gf_list_enum(toolList->ipmp_tools, &i))) {
227
242
if (!Term_CheckIPMPTool(odm->term, ipmpt)) {
258
274
/*locate ESD by ID*/
259
275
static GF_ESD *od_get_esd(GF_ObjectDescriptor *OD, u16 ESID)
263
for (i=0; i<gf_list_count(OD->ESDescriptors); i++) {
264
esd = gf_list_get(OD->ESDescriptors, i);
279
while ((esd = gf_list_enum(OD->ESDescriptors, &i)) ) {
265
280
if (esd->ESID==ESID) return esd;
270
285
static void ODM_SelectAlternateStream(GF_ObjectManager *odm, u32 lang_code, u8 stream_type)
273
289
u16 def_id, es_id;
276
for (i=0; i<gf_list_count(odm->OD->ESDescriptors); i++) {
277
GF_ESD *esd = gf_list_get(odm->OD->ESDescriptors, i);
293
while ( (esd = gf_list_enum(odm->OD->ESDescriptors, &i)) ) {
278
294
if (esd->decoderConfig->streamType != stream_type) continue;
280
296
if (!esd->langDesc) {
292
308
/*remove all other media streams*/
293
for (i=0; i<gf_list_count(odm->OD->ESDescriptors); i++) {
294
GF_ESD *esd = (GF_ESD *)gf_list_get(odm->OD->ESDescriptors, i);
310
while ((esd = gf_list_enum(odm->OD->ESDescriptors, &i)) ) {
295
311
if (esd->decoderConfig->streamType != stream_type) continue;
297
313
/*get base stream ID for this stream*/
333
349
*externalClock = 0;
335
351
/*step 1: validate OD*/
336
for (i = 0; i < gf_list_count(odm->OD->ESDescriptors); i++) {
337
esd = (GF_ESD *)gf_list_get(odm->OD->ESDescriptors, i);
353
while ((esd = gf_list_enum(odm->OD->ESDescriptors, &i))) {
338
354
/*check external clock refs*/
339
355
if (esd->OCRESID && (esd->OCRESID!=esd->ESID) && (od_get_esd(odm->OD, esd->OCRESID) == NULL) ) {
340
356
*externalClock = 1;
342
358
switch (esd->decoderConfig->streamType) {
345
if (esd->decoderConfig->objectTypeIndication == GPAC_STATIC_OD_OTI) nb_scene++;
359
case GF_STREAM_OD: nb_od++; break;
347
360
case GF_STREAM_OCR: nb_ocr++; break;
348
361
case GF_STREAM_SCENE: nb_scene++; break;
349
362
case GF_STREAM_MPEG7: nb_mp7++; break;
370
383
/*the rest should be OK*/
372
385
/*select independant streams - check language and (TODO) bitrate & term caps*/
373
sOpt = gf_cfg_get_key(odm->term->user->config, "Systems", "Language");
386
sOpt = gf_cfg_get_key(odm->term->user->config, "Systems", "Language3CC");
375
gf_cfg_set_key(odm->term->user->config, "Systems", "Language", "und");
388
gf_cfg_set_key(odm->term->user->config, "Systems", "Language3CC", "und");
378
391
lang = (sOpt[0]<<16) | (sOpt[1]<<8) | sOpt[2];
392
405
/*check if inline or animation stream*/
394
407
base_scene = NULL;
395
for (i=0; i<gf_list_count(odm->OD->ESDescriptors); i++) {
396
esd = (GF_ESD *)gf_list_get(odm->OD->ESDescriptors, i);
409
while ( (esd = gf_list_enum(odm->OD->ESDescriptors, &i)) ) {
397
410
switch (esd->decoderConfig->streamType) {
398
411
case GF_STREAM_PRIVATE_SCENE:
399
412
case GF_STREAM_SCENE:
485
499
numOK = odm->pending_channels = 0;
486
/*avoid channels PLAY request when confirming connection (sync network service)*/
489
for (i=0; i<gf_list_count(odm->OD->ESDescriptors); i++) {
490
GF_ESD *esd = gf_list_get(odm->OD->ESDescriptors, i);
491
e = gf_odm_setup_es(odm, esd, serv);
492
/*notify error but still go on, all streams are not so usefull*/
496
gf_term_message(odm->term, odm->net_service->url, "Stream Setup Failure", e);
501
/*empty IOD, use a dynamic scene*/
502
if (!gf_list_count(odm->OD->ESDescriptors) && odm->subscene && (odm->subscene->root_od==odm)) {
503
odm->subscene->is_dynamic_scene = 1;
506
/*avoid channels PLAY request when confirming connection (sync network service)*/
510
while ((esd = gf_list_enum(odm->OD->ESDescriptors, &i)) ) {
511
e = gf_odm_setup_es(odm, esd, serv);
512
/*notify error but still go on, all streams are not so usefull*/
516
gf_term_message(odm->term, odm->net_service->url, "Stream Setup Failure", e);
501
522
/*special case for ODs only having OCRs: force a START since they're never refered to by media nodes*/
502
523
if (odm->ocr_codec) gf_odm_start(odm);
557
579
in_scene = odm->parentscene;
558
580
if (odm->subscene && odm->subscene->root_od == odm) {
559
581
in_scene = odm->subscene;
560
for (j=0; j<gf_list_count(odm->channels); j++) {
561
ch = gf_list_get(odm->channels, j);
583
while ((ch = gf_list_enum(odm->channels, &i)) ) {
562
584
if (ch->clock->no_time_ctrl) {
563
585
odm->no_time_ctrl = 1;
569
for (i=0; i<gf_list_count(in_scene->ODlist); i++) {
570
test_od = gf_list_get(in_scene->ODlist, i);
592
while ((test_od = gf_list_enum(in_scene->ODlist, &i)) ) {
571
593
if (odm==test_od) continue;
572
for (j=0; j<gf_list_count(test_od->channels); j++) {
573
ch = gf_list_get(test_od->channels, j);
595
while ((ch = gf_list_enum(test_od->channels, &j)) ) {
574
596
if (ch->clock->no_time_ctrl) {
575
597
test_od->no_time_ctrl = 1;
676
699
e = GF_NON_COMPLIANT_BITSTREAM;
680
702
/*OD codec acts as main scene codec when used to generate scene graph*/
681
if (esd->decoderConfig->objectTypeIndication==GPAC_STATIC_OD_OTI) {
682
dec = odm->subscene->scene_codec = gf_codec_new(odm, esd, odm->OD_PL, &e);
683
gf_mm_add_codec(odm->term->mediaman, odm->subscene->scene_codec);
684
odm->subscene->is_dynamic_scene = 1;
685
dec->flags |= GF_ESM_CODEC_IS_STATIC_OD;
686
} else if (! odm->subscene->od_codec) {
687
dec = odm->subscene->od_codec = gf_codec_new(odm, esd, odm->OD_PL, &e);
703
if (! odm->subscene->od_codec) {
704
odm->subscene->od_codec = gf_codec_new(odm, esd, odm->OD_PL, &e);
688
705
gf_mm_add_codec(odm->term->mediaman, odm->subscene->od_codec);
707
dec = odm->subscene->od_codec;
691
709
case GF_STREAM_OCR:
692
710
/*OD codec acts as main scene codec when used to generate scene graph*/
707
725
if (! odm->subscene->scene_codec) {
708
726
odm->subscene->scene_codec = gf_codec_new(odm, esd, odm->Scene_PL, &e);
709
gf_mm_add_codec(odm->term->mediaman, odm->subscene->scene_codec);
727
if (!e) gf_mm_add_codec(odm->term->mediaman, odm->subscene->scene_codec);
711
729
dec = odm->subscene->scene_codec;
814
839
cs = malloc(sizeof(GF_ChannelSetup));
843
/*HACK: special case when OD resources are statically described in the ESD itself (ISMA streaming)*/
844
if ((ch->esd->decoderConfig->streamType==GF_STREAM_OD) && strstr(ch->esd->URLString, "data:application/mpeg4-od-au;") )
845
dec->flags |= GF_ESM_CODEC_IS_STATIC_OD;
817
847
gf_term_lock_net(odm->term, 1);
818
848
gf_list_add(odm->term->channels_pending, cs);
819
849
e = gf_term_connect_remote_channel(odm->term, ch, esd->URLString);
845
875
char szURL[2048];
877
GF_NetworkCommand com;
850
881
ch->odm->pending_channels--;
853
if (ch->esd->URLString) {
854
strcpy(szURL, ch->esd->URLString);
856
sprintf(szURL, "ES_ID=%d", ch->esd->ESID);
860
885
/*insert channel*/
861
886
if (dec) gf_list_insert(ch->odm->channels, ch, 0);
863
ch->es_state = GF_ESM_ES_WAIT_FOR_ACK;
889
ch->es_state = GF_ESM_ES_WAIT_FOR_ACK;
890
if (ch->esd->URLString) {
891
strcpy(szURL, ch->esd->URLString);
893
sprintf(szURL, "ES_ID=%d", ch->esd->ESID);
865
/*connect before setup: this is needed in case the decoder cfg is wrong, we may need to get it from
867
e = ch->service->ifce->ConnectChannel(ch->service->ifce, ch, szURL, ch->esd->decoderConfig->upstream);
896
/*connect before setup: this is needed in case the decoder cfg is wrong, we may need to get it from
898
e = ch->service->ifce->ConnectChannel(ch->service->ifce, ch, szURL, ch->esd->decoderConfig->upstream);
900
ch->es_state = GF_ESM_ES_CONNECTED;
901
ch->odm->pending_channels--;
870
905
if (dec) gf_list_rem(ch->odm->channels, 0);
893
928
/*in case a channel is inserted in a running OD, open and play if not in queue*/
894
if (ch->odm->is_open==1) {
929
if ( (ch->odm->is_open==1)
930
/*HACK: special case when OD resources are statically described in the ESD itself (ISMA streaming)*/
931
|| (dec && (dec->flags & GF_ESM_CODEC_IS_STATIC_OD))
895
934
gf_term_lock_net(ch->odm->term, 1);
935
gf_list_del_item(ch->odm->term->od_pending, ch->odm);
897
if (gf_list_find(ch->odm->term->od_pending, ch->odm)<0) {
898
GF_NetworkCommand com;
899
com.command_type = GF_NET_CHAN_PLAY;
900
com.base.on_channel = ch;
901
com.play.speed = FIX2FLT(ch->clock->speed);
902
com.play.start_range = gf_clock_time(ch->clock);
903
com.play.start_range /= 1000;
904
com.play.end_range = -1.0;
905
gf_term_service_command(ch->service, &com);
938
com.command_type = GF_NET_CHAN_PLAY;
939
com.base.on_channel = ch;
940
com.play.speed = FIX2FLT(ch->clock->speed);
941
com.play.start_range = gf_clock_time(ch->clock);
942
com.play.start_range /= 1000;
943
com.play.end_range = -1.0;
944
gf_term_service_command(ch->service, &com);
907
945
if (dec && (dec->Status!=GF_ESM_CODEC_PLAY)) gf_mm_start_codec(dec);
908
946
gf_term_lock_net(ch->odm->term, 0);
957
994
if (!count) count = gf_codec_remove_channel(odm->subscene->od_codec, ch);
961
ch->service->ifce->DisconnectChannel(ch->service->ifce, ch);
962
if (ch->esd->URLString) ch->service->nb_ch_users--;
963
ODM_CheckChannelService(ch);
999
ch->service->ifce->DisconnectChannel(ch->service->ifce, ch);
1000
if (ch->esd->URLString) ch->service->nb_ch_users--;
1001
ODM_CheckChannelService(ch);
974
for (i=0; i<gf_list_count(odm->OD->ESDescriptors); i++) {
975
esd = gf_list_get(odm->OD->ESDescriptors, i);
1013
while ((esd = gf_list_enum(odm->OD->ESDescriptors, &i)) ) {
976
1014
if (esd->ESID==ES_ID) goto esd_found;
982
gf_list_rem(odm->OD->ESDescriptors, i);
1020
gf_list_rem(odm->OD->ESDescriptors, i-1);
983
1021
/*locate channel*/
985
for (i=0; i<gf_list_count(odm->channels); i++) {
986
ch = gf_list_get(odm->channels, i);
1024
while ((ch = gf_list_enum(odm->channels, &i)) ) {
987
1025
if (ch->esd->ESID == ES_ID) break;
998
1036
void gf_odm_start(GF_ObjectManager *odm)
1000
1038
gf_term_lock_net(odm->term, 1);
1001
1040
/*only if not open & ready (not waiting for ACK on channel setup)*/
1002
1041
if (!odm->is_open && !odm->pending_channels) {
1004
1044
odm->is_open = 1;
1005
1045
/*start all channels and postpone play - this assures that all channels of a multiplexed are setup
1006
1046
before one starts playing*/
1007
for (i=0; i<gf_list_count(odm->channels); i++) {
1008
GF_Channel *ch = gf_list_get(odm->channels, i);
1047
while ( (ch = gf_list_enum(odm->channels, &i)) ) {
1009
1048
gf_es_start(ch);
1011
1050
if (gf_list_find(odm->term->od_pending, odm)<0) gf_list_add(odm->term->od_pending, odm);
1016
1055
void gf_odm_play(GF_ObjectManager *odm)
1019
1059
Bool skip_od_st;
1020
1060
GF_NetworkCommand com;
1021
1061
MediaControlStack *ctrl;
1062
GF_Clock *parent_ck = NULL;
1064
if (odm->parentscene) {
1065
parent_ck = gf_odm_get_media_clock(odm->parentscene->root_od);
1066
if (!gf_odm_shares_clock(odm, parent_ck)) parent_ck = NULL;
1023
1069
skip_od_st = (odm->subscene && odm->subscene->static_media_ressources) ? 1 : 0;
1025
1071
/*send play command*/
1026
1072
com.command_type = GF_NET_CHAN_PLAY;
1027
for (i=0; i<gf_list_count(odm->channels); i++) {
1074
while ( (ch = gf_list_enum(odm->channels, &i)) ) {
1028
1075
Double ck_time;
1029
GF_Channel *ch = gf_list_get(odm->channels, i);
1031
1077
com.base.on_channel = ch;
1032
1078
com.play.speed = 1.0;
1033
/*plays from current time*/
1034
ck_time = gf_clock_time(ch->clock);
1036
/*handle initial start - MPEG-4 is a bit annoying here, streams are not started through OD but through
1037
scene nodes. If the stream runs on the BIFS/OD clock, the clock is already started at this point and we're
1038
sure to get at least a one-frame delay in PLAY, so just remove it - note we're generous (one second)
1039
but this shouldn't hurt*/
1040
if (ck_time<=1.0) ck_time = 0;
1079
/*play from requested time (seeking or non-mpeg4 media control)*/
1080
if (odm->media_start_time && !ch->clock->clock_init) {
1081
ck_time = (Double) (s64) odm->media_start_time;
1084
/*play from current time*/
1086
ck_time = gf_clock_time(ch->clock);
1088
/*handle initial start - MPEG-4 is a bit annoying here, streams are not started through OD but through
1089
scene nodes. If the stream runs on the BIFS/OD clock, the clock is already started at this point and we're
1090
sure to get at least a one-frame delay in PLAY, so just remove it - note we're generous but this shouldn't hurt*/
1091
if (ck_time<=0.5) ck_time = 0;
1041
1093
com.play.start_range = ck_time;
1042
1094
com.play.end_range = -1;
1043
/*override range and speed with MC - here we don't adjust since mediaControl is here to give us the exact
1045
ctrl = ODM_GetMediaControl(odm);
1095
/*if object shares parent scene clock, do not use media control*/
1096
ctrl = parent_ck ? NULL : ODM_GetMediaControl(odm);
1097
/*override range and speed with MC*/
1047
1099
MC_GetRange(ctrl, &com.play.start_range, &com.play.end_range);
1048
1100
com.play.speed = FIX2FLT(ctrl->control->mediaSpeed);
1051
1103
com.play.start_range = ck_time;
1053
1105
gf_clock_set_speed(ch->clock, ctrl->control->mediaSpeed);
1055
/*user-defined seek on top scene*/
1056
else if (odm->term->root_scene->root_od==odm) {
1057
com.play.start_range = odm->term->restart_time;
1058
com.play.start_range /= 1000.0;
1106
/*if requested seek time AND media control, adjust start range to current play time*/
1107
if (odm->media_start_time) {
1108
if ((com.play.start_range>=0) && (com.play.end_range>com.play.start_range)) {
1109
if (ctrl->control->loop) {
1110
Double active_dur = com.play.end_range - com.play.start_range;
1111
while (ck_time>active_dur) ck_time -= active_dur;
1114
//com.play.start_range = com.play.end_range;
1117
com.play.start_range += ck_time;
1060
1120
/*full object playback*/
1061
1121
if (com.play.end_range<=0) {
1062
odm->range_end = odm->duration;
1122
odm->range_end = (u32) odm->duration;
1064
1124
/*segment playback - since our timing is in ms whereas segment ranges are double precision,
1065
1125
make sure we have a LARGER range in ms, otherwise media sensors won't deactivate properly*/
1069
1129
/*don't replay OD channel, only init clock if needed*/
1070
if (skip_od_st && (ch->esd->decoderConfig->streamType==GF_STREAM_OD)) {
1130
if (!ch->service || (skip_od_st && (ch->esd->decoderConfig->streamType==GF_STREAM_OD))) {
1071
1131
Bool gf_es_owns_clock(GF_Channel *ch);
1073
1133
if (gf_es_owns_clock(ch) )
1082
1142
gf_term_service_command(ch->service, &com);
1085
/*if root OD reset the global seek time*/
1086
if (odm->term->root_scene->root_od==odm) odm->term->restart_time = 0;
1145
odm->media_start_time = 0;
1089
1147
/*start codecs last (otherwise we end up pulling data from channels not yet connected->pbs when seeking)*/
1090
1148
if (odm->codec) {
1092
1150
if (odm->codec->CB) {
1093
CB_SetStatus(odm->codec->CB, CB_STOP);
1151
gf_cm_set_status(odm->codec->CB, CB_STOP);
1094
1152
odm->codec->CB->HasSeenEOS = 0;
1096
1154
gf_mm_start_codec(odm->codec);
1106
1164
void gf_odm_stop(GF_ObjectManager *odm, Bool force_close)
1109
1168
MediaControlStack *ctrl;
1169
MediaSensorStack *media_sens;
1110
1170
GF_NetworkCommand com;
1172
if (!odm->is_open) return;
1175
/*Handle broadcast environment, do not stop the object if no time control and instruction
1176
comes from the scene*/
1177
if (odm->no_time_ctrl && !force_close) {
1178
//fprintf(stdout, "OD%d - broadcast detected, ignoring Stop from scene\n", odm->OD->objectDescriptorID);
1112
1183
gf_list_del_item(odm->term->od_pending, odm);
1114
if (!odm->is_open) return;
1116
1185
/*little opt for image codecs: don't actually stop the OD*/
1117
1186
if (!force_close && odm->codec && odm->codec->CB) {
1118
1187
if (odm->codec->CB->Capacity==1) return;
1128
1197
if (odm->ocr_codec) gf_mm_stop_codec(odm->ocr_codec);
1129
1198
if (odm->oci_codec) gf_mm_stop_codec(odm->oci_codec);
1200
gf_term_lock_net(odm->term, 1);
1202
/*send stop command*/
1203
com.command_type = GF_NET_CHAN_STOP;
1205
while ((ch = gf_list_enum(odm->channels, &i)) ) {
1207
com.base.on_channel = ch;
1208
gf_term_service_command(ch->service, &com);
1131
1212
/*stop channels*/
1132
for (i=0; i<gf_list_count(odm->channels); i++) {
1133
GF_Channel *ch = gf_list_get(odm->channels, i);
1214
while ((ch = gf_list_enum(odm->channels, &i)) ) {
1134
1215
gf_es_stop(ch);
1137
/*send stop command*/
1138
com.command_type = GF_NET_CHAN_STOP;
1139
for (i=0; i<gf_list_count(odm->channels); i++) {
1140
GF_Channel *ch = gf_list_get(odm->channels, i);
1141
com.base.on_channel = ch;
1142
gf_term_service_command(ch->service, &com);
1218
gf_term_lock_net(odm->term, 0);
1145
1220
odm->is_open = 0;
1146
1221
odm->current_time = 0;
1148
1223
/*reset media sensor(s)*/
1149
count = gf_list_count(odm->ms_stack);
1150
for (i = 0; i<count; i++) {
1151
MediaSensorStack *media_sens = gf_list_get(odm->ms_stack, i);
1152
MS_Stop(media_sens);
1224
if (force_close!=2) {
1226
while ((media_sens = gf_list_enum(odm->ms_stack, &i))){
1227
MS_Stop(media_sens);
1154
1230
/*reset media control state*/
1155
1231
ctrl = ODM_GetMediaControl(odm);
1156
1232
if (ctrl) ctrl->current_seg = 0;
1160
1235
void gf_odm_on_eos(GF_ObjectManager *odm, GF_Channel *on_channel)
1189
void gf_odm_set_duration(GF_ObjectManager *odm, GF_Channel *ch, u32 stream_duration)
1264
void gf_odm_set_duration(GF_ObjectManager *odm, GF_Channel *ch, u64 stream_duration)
1191
1266
if (odm->codec) {
1192
1267
if (ch->esd->decoderConfig->streamType == odm->codec->type)
1225
1301
if (ctrl && (gf_list_find(odm->mc_stack, ctrl) < 0)) gf_list_add(odm->mc_stack, ctrl);
1226
1302
if (ctrl && !ctrl->control->enabled) return;
1228
/*for each clock in the controled OD*/
1229
for (i=0; i<gf_list_count(odm->channels); i++) {
1230
ch = gf_list_get(odm->channels, i);
1231
if (ch->clock->mc != ctrl) {
1304
if (odm->subscene && odm->subscene->is_dynamic_scene) {
1305
if (odm->subscene->dyn_ck) {
1232
1306
/*deactivate current control*/
1233
if (ctrl && ch->clock->mc) {
1234
ch->clock->mc->control->enabled = 0;
1235
gf_node_event_out_str((GF_Node *)ch->clock->mc->control, "enabled");
1237
/*and attach this control to the clock*/
1238
ch->clock->mc = ctrl;
1307
if (ctrl && odm->subscene->dyn_ck->mc) {
1308
odm->subscene->dyn_ck->mc->control->enabled = 0;
1309
gf_node_event_out_str((GF_Node *)odm->subscene->dyn_ck->mc->control, "enabled");
1311
odm->subscene->dyn_ck->mc = ctrl;
1314
/*for each clock in the controled OD*/
1316
while ((ch = gf_list_enum(odm->channels, &i))) {
1317
if (ch->clock->mc != ctrl) {
1318
/*deactivate current control*/
1319
if (ctrl && ch->clock->mc) {
1320
ch->clock->mc->control->enabled = 0;
1321
gf_node_event_out_str((GF_Node *)ch->clock->mc->control, "enabled");
1323
/*and attach this control to the clock*/
1324
ch->clock->mc = ctrl;
1241
1328
/*store active control on media*/
1271
1358
Bool ODM_SwitchMediaControl(GF_ObjectManager *odm, MediaControlStack *ctrl)
1361
MediaControlStack *st2;
1274
1362
if (!ctrl->control->enabled) return 0;
1276
1364
/*for all media controls other than this one force enable to false*/
1277
for (i=0; i<gf_list_count(odm->mc_stack); i++) {
1278
MediaControlStack *st2 = gf_list_get(odm->mc_stack, i);
1366
while ((st2 = gf_list_enum(odm->mc_stack, &i))) {
1279
1367
if (st2 == ctrl) continue;
1280
1368
if (st2->control->enabled) {
1281
1369
st2->control->enabled = 0;
1291
1379
Bool gf_odm_shares_clock(GF_ObjectManager *odm, GF_Clock *ck)
1294
1382
GF_Channel *ch;
1295
for (i=0; i<gf_list_count(odm->channels); i++) {
1296
ch = gf_list_get(odm->channels, i);
1383
while ((ch = gf_list_enum(odm->channels, &i))) {
1297
1384
if (ch->clock == ck) return 1;
1325
1413
if (odm->oci_codec) gf_mm_stop_codec(odm->oci_codec);
1327
1415
com.command_type = GF_NET_CHAN_PAUSE;
1328
for (i=0; i<gf_list_count(odm->channels); i++) {
1329
ch = gf_list_get(odm->channels, i);
1417
while ((ch = gf_list_enum(odm->channels, &i))) {
1330
1418
gf_clock_pause(ch->clock);
1331
1419
com.base.on_channel = ch;
1332
1420
gf_term_service_command(ch->service, &com);
1335
1423
/*mediaSensor shall generate isActive false when paused*/
1336
for (i = 0; i<gf_list_count(odm->ms_stack); i++) {
1337
MediaSensorStack *media_sens = gf_list_get(odm->ms_stack, i);
1425
while ((media_sens = gf_list_enum(odm->ms_stack, &i)) ) {
1338
1426
if (media_sens && media_sens->sensor->isActive) {
1339
1427
media_sens->sensor->isActive = 0;
1340
1428
gf_node_event_out_str((GF_Node *) media_sens->sensor, "isActive");
1366
1455
if (odm->oci_codec) gf_mm_start_codec(odm->oci_codec);
1368
1457
com.command_type = GF_NET_CHAN_RESUME;
1369
for (i=0; i<gf_list_count(odm->channels); i++) {
1370
ch = gf_list_get(odm->channels, i);
1459
while ((ch = gf_list_enum(odm->channels, &i)) ){
1371
1460
gf_clock_resume(ch->clock);
1372
1461
com.base.on_channel = ch;
1373
1462
gf_term_service_command(ch->service, &com);
1376
1465
/*mediaSensor shall generate isActive TRUE when resumed*/
1377
for (i = 0; i<gf_list_count(odm->ms_stack); i++) {
1378
MediaSensorStack *media_sens = gf_list_get(odm->ms_stack, i);
1467
while ((media_sens = gf_list_enum(odm->ms_stack, &i)) ){
1379
1468
if (media_sens && !media_sens->sensor->isActive) {
1380
1469
media_sens->sensor->isActive = 1;
1381
1470
gf_node_event_out_str((GF_Node *) media_sens->sensor, "isActive");
1394
1483
com.command_type = GF_NET_CHAN_SET_SPEED;
1395
1484
com.play.speed = FIX2FLT(speed);
1396
for (i=0; i<gf_list_count(odm->channels); i++) {
1397
ch = gf_list_get(odm->channels, i);
1486
while ((ch = gf_list_enum(odm->channels, &i)) ) {
1398
1487
gf_clock_set_speed(ch->clock, speed);
1399
1488
com.play.on_channel = ch;
1400
1489
gf_term_service_command(ch->service, &com);
1404
1493
GF_Segment *ODM_GetSegment(GF_ObjectManager *odm, char *descName)
1407
for (i=0; i<gf_list_count(odm->OD->OCIDescriptors); i++) {
1408
GF_Segment *desc = gf_list_get(odm->OD->OCIDescriptors, i);
1497
while ( (desc = gf_list_enum(odm->OD->OCIDescriptors, &i)) ){
1409
1498
if (desc->tag != GF_ODF_SEGMENT_TAG) continue;
1410
1499
if (!stricmp(desc->SegmentName, descName)) return desc;
1417
1506
/*this reorders segments when inserting into list - I believe this is not compliant*/
1420
for (i=0; i<gf_list_count(list); i++) {
1421
GF_Segment *desc = gf_list_get(list, i);
1510
while ((desc = gf_list_enum(list, &i))) {
1422
1511
if (desc == seg) return;
1423
1512
if (seg->startTime + seg->Duration <= desc->startTime) {
1424
1513
gf_list_insert(list, seg, i);
1435
1524
char *str, *sep;
1436
1525
char seg1[1024], seg2[1024], seg_url[4096];
1437
GF_Segment *first_seg, *last_seg;
1526
GF_Segment *first_seg, *last_seg, *seg;
1440
1529
/*browse all URLs*/
1471
1560
/*segment range process*/
1472
1561
ODM_InsertSegment(odm, first_seg, list);
1473
for (j=0; j<gf_list_count(odm->OD->OCIDescriptors); j++) {
1474
GF_Segment *seg = gf_list_get(odm->OD->OCIDescriptors, j);
1563
while ( (seg = gf_list_enum(odm->OD->OCIDescriptors, &j)) ) {
1475
1564
if (seg->tag != GF_ODF_SEGMENT_TAG) continue;
1476
1565
if (seg==first_seg) continue;
1477
1566
if (seg->startTime + seg->Duration <= first_seg->startTime) continue;
1499
1588
if (!odm->codec || ((odm->codec->type!=GF_STREAM_VISUAL) && (odm->codec->type!=GF_STREAM_AUDIO))) {
1500
1589
GF_Clock *ck = gf_odm_get_media_clock(odm);
1501
1590
u32 now = gf_clock_time(ck);
1502
u32 dur = odm->subscene ? odm->subscene->duration : odm->duration;
1591
u64 dur = odm->subscene ? odm->subscene->duration : odm->duration;
1503
1592
cur = gf_list_get(ctrl->seg, ctrl->current_seg);
1504
1593
if (odm->subscene && odm->subscene->needs_restart) return 0;
1505
1594
if (cur) dur = (u32) ((cur->Duration+cur->startTime)*1000);