📄 com_dec.c
字号:
e = gf_node_get_field(node, field_ind, &field); if (gf_sg_vrml_is_sf_field(field.fieldType)) return GF_NON_COMPLIANT_BITSTREAM; type = gf_bs_read_int(bs, 2); switch (type) { case 0: pos = gf_bs_read_int(bs, 16); break; case 2: pos = 0; break; case 3: pos = ((GenMFField *) field.far_ptr)->count - 1; break; default: return GF_NON_COMPLIANT_BITSTREAM; } /*if MFNode remove the child and parse new node*/ if (field.fieldType == GF_SG_VRML_MFNODE) { /*get the new node*/ new_node = gf_bifs_dec_node(codec, bs, field.NDTtype); if (codec->LastError) { e = codec->LastError; goto exit; } if (new_node) { e = gf_node_register(new_node, node); if (e) return e; } /*replace prev node*/ e = gf_node_replace_child(node, (GF_ChildNodeItem**) field.far_ptr, pos, new_node); if (!e) gf_bifs_check_field_change(node, &field); } /*erase the field item*/ else { memcpy(&sffield, &field, sizeof(GF_FieldInfo)); sffield.fieldType = gf_sg_vrml_get_sf_type(field.fieldType); /*make sure this is consistent*/ if (pos && pos >= ((GenMFField *)field.far_ptr)->count) { pos = ((GenMFField *)field.far_ptr)->count - 1; } e = gf_sg_vrml_mf_get_item(field.far_ptr, field.fieldType, & sffield.far_ptr, pos); if (e) return e; e = gf_bifs_dec_sf_field(codec, bs, node, &sffield); if (!e) gf_bifs_check_field_change(node, &field); }exit: return e;}static GF_Err BD_DecRouteReplace(GF_BifsDecoder * codec, GF_BitStream *bs){ GF_Err e; u32 RouteID, numBits, ind, node_id, fromID, toID; char name[1000], *ptr; GF_Route *r; GF_Node *OutNode, *InNode; RouteID = 1+gf_bs_read_int(bs, codec->info->config.RouteIDBits); r = gf_sg_route_find(codec->current_graph, RouteID);#ifdef MPEG4_STRICT if (!r) return GF_NON_COMPLIANT_BITSTREAM; ptr = gf_sg_route_get_name(r); gf_sg_route_del(r);#else ptr = NULL; if (r) { ptr = gf_sg_route_get_name(r); gf_sg_route_del(r); }#endif if (ptr) strcpy(name, ptr); /*origin*/ node_id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); OutNode = gf_sg_find_node(codec->current_graph, node_id); if (!OutNode) return GF_NON_COMPLIANT_BITSTREAM; numBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(OutNode, GF_SG_FIELD_CODING_OUT) - 1); ind = gf_bs_read_int(bs, numBits); e = gf_bifs_get_field_index(OutNode, ind, GF_SG_FIELD_CODING_OUT, &fromID); if (e) return e; /*target*/ node_id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); InNode = gf_sg_find_node(codec->current_graph, node_id); if (!InNode) return GF_NON_COMPLIANT_BITSTREAM; numBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(InNode, GF_SG_FIELD_CODING_IN) - 1); ind = gf_bs_read_int(bs, numBits); e = gf_bifs_get_field_index(InNode, ind, GF_SG_FIELD_CODING_IN, &toID); if (e) return e; r = gf_sg_route_new(codec->current_graph, OutNode, fromID, InNode, toID); if (!r) return GF_OUT_OF_MEM; gf_sg_route_set_id(r, RouteID); if (ptr) e = gf_sg_route_set_name(r, name); return e;}static GF_Err BD_DecReplace(GF_BifsDecoder * codec, GF_BitStream *bs){ u8 type; type = gf_bs_read_int(bs, 2); switch (type) { case 0: return BD_DecNodeReplace(codec, bs); case 1: return BD_DecFieldReplace(codec, bs); case 2: return BD_DecIndexValueReplace(codec, bs); case 3: return BD_DecRouteReplace(codec, bs); } return GF_OK;}/*if parent is non-NULL, we are in a proto code parsing, otherwise this is a top-level proto*/GF_Err gf_bifs_dec_proto_list(GF_BifsDecoder * codec, GF_BitStream *bs, GF_List *proto_list){ u8 flag, field_type, event_type, useQuant, useAnim, f; u32 i, NbRoutes, ID, numProtos, numFields, count, qpsftype, QP_Type, NumBits, Anim_Type; GF_Node *node; char name[1000]; GF_ProtoFieldInterface *proto_field; GF_Proto *proto, *ParentProto; GF_Err e; u32 hasMinMax; void *qp_min_value, *qp_max_value; GF_SceneGraph *rootSG; GF_FieldInfo field; NumBits = qpsftype = 0; //store proto at codec level rootSG = codec->current_graph; ParentProto = codec->pCurrentProto; e = GF_OK; numProtos = 0; proto = NULL; flag = gf_bs_read_int(bs, 1); while (flag) { if (!codec->info->config.ProtoIDBits) return GF_NON_COMPLIANT_BITSTREAM; /*1- proto interface declaration*/ ID = gf_bs_read_int(bs, codec->info->config.ProtoIDBits); if (codec->info->UseName) { gf_bifs_dec_name(bs, name); } else { sprintf(name, "Proto%d", numProtos); } /*create a proto in the current graph*/ proto = gf_sg_proto_new(codec->current_graph, ID, name, proto_list ? 1 : 0); if (proto_list) gf_list_add(proto_list, proto); /*during parsing, this proto is the current active one - all nodes/proto defined/declared below it will belong to its namespace*/ codec->current_graph = gf_sg_proto_get_graph(proto); codec->pCurrentProto = proto; numFields = 0; flag = gf_bs_read_int(bs, 1); while (flag) { event_type = gf_bs_read_int(bs, 2); field_type = gf_bs_read_int(bs, 6); if (codec->info->UseName) { gf_bifs_dec_name(bs, name); } else { sprintf(name, "_field%d", numFields); } /*create field interface*/ proto_field = gf_sg_proto_field_new(proto, field_type, event_type, name); /*get field info */ gf_sg_proto_field_get_field(proto_field, &field); switch (event_type) { case GF_SG_EVENT_EXPOSED_FIELD: case GF_SG_EVENT_FIELD: /*parse default value except nodes ...*/ if (gf_sg_vrml_is_sf_field(field_type)) { e = gf_bifs_dec_sf_field(codec, bs, NULL, &field); } else { f = 0; if (codec->info->config.UsePredictiveMFField) { f = gf_bs_read_int(bs, 1); /*predictive encoding of proto field is not possible since QP info is not present yet*/ assert(!f); } /*reserved*/ f = gf_bs_read_int(bs, 1); if (!f) { if (gf_bs_read_int(bs, 1)) { e = BD_DecMFFieldList(codec, bs, NULL, &field); } else { e = BD_DecMFFieldVec(codec, bs, NULL, &field); } } } if (e) goto exit; break; } flag = gf_bs_read_int(bs, 1); numFields++; } /*2- parse proto code*/ flag = gf_bs_read_int(bs, 1); /*externProto*/ if (flag) { memset(&field, 0, sizeof(GF_FieldInfo)); field.far_ptr = gf_sg_proto_get_extern_url(proto); field.fieldType = GF_SG_VRML_MFURL; field.name = "ExternProto"; if (codec->info->config.UsePredictiveMFField) { flag = gf_bs_read_int(bs, 1); assert(!flag); } /*reserved*/ flag = gf_bs_read_int(bs, 1); /*list or vector*/ flag = gf_bs_read_int(bs, 1); if (flag) { e = BD_DecMFFieldList(codec, bs, NULL, &field); } else { e = BD_DecMFFieldVec(codec, bs, NULL, &field); } if (e) goto exit; } /*get proto code*/ else { /*parse sub-proto list - subprotos are ALWAYS registered with parent proto graph*/ e = gf_bifs_dec_proto_list(codec, bs, NULL); if (e) goto exit; flag = 1; while (flag) { /*parse all nodes in SFWorldNode table*/ node = gf_bifs_dec_node(codec, bs, NDT_SFWorldNode); if (!node) { e = codec->LastError; goto exit; } e = gf_node_register(node, NULL); if (e) goto exit; gf_sg_proto_add_node_code(proto, node); flag = gf_bs_read_int(bs, 1); } /*routes*/ flag = gf_bs_read_int(bs, 1); if (flag) { flag = gf_bs_read_int(bs, 1); if (flag) { /*list route*/ while (flag) { e = gf_bifs_dec_route(codec, bs, 0); if (e) goto exit; flag = gf_bs_read_int(bs, 1); } } else { /*vector*/ i = gf_bs_read_int(bs, 5); NbRoutes = gf_bs_read_int(bs, i); for (i=0; i<NbRoutes; i++) { e = gf_bifs_dec_route(codec, bs, 0); if (e) goto exit; } } } } /*restore the namespace*/ codec->current_graph = rootSG; /*3- parse anim and Quantization stuff*/ useQuant = gf_bs_read_int(bs, 1); useAnim = gf_bs_read_int(bs, 1); count = gf_sg_proto_get_field_count(proto); for (i=0; i<count; i++) { proto_field = gf_sg_proto_field_find(proto, i); gf_sg_proto_field_get_field(proto_field, &field); /*quant*/ if (useQuant && ( (field.eventType == GF_SG_EVENT_FIELD) || (field.eventType == GF_SG_EVENT_EXPOSED_FIELD) )) { QP_Type = gf_bs_read_int(bs, 4); if (QP_Type==QC_LINEAR_SCALAR) { NumBits = gf_bs_read_int(bs, 5); } hasMinMax = gf_bs_read_int(bs, 1); qp_min_value = qp_max_value = NULL; if (hasMinMax) { /*parse min and max*/ qpsftype = gf_sg_vrml_get_sf_type(field.fieldType); switch (qpsftype) { case GF_SG_VRML_SFINT32: case GF_SG_VRML_SFTIME: break; /*other fields are of elementary type SFFloat or shouldn't have min/max*/ default: qpsftype = GF_SG_VRML_SFFLOAT; break; } field.fieldType = qpsftype; qp_min_value = gf_sg_vrml_field_pointer_new(qpsftype); field.name = "QPMinValue"; field.far_ptr = qp_min_value; gf_bifs_dec_sf_field(codec, bs, NULL, &field); qp_max_value = gf_sg_vrml_field_pointer_new(qpsftype); field.name = "QPMaxValue"; field.far_ptr = qp_max_value; gf_bifs_dec_sf_field(codec, bs, NULL, &field); } /*and store*/ if (QP_Type) { e = gf_bifs_proto_field_set_aq_info(proto_field, QP_Type, hasMinMax, qpsftype, qp_min_value, qp_max_value, NumBits); gf_sg_vrml_field_pointer_del(qp_min_value, qpsftype); gf_sg_vrml_field_pointer_del(qp_max_value, qpsftype); } } /*anim - not supported yet*/ if (useAnim && ( (field.eventType == GF_SG_EVENT_IN) || (field.eventType == GF_SG_EVENT_EXPOSED_FIELD) )) { flag = gf_bs_read_int(bs, 1); if (flag) { Anim_Type = gf_bs_read_int(bs, 4); } else { Anim_Type = 0; } } } numProtos ++; /*4- get next proto*/ flag = gf_bs_read_int(bs, 1); }exit: if (e) { if (proto) gf_sg_proto_del(proto); codec->current_graph = rootSG; } /*restore original parent proto at codec level*/ codec->pCurrentProto = ParentProto; return e;}GF_Err gf_bifs_dec_route(GF_BifsDecoder * codec, GF_BitStream *bs, Bool is_insert){ GF_Err e; u8 flag; GF_Route *r; GF_Node *InNode, *OutNode; u32 RouteID, outField, inField, numBits, ind, node_id; char name[1000]; RouteID = 0; flag = gf_bs_read_int(bs, 1); /*def'ed route*/ if (flag) { RouteID = 1 + gf_bs_read_int(bs, codec->info->config.RouteIDBits); if (codec->info->UseName) gf_bifs_dec_name(bs, name); } /*origin*/ node_id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); OutNode = gf_sg_find_node(codec->current_graph, node_id); if (!OutNode) return GF_SG_UNKNOWN_NODE; numBits = gf_node_get_num_fields_in_mode(OutNode, GF_SG_FIELD_CODING_OUT) - 1; numBits = gf_get_bit_size(numBits); ind = gf_bs_read_int(bs, numBits); e = gf_bifs_get_field_index(OutNode, ind, GF_SG_FIELD_CODING_OUT, &outField); /*target*/ node_id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); InNode = gf_sg_find_node(codec->current_graph, node_id); if (!InNode) return GF_SG_UNKNOWN_NODE; numBits = gf_node_get_num_fields_in_mode(InNode, GF_SG_FIELD_CODING_IN) - 1; numBits = gf_get_bit_size(numBits); ind = gf_bs_read_int(bs, numBits); e = gf_bifs_get_field_index(InNode, ind, GF_SG_FIELD_CODING_IN, &inField); if (e) return e; r = gf_sg_route_new(codec->current_graph, OutNode, outField, InNode, inField); if (!r) return GF_OUT_OF_MEM; if (RouteID) { e = gf_sg_route_set_id(r, RouteID); if (!e && codec->info->UseName) e = gf_sg_route_set_name(r, name); } return e;}GF_Err BD_DecSceneReplace(GF_BifsDecoder * codec, GF_BitStream *bs, GF_List *proto_list){ u8 flag; u32 i, nbR; GF_Err e; GF_Node *root; /*Reset the existing scene / scene graph, protos and route lists*/ if (!proto_list) gf_sg_reset(codec->current_graph); /*reserved*/ i = gf_bs_read_int(bs, 6); codec->info->UseName = gf_bs_read_int(bs, 1); /*parse PROTOS*/ e = gf_bifs_dec_proto_list(codec, bs, proto_list); if (e) goto exit; assert(codec->pCurrentProto==NULL); /*Parse the top node - always of type SFTopNode*/ root = gf_bifs_dec_node(codec, bs, NDT_SFTopNode); if (!root && codec->LastError) { e = codec->LastError; goto exit; } if (root) { e = gf_node_register(root, NULL); if (e) goto exit; } gf_sg_set_root_node(codec->current_graph, root); /*Parse the routes*/ flag = gf_bs_read_int(bs, 1); if (flag) { flag = gf_bs_read_int(bs, 1); if (flag) { /*list*/ while (flag) { e = gf_bifs_dec_route(codec, bs, 0); if (e) goto exit; flag = gf_bs_read_int(bs, 1); } } else { /*vector*/ i = gf_bs_read_int(bs, 5); nbR = gf_bs_read_int(bs, i); for (i=0; i<nbR; i++) { e = gf_bifs_dec_route(codec, bs, 0); if (e) goto exit; } } }exit: return e;}GF_Err gf_bifs_dec_command(GF_BifsDecoder * codec, GF_BitStream *bs){ GF_Err e; e = codec->LastError = GF_OK; while (1) { u8 type = gf_bs_read_int(bs, 2); switch (type) { case 0: e = BD_DecInsert(codec, bs); break; case 1: e = BD_DecDelete(codec, bs); break; case 2: e = BD_DecReplace(codec, bs); break; case 3: e = BD_DecSceneReplace(codec, bs, NULL); break; } if (e) return e; if (! gf_bs_read_int(bs, 1)) break; } while (gf_list_count(codec->QPs)) { gf_bifs_dec_qp_remove(codec, 1); } return GF_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -