/* * GPAC - Multimedia Framework C SDK * * Copyright (c) Jean Le Feuvre 2000-2005 * All rights reserved * * This file is part of GPAC / BIFS codec sub-project * * GPAC is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * GPAC is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include #include "quant.h" GF_Err BD_DecMFFieldList(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field); GF_Err BD_DecMFFieldVec(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field); void gf_bifs_dec_name(GF_BitStream *bs, char *name) { u32 i = 0; while (1) { name[i] = gf_bs_read_int(bs, 8); if (!name[i]) break; i++; } } static GF_Err BD_DecProtoDelete(GF_BifsDecoder * codec, GF_BitStream *bs) { u32 ID, flag, count; GF_Proto *proto; flag = gf_bs_read_int(bs, 1); if (flag) { flag = gf_bs_read_int(bs, 1); while (flag) { ID = gf_bs_read_int(bs, codec->info->config.ProtoIDBits); proto = gf_sg_find_proto(codec->current_graph, ID, NULL); if (proto) gf_sg_proto_del(proto); flag = gf_bs_read_int(bs, 1); } } else { flag = gf_bs_read_int(bs, 5); count = gf_bs_read_int(bs, flag); while (count) { ID = gf_bs_read_int(bs, codec->info->config.ProtoIDBits); proto = gf_sg_find_proto(codec->current_graph, ID, NULL); if (proto) gf_sg_proto_del(proto); count--; } } return GF_OK; } static GF_Err BD_DecMultipleIndexReplace(GF_BifsDecoder * codec, GF_BitStream *bs) { u32 ID, ind, field_ind, NumBits, lenpos, lennum, count, pos; GF_Node *node, *new_node; GF_Err e; GF_FieldInfo field, sffield; ID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); node = gf_sg_find_node(codec->current_graph, ID); if (!node) return GF_NON_COMPLIANT_BITSTREAM; NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_IN)-1); ind = gf_bs_read_int(bs, NumBits); e = gf_bifs_get_field_index(node, ind, GF_SG_FIELD_CODING_IN, &field_ind); if (e) return e; e = gf_node_get_field(node, field_ind, &field); if (gf_sg_vrml_is_sf_field(field.fieldType)) return GF_NON_COMPLIANT_BITSTREAM; lenpos = gf_bs_read_int(bs, 5); lennum = gf_bs_read_int(bs, 5); count = gf_bs_read_int(bs, lennum); /*cf index value replace */ if (field.fieldType == GF_SG_VRML_MFNODE) { while (count) { pos = gf_bs_read_int(bs, lenpos); /*first decode*/ new_node = gf_bifs_dec_node(codec, bs, field.NDTtype); if (!new_node) return codec->LastError; e = gf_node_register(new_node, node); if (e) return e; /*then replace*/ e = gf_node_replace_child(node, (GF_ChildNodeItem**) field.far_ptr, pos, new_node); count--; } if (!e) gf_bifs_check_field_change(node, &field); return e; } /*Not a node list*/ memcpy(&sffield, &field, sizeof(GF_FieldInfo)); sffield.fieldType = gf_sg_vrml_get_sf_type(field.fieldType); while (count) { pos = gf_bs_read_int(bs, lenpos); 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) break; count--; } if (!e) gf_bifs_check_field_change(node, &field); return e; } static GF_Err BD_DecMultipleReplace(GF_BifsDecoder * codec, GF_BitStream *bs) { GF_Err e; u32 NodeID, flag; GF_Node *node; NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); node = gf_sg_find_node(codec->current_graph, NodeID); if (!node) return GF_NON_COMPLIANT_BITSTREAM; flag = gf_bs_read_int(bs, 1); if (flag) { e = gf_bifs_dec_node_mask(codec, bs, node); } else { e = gf_bifs_dec_node_list(codec, bs, node); } return e; } static GF_Err BD_DecGlobalQuantizer(GF_BifsDecoder * codec, GF_BitStream *bs) { GF_Node *node; node = gf_bifs_dec_node(codec, bs, NDT_SFWorldNode); /*reset global QP*/ if (codec->GlobalQP) gf_node_unregister((GF_Node *) codec->GlobalQP, NULL); codec->GlobalQP = codec->ActiveQP = NULL; if (!node || (gf_node_get_tag(node) != TAG_MPEG4_QuantizationParameter)) { if (node) gf_node_unregister(node, NULL); return codec->LastError; } /*register global QP*/ codec->GlobalQP = codec->ActiveQP = (M_QuantizationParameter *) node; codec->GlobalQP->isLocal = 0; gf_node_register(node, NULL); return GF_OK; } static GF_Err BD_DecNodeDeleteEx(GF_BifsDecoder * codec, GF_BitStream *bs) { u32 NodeID; GF_Node *node; NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); node = gf_sg_find_node(codec->current_graph, NodeID); if (!node) return GF_NON_COMPLIANT_BITSTREAM; return gf_node_replace(node, NULL, 1); } static GF_Err BD_DecExtendedUpdate(GF_BifsDecoder * codec, GF_BitStream *bs) { u32 type; type = gf_bs_read_int(bs, 8); switch (type) { case 0: return gf_bifs_dec_proto_list(codec, bs, NULL); case 1: return BD_DecProtoDelete(codec, bs); case 2: return gf_sg_delete_all_protos(codec->current_graph); case 3: return BD_DecMultipleIndexReplace(codec, bs); case 4: return BD_DecMultipleReplace(codec, bs); case 5: return BD_DecGlobalQuantizer(codec, bs); case 6: return BD_DecNodeDeleteEx(codec, bs); default: return GF_BIFS_UNKNOWN_VERSION; } } /*inserts a node in a container (node.children)*/ static GF_Err BD_DecNodeInsert(GF_BifsDecoder * codec, GF_BitStream *bs) { u32 NodeID, NDT; s32 type, pos; GF_Node *node, *def; GF_Err e; NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); def = gf_sg_find_node(codec->current_graph, NodeID); if (!def) return GF_NON_COMPLIANT_BITSTREAM; NDT = gf_bifs_get_child_table(def); if (!NDT) return GF_NON_COMPLIANT_BITSTREAM; type = gf_bs_read_int(bs, 2); switch (type) { case 0: pos = gf_bs_read_int(bs, 8); break; case 2: pos = 0; break; case 3: /*-1 means append*/ pos = -1; break; default: return GF_NON_COMPLIANT_BITSTREAM; } node = gf_bifs_dec_node(codec, bs, NDT); if (!node) return codec->LastError; e = gf_node_register(node, def); if (e) return e; e = gf_node_insert_child(def, node, pos); if (!e) { GF_FieldInfo field; /*get it by name in case no add/removeChildren*/ gf_node_get_field_by_name(def, "children", &field); gf_bifs_check_field_change(def, &field); } return e; } /*NB This can insert a node as well (but usually not in the .children field)*/ static GF_Err BD_DecIndexInsert(GF_BifsDecoder * codec, GF_BitStream *bs) { GF_Err e; u32 NodeID; u32 NumBits, ind, field_ind; u8 type; s32 pos; GF_Node *def, *node; GF_FieldInfo field, sffield; NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); def = gf_sg_find_node(codec->current_graph, NodeID); if (!def) return GF_NON_COMPLIANT_BITSTREAM; /*index insertion uses IN mode for field index*/ NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(def, GF_SG_FIELD_CODING_IN)-1); ind = gf_bs_read_int(bs, NumBits); e = gf_bifs_get_field_index(def, ind, GF_SG_FIELD_CODING_IN, &field_ind); if (e) return e; 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 = -1; break; default: return GF_NON_COMPLIANT_BITSTREAM; } e = gf_node_get_field(def, field_ind, &field); if (e) return e; if (gf_sg_vrml_is_sf_field(field.fieldType)) return GF_NON_COMPLIANT_BITSTREAM; memcpy(&sffield, &field, sizeof(GF_FieldInfo)); sffield.fieldType = gf_sg_vrml_get_sf_type(field.fieldType); /*rescale the MFField and parse the SFField*/ if (field.fieldType==GF_SG_VRML_MFNODE) { node = gf_bifs_dec_node(codec, bs, field.NDTtype); if (!node) return codec->LastError; e = gf_node_register(node, def); if (e) return e; /*this is generic MFNode container*/ if (pos== -1) { e = gf_node_list_add_child( (GF_ChildNodeItem **) field.far_ptr, node); } else { e = gf_node_list_insert_child((GF_ChildNodeItem **) field.far_ptr, node, pos); } if (!e) gf_bifs_check_field_change(def, &field); } else { if (pos == -1) { e = gf_sg_vrml_mf_append(field.far_ptr, field.fieldType, & sffield.far_ptr); } else { /*insert is 0-based*/ e = gf_sg_vrml_mf_insert(field.far_ptr, field.fieldType, & sffield.far_ptr, pos); } if (e) return e; e = gf_bifs_dec_sf_field(codec, bs, def, &sffield); if (!e) gf_bifs_check_field_change(def, &field); } return e; } static GF_Err BD_DecInsert(GF_BifsDecoder * codec, GF_BitStream *bs) { u8 type; type = gf_bs_read_int(bs, 2); switch (type) { case 0: return BD_DecNodeInsert(codec, bs); /*Extended BIFS updates*/ case 1: return BD_DecExtendedUpdate(codec, bs); case 2: return BD_DecIndexInsert(codec, bs); case 3: return gf_bifs_dec_route(codec, bs, 1); default: return GF_NON_COMPLIANT_BITSTREAM; } } static GF_Err BD_DecIndexDelete(GF_BifsDecoder * codec, GF_BitStream *bs) { u32 NodeID, NumBits, SF_type, ind, field_ind; s32 pos; u8 type; GF_Node *node; GF_Err e; GF_FieldInfo field; NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); node = gf_sg_find_node(codec->current_graph, NodeID); if (!node) return GF_NON_COMPLIANT_BITSTREAM; NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_IN) - 1); ind = gf_bs_read_int(bs, NumBits); type = gf_bs_read_int(bs, 2); switch (type) { case 0: pos = (u32) gf_bs_read_int(bs, 16); break; case 2: pos = 0; break; case 3: pos = -1; break; default: return GF_NON_COMPLIANT_BITSTREAM; } e = gf_bifs_get_field_index(node, ind, GF_SG_FIELD_CODING_IN, &field_ind); if (e) return e; e = gf_node_get_field(node, field_ind, &field); if (e) return e; if (gf_sg_vrml_is_sf_field(field.fieldType)) return GF_NON_COMPLIANT_BITSTREAM; SF_type = gf_sg_vrml_get_sf_type(field.fieldType); /*special handling in case of a node*/ if (SF_type == GF_SG_VRML_SFNODE) { e = gf_node_replace_child(node, (GF_ChildNodeItem**) field.far_ptr, pos, NULL); } else { e = gf_sg_vrml_mf_remove(field.far_ptr, field.fieldType, pos); } /*deletion -> node has changed*/ if (!e) gf_bifs_check_field_change(node, &field); return e; } static GF_Err BD_DecDelete(GF_BifsDecoder * codec, GF_BitStream *bs) { u8 type; u32 ID; GF_Node *n; type = gf_bs_read_int(bs, 2); switch (type) { case 0: ID = 1+gf_bs_read_int(bs, codec->info->config.NodeIDBits); n = gf_sg_find_node(codec->current_graph, ID); #ifdef MPEG4_STRICT if (!n) return GF_NON_COMPLIANT_BITSTREAM; #else if (!n) return GF_OK; #endif /*this is a delete of a DEF node, remove ALL INSTANCES*/ return gf_node_replace(n, NULL, 0); case 2: return BD_DecIndexDelete(codec, bs); case 3: ID = 1+gf_bs_read_int(bs, codec->info->config.RouteIDBits); /*don't complain if route can't be deleted (not present)*/ gf_sg_route_del_by_id(codec->current_graph, ID); return GF_OK; default: return GF_NON_COMPLIANT_BITSTREAM; } return GF_OK; } static GF_Err BD_DecNodeReplace(GF_BifsDecoder * codec, GF_BitStream *bs) { u32 NodeID; GF_Node *node, *new_node; GF_Err e; NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); /*this is delete / new on a DEF node: replace ALL instances*/ node = gf_sg_find_node(codec->current_graph, NodeID); if (!node) return GF_NON_COMPLIANT_BITSTREAM; /*and just parse a new GF_Node - it is encoded in SFWorldNode table */ new_node = gf_bifs_dec_node(codec, bs, NDT_SFWorldNode); if (!new_node && codec->LastError) return codec->LastError; e = gf_node_replace(node, new_node, 0); return e; } static GF_Err BD_DecFieldReplace(GF_BifsDecoder * codec, GF_BitStream *bs) { GF_Err e; u32 NodeID, ind, field_ind, NumBits; GF_Node *node, *prev_node; GF_ChildNodeItem *prev_child; GF_FieldInfo field; NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); node = gf_sg_find_node(codec->current_graph, NodeID); if (!node) return GF_NON_COMPLIANT_BITSTREAM; NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_IN)-1); ind = gf_bs_read_int(bs, NumBits); e = gf_bifs_get_field_index(node, ind, GF_SG_FIELD_CODING_IN, &field_ind); if (e) return e; e = gf_node_get_field(node, field_ind, &field); prev_node = NULL; prev_child = NULL; /*store prev SF node*/ if (field.fieldType == GF_SG_VRML_SFNODE) { prev_node = *((GF_Node **) field.far_ptr); } /*store prev MFNode content*/ else if (field.fieldType == GF_SG_VRML_MFNODE) { prev_child = * ((GF_ChildNodeItem **) field.far_ptr); * ((GF_ChildNodeItem **) field.far_ptr) = NULL; } /*regular field*/ else if (!gf_sg_vrml_is_sf_field(field.fieldType)) { gf_sg_vrml_mf_reset(field.far_ptr, field.fieldType); } /*parse the field*/ codec->is_com_dec = 1; e = gf_bifs_dec_field(codec, bs, node, &field); codec->is_com_dec = 0; /*remove prev nodes*/ if (field.fieldType == GF_SG_VRML_SFNODE) { if (prev_node) e = gf_node_unregister(prev_node, node); } else if (field.fieldType == GF_SG_VRML_MFNODE) { gf_node_unregister_children(node, prev_child); } if (!e) gf_bifs_check_field_change(node, &field); return e; } static GF_Err BD_DecIndexValueReplace(GF_BifsDecoder * codec, GF_BitStream *bs) { GF_Node *new_node; u32 NodeID, ind, field_ind, NumBits, pos; u8 type; GF_Node *node; GF_Err e; GF_FieldInfo field, sffield; /*get the node*/ NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); node = gf_sg_find_node(codec->current_graph, NodeID); if (!node) return GF_NON_COMPLIANT_BITSTREAM; NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_IN)-1); ind = gf_bs_read_int(bs, NumBits); e = gf_bifs_get_field_index(node, ind, GF_SG_FIELD_CODING_IN, &field_ind); if (e) return e; 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; icurrent_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; icurrent_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; iLastError = 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; }