📄 loader_xmt.c
字号:
ocr_id = atoi(esdl->OCR_Name); sprintf(szTest, "%d", ocr_id); if (!stricmp(szTest, esdl->OCR_Name)) use_old_fmt = 1; j=0; while ((esdl2 = (XMT_ESDLink *)gf_list_enum(parser->esd_links, &j))) { if (esdl2->desc_name && !strcmp(esdl2->desc_name, esdl->OCR_Name)) { esdl->esd->OCRESID = esdl2->esd->ESID; break; } if (use_old_fmt && (esdl2->esd->ESID==ocr_id)) { esdl->esd->OCRESID = ocr_id; break; } } if (!esdl->esd->OCRESID) { xmt_report(parser, GF_OK, "WARNING: Could not find clock reference %s for ES %s - forcing self-synchronization", esdl->OCR_Name, esdl->desc_name); } free(esdl->OCR_Name); esdl->OCR_Name = NULL; } /*set dependsOn es ids*/ i=0; while ((esdl = (XMT_ESDLink *)gf_list_enum(parser->esd_links, &i))) { Bool use_old_fmt; u16 dep_id; char szTest[50]; esdl->esd->dependsOnESID = 0; if (!esdl->Depends_Name) continue; use_old_fmt = 0; dep_id = atoi(esdl->Depends_Name); sprintf(szTest, "%d", dep_id); if (!stricmp(szTest, esdl->Depends_Name)) use_old_fmt = 1; j=0; while ((esdl2 = (XMT_ESDLink *)gf_list_enum(parser->esd_links, &j))) { if (esdl2->desc_name && !strcmp(esdl2->desc_name, esdl->Depends_Name)) { esdl->esd->dependsOnESID = esdl2->esd->ESID; break; } if (use_old_fmt && (esdl2->esd->ESID==dep_id)) { esdl->esd->dependsOnESID = dep_id; break; } } if (!esdl->esd->dependsOnESID) { xmt_report(parser, GF_OK, "WARNING: Could not find stream dependance %s for ES %s - forcing self-synchronization", esdl->Depends_Name, esdl->desc_name); } free(esdl->Depends_Name); esdl->Depends_Name = NULL; } while (gf_list_count(parser->esd_links)) { esdl = (XMT_ESDLink *)gf_list_get(parser->esd_links, 0); gf_list_rem(parser->esd_links, 0); if (esdl->desc_name) free(esdl->desc_name); free(esdl); } i=0; while ((l = (XMT_ODLink*)gf_list_enum(parser->od_links, &i))) { if (l->od && !l->od->objectDescriptorID) { u16 ODID = 1; while (!xmt_odid_available(parser, ODID)) ODID++; l->od->objectDescriptorID = ODID; } if (l->od) { if (!l->ID) l->ID = l->od->objectDescriptorID; assert(l->ID == l->od->objectDescriptorID); } } /*unroll dep in case some URLs reference ODs by their binary IDs not their string ones*/ i=0; while ((l = (XMT_ODLink*)gf_list_enum(parser->od_links, &i))) { XMT_ODLink *l2; /*not OD URL*/ if (!l->ID) continue; j=i+1; while ((l2 = (XMT_ODLink*)gf_list_enum(parser->od_links, &j))) { /*not OD URL*/ if (!l2->ID) continue; if (l->ID == l2->ID) { while (gf_list_count(l2->mf_urls)) { MFURL *url = (MFURL *)gf_list_get(l2->mf_urls, 0); gf_list_rem(l2->mf_urls, 0); gf_list_add(l->mf_urls, url); } j--; gf_list_rem(parser->od_links, j); if (l2->desc_name) free(l2->desc_name); gf_list_del(l2->mf_urls); free(l2); } } } while (gf_list_count(parser->od_links) ) { l = (XMT_ODLink*)gf_list_get(parser->od_links, 0); if (!l->od) { /*if no ID found this is not an OD URL*/ if (l->ID) { if (l->desc_name) { xmt_report(parser, GF_OK, "WARNING: OD \"%s\" (ID %d) not assigned", l->desc_name, l->ID); } else{ xmt_report(parser, GF_OK, "WARNING: OD ID %d not assigned", l->ID); } } } else { MFURL *the_url; j=0; while ((the_url = (MFURL *)gf_list_enum(l->mf_urls, &j))) { u32 k; char *seg = NULL; for (k=0; k<the_url->count; k++) { SFURL *url = &the_url->vals[k]; if (url->url) seg = strstr(url->url, "#"); if (seg) { sprintf(szURL, "od:%d#%s", l->od->objectDescriptorID, seg+1); free(url->url); url->url = strdup(szURL); } else { if (url->url) free(url->url); url->url = NULL; url->OD_ID = l->od->objectDescriptorID; } } } } if (l->desc_name) free(l->desc_name); gf_list_del(l->mf_urls); free(l); gf_list_rem(parser->od_links, 0); }}static u32 xmt_get_next_node_id(GF_XMTParser *parser){ u32 ID; GF_SceneGraph *sc = parser->load->scene_graph; if (parser->parsing_proto) sc = gf_sg_proto_get_graph(parser->parsing_proto); ID = gf_sg_get_next_available_node_id(sc); if (parser->load->ctx && (ID>parser->load->ctx->max_node_id)) parser->load->ctx->max_node_id = ID; return ID;}static u32 xmt_get_node_id(GF_XMTParser *parser, char *name){ GF_Node *n; u32 ID; if (sscanf(name, "N%d", &ID) == 1) { ID ++; n = gf_sg_find_node(parser->load->scene_graph, ID); if (n) { u32 nID = xmt_get_next_node_id(parser); xmt_report(parser, GF_OK, "WARNING: changing node \"%s\" ID from %d to %d", gf_node_get_name(n), gf_node_get_id(n)-1, nID-1); gf_node_set_id(n, nID, gf_node_get_name(n)); } if (parser->load->ctx && (parser->load->ctx->max_node_id<ID)) parser->load->ctx->max_node_id=ID; } else { ID = xmt_get_next_node_id(parser); } return ID;}static u32 xmt_get_node_tag(GF_XMTParser *parser, char *node_name) { u32 tag; /*if VRML and allowing non MPEG4 nodes, use X3D*/ if ((parser->doc_type==2) && !(parser->load->flags & GF_SM_LOAD_MPEG4_STRICT)) { tag = gf_node_x3d_type_by_class_name(node_name); if (!tag) tag = gf_node_mpeg4_type_by_class_name(node_name); } else { tag = gf_node_mpeg4_type_by_class_name(node_name); /*if allowing non MPEG4 nodes, try X3D*/ if (!tag && !(parser->load->flags & GF_SM_LOAD_MPEG4_STRICT)) tag = gf_node_x3d_type_by_class_name(node_name); } return tag;}static GF_Node *xmt_find_node(GF_XMTParser *parser, char *ID){ u32 i, count, tag; Bool is_proto; char *node_class; GF_Node *n = gf_sg_find_node_by_name(parser->load->scene_graph, ID); if (n) return n; count = gf_list_count(parser->peeked_nodes); for (i=0; i<count; i++) { n = (GF_Node*)gf_list_get(parser->peeked_nodes, i); if (!strcmp(gf_node_get_name(n), ID)) return n; } node_class = gf_xml_sax_peek_node(parser->sax_parser, "DEF", ID, "ProtoInstance", "name", "<par", &is_proto); if (!node_class) return NULL; n = NULL; if (is_proto) { GF_Proto *p; GF_SceneGraph *sg = parser->load->scene_graph; while (1) { p = gf_sg_find_proto(sg, 0, node_class); if (p) break; sg = sg->parent_scene; if (!sg) break; } if (!p) { xmt_report(parser, GF_BAD_PARAM, "%s: not a valid/supported proto", node_class); free(node_class); return NULL; } n = gf_sg_proto_create_instance(parser->load->scene_graph, p); } else { tag = xmt_get_node_tag(parser, node_class); n = gf_node_new(parser->load->scene_graph, tag); } free(node_class); if (n) { u32 nID = xmt_get_node_id(parser, ID); gf_node_set_id(n, nID, ID); if (!parser->parsing_proto) gf_node_init(n); gf_list_add(parser->peeked_nodes, n); } return n;}#define XMT_GET_ONE_VAL \ char value[100]; \ u32 i; \ char *str = a_value; \ if (!str) { \ xmt_report(parser, GF_BAD_PARAM, "%s: Number expected", name); \ return 0; \ } \ while (str[0] == ' ') str += 1; \ i = 0; \ while ((str[i] != ' ') && str[i]) { \ value[i] = str[i]; \ i++; \ } \ value[i] = 0; \ while ((str[i] == ' ') && str[i]) i++;static u32 xmt_parse_int(GF_XMTParser *parser, const char *name, SFInt32 *val, char *a_value){ XMT_GET_ONE_VAL *val = atoi(value); return i;}static u32 xmt_parse_float(GF_XMTParser *parser, const char *name, SFFloat *val, char *a_value){ XMT_GET_ONE_VAL *val = FLT2FIX(atof(value)); return i;}static u32 xmt_parse_time(GF_XMTParser *parser, const char *name, SFTime *val, char *a_value){ XMT_GET_ONE_VAL *val = atof(value); return i;}static u32 xmt_parse_bool(GF_XMTParser *parser, const char *name, SFBool *val, char *a_value){ XMT_GET_ONE_VAL if (!stricmp(value, "1") || !stricmp(value, "true")) *val = 1; else *val = 0; return i;}static u32 xmt_parse_string(GF_XMTParser *parser, const char *name, SFString *val, Bool is_mf, char *a_value){ char *value; char sep[10]; u32 len; u32 i=0; u32 k=0; char *str = a_value; if (!str) return 0; /*SF string, no inspection*/ if (!is_mf) { len = strlen(str); if (val->buffer) free(val->buffer); val->buffer = NULL; if (len) val->buffer = strdup(str); return len+1; } /*now this is the REAL pain: X3D allows '"String1" "String2"' and therefore '"String "test""' XMT allows '"String1" "String2"' and therefore '"String \"test\""' thus translating the string from xml to UTF may screw up the separators !! We need to identify them */ i = 0; while ((str[i]==' ') || (str[i]=='\t')) i++; if (!strncmp(&str[i], """, 6)) strcpy(sep, """); else if (!strncmp(&str[i], "'", 6)) strcpy(sep, "'"); else if (str[i]=='\'') strcpy(sep, "\'"); else if (str[i]=='\"') strcpy(sep, "\""); /*handle as a single field (old GPAC XMT & any unknown cases...*/ else { len = strlen(str); if (val->buffer) free(val->buffer); val->buffer = NULL; if (len) val->buffer = strdup(str); return len; } k = 0; i += strlen(sep); value = strdup(str); if (strncmp(&str[i], sep, strlen(sep))) { while (str[i]) { if ((str[i] == '\\') && !strncmp(&str[i+1], sep, strlen(sep))) { i++; continue; } value[k] = str[i]; i++; k++; if (!strncmp(&str[i], sep, strlen(sep)) && (str[i-1] != '\\')) break; } } value[k] = 0; len = strlen(sep) + i; if (val->buffer) free(val->buffer); val->buffer = NULL; if (strlen(value)) val->buffer = strdup(value); free(value); return len;}static u32 xmt_parse_url(GF_XMTParser *parser, const char *name, MFURL *val, GF_Node *owner, Bool is_mf, char *a_value){ SFString sfstr; u32 res, idx; char value[5000], *tmp; /*parse as a string*/ sfstr.buffer = NULL; res = xmt_parse_string(parser, name, &sfstr, is_mf, a_value); if (parser->last_error) return res; assert(val->count); idx = val->count - 1; if (val->vals[idx].url) free(val->vals[idx].url); val->vals[idx].url = sfstr.buffer; val->vals[idx].OD_ID = 0; /*empty*/ if (!val->vals[idx].url) return res; /*remove segments & viewpoints info to create OD link*/ strcpy(value, val->vals[idx].url); tmp = strstr(value, "#"); if (tmp) tmp[0] = 0; /*according to XMT-A spec, both 'od:' and 'od://' are tolerated in XMT-A*/ if (!strnicmp(value, "od://", 5)) xmt_new_od_link_from_node(parser, value+5, val); else if (!strnicmp(value, "od:", 3)) xmt_new_od_link_from_node(parser, value+3, val); else xmt_new_od_link_from_node(parser, value, val); return res;}static u32 xmt_parse_script(GF_XMTParser *parser, const char *name, SFScript *val, Bool is_mf, char *a_value){ SFString sfstr; u32 res; /*parse as a string*/ sfstr.buffer = NULL; res = xmt_parse_string(parser, name, &sfstr, is_mf, a_value); if (parser->last_error) return res; if (val->script_text) free(val->script_text); val->script_text = (unsigned char*)sfstr.buffer; return res;}static void xmt_offset_time(GF_XMTParser *parser, Double *time){ *time += parser->au_time;}static void xmt_check_time_offset(GF_XMTParser *parser, GF_Node *n, GF_FieldInfo *info){ if (!(parser->load->flags & GF_SM_LOAD_FOR_PLAYBACK)) return; if (gf_node_get_tag(n) != TAG_ProtoNode) { if (!stricmp(info->name, "startTime") || !stricmp(info->name, "stopTime")) xmt_offset_time(parser, (Double *)info->far_ptr);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -