GF_Err gf_bifs_enc_mf_field(GF_BifsEncoder *codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field) { GF_ChildNodeItem *list = NULL; GF_Err e; u32 nbBits, qp_local; Bool use_list, qp_on, initial_qp; u32 nbF, i; GF_FieldInfo sffield; nbF = 0; if (field->fieldType != GF_SG_VRML_MFNODE) { nbF = field->far_ptr ? ((GenMFField *)field->far_ptr)->count : 0; if (!nbF && (field->fieldType == GF_SG_VRML_MFSCRIPT)) nbF = 1; } else if (field->far_ptr) { list = *((GF_ChildNodeItem **)field->far_ptr); nbF = gf_node_list_get_count(list); } /*reserved*/ GF_BIFS_WRITE_INT(codec, bs, 0, 1, "reserved", NULL); if (!nbF) { /*is list*/ GF_BIFS_WRITE_INT(codec, bs, 1, 1, "isList", NULL); /*end flag*/ GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL); return GF_OK; } /*do we work in list or vector*/ use_list = GF_FALSE; nbBits = gf_get_bit_size(nbF); if (nbBits + 5 > nbF + 1) use_list = GF_TRUE; GF_BIFS_WRITE_INT(codec, bs, use_list, 1, "isList", NULL); if (!use_list) { GF_BIFS_WRITE_INT(codec, bs, nbBits, 5, "nbBits", NULL); GF_BIFS_WRITE_INT(codec, bs, nbF, nbBits, "length", NULL); } memset(&sffield, 0, sizeof(GF_FieldInfo)); sffield.fieldIndex = field->fieldIndex; sffield.fieldType = gf_sg_vrml_get_sf_type(field->fieldType); sffield.NDTtype = field->NDTtype; initial_qp = qp_on = GF_FALSE; qp_local = 0; initial_qp = codec->ActiveQP ? GF_TRUE : GF_FALSE; for (i=0; i<nbF; i++) { if (use_list) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "end", NULL); if (field->fieldType != GF_SG_VRML_MFNODE) { gf_sg_vrml_mf_get_item(field->far_ptr, field->fieldType, &sffield.far_ptr, i); e = gf_bifs_enc_sf_field(codec, bs, node, &sffield); } else { assert(list); e = gf_bifs_enc_node(codec, list->node, field->NDTtype, bs, node); /*activate QP*/ if (list->node->sgprivate->tag == TAG_MPEG4_QuantizationParameter) { qp_local = ((M_QuantizationParameter *)list->node)->isLocal; if (qp_on) gf_bifs_enc_qp_remove(codec, GF_FALSE); e = gf_bifs_enc_qp_set(codec, list->node); if (e) return e; qp_on = GF_TRUE; if (qp_local) qp_local = 2; } list = list->next; } if (e) return e; if (qp_on && qp_local) { if (qp_local == 2) qp_local -= 1; else { gf_bifs_enc_qp_remove(codec, initial_qp); qp_local = qp_on = GF_FALSE; } } } if (use_list) GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL); if (qp_on) gf_bifs_enc_qp_remove(codec, initial_qp); /*for QP14*/ gf_bifs_enc_qp14_set_length(codec, nbF); return GF_OK; }
GF_Err gf_bifs_enc_commands(GF_BifsEncoder *codec, GF_List *comList, GF_BitStream *bs) { u32 i; u32 count; GF_List *routes; GF_Err e = GF_OK; routes = NULL; codec->LastError = GF_OK; count = gf_list_count(comList); for (i=0; i<count; i++) { GF_Command *com = (GF_Command*)gf_list_get(comList, i); switch (com->tag) { case GF_SG_SCENE_REPLACE: { /*reset node context*/ while (gf_list_count(codec->encoded_nodes)) gf_list_rem(codec->encoded_nodes, 0); GF_BIFS_WRITE_INT(codec, bs, 3, 2, "SceneReplace", NULL); if (!com->aggregated) { routes = gf_list_new(); /*now the trick: get all following InsertRoutes and convert as routes*/ for (; i<count-1; i++) { GF_Route *r; GF_Command *rcom = (GF_Command*)gf_list_get(comList, i+1); if (rcom->tag!=GF_SG_ROUTE_INSERT) break; GF_SAFEALLOC(r, GF_Route); r->FromField.fieldIndex = rcom->fromFieldIndex; r->FromNode = gf_sg_find_node(codec->scene_graph, rcom->fromNodeID); r->ToField.fieldIndex = rcom->toFieldIndex; r->ToNode = gf_sg_find_node(codec->scene_graph, rcom->toNodeID); r->ID = rcom->RouteID; r->name = rcom->def_name; gf_list_add(routes, r); } e = BE_SceneReplaceEx(codec, com, bs, routes); while (gf_list_count(routes)) { GF_Route *r = (GF_Route*)gf_list_get(routes, 0); gf_list_rem(routes, 0); gf_free(r); } gf_list_del(routes); } else { e = BE_SceneReplaceEx(codec, com, bs, codec->scene_graph->Routes); } } break; /*replace commands*/ case GF_SG_NODE_REPLACE: GF_BIFS_WRITE_INT(codec, bs, 2, 2, "Replace", NULL); GF_BIFS_WRITE_INT(codec, bs, 0, 2, "Node", NULL); e = BE_NodeReplace(codec, com, bs); break; case GF_SG_FIELD_REPLACE: GF_BIFS_WRITE_INT(codec, bs, 2, 2, "Replace", NULL); GF_BIFS_WRITE_INT(codec, bs, 1, 2, "Field", NULL); e = BE_FieldReplace(codec, com, bs); break; case GF_SG_INDEXED_REPLACE: GF_BIFS_WRITE_INT(codec, bs, 2, 2, "Replace", NULL); GF_BIFS_WRITE_INT(codec, bs, 2, 2, "FieldIndex", NULL); e = BE_IndexFieldReplace(codec, com, bs); break; case GF_SG_ROUTE_REPLACE: GF_BIFS_WRITE_INT(codec, bs, 2, 2, "Replace", NULL); GF_BIFS_WRITE_INT(codec, bs, 3, 2, "Route", NULL); e = BE_RouteReplace(codec, com, bs, 0); break; case GF_SG_NODE_INSERT: GF_BIFS_WRITE_INT(codec, bs, 0, 2, "Insert", NULL); GF_BIFS_WRITE_INT(codec, bs, 0, 2, "Node", NULL); e = BE_NodeInsert(codec, com, bs); break; case GF_SG_INDEXED_INSERT: GF_BIFS_WRITE_INT(codec, bs, 0, 2, "Insert", NULL); GF_BIFS_WRITE_INT(codec, bs, 2, 2, "FieldIndex", NULL); e = BE_IndexInsert(codec, com, bs); break; case GF_SG_ROUTE_INSERT: GF_BIFS_WRITE_INT(codec, bs, 0, 2, "Insert", NULL); GF_BIFS_WRITE_INT(codec, bs, 3, 2, "Route", NULL); e = BE_RouteReplace(codec, com, bs, 1); break; case GF_SG_NODE_DELETE: GF_BIFS_WRITE_INT(codec, bs, 1, 2, "Delete", NULL); GF_BIFS_WRITE_INT(codec, bs, 0, 2, "Node", NULL); GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(com->node) - 1, codec->info->config.NodeIDBits, "NodeID", NULL); break; case GF_SG_INDEXED_DELETE: GF_BIFS_WRITE_INT(codec, bs, 1, 2, "Delete", NULL); GF_BIFS_WRITE_INT(codec, bs, 2, 2, "FieldIndex", NULL); e = BE_IndexDelete(codec, com, bs); break; case GF_SG_ROUTE_DELETE: GF_BIFS_WRITE_INT(codec, bs, 1, 2, "Delete", NULL); GF_BIFS_WRITE_INT(codec, bs, 3, 2, "Route", NULL); GF_BIFS_WRITE_INT(codec, bs, com->RouteID - 1, codec->info->config.RouteIDBits, "RouteID", NULL); break; default: e = BE_ExtendedUpdate(codec, com, bs); break; } if (e) break; GF_BIFS_WRITE_INT(codec, bs, (i+1==count) ? 0 : 1, 1, "moreCommands", NULL); } while (gf_list_count(codec->QPs)) gf_bifs_enc_qp_remove(codec, 1); return e; }