📄 memory_decoder.c
字号:
/* * 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 <gpac/internal/bifs_dev.h>/*for scene replace tricks*/#include <gpac/internal/scenegraph_dev.h>#include "quant.h"GF_Err ParseMFFieldList(GF_BifsDecoder *codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field);GF_Err ParseMFFieldVec(GF_BifsDecoder *codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field);static void BM_SetCommandNode(GF_Command *com, GF_Node *node){ com->node = node; gf_node_register(node, NULL);}static GF_Err BM_ParseMultipleIndexedReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list){ u32 ID, ind, field_ind, NumBits, lenpos, lennum, count; GF_Node *node; GF_Err e; GF_Command *com; GF_CommandField *inf; GF_FieldInfo field; 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); com = gf_sg_command_new(codec->current_graph, GF_SG_MULTIPLE_INDEXED_REPLACE); BM_SetCommandNode(com, node); field.fieldType = gf_sg_vrml_get_sf_type(field.fieldType); while (count) { inf = gf_sg_command_field_new(com); inf->pos = gf_bs_read_int(bs, lenpos); inf->fieldIndex = field.fieldIndex; inf->fieldType = field.fieldType; if (field.fieldType==GF_SG_VRML_SFNODE) { inf->new_node = gf_bifs_dec_node(codec, bs, field.NDTtype); if (codec->LastError) goto err; inf->field_ptr = &inf->new_node; gf_node_register(inf->new_node, node); } else { field.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(inf->fieldType); e = gf_bifs_dec_sf_field(codec, bs, node, &field); if (e) goto err; } count--; }err: if (e) gf_sg_command_del(com); else gf_list_add(com_list, com); return e;}static GF_Err BM_ParseMultipleReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list){ u32 i, numFields, index, flag, nbBits, field_ref, fieldind; GF_Err e; GF_FieldInfo field; u32 NodeID; GF_Node *node; GF_Command *com; GF_CommandField *inf; 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; e = GF_OK; com = gf_sg_command_new(codec->current_graph, GF_SG_MULTIPLE_REPLACE); BM_SetCommandNode(com, node); flag = gf_bs_read_int(bs, 1); if (flag) { numFields = gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_DEF); for (i=0; i<numFields; i++) { flag = gf_bs_read_int(bs, 1); if (!flag) continue; gf_bifs_get_field_index(node, i, GF_SG_FIELD_CODING_DEF, &index); e = gf_node_get_field(node, index, &field); if (e) goto exit; inf = gf_sg_command_field_new(com); inf->fieldType = field.fieldType; inf->fieldIndex = field.fieldIndex; if (inf->fieldType==GF_SG_VRML_SFNODE) { field.far_ptr = inf->field_ptr = &inf->new_node; } else if (inf->fieldType==GF_SG_VRML_MFNODE) { field.far_ptr = inf->field_ptr = &inf->node_list; } else { field.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(inf->fieldType); } e = gf_bifs_dec_field(codec, bs, node, &field); if (e) goto exit; } } else { flag = gf_bs_read_int(bs, 1); nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_DEF)-1); while (!flag) { field_ref = gf_bs_read_int(bs, nbBits); e = gf_bifs_get_field_index(node, field_ref, GF_SG_FIELD_CODING_DEF, &fieldind); if (e) goto exit; e = gf_node_get_field(node, fieldind, &field); if (e) goto exit; inf = gf_sg_command_field_new(com); inf->fieldType = field.fieldType; inf->fieldIndex = field.fieldIndex; if (inf->fieldType==GF_SG_VRML_SFNODE) { field.far_ptr = inf->field_ptr = &inf->new_node; } else if (inf->fieldType==GF_SG_VRML_MFNODE) { field.far_ptr = inf->field_ptr = &inf->node_list; } else { field.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(inf->fieldType); } e = gf_bifs_dec_field(codec, bs, node, &field); if (e) goto exit; flag = gf_bs_read_int(bs, 1); } } exit: if (e) gf_sg_command_del(com); else gf_list_add(com_list, com); return e;}static GF_Err BM_ParseGlobalQuantizer(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list){ GF_Node *node; GF_Command *com; GF_CommandField *inf; 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)) { gf_node_unregister(node, NULL); return GF_NON_COMPLIANT_BITSTREAM; } /*register global QP*/ codec->GlobalQP = codec->ActiveQP = (M_QuantizationParameter *) node; codec->GlobalQP->isLocal = 0; if (node) { /*register TWICE: once for the command, and for the codec*/ node->sgprivate->num_instances = 2; } com = gf_sg_command_new(codec->current_graph, GF_SG_GLOBAL_QUANTIZER); inf = gf_sg_command_field_new(com); inf->new_node = node; inf->field_ptr = &inf->new_node; inf->fieldType = GF_SG_VRML_SFNODE; gf_list_add(com_list, com); return GF_OK;}static GF_Err BM_ParseProtoDelete(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list){ u32 flag, count; GF_Command *com = gf_sg_command_new(codec->current_graph, GF_SG_PROTO_DELETE); flag = gf_bs_read_int(bs, 1); if (flag) { count = 0; flag = gf_bs_read_int(bs, 1); while (flag) { com->del_proto_list = (u32*)realloc(com->del_proto_list, sizeof(u32) * (com->del_proto_list_size+1)); com->del_proto_list[count] = gf_bs_read_int(bs, codec->info->config.ProtoIDBits); com->del_proto_list_size++; flag = gf_bs_read_int(bs, 1); } } else { flag = gf_bs_read_int(bs, 5); com->del_proto_list_size = gf_bs_read_int(bs, flag); com->del_proto_list = (u32*)realloc(com->del_proto_list, sizeof(u32) * (com->del_proto_list_size)); flag = 0; while (flag<com->del_proto_list_size) { com->del_proto_list[flag] = gf_bs_read_int(bs, codec->info->config.ProtoIDBits); flag++; } } gf_list_add(com_list, com); return GF_OK;}static GF_Err BM_ParseExtendedUpdates(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list){ u32 type = gf_bs_read_int(bs, 8); GF_Err e; switch (type) { case 0: { GF_Command *com = gf_sg_command_new(codec->current_graph, GF_SG_PROTO_INSERT); e = gf_bifs_dec_proto_list(codec, bs, com->new_proto_list); if (e) gf_sg_command_del(com); else gf_list_add(com_list, com); } return e; case 1: return BM_ParseProtoDelete(codec, bs, com_list); case 2: { GF_Command *com = gf_sg_command_new(codec->current_graph, GF_SG_PROTO_DELETE_ALL); return gf_list_add(com_list, com); } case 3: return BM_ParseMultipleIndexedReplace(codec, bs, com_list); case 4: return BM_ParseMultipleReplace(codec, bs, com_list); case 5: return BM_ParseGlobalQuantizer(codec, bs, com_list); case 6: { GF_Command *com; u32 ID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); GF_Node *n = gf_sg_find_node(codec->current_graph, ID); if (!n) return GF_OK; com = gf_sg_command_new(codec->current_graph, GF_SG_NODE_DELETE_EX); BM_SetCommandNode(com, n); gf_list_add(com_list, com); } return GF_OK; default: return GF_BIFS_UNKNOWN_VERSION; }}/*inserts a node in a container (node.children)*/GF_Err BM_ParseNodeInsert(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list){ u32 NodeID, NDT; GF_Command *com; GF_CommandField *inf; s32 type, pos; GF_Node *node, *def; 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 (!codec->LastError) { com = gf_sg_command_new(codec->current_graph, GF_SG_NODE_INSERT); BM_SetCommandNode(com, def); inf = gf_sg_command_field_new(com); inf->pos = pos; inf->new_node = node; inf->field_ptr = &inf->new_node; inf->fieldType = GF_SG_VRML_SFNODE; gf_list_add(com_list, com); /*register*/ gf_node_register(node, def); } return codec->LastError;}/*NB This can insert a node as well (but usually not in the .children field)*/GF_Err BM_ParseIndexInsert(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list){ GF_Err e; u32 NodeID; u32 NumBits, ind, field_ind; u8 type; GF_Command *com; GF_CommandField *inf; 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 (!codec->LastError) { com = gf_sg_command_new(codec->current_graph, GF_SG_INDEXED_INSERT); BM_SetCommandNode(com, def); inf = gf_sg_command_field_new(com); inf->pos = pos; inf->fieldIndex = field_ind; inf->fieldType = sffield.fieldType; inf->new_node = node; inf->field_ptr = &inf->new_node; gf_list_add(com_list, com); /*register*/ gf_node_register(node, def); } } else { com = gf_sg_command_new(codec->current_graph, GF_SG_INDEXED_INSERT); BM_SetCommandNode(com, def); inf = gf_sg_command_field_new(com); inf->pos = pos; inf->fieldIndex = field_ind; inf->fieldType = sffield.fieldType; sffield.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(sffield.fieldType); codec->LastError = gf_bifs_dec_sf_field(codec, bs, def, &sffield); gf_list_add(com_list, com); } return codec->LastError;}GF_Err BM_ParseRouteInsert(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list){ GF_Err e; u8 flag; GF_Command *com; 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; com = gf_sg_command_new(codec->current_graph, GF_SG_ROUTE_INSERT); com->RouteID = RouteID; if (codec->info->UseName) com->def_name = strdup( name); com->fromNodeID = gf_node_get_id(OutNode); com->fromFieldIndex = outField; com->toNodeID = gf_node_get_id(InNode); com->toFieldIndex = inField; gf_list_add(com_list, com); return codec->LastError;}GF_Err BM_ParseInsert(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list){ u8 type; type = gf_bs_read_int(bs, 2); switch (type) { case 0: return BM_ParseNodeInsert(codec, bs, com_list); case 1: return BM_ParseExtendedUpdates(codec, bs, com_list); case 2: return BM_ParseIndexInsert(codec, bs, com_list); case 3: return BM_ParseRouteInsert(codec, bs, com_list); default: return GF_NON_COMPLIANT_BITSTREAM; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -