GF_Err BE_FieldReplace(GF_BifsEncoder *codec, GF_Command *com, GF_BitStream *bs) { GF_Err e; u32 ind, NumBits; GF_FieldInfo field; GF_CommandField *inf; if (!gf_list_count(com->command_fields)) return GF_OK; inf = (GF_CommandField *)gf_list_get(com->command_fields, 0); GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(com->node) - 1, codec->info->config.NodeIDBits, "NodeID", NULL); NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(com->node, GF_SG_FIELD_CODING_IN)-1); gf_bifs_field_index_by_mode(com->node, inf->fieldIndex, GF_SG_FIELD_CODING_IN, &ind); GF_BIFS_WRITE_INT(codec, bs, ind, NumBits, "field", NULL); e = gf_node_get_field(com->node, inf->fieldIndex, &field); if (e) return e; field.far_ptr = inf->field_ptr; /* Warning: To be changed when proper solution is found */ if (gf_sg_vrml_get_sf_type(field.fieldType) == GF_SG_VRML_SFSCRIPT) codec->is_encoding_command = 1; e = gf_bifs_enc_field(codec, bs, com->node, &field); codec->is_encoding_command = 0; return e; }
/*inserts a node in a container (node.children)*/ GF_Err BE_NodeInsert(GF_BifsEncoder *codec, GF_Command *com, GF_BitStream *bs) { u32 NDT; GF_CommandField *inf; if (!gf_list_count(com->command_fields)) return GF_OK; inf = (GF_CommandField *)gf_list_get(com->command_fields, 0); GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(com->node) - 1, codec->info->config.NodeIDBits, "NodeID", NULL); NDT = gf_bifs_get_child_table(com->node); switch (inf->pos) { case 0: GF_BIFS_WRITE_INT(codec, bs, 2, 2, "FIRST", "idx"); break; case -1: GF_BIFS_WRITE_INT(codec, bs, 3, 2, "LAST", "idx"); break; default: GF_BIFS_WRITE_INT(codec, bs, 0, 2, "pos", "idx"); GF_BIFS_WRITE_INT(codec, bs, inf->pos, 8, "pos", NULL); break; } return gf_bifs_enc_node(codec, inf->new_node, NDT, bs); }
GF_EXPORT GF_Err gf_bifs_encoder_get_rap(GF_BifsEncoder *codec, char **out_data, u32 *out_data_length) { GF_BitStream *bs; GF_Err e; GF_List *ctx_bck; /*reset context for RAP encoding*/ ctx_bck = codec->encoded_nodes; codec->encoded_nodes = gf_list_new(); if (!codec->info) codec->info = (BIFSStreamInfo*)gf_list_get(codec->streamInfo, 0); bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); GF_BIFS_WRITE_INT(codec, bs, 3, 2, "SceneReplace", NULL); e = BE_SceneReplace(codec, codec->scene_graph, bs); if (e == GF_OK) { GF_BIFS_WRITE_INT(codec, bs, 0, 1, "moreCommands", NULL); gf_bs_get_content(bs, out_data, out_data_length); } gf_bs_del(bs); /*restore context*/ gf_list_del(codec->encoded_nodes); codec->encoded_nodes = ctx_bck; return e; }
void SFE_PutIdentifier(ScriptEnc *sc_enc, char *id) { u32 i; u32 nbBits, length; char *str; if (sc_enc->emul) return; i=0; while ((str = (char *)gf_list_enum(sc_enc->identifiers, &i))) { if (strcmp(str, id)) continue; nbBits = 0; length = gf_list_count(sc_enc->identifiers) - 1; while (length > 0) { length >>= 1; nbBits ++; } GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 1, 1, "received", str); GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, i-1, nbBits, "identifierCode", str); return; } GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 0, 1, "received", id); gf_list_add(sc_enc->identifiers, gf_strdup(id)); gf_bifs_enc_name(sc_enc->codec, sc_enc->bs, id); }
void SFE_Arguments(ScriptEnc *sc_enc) { while (1) { if (!SFE_NextToken(sc_enc)) return; if (sc_enc->token_code == TOK_RIGHT_CURVE) break; else if (sc_enc->token_code == TOK_COMMA) continue; GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 1, 1, "hasArgument", NULL); SFE_PutIdentifier(sc_enc, sc_enc->token); } GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 0, 1, "hasArgument", NULL); }
GF_Err BE_NodeReplace(GF_BifsEncoder *codec, GF_Command *com, GF_BitStream *bs) { GF_CommandField *inf; if (!gf_list_count(com->command_fields)) return GF_OK; inf = (GF_CommandField *)gf_list_get(com->command_fields, 0); GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(com->node) - 1, codec->info->config.NodeIDBits, "NodeID", NULL); return gf_bifs_enc_node(codec, inf->new_node, NDT_SFWorldNode, bs); }
GF_Err BE_RouteReplace(GF_BifsEncoder *codec, GF_Command *com, GF_BitStream *bs, Bool isInsert) { GF_Err e; GF_Node *n; u32 numBits, ind; if (isInsert) { GF_BIFS_WRITE_INT(codec, bs, com->RouteID ? 1 : 0, 1, "isDEF", NULL); if (com->RouteID) { GF_BIFS_WRITE_INT(codec, bs, com->RouteID-1, codec->info->config.RouteIDBits, "RouteID", NULL); if (codec->UseName) gf_bifs_enc_name(codec, bs, com->def_name); } } else { GF_BIFS_WRITE_INT(codec, bs, com->RouteID - 1, codec->info->config.RouteIDBits, "RouteID", NULL); } /*origin*/ GF_BIFS_WRITE_INT(codec, bs, com->fromNodeID - 1, codec->info->config.NodeIDBits, "outNodeID", NULL); n = gf_bifs_enc_find_node(codec, com->fromNodeID); numBits = gf_node_get_num_fields_in_mode(n, GF_SG_FIELD_CODING_OUT) - 1; numBits = gf_get_bit_size(numBits); e = gf_bifs_field_index_by_mode(n, com->fromFieldIndex, GF_SG_FIELD_CODING_OUT, &ind); if (e) return e; GF_BIFS_WRITE_INT(codec, bs, ind, numBits, "outField", NULL); /*target*/ GF_BIFS_WRITE_INT(codec, bs, com->toNodeID - 1, codec->info->config.NodeIDBits, "inNodeID", NULL); n = gf_bifs_enc_find_node(codec, com->toNodeID); numBits = gf_node_get_num_fields_in_mode(n, GF_SG_FIELD_CODING_IN) - 1; numBits = gf_get_bit_size(numBits); e = gf_bifs_field_index_by_mode(n, com->toFieldIndex, GF_SG_FIELD_CODING_IN, &ind); GF_BIFS_WRITE_INT(codec, bs, ind, numBits, "inField", NULL); return e; }
void SFE_PutInteger(ScriptEnc *sc_enc, char *str) { u32 nbBits, val = 0; if (sc_enc->emul) return; if ((str[0]=='0') && (str[1]=='x' || str[1]=='X')) { val = strtoul(sc_enc->token, (char **) NULL, 16); } else if (str[0]=='0' && isdigit(str[1])) { val = strtoul(str, (char **) NULL, 8); } else if (isdigit(str[0])) { val = strtoul(str, (char **) NULL, 10); } else { GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[bifs] Script encoding: %s is not an integer\n", str)); sc_enc->err = GF_BAD_PARAM; return; } nbBits = gf_get_bit_size(val); GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, nbBits, 5, "nbBitsInteger", NULL); GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, val, nbBits, "value", sc_enc->token); }
GF_Err BE_SceneReplaceEx(GF_BifsEncoder *codec, GF_Command *com, GF_BitStream *bs, GF_List *routes) { u32 i, nbR, nbBits; GF_Err e; /*reserved*/ GF_BIFS_WRITE_INT(codec, bs, 0, 6, "reserved", NULL); GF_BIFS_WRITE_INT(codec, bs, codec->UseName ? 1 : 0, 1, "useName", NULL); if (gf_list_count(com->new_proto_list)) { e = BE_EncProtoList(codec, com->new_proto_list, bs); if (e) goto exit; } else { e = BE_EncProtoList(codec, com->in_scene->protos, bs); if (e) goto exit; } /*NULL root is valid for ProtoLibraries*/ e = gf_bifs_enc_node(codec, com->node, NDT_SFTopNode, bs); if (e || !gf_list_count(routes) ) { GF_BIFS_WRITE_INT(codec, bs, 0, 1, "hasRoute", NULL); return codec->LastError = e; } GF_BIFS_WRITE_INT(codec, bs, 1, 1, "hasRoute", NULL); nbR = gf_list_count(routes); nbBits = gf_get_bit_size(nbR); if (nbBits + 5 > nbR) { GF_BIFS_WRITE_INT(codec, bs, 1, 1, "isList", NULL); /*list*/ for (i=0; i<nbR; i++) { e = gf_bifs_enc_route(codec, (GF_Route*)gf_list_get(routes, i), bs); if (e) goto exit; GF_BIFS_WRITE_INT(codec, bs, (i+1==nbR) ? 0 : 1, 1, "moreRoute", NULL); } } else { GF_BIFS_WRITE_INT(codec, bs, 0, 1, "isList", NULL); GF_BIFS_WRITE_INT(codec, bs, nbBits, 5, "nbBits", NULL); GF_BIFS_WRITE_INT(codec, bs, nbR, nbBits, "nbRoutes", NULL); for (i=0; i<nbR; i++) { e = gf_bifs_enc_route(codec, (GF_Route*)gf_list_get(routes, i), bs); if (e) goto exit; } } exit: return codec->LastError = e; }
static GF_Err BE_MultipleIndexedReplace(GF_BifsEncoder * codec, GF_Command *com, GF_BitStream *bs) { u32 i,nbBits, count, maxPos, nbBitsPos; GF_FieldInfo field; GF_Err e; GF_CommandField *inf; if (!gf_list_count(com->command_fields)) return GF_OK; inf = (GF_CommandField *)gf_list_get(com->command_fields, 0); gf_bs_write_int(bs, gf_node_get_id(com->node)-1, codec->info->config.NodeIDBits); nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(com->node, GF_SG_FIELD_CODING_IN)-1); gf_bifs_field_index_by_mode(com->node, inf->fieldIndex, GF_SG_FIELD_CODING_IN, &i); GF_BIFS_WRITE_INT(codec, bs, i, nbBits, "field", NULL); gf_node_get_field(com->node, inf->fieldIndex, &field); field.fieldType = inf->fieldType; count = gf_list_count(com->command_fields); maxPos = 0; for (i=0; i<count; i++) { inf = (GF_CommandField *)gf_list_get(com->command_fields, i); if (maxPos < (u32) inf->pos) maxPos = inf->pos; } nbBitsPos = gf_get_bit_size(maxPos); GF_BIFS_WRITE_INT(codec, bs, nbBitsPos, 5, "nbBitsPos", NULL); nbBits = gf_get_bit_size(count); GF_BIFS_WRITE_INT(codec, bs, nbBits, 5, "nbBits", NULL); GF_BIFS_WRITE_INT(codec, bs, count, nbBits, "count", NULL); for (i=0; i<count; i++) { inf = (GF_CommandField *)gf_list_get(com->command_fields, i); GF_BIFS_WRITE_INT(codec, bs, inf->pos, nbBitsPos, "idx", NULL); field.far_ptr = inf->field_ptr; e = gf_bifs_enc_field(codec, bs, com->node, &field); if (e) return e; } return GF_OK; }
GF_Err BE_SceneReplace(GF_BifsEncoder *codec, GF_SceneGraph *graph, GF_BitStream *bs) { u32 i, nbR, nbBits; GF_Err e; /*reserved*/ GF_BIFS_WRITE_INT(codec, bs, 0, 6, "reserved", NULL); GF_BIFS_WRITE_INT(codec, bs, codec->UseName ? 1 : 0, 1, "useName", NULL); /*assign current graph*/ codec->scene_graph = graph; e = BE_EncProtoList(codec, codec->scene_graph ? codec->scene_graph->protos : NULL, bs); if (e) goto exit; /*NULL root is valid for ProtoLibraries*/ e = gf_bifs_enc_node(codec, graph ? graph->RootNode : NULL, NDT_SFTopNode, bs); if (e || !graph || !gf_list_count(graph->Routes) ) { GF_BIFS_WRITE_INT(codec, bs, 0, 1, "hasRoute", NULL); return codec->LastError = e; } GF_BIFS_WRITE_INT(codec, bs, 1, 1, "hasRoute", NULL); nbR = gf_list_count(graph->Routes); nbBits = gf_get_bit_size(nbR); if (nbBits + 5 > nbR) { GF_BIFS_WRITE_INT(codec, bs, 1, 1, "isList", NULL); /*list*/ for (i=0; i<nbR; i++) { e = gf_bifs_enc_route(codec, (GF_Route*)gf_list_get(graph->Routes, i), bs); if (e) goto exit; GF_BIFS_WRITE_INT(codec, bs, (i+1==nbR) ? 0 : 1, 1, "moreRoute", NULL); } } else { GF_BIFS_WRITE_INT(codec, bs, 0, 1, "isList", NULL); GF_BIFS_WRITE_INT(codec, bs, nbBits, 5, "nbBits", NULL); GF_BIFS_WRITE_INT(codec, bs, nbR, nbBits, "nbRoutes", NULL); for (i=0; i<nbR; i++) { e = gf_bifs_enc_route(codec, (GF_Route*)gf_list_get(graph->Routes, i), bs); if (e) goto exit; } } exit: return codec->LastError = e; }
GF_Err gf_bifs_enc_route(GF_BifsEncoder *codec, GF_Route *r, GF_BitStream *bs) { GF_Err e; u32 numBits, ind; if (!r) return GF_BAD_PARAM; GF_BIFS_WRITE_INT(codec, bs, r->ID ? 1: 0, 1, "isDEF", NULL); /*def'ed route*/ if (r->ID) { GF_BIFS_WRITE_INT(codec, bs, r->ID-1, codec->info->config.RouteIDBits, "routeID", NULL); if (codec->UseName) gf_bifs_enc_name(codec, bs, r->name); } /*origin*/ GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(r->FromNode) - 1, codec->info->config.NodeIDBits, "outNodeID", NULL); numBits = gf_node_get_num_fields_in_mode(r->FromNode, GF_SG_FIELD_CODING_OUT) - 1; numBits = gf_get_bit_size(numBits); e = gf_bifs_field_index_by_mode(r->FromNode, r->FromField.fieldIndex, GF_SG_FIELD_CODING_OUT, &ind); if (e) return e; GF_BIFS_WRITE_INT(codec, bs, ind, numBits, "outField", NULL); /*target*/ GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(r->ToNode) - 1, codec->info->config.NodeIDBits, "inNodeID", NULL); numBits = gf_node_get_num_fields_in_mode(r->ToNode, GF_SG_FIELD_CODING_IN) - 1; numBits = gf_get_bit_size(numBits); e = gf_bifs_field_index_by_mode(r->ToNode, r->ToField.fieldIndex, GF_SG_FIELD_CODING_IN, &ind); GF_BIFS_WRITE_INT(codec, bs, ind, numBits, "inField", NULL); return e; }
GF_Err BE_IndexDelete(GF_BifsEncoder *codec, GF_Command *com, GF_BitStream *bs) { u32 NumBits, ind; GF_Err e; GF_CommandField *inf; if (!gf_list_count(com->command_fields)) return GF_OK; inf = (GF_CommandField *)gf_list_get(com->command_fields, 0); GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(com->node) - 1, codec->info->config.NodeIDBits, "NodeID", NULL); NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(com->node, GF_SG_FIELD_CODING_IN) - 1); e = gf_bifs_field_index_by_mode(com->node, inf->fieldIndex, GF_SG_FIELD_CODING_IN, &ind); if (e) return e; GF_BIFS_WRITE_INT(codec, bs, ind, NumBits, "field", NULL); switch (inf->pos) { case 0: GF_BIFS_WRITE_INT(codec, bs, 2, 2, "FIRST", "idw"); break; case -1: GF_BIFS_WRITE_INT(codec, bs, 3, 2, "LAST", "idx"); break; default: GF_BIFS_WRITE_INT(codec, bs, 0, 2, "pos", "idx"); GF_BIFS_WRITE_INT(codec, bs, inf->pos, 16, "pos", NULL); break; } return GF_OK; }
GF_Err gf_bifs_enc_field(GF_BifsEncoder * codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field) { assert(node); if (field->fieldType == GF_SG_VRML_UNKNOWN) return GF_NON_COMPLIANT_BITSTREAM; if (gf_sg_vrml_is_sf_field(field->fieldType)) { return gf_bifs_enc_sf_field(codec, bs, node, field); } /*TO DO : PMF support*/ if (codec->info->config.UsePredictiveMFField) { GF_BIFS_WRITE_INT(codec, bs, 0, 1, "usePredictive", NULL); } return gf_bifs_enc_mf_field(codec, bs, node, field); }
static GF_Err BE_MultipleReplace(GF_BifsEncoder * codec, GF_Command *com, GF_BitStream *bs) { u32 i, j, nbBits, count, numFields, allField; Bool use_list; GF_FieldInfo field; GF_Err e; gf_bs_write_int(bs, gf_node_get_id(com->node)-1, codec->info->config.NodeIDBits); count = gf_list_count(com->command_fields); use_list = 1; numFields = gf_node_get_num_fields_in_mode(com->node, GF_SG_FIELD_CODING_DEF); nbBits = gf_get_bit_size(numFields - 1); if (count < 1+count*(1+nbBits)) use_list = 0; GF_BIFS_WRITE_INT(codec, bs, use_list ? 0 : 1, 1, "isMask", NULL); for (i=0; i<numFields; i++) { GF_CommandField *inf = NULL; gf_bifs_get_field_index(com->node, i, GF_SG_FIELD_CODING_DEF, &allField); for (j=0; j<count; j++) { inf = (GF_CommandField *)gf_list_get(com->command_fields, j); if (inf->fieldIndex==allField) break; inf = NULL; } if (!inf) { if (!use_list) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "Mask", NULL); continue; } /*common case*/ gf_node_get_field(com->node, inf->fieldIndex, &field); if (use_list) { /*not end flag*/ GF_BIFS_WRITE_INT(codec, bs, 0, 1, "end", NULL); } else { /*mask flag*/ GF_BIFS_WRITE_INT(codec, bs, 1, 1, "Mask", NULL); } if (use_list) GF_BIFS_WRITE_INT(codec, bs, i, nbBits, "field", (char*)field.name); field.far_ptr = inf->field_ptr; e = gf_bifs_enc_field(codec, bs, com->node, &field); if (e) return e; } /*end flag*/ if (use_list) GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL); return GF_OK; }
static GF_Err BE_EncProtoDelete(GF_BifsEncoder * codec, GF_Command *com, GF_BitStream *bs) { u32 nbBits, i; Bool use_list = 0; nbBits = gf_get_bit_size(com->del_proto_list_size); if (nbBits+5>com->del_proto_list_size) use_list = 1; GF_BIFS_WRITE_INT(codec, bs, use_list, 1, "isList", NULL); if (!use_list) { GF_BIFS_WRITE_INT(codec, bs, nbBits, 5, "len", NULL); GF_BIFS_WRITE_INT(codec, bs, com->del_proto_list_size, nbBits, "len", NULL); } for (i=0; i<com->del_proto_list_size; i++) { if (use_list) GF_BIFS_WRITE_INT(codec, bs, 1, 1, "moreProto", NULL); GF_BIFS_WRITE_INT(codec, bs, com->del_proto_list[i], codec->info->config.ProtoIDBits, "protoID", NULL); } if (use_list) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "moreProto", NULL); return GF_OK; }
GF_Err BE_IndexInsert(GF_BifsEncoder *codec, GF_Command *com, GF_BitStream *bs) { GF_Err e; u32 NumBits, ind; GF_FieldInfo field, sffield; GF_CommandField *inf; if (!gf_list_count(com->command_fields)) return GF_OK; inf = (GF_CommandField *)gf_list_get(com->command_fields, 0); GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(com->node) - 1, codec->info->config.NodeIDBits, "NodeID", NULL); /*index insertion uses IN mode for field index*/ NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(com->node, GF_SG_FIELD_CODING_IN)-1); gf_bifs_field_index_by_mode(com->node, inf->fieldIndex, GF_SG_FIELD_CODING_IN, &ind); GF_BIFS_WRITE_INT(codec, bs, ind, NumBits, "field", NULL); switch (inf->pos) { case 0: GF_BIFS_WRITE_INT(codec, bs, 2, 2, "FIRST", "idx"); break; case -1: GF_BIFS_WRITE_INT(codec, bs, 3, 2, "LAST", "idx"); break; default: GF_BIFS_WRITE_INT(codec, bs, 0, 2, "pos", "idx"); GF_BIFS_WRITE_INT(codec, bs, inf->pos, 16, "pos", NULL); break; } e = gf_node_get_field(com->node, inf->fieldIndex, &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); sffield.far_ptr = inf->field_ptr; /*rescale the MFField and parse the SFField*/ if (field.fieldType==GF_SG_VRML_MFNODE) { return gf_bifs_enc_node(codec, inf->new_node, field.NDTtype, bs); } else { return gf_bifs_enc_sf_field(codec, bs, com->node, &sffield); } }
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; }
static GF_Err EncScriptFields(ScriptEnc *sc_enc) { u32 nbFields, nbBits, eType, nbBitsProto, i; Bool use_list; GF_Err e; GF_FieldInfo info; nbFields = gf_node_get_num_fields_in_mode(sc_enc->script, GF_SG_FIELD_CODING_ALL) - 3; use_list = 1; nbBits = gf_get_bit_size(nbFields); if (nbFields+1 > 4 + gf_get_bit_size(nbFields)) use_list = 0; if (!nbFields) { GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 1, 1, "Script::isList", NULL); GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 1, 1, "end", NULL); return GF_OK; } GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, use_list ? 1 : 0, 1, "Script::isList", NULL); if (!use_list) { GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, nbBits, 4, "nbBits", NULL); GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, nbFields, nbBits, "count", NULL); } nbBitsProto = 0; if (sc_enc->codec->encoding_proto) nbBitsProto = gf_get_bit_size(gf_sg_proto_get_field_count(sc_enc->codec->encoding_proto) - 1); for (i=0; i<nbFields; i++) { if (use_list) GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 0, 1, "end", NULL); gf_node_get_field(sc_enc->script, i+3, &info); switch (info.eventType) { case GF_SG_EVENT_IN: eType = GF_SG_SCRIPT_TYPE_EVENT_IN; break; case GF_SG_EVENT_OUT: eType = GF_SG_SCRIPT_TYPE_EVENT_OUT; break; default: eType = GF_SG_SCRIPT_TYPE_FIELD; break; } GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, eType, 2, "eventType", NULL); GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, info.fieldType, 6, "fieldType", NULL); gf_bifs_enc_name(sc_enc->codec, sc_enc->bs, (char *) info.name); /*this is an identifier for script*/ gf_list_add(sc_enc->identifiers, gf_strdup(info.name)); if (sc_enc->codec->encoding_proto) { GF_Route *isedField = gf_bifs_enc_is_field_ised(sc_enc->codec, sc_enc->script, i+3); if (isedField) { GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 1, 1, "isedField", NULL); if (isedField->ToNode == sc_enc->script) { GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, isedField->FromField.fieldIndex, nbBitsProto, "protoField", NULL); } else { GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, isedField->ToField.fieldIndex, nbBitsProto, "protoField", NULL); } continue; } GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 0, 1, "isedField", NULL); } /*default value*/ if (eType == GF_SG_SCRIPT_TYPE_FIELD) { GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, (info.far_ptr) ? 1 : 0, 1, "hasInitialValue", NULL); if (info.far_ptr) { e = gf_bifs_enc_field(sc_enc->codec, sc_enc->bs, sc_enc->script, &info); if (e) return e; } } } if (use_list) GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 1, 1, "end", NULL); return GF_OK; }
u32 SFE_Expression(ScriptEnc *sc_enc, u32 start, u32 end, Bool memberAccess) { char *str; u32 n = start; u32 curPos = 0, finalPos = 0; u32 curTok, prevTok; u32 curExpr = 0, expr = 0; u32 curRank, maxRank=0; if (sc_enc->err) return 0; curTok = prevTok = sc_enc->expr_toks[n]; do { curPos = n; switch (curTok) { case TOK_IDENTIFIER: curExpr = ET_IDENTIFIER; break; case TOK_NUMBER: curExpr = ET_NUMBER; break; case TOK_BOOLEAN: curExpr = ET_BOOLEAN; break; case TOK_STRING: curExpr = ET_STRING; break; case TOK_LEFT_CURVE: if (prevTok == TOK_IDENTIFIER) curExpr = ET_FUNCTION_CALL; else curExpr = ET_CURVED_EXPR; n = MoveToToken(sc_enc, TOK_RIGHT_CURVE, n, end); curTok = TOK_RIGHT_CURVE; break; case TOK_LEFT_BRACKET: curExpr = ET_ARRAY_DEREFERENCE; n = MoveToToken(sc_enc, TOK_RIGHT_BRACKET, n, end); curTok = TOK_RIGHT_BRACKET; break; case TOK_PERIOD: curTok = sc_enc->expr_toks[++n]; CHECK_TOK(TOK_IDENTIFIER); if (sc_enc->expr_toks[n+1] == TOK_LEFT_CURVE) { curExpr = ET_OBJECT_METHOD_CALL; n = MoveToToken(sc_enc, TOK_RIGHT_CURVE, n+1, end); curTok = TOK_RIGHT_CURVE; } else { curExpr = ET_OBJECT_MEMBER_ACCESS; } break; case TOK_NEW: curExpr = ET_NEW; curTok = sc_enc->expr_toks[++n]; CHECK_TOK(TOK_IDENTIFIER); curTok = sc_enc->expr_toks[++n]; CHECK_TOK(TOK_LEFT_CURVE); n = MoveToToken(sc_enc, TOK_RIGHT_CURVE, n, end); curTok = TOK_RIGHT_CURVE; break; case TOK_FUNCTION: curExpr = ET_FUNCTION_ASSIGN; break; case TOK_PLUS: if ( prevTok==TOK_RIGHT_CURVE || prevTok==TOK_RIGHT_BRACKET || prevTok==TOK_IDENTIFIER || prevTok==TOK_NUMBER || prevTok==TOK_STRING || prevTok==TOK_INCREMENT || prevTok==TOK_DECREMENT ) { curExpr = ET_PLUS; } else { goto skip_token; } break; case TOK_MINUS: if ( prevTok==TOK_RIGHT_CURVE || prevTok==TOK_RIGHT_BRACKET || prevTok==TOK_IDENTIFIER || prevTok==TOK_NUMBER || prevTok==TOK_STRING || prevTok==TOK_INCREMENT || prevTok==TOK_DECREMENT ) { curExpr = ET_MINUS; } else { curExpr = ET_NEGATIVE; curTok = TOK_NEGATIVE; } break; case TOK_INCREMENT: curExpr = ET_INCREMENT; break; case TOK_DECREMENT: curExpr = ET_DECREMENT; break; case TOK_NOT: curExpr = ET_NOT; break; case TOK_ONESCOMP: curExpr = ET_ONESCOMP; break; case TOK_CONDTEST: curExpr = ET_CONDTEST; break; case TOK_CONDSEP: break; case TOK_LEFT_BRACE: curExpr = ET_CURVED_EXPR; n = MoveToToken(sc_enc, TOK_RIGHT_BRACE, n, end); curTok = TOK_RIGHT_BRACE; break; break; default: if (curTok && (curTok != TOK_VAR) && (curTok < TOK_MULTIPLY || curTok > TOK_OREQ)) { GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[bifs] Script encoding: illegal token %s read\n", tok_names[curTok])); sc_enc->err = GF_BAD_PARAM; return 0; } curExpr = TOK_To_ET(curTok); } if (curTok == TOK_CONDSEP) { prevTok = curTok; curTok = sc_enc->expr_toks[++n]; continue; } curRank = ET_Rank[curExpr]; if (curRank > maxRank) { maxRank = curRank; expr = curExpr; finalPos = curPos; } else if (curRank == maxRank && ET_leftAssoc[curRank]) { expr = curExpr; finalPos = curPos; } prevTok = curTok; skip_token: curTok = sc_enc->expr_toks[++n]; } while (n<end); if (expr == ET_INCREMENT) { if (finalPos==start) {} else if (finalPos==end-1) expr = ET_POST_INCREMENT; else { GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[bifs] Script encoding: illegal Increment expression\n")); sc_enc->err = GF_BAD_PARAM; return expr; } } else if (expr == ET_DECREMENT) { if (finalPos==start) {} else if (finalPos==end-1) expr = ET_POST_DECREMENT; else { GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[bifs] Script encoding: illegal Decrement expression\n")); sc_enc->err = GF_BAD_PARAM; return expr; } } SFE_WRITE_INT(sc_enc, expr, NUMBITS_EXPR_TYPE, "expressionType", (char *) expr_name[expr]); switch (expr) { case ET_MULTIPLY: case ET_DIVIDE: case ET_MOD: case ET_PLUS: case ET_MINUS: case ET_LSHIFT: case ET_RSHIFT: case ET_RSHIFTFILL: case ET_LT: case ET_LE: case ET_GT: case ET_GE: case ET_EQ: case ET_NE: case ET_AND: case ET_XOR: case ET_OR: case ET_LAND: case ET_LOR: SFE_Expression(sc_enc, start, finalPos, 0); SFE_Expression(sc_enc, finalPos+1, end, 0); break; case ET_ASSIGN: case ET_PLUSEQ: case ET_MINUSEQ: case ET_MULTIPLYEQ: case ET_DIVIDEEQ: case ET_MODEQ: case ET_LSHIFTEQ: case ET_RSHIFTEQ: case ET_RSHIFTFILLEQ: case ET_ANDEQ: case ET_XOREQ: case ET_OREQ: { u32 ret = SFE_Expression(sc_enc, start, finalPos, 0); if ( ret != ET_IDENTIFIER && ret != ET_OBJECT_MEMBER_ACCESS && ret != ET_ARRAY_DEREFERENCE ) { GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[bifs] Script encoding: LeftVariable expected, %s returned\n", expr_name[ret])); sc_enc->err = GF_BAD_PARAM; return expr; } SFE_Expression(sc_enc, finalPos+1, end, 0); } break; case ET_IDENTIFIER: str = (char *)gf_list_get(sc_enc->id_buf, 0); gf_list_rem(sc_enc->id_buf, 0); /*TODO: when accessing member, we should try to translate proto fields into _fieldALL when not using USENAMEs...*/ if (memberAccess) { } SFE_PutIdentifier(sc_enc, str); gf_free(str); break; case ET_NUMBER: str = (char *)gf_list_get(sc_enc->id_buf, 0); gf_list_rem(sc_enc->id_buf, 0); SFE_PutNumber(sc_enc, str); gf_free(str); break; case ET_BOOLEAN: str = (char *)gf_list_get(sc_enc->id_buf, 0); gf_list_rem(sc_enc->id_buf, 0); SFE_PutBoolean(sc_enc, str); gf_free(str); break; case ET_VAR: while (1) { str = (char *)gf_list_get(sc_enc->id_buf, 0); if (!str) break; gf_list_rem(sc_enc->id_buf, 0); GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 1, 1, "hasArgument", NULL); SFE_PutIdentifier(sc_enc, str); gf_free(str); } GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 0, 1, "hasArgument", NULL); break; case ET_STRING: str = (char *)gf_list_get(sc_enc->id_buf, 0); gf_list_rem(sc_enc->id_buf, 0); if (!sc_enc->emul) gf_bifs_enc_name(sc_enc->codec, sc_enc->bs, str); gf_free(str); break; case ET_NEGATIVE: case ET_INCREMENT: case ET_DECREMENT: case ET_NOT: case ET_ONESCOMP: SFE_Expression(sc_enc, finalPos+1, end, 0); break; case ET_CURVED_EXPR: SFE_CompoundExpression(sc_enc, finalPos+1, end-1, 0); break; case ET_POST_INCREMENT : case ET_POST_DECREMENT : SFE_Expression(sc_enc, start, finalPos, 0); break; case ET_FUNCTION_CALL: SFE_FunctionCall(sc_enc, start, end); break; case ET_OBJECT_MEMBER_ACCESS : SFE_ObjectMemberAccess(sc_enc, start, finalPos, end); break; case ET_OBJECT_METHOD_CALL: SFE_ObjectMethodCall(sc_enc, start, finalPos, end); break; case ET_ARRAY_DEREFERENCE: SFE_ArrayDereference(sc_enc, start, finalPos, end); break; case ET_NEW: SFE_ObjectConstruct(sc_enc, start, finalPos, end); break; case ET_CONDTEST: SFE_ConditionTest(sc_enc, start, finalPos, end); break; case ET_FUNCTION_ASSIGN: SFE_NextToken(sc_enc); SFE_CheckToken(sc_enc, TOK_LEFT_CURVE); SFE_Arguments(sc_enc); SFE_StatementBlock(sc_enc); SFE_NextToken(sc_enc); SFE_CheckToken(sc_enc, TOK_SEMICOLON); break; default: GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[bifs] Script encoding: illegal expression type %s\n", expr_name[expr])); sc_enc->err = GF_BAD_PARAM; break; } return expr; }
GF_Err gf_bifs_enc_node(GF_BifsEncoder * codec, GF_Node *node, u32 NDT_Tag, GF_BitStream *bs, GF_Node *parent_node) { u32 NDTBits, node_type, node_tag, BVersion, node_id; const char *node_name; Bool flag, reset_qp14; GF_Node *new_node; GF_Err e; assert(codec->info); GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[BIFS] Encode node %s\n", gf_node_get_class_name(node) )); /*NULL node is a USE of maxID*/ if (!node) { GF_BIFS_WRITE_INT(codec, bs, 1, 1, "USE", NULL); GF_BIFS_WRITE_INT(codec, bs, (1<<codec->info->config.NodeIDBits) - 1 , codec->info->config.NodeIDBits, "NodeID", "NULL"); return GF_OK; } flag = BE_NodeIsUSE(codec, node); GF_BIFS_WRITE_INT(codec, bs, flag ? 1 : 0, 1, "USE", (char*)gf_node_get_class_name(node)); if (flag) { gf_bs_write_int(bs, gf_node_get_id(node) - 1, codec->info->config.NodeIDBits); new_node = gf_bifs_enc_find_node(codec, gf_node_get_id(node) ); if (!new_node) return codec->LastError = GF_SG_UNKNOWN_NODE; /*restore QP14 length*/ switch (gf_node_get_tag(new_node)) { case TAG_MPEG4_Coordinate: { u32 nbCoord = ((M_Coordinate *)new_node)->point.count; gf_bifs_enc_qp14_enter(codec, GF_TRUE); gf_bifs_enc_qp14_set_length(codec, nbCoord); gf_bifs_enc_qp14_enter(codec, GF_FALSE); } break; case TAG_MPEG4_Coordinate2D: { u32 nbCoord = ((M_Coordinate2D *)new_node)->point.count; gf_bifs_enc_qp14_enter(codec, GF_TRUE); gf_bifs_enc_qp14_set_length(codec, nbCoord); gf_bifs_enc_qp14_enter(codec, GF_FALSE); } break; } return GF_OK; } BVersion = GF_BIFS_V1; node_tag = node->sgprivate->tag; while (1) { node_type = gf_bifs_get_node_type(NDT_Tag, node_tag, BVersion); NDTBits = gf_bifs_get_ndt_bits(NDT_Tag, BVersion); if (BVersion==2 && (node_tag==TAG_ProtoNode)) node_type = 1; GF_BIFS_WRITE_INT(codec, bs, node_type, NDTBits, "ndt", NULL); if (node_type) break; BVersion += 1; if (BVersion > GF_BIFS_NUM_VERSION) { if (parent_node) { GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[BIFS] Cannot encode node %s as a child of %s\n", gf_node_get_class_name(node), gf_node_get_class_name(parent_node) )); } else { GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[BIFS] Cannot encode node %s in the SFWorldNode context\n", gf_node_get_class_name(node) )); } return codec->LastError = GF_BIFS_UNKNOWN_VERSION; } } if (BVersion==2 && node_type==1) { GF_Proto *proto = ((GF_ProtoInstance *)node)->proto_interface; GF_BIFS_WRITE_INT(codec, bs, proto->ID, codec->info->config.ProtoIDBits, "protoID", NULL); } /*special handling of 3D mesh*/ /*DEF'd node*/ node_name = gf_node_get_name_and_id(node, &node_id); GF_BIFS_WRITE_INT(codec, bs, node_id ? 1 : 0, 1, "DEF", NULL); if (node_id) { GF_BIFS_WRITE_INT(codec, bs, node_id - 1, codec->info->config.NodeIDBits, "NodeID", NULL); if (codec->UseName) gf_bifs_enc_name(codec, bs, (char*) node_name ); } /*no updates of time fields for now - NEEDED FOR A LIVE ENCODER*/ /*if coords were not stored for QP14 before coding this node, reset QP14 it when leaving*/ reset_qp14 = !codec->coord_stored; /*QP14 case*/ switch (node_tag) { case TAG_MPEG4_Coordinate: case TAG_MPEG4_Coordinate2D: gf_bifs_enc_qp14_enter(codec, GF_TRUE); } e = EncNodeFields(codec, bs, node); if (e) return e; if (codec->coord_stored && reset_qp14) gf_bifs_enc_qp14_reset(codec); switch (node_tag) { case TAG_MPEG4_Coordinate: case TAG_MPEG4_Coordinate2D: gf_bifs_enc_qp14_enter(codec, GF_FALSE); break; } 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; }
GF_Err BE_EncProtoList(GF_BifsEncoder *codec, GF_List *protoList, GF_BitStream *bs) { u8 useQuant, useAnim; u32 i, j, nbRoutes, nbBits, numProtos, numFields, count; GF_Node *node; GF_ProtoFieldInterface *proto_field; GF_Proto *proto, *prev_proto; GF_Route *r; GF_Err e; GF_SceneGraph *rootSG; GF_FieldInfo field; e = GF_OK; if (!protoList || !gf_list_count(protoList)) { GF_BIFS_WRITE_INT(codec, bs, 0, 1, "moreProto", NULL); return GF_OK; } if (!codec->info->config.ProtoIDBits) return GF_NON_COMPLIANT_BITSTREAM; /*store state*/ rootSG = codec->current_proto_graph; prev_proto = codec->encoding_proto; numProtos = gf_list_count(protoList); for (i=0; i<numProtos; i++) { proto = (GF_Proto*)gf_list_get(protoList, i); useQuant = useAnim = 0; /*set current proto state*/ codec->encoding_proto = proto; codec->current_proto_graph = proto->sub_graph; GF_BIFS_WRITE_INT(codec, bs, 1, 1, "moreProto", NULL); /*1- proto interface declaration*/ GF_BIFS_WRITE_INT(codec, bs, proto->ID, codec->info->config.ProtoIDBits, "protoID", NULL); if (codec->UseName) gf_bifs_enc_name(codec, bs, proto->Name); numFields = gf_list_count(proto->proto_fields); for (j=0; j<numFields; j++) { proto_field = (GF_ProtoFieldInterface*)gf_list_get(proto->proto_fields, j); GF_BIFS_WRITE_INT(codec, bs, 1, 1, "moreField", NULL); GF_BIFS_WRITE_INT(codec, bs, proto_field->EventType, 2, "eventType", NULL); GF_BIFS_WRITE_INT(codec, bs, proto_field->FieldType, 6, "fieldType", NULL); if (codec->UseName) gf_bifs_enc_name(codec, bs, proto_field->FieldName); switch (proto_field->EventType) { case GF_SG_EVENT_EXPOSED_FIELD: case GF_SG_EVENT_FIELD: gf_sg_proto_field_get_field(proto_field, &field); if (gf_sg_vrml_is_sf_field(field.fieldType)) { e = gf_bifs_enc_sf_field(codec, bs, NULL, &field); } else { if (codec->info->config.UsePredictiveMFField) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "usePredictive", NULL); e = gf_bifs_enc_mf_field(codec, bs, NULL, &field); } if (e) goto exit; break; } if (proto_field->QP_Type) useQuant = 1; if (proto_field->Anim_Type) useAnim = 1; } GF_BIFS_WRITE_INT(codec, bs, 0, 1, "moreField", NULL); GF_BIFS_WRITE_INT(codec, bs, proto->ExternProto.count ? 1 : 0, 1, "externProto", NULL); /*externProto*/ if (proto->ExternProto.count) { memset(&field, 0, sizeof(GF_FieldInfo)); field.far_ptr = &proto->ExternProto; field.fieldType = GF_SG_VRML_MFURL; field.name = "ExternProto"; if (codec->info->config.UsePredictiveMFField) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "usePredictive", NULL); e = gf_bifs_enc_mf_field(codec, bs, NULL, &field); if (e) goto exit; } else { /*encode sub-proto list*/ e = BE_EncProtoList(codec, proto->sub_graph->protos, bs); if (e) goto exit; count = gf_list_count(proto->node_code); /*BIFS cannot encode empty protos ! We therefore encode a NULL node instead*/ if (!count) { gf_bifs_enc_node(codec, NULL, NDT_SFWorldNode, bs); GF_BIFS_WRITE_INT(codec, bs, 0, 1, "moreNodes", NULL); } else { for (j=0; j<count; j++) { /*parse all nodes in SFWorldNode table*/ node = (GF_Node*)gf_list_get(proto->node_code, j); e = gf_bifs_enc_node(codec, node, NDT_SFWorldNode, bs); if (e) goto exit; GF_BIFS_WRITE_INT(codec, bs, (j+1==count) ? 0 : 1, 1, "moreNodes", NULL); } } /*encode routes routes*/ nbRoutes = count = gf_list_count(proto->sub_graph->Routes); for (j=0; j<count; j++) { r = (GF_Route*)gf_list_get(proto->sub_graph->Routes, j); if (r->IS_route) nbRoutes--; } GF_BIFS_WRITE_INT(codec, bs, nbRoutes ? 1 : 0, 1, "hasRoute", NULL); if (nbRoutes) { nbBits = gf_get_bit_size(nbRoutes); if (nbBits + 5 > nbRoutes) { GF_BIFS_WRITE_INT(codec, bs, 1, 1, "isList", NULL); /*list*/ for (j=0; j<count; j++) { r = (GF_Route*)gf_list_get(proto->sub_graph->Routes, j); if (r->IS_route) continue; e = gf_bifs_enc_route(codec, r, bs); if (e) goto exit; nbRoutes--; GF_BIFS_WRITE_INT(codec, bs, nbRoutes ? 1 : 0, 1, "moreRoute", NULL); } } else { GF_BIFS_WRITE_INT(codec, bs, 0, 1, "isList", NULL); GF_BIFS_WRITE_INT(codec, bs, nbBits, 5, "nbBits", NULL); GF_BIFS_WRITE_INT(codec, bs, nbRoutes, nbBits, "length", NULL); for (j=0; j<count; j++) { r = (GF_Route*)gf_list_get(proto->sub_graph->Routes, j); if (r->IS_route) continue; e = gf_bifs_enc_route(codec, r, bs); if (e) goto exit; } } } } /*anim and Quantization stuff*/ GF_BIFS_WRITE_INT(codec, bs, useQuant, 1, "useQuant", NULL); GF_BIFS_WRITE_INT(codec, bs, useAnim, 1, "useAnim", NULL); if (!useAnim && !useQuant) continue; count = gf_sg_proto_get_field_count(proto); for (j=0; j<count; j++) { proto_field = gf_sg_proto_field_find(proto, j); 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) )) { GF_BIFS_WRITE_INT(codec, bs, proto_field->QP_Type, 4, "QPType", NULL); if (proto_field->QP_Type==QC_LINEAR_SCALAR) GF_BIFS_WRITE_INT(codec, bs, proto_field->NumBits, 5, "nbBits", NULL); GF_BIFS_WRITE_INT(codec, bs, proto_field->hasMinMax, 1, "hasMinMax", NULL); if (proto_field->hasMinMax) { field.fieldType = gf_sg_vrml_get_sf_type(field.fieldType); switch (field.fieldType) { case GF_SG_VRML_SFINT32: case GF_SG_VRML_SFTIME: break; default: field.fieldType = GF_SG_VRML_SFFLOAT; break; } field.name = "QPMinValue"; field.far_ptr = proto_field->qp_min_value; gf_bifs_enc_sf_field(codec, bs, NULL, &field); field.name = "QPMaxValue"; field.far_ptr = proto_field->qp_max_value; gf_bifs_enc_sf_field(codec, bs, NULL, &field); } } /*anim - not supported yet*/ if (useAnim && ( (field.eventType == GF_SG_EVENT_IN) || (field.eventType == GF_SG_EVENT_EXPOSED_FIELD) )) { e = GF_NOT_SUPPORTED; goto exit; } } } GF_BIFS_WRITE_INT(codec, bs, 0, 1, "moreProto", NULL); exit: /*restore scene graph state*/ codec->encoding_proto = prev_proto; codec->current_proto_graph = rootSG; return e; }
static GF_Err BE_XReplace(GF_BifsEncoder * codec, GF_Command *com, GF_BitStream *bs) { u32 i,nbBits; GF_FieldInfo field; GF_Err e; GF_CommandField *inf; if (!gf_list_count(com->command_fields)) return GF_BAD_PARAM; inf = (GF_CommandField *)gf_list_get(com->command_fields, 0); gf_bs_write_int(bs, gf_node_get_id(com->node)-1, codec->info->config.NodeIDBits); nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(com->node, GF_SG_FIELD_CODING_IN)-1); gf_bifs_field_index_by_mode(com->node, inf->fieldIndex, GF_SG_FIELD_CODING_IN, &i); GF_BIFS_WRITE_INT(codec, bs, i, nbBits, "field", NULL); gf_node_get_field(com->node, inf->fieldIndex, &field); if (!gf_sg_vrml_is_sf_field(field.fieldType)) { if ((inf->pos != -2) || com->toNodeID) { GF_BIFS_WRITE_INT(codec, bs, 1, 1, "indexedReplacement", NULL); if (com->toNodeID) { GF_Node *n = gf_bifs_enc_find_node(codec, com->toNodeID); GF_BIFS_WRITE_INT(codec, bs, 1, 1, "dynamicIndex", NULL); GF_BIFS_WRITE_INT(codec, bs, com->toNodeID-1, codec->info->config.NodeIDBits, "idxNodeID", NULL); nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(n, GF_SG_FIELD_CODING_DEF)-1); gf_bifs_field_index_by_mode(n, com->toFieldIndex, GF_SG_FIELD_CODING_DEF, &i); GF_BIFS_WRITE_INT(codec, bs, i, nbBits, "idxField", NULL); } else { GF_BIFS_WRITE_INT(codec, bs, 0, 1, "dynamicIndex", NULL); if (inf->pos==-1) { GF_BIFS_WRITE_INT(codec, bs, 3, 2, "replacementPosition", NULL); } else if (inf->pos==0) { GF_BIFS_WRITE_INT(codec, bs, 2, 2, "replacementPosition", NULL); } else { GF_BIFS_WRITE_INT(codec, bs, 0, 2, "replacementPosition", NULL); GF_BIFS_WRITE_INT(codec, bs, inf->pos, 16, "position", NULL); } } } else { GF_BIFS_WRITE_INT(codec, bs, 0, 1, "indexedReplacement", NULL); } } if (field.fieldType==GF_SG_VRML_MFNODE) { if (com->ChildNodeTag) { GF_Node *n; if (com->ChildNodeTag>0) { n = gf_node_new(codec->scene_graph, com->ChildNodeTag); } else { GF_Proto *proto = gf_sg_find_proto(codec->scene_graph, -com->ChildNodeTag , NULL); if (!proto) return GF_SG_UNKNOWN_NODE; n = gf_sg_proto_create_instance(codec->scene_graph, proto); } if (!n) return GF_SG_UNKNOWN_NODE; gf_node_register(n, NULL); GF_BIFS_WRITE_INT(codec, bs, 1, 1, "childField", NULL); nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(n, GF_SG_FIELD_CODING_IN)-1); gf_bifs_field_index_by_mode(n, com->child_field, GF_SG_FIELD_CODING_IN, &i); GF_BIFS_WRITE_INT(codec, bs, i, nbBits, "childField", NULL); gf_node_unregister(n, NULL); } else { GF_BIFS_WRITE_INT(codec, bs, 0, 1, "childField", NULL); } } if (com->fromNodeID) { GF_Node *n = gf_bifs_enc_find_node(codec, com->fromNodeID); GF_BIFS_WRITE_INT(codec, bs, 1, 1, "valueFromNode", NULL); GF_BIFS_WRITE_INT(codec, bs, com->fromNodeID-1, codec->info->config.NodeIDBits, "sourceNodeID", NULL); nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(n, GF_SG_FIELD_CODING_DEF)-1); gf_bifs_field_index_by_mode(n, com->fromFieldIndex, GF_SG_FIELD_CODING_DEF, &i); GF_BIFS_WRITE_INT(codec, bs, i, nbBits, "sourceField", NULL); return GF_OK; } GF_BIFS_WRITE_INT(codec, bs, 0, 1, "valueFromNode", NULL); field.far_ptr = inf->field_ptr; field.fieldType = inf->fieldType; e = gf_bifs_enc_field(codec, bs, com->node, &field); return e; }
GF_Err EncNodeFields(GF_BifsEncoder * codec, GF_BitStream *bs, GF_Node *node) { u8 mode; GF_Route *isedField; GF_Node *clone; GF_Err e; s32 *enc_fields; u32 numBitsALL, numBitsDEF, allInd, count, i, nbBitsProto, nbFinal; Bool use_list, nodeIsFDP = GF_FALSE; GF_FieldInfo field, clone_field; e = GF_OK; if (codec->encoding_proto) { mode = GF_SG_FIELD_CODING_ALL; nbBitsProto = gf_get_bit_size(gf_sg_proto_get_field_count(codec->encoding_proto) - 1); numBitsALL = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_ALL) - 1); } else { mode = GF_SG_FIELD_CODING_DEF; nbBitsProto = 0; numBitsALL = 0; } count = gf_node_get_num_fields_in_mode(node, mode); if (node->sgprivate->tag==TAG_MPEG4_Script) count = 3; if (!count) { GF_BIFS_WRITE_INT(codec, bs, 0, 1, "isMask", NULL); GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL); return GF_OK; } if (node->sgprivate->tag == TAG_ProtoNode) { clone = gf_sg_proto_create_instance(node->sgprivate->scenegraph, ((GF_ProtoInstance *)node)->proto_interface);; } else { clone = gf_node_new(node->sgprivate->scenegraph, node->sgprivate->tag); } if (clone) gf_node_register(clone, NULL); numBitsDEF = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_DEF) - 1); enc_fields = (s32*)gf_malloc(sizeof(s32) * count); nbFinal = 0; for (i=0; i<count; i++) { enc_fields[i] = -1; /*get field in ALL mode*/ if (mode == GF_SG_FIELD_CODING_ALL) { allInd = i; } else { gf_bifs_get_field_index(node, i, GF_SG_FIELD_CODING_DEF, &allInd); } /*encode proto code*/ if (codec->encoding_proto) { isedField = gf_bifs_enc_is_field_ised(codec, node, allInd); if (isedField) { enc_fields[i] = allInd; nbFinal ++; continue; } } /*common case*/ gf_node_get_field(node, allInd, &field); /*if event don't encode (happens when encoding protos)*/ if ((field.eventType == GF_SG_EVENT_IN) || (field.eventType == GF_SG_EVENT_OUT)) continue; /*if field is default skip*/ switch (field.fieldType) { case GF_SG_VRML_SFNODE: if (* (GF_Node **) field.far_ptr) { enc_fields[i] = allInd; nbFinal++; } break; case GF_SG_VRML_MFNODE: if (* (GF_ChildNodeItem **) field.far_ptr) { enc_fields[i] = allInd; nbFinal++; } break; case GF_SG_VRML_SFCOMMANDBUFFER: { SFCommandBuffer *cb = (SFCommandBuffer *)field.far_ptr; if (gf_list_count(cb->commandList)) { enc_fields[i] = allInd; nbFinal++; } } break; case GF_SG_VRML_MFSCRIPT: enc_fields[i] = allInd; nbFinal++; break; default: gf_node_get_field(clone, allInd, &clone_field); if (!gf_sg_vrml_field_equal(clone_field.far_ptr, field.far_ptr, field.fieldType)) { enc_fields[i] = allInd; nbFinal++; } break; } } if (clone) gf_node_unregister(clone, NULL); use_list = GF_TRUE; /* patch for FDP node : */ /* cannot use default field sorting due to spec "mistake", so use list to imply inversion between field 2 and field 3 of FDP*/ if (node->sgprivate->tag == TAG_MPEG4_FDP) { s32 s4SwapValue = enc_fields[2]; enc_fields[2] = enc_fields[3]; enc_fields[3] = s4SwapValue; nodeIsFDP = GF_TRUE; use_list = GF_TRUE; } /*number of bits in mask node is count*1, in list node is 1+nbFinal*(1+numBitsDEF) */ else if (count < 1+nbFinal*(1+numBitsDEF)) use_list = GF_FALSE; GF_BIFS_WRITE_INT(codec, bs, use_list ? 0 : 1, 1, "isMask", NULL); for (i=0; i<count; i++) { if (enc_fields[i] == -1) { if (!use_list) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "Mask", NULL); continue; } allInd = (u32) enc_fields[i]; /*encode proto code*/ if (codec->encoding_proto) { isedField = gf_bifs_enc_is_field_ised(codec, node, allInd); if (isedField) { if (use_list) { GF_BIFS_WRITE_INT(codec, bs, 0, 1, "end", NULL); } else { GF_BIFS_WRITE_INT(codec, bs, 1, 1, "Mask", NULL); } GF_BIFS_WRITE_INT(codec, bs, 1, 1, "isedField", NULL); if (use_list) GF_BIFS_WRITE_INT(codec, bs, allInd, numBitsALL, "nodeField", NULL); if (isedField->ToNode == node) { GF_BIFS_WRITE_INT(codec, bs, isedField->FromField.fieldIndex, nbBitsProto, "protoField", NULL); } else { GF_BIFS_WRITE_INT(codec, bs, isedField->ToField.fieldIndex, nbBitsProto, "protoField", NULL); } continue; } } /*common case*/ gf_node_get_field(node, allInd, &field); if (use_list) { /*not end flag*/ GF_BIFS_WRITE_INT(codec, bs, 0, 1, "end", NULL); } else { /*mask flag*/ GF_BIFS_WRITE_INT(codec, bs, 1, 1, "Mask", NULL); } /*not ISed field*/ if (codec->encoding_proto) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "isedField", NULL); if (use_list) { if (codec->encoding_proto || nodeIsFDP) { u32 ind=0; /*for proto, we're in ALL mode and we need DEF mode*/ /*for FDP, encoding requires to get def id from all id as fields 2 and 3 are reversed*/ gf_bifs_field_index_by_mode(node, allInd, GF_SG_FIELD_CODING_DEF, &ind); GF_BIFS_WRITE_INT(codec, bs, ind, numBitsDEF, "field", (char*)field.name); } else { GF_BIFS_WRITE_INT(codec, bs, i, numBitsDEF, "field", (char*)field.name); } } e = gf_bifs_enc_field(codec, bs, node, &field); if (e) goto exit; } /*end flag*/ if (use_list) GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL); exit: gf_free(enc_fields); return e; }
static GF_Err BE_ExtendedUpdate(GF_BifsEncoder * codec, GF_Command *com, GF_BitStream *bs) { GF_BIFS_WRITE_INT(codec, bs, 0, 2, "Insert", NULL); GF_BIFS_WRITE_INT(codec, bs, 1, 2, "ExtendedUpdate", NULL); switch (com->tag) { case GF_SG_PROTO_INSERT: GF_BIFS_WRITE_INT(codec, bs, 0, 8, "MultipleReplace", NULL); return BE_EncProtoList(codec, com->new_proto_list, bs); case GF_SG_PROTO_DELETE: GF_BIFS_WRITE_INT(codec, bs, 1, 8, "ProtoDelete", NULL); return BE_EncProtoDelete(codec, com, bs); case GF_SG_PROTO_DELETE_ALL: GF_BIFS_WRITE_INT(codec, bs, 2, 8, "DeleteAllProtos", NULL); return GF_OK; case GF_SG_MULTIPLE_INDEXED_REPLACE: GF_BIFS_WRITE_INT(codec, bs, 3, 8, "MultipleReplace", NULL); return BE_MultipleIndexedReplace(codec, com, bs); case GF_SG_MULTIPLE_REPLACE: GF_BIFS_WRITE_INT(codec, bs, 4, 8, "MultipleReplace", NULL); return BE_MultipleReplace(codec, com, bs); case GF_SG_GLOBAL_QUANTIZER: GF_BIFS_WRITE_INT(codec, bs, 5, 8, "GlobalQuantizer", NULL); return BE_GlobalQuantizer(codec, com, bs); case GF_SG_NODE_DELETE_EX: GF_BIFS_WRITE_INT(codec, bs, 6, 8, "MultipleReplace", NULL); GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(com->node) - 1, codec->info->config.NodeIDBits, "NodeID", NULL); return GF_OK; case GF_SG_XREPLACE: GF_BIFS_WRITE_INT(codec, bs, 7, 8, "XReplace", NULL); return BE_XReplace(codec, com, bs); default: return GF_BAD_PARAM; } }
GF_Err gf_bifs_enc_sf_field(GF_BifsEncoder *codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field) { GF_Err e; if (node) { e = gf_bifs_enc_quant_field(codec, bs, node, field); if (e != GF_EOS) return e; } switch (field->fieldType) { case GF_SG_VRML_SFBOOL: GF_BIFS_WRITE_INT(codec, bs, * ((SFBool *)field->far_ptr), 1, "SFBool", NULL); break; case GF_SG_VRML_SFCOLOR: BE_WriteSFFloat(codec, ((SFColor *)field->far_ptr)->red, bs, "color.red"); BE_WriteSFFloat(codec, ((SFColor *)field->far_ptr)->green, bs, "color.green"); BE_WriteSFFloat(codec, ((SFColor *)field->far_ptr)->blue, bs, "color.blue"); break; case GF_SG_VRML_SFFLOAT: BE_WriteSFFloat(codec, * ((SFFloat *)field->far_ptr), bs, NULL); break; case GF_SG_VRML_SFINT32: GF_BIFS_WRITE_INT(codec, bs, * ((SFInt32 *)field->far_ptr), 32, "SFInt32", NULL); break; case GF_SG_VRML_SFROTATION: BE_WriteSFFloat(codec, ((SFRotation *)field->far_ptr)->x, bs, "rot.x"); BE_WriteSFFloat(codec, ((SFRotation *)field->far_ptr)->y, bs, "rot.y"); BE_WriteSFFloat(codec, ((SFRotation *)field->far_ptr)->z, bs, "rot.z"); BE_WriteSFFloat(codec, ((SFRotation *)field->far_ptr)->q, bs, "rot.theta"); break; case GF_SG_VRML_SFSTRING: if (node && (node->sgprivate->tag==TAG_MPEG4_CacheTexture) && (field->fieldIndex<=2)) { u32 size, val; char buf[4096]; char *res_src = NULL; const char *src = ((SFString*)field->far_ptr)->buffer; FILE *f; if (codec->src_url) res_src = gf_url_concatenate(codec->src_url, src); f = gf_fopen(res_src ? res_src : src, "rb"); if (!f) { GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[BIFS] Cannot open source file %s for encoding CacheTexture\n", res_src ? res_src : src)); return GF_URL_ERROR; } if (res_src) gf_free(res_src); gf_fseek(f, 0, SEEK_END); size = (u32) gf_ftell(f); val = gf_get_bit_size(size); GF_BIFS_WRITE_INT(codec, bs, val, 5, "nbBits", NULL); GF_BIFS_WRITE_INT(codec, bs, size, val, "length", NULL); gf_fseek(f, 0, SEEK_SET); while (size) { u32 read = (u32) fread(buf, 1, 4096, f); gf_bs_write_data(bs, buf, read); size -= read; } } else { u32 i, val, len; char *str = (char *) ((SFString*)field->far_ptr)->buffer; if (node && (node->sgprivate->tag==TAG_MPEG4_BitWrapper) ) { len = ((M_BitWrapper*)node)->buffer_len; } else { len = str ? (u32) strlen(str) : 0; } val = gf_get_bit_size(len); GF_BIFS_WRITE_INT(codec, bs, val, 5, "nbBits", NULL); GF_BIFS_WRITE_INT(codec, bs, len, val, "length", NULL); for (i=0; i<len; i++) gf_bs_write_int(bs, str[i], 8); GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] string\t\t%d\t\t%s\n", 8*len, str) ); } break; case GF_SG_VRML_SFTIME: gf_bs_write_double(bs, *((SFTime *)field->far_ptr)); GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] SFTime\t\t%d\t\t%g\n", 64, *((SFTime *)field->far_ptr))); break; case GF_SG_VRML_SFVEC2F: BE_WriteSFFloat(codec, ((SFVec2f *)field->far_ptr)->x, bs, "vec2f.x"); BE_WriteSFFloat(codec, ((SFVec2f *)field->far_ptr)->y, bs, "vec2f.y"); break; case GF_SG_VRML_SFVEC3F: BE_WriteSFFloat(codec, ((SFVec3f *)field->far_ptr)->x, bs, "vec3f.x"); BE_WriteSFFloat(codec, ((SFVec3f *)field->far_ptr)->y, bs, "vec3f.y"); BE_WriteSFFloat(codec, ((SFVec3f *)field->far_ptr)->z, bs, "vec3f.z"); break; case GF_SG_VRML_SFURL: { SFURL *url = (SFURL *) field->far_ptr; GF_BIFS_WRITE_INT(codec, bs, (url->OD_ID>0) ? 1 : 0, 1, "hasODID", "SFURL"); if (url->OD_ID>0) { GF_BIFS_WRITE_INT(codec, bs, url->OD_ID, 10, "ODID", "SFURL"); } else { u32 i, len = url->url ? (u32) strlen(url->url) : 0; u32 val = gf_get_bit_size(len); GF_BIFS_WRITE_INT(codec, bs, val, 5, "nbBits", NULL); GF_BIFS_WRITE_INT(codec, bs, len, val, "length", NULL); for (i=0; i<len; i++) gf_bs_write_int(bs, url->url[i], 8); GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] string\t\t%d\t\t%s\t\t//SFURL\n", 8*len, url->url)); } } break; case GF_SG_VRML_SFIMAGE: { u32 size, i; SFImage *img = (SFImage *)field->far_ptr; GF_BIFS_WRITE_INT(codec, bs, img->width, 12, "width", "SFImage"); GF_BIFS_WRITE_INT(codec, bs, img->height, 12, "height", "SFImage"); GF_BIFS_WRITE_INT(codec, bs, img->numComponents - 1, 2, "nbComp", "SFImage"); size = img->width * img->height * img->numComponents; for (i=0; i<size; i++) gf_bs_write_int(bs, img->pixels[i], 8); GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] pixels\t\t%d\t\tnot dumped\t\t//SFImage\n", 8*size)); } break; case GF_SG_VRML_SFCOMMANDBUFFER: { SFCommandBuffer *cb = (SFCommandBuffer *) field->far_ptr; if (cb->buffer) gf_free(cb->buffer); cb->buffer = NULL; cb->bufferSize = 0; if (gf_list_count(cb->commandList)) { u32 i, nbBits; GF_BitStream *bs_cond = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] /*SFCommandBuffer*/\n" )); e = gf_bifs_enc_commands(codec, cb->commandList, bs_cond); if (!e) gf_bs_get_content(bs_cond, (char**)&cb->buffer, &cb->bufferSize); gf_bs_del(bs_cond); if (e) return e; GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] /*End SFCommandBuffer*/\n")); nbBits = gf_get_bit_size(cb->bufferSize); GF_BIFS_WRITE_INT(codec, bs, nbBits, 5, "NbBits", NULL); GF_BIFS_WRITE_INT(codec, bs, cb->bufferSize, nbBits, "BufferSize", NULL); for (i=0; i<cb->bufferSize; i++) GF_BIFS_WRITE_INT(codec, bs, cb->buffer[i], 8, "buffer byte", NULL); } /*empty command buffer*/ else { GF_BIFS_WRITE_INT(codec, bs, 0, 5, "NbBits", NULL); } } break; case GF_SG_VRML_SFNODE: return gf_bifs_enc_node(codec, *((GF_Node **)field->far_ptr), field->NDTtype, bs, node); case GF_SG_VRML_SFSCRIPT: #ifdef GPAC_HAS_SPIDERMONKEY codec->LastError = SFScript_Encode(codec, (SFScript *)field->far_ptr, bs, node); #else return GF_NOT_SUPPORTED; #endif break; case GF_SG_VRML_SFATTRREF: { u32 idx=0; SFAttrRef *ar = (SFAttrRef *)field->far_ptr; u32 nbBitsDEF = gf_get_bit_size(gf_node_get_num_fields_in_mode(ar->node, GF_SG_FIELD_CODING_DEF) - 1); GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(ar->node) - 1, codec->info->config.NodeIDBits, "NodeID", NULL); gf_bifs_field_index_by_mode(ar->node, ar->fieldIndex, GF_SG_FIELD_CODING_DEF, &idx); GF_BIFS_WRITE_INT(codec, bs, idx, nbBitsDEF, "field", NULL); } break; default: return GF_NOT_SUPPORTED; } return codec->LastError; }
GF_Err SFScript_Encode(GF_BifsEncoder *codec, SFScript *script_field, GF_BitStream *bs, GF_Node *n) { char *ptr; ScriptEnc sc_enc; if (gf_node_get_tag(n) != TAG_MPEG4_Script) return GF_NON_COMPLIANT_BITSTREAM; memset(&sc_enc, 0, sizeof(ScriptEnc)); sc_enc.codec = codec; sc_enc.script = n; sc_enc.bs = bs; sc_enc.identifiers = gf_list_new(); sc_enc.id_buf = gf_list_new(); sc_enc.err = GF_OK; if (codec->is_encoding_command) { GF_BIFS_WRITE_INT(codec, bs, 1, 1, "Script::isList", NULL); GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL); } else { EncScriptFields(&sc_enc); } /*reserevd*/ GF_BIFS_WRITE_INT(codec, bs, 1, 1, "reserved", NULL); if (script_field) { sc_enc.cur_buf = (char *)script_field->script_text; } else if (((M_Script*)n)->url.count) { sc_enc.cur_buf = (char *)((M_Script*)n)->url.vals[0].script_text; } if (sc_enc.cur_buf) { if (!strnicmp(sc_enc.cur_buf, "javascript:", 11) || !strnicmp(sc_enc.cur_buf, "vrmlscript:", 11) || !strnicmp(sc_enc.cur_buf, "ECMAScript:", 11) ) { sc_enc.cur_buf += 11; } else if (!strnicmp(sc_enc.cur_buf, "mpeg4script:", 12) ) { sc_enc.cur_buf += 12; } } /*encode functions*/ while (sc_enc.cur_buf && sc_enc.cur_buf[0] && (sc_enc.cur_buf[0]!='}')) { if (strchr("\r\n\t ", sc_enc.cur_buf[0]) ) { sc_enc.cur_buf++; continue; } GF_BIFS_WRITE_INT(codec, bs, 1, 1, "hasFunction", NULL); SFE_Function(&sc_enc); if (sc_enc.err) break; } GF_BIFS_WRITE_INT(codec, bs, 0, 1, "hasFunction", NULL); //clean up while (gf_list_count(sc_enc.identifiers)) { ptr = (char *)gf_list_get(sc_enc.identifiers, 0); gf_list_rem(sc_enc.identifiers, 0); gf_free(ptr); } gf_list_del(sc_enc.identifiers); /*in case of error this is needed*/ while (gf_list_count(sc_enc.id_buf)) { ptr = (char *)gf_list_get(sc_enc.id_buf, 0); gf_list_rem(sc_enc.id_buf, 0); gf_free(ptr); } gf_list_del(sc_enc.id_buf); return sc_enc.err; }