/src/gpac/src/bifs/com_enc.c
Line | Count | Source |
1 | | /* |
2 | | * GPAC - Multimedia Framework C SDK |
3 | | * |
4 | | * Authors: Jean Le Feuvre |
5 | | * Copyright (c) Telecom ParisTech 2000-2012 |
6 | | * All rights reserved |
7 | | * |
8 | | * This file is part of GPAC / BIFS codec sub-project |
9 | | * |
10 | | * GPAC is free software; you can redistribute it and/or modify |
11 | | * it under the terms of the GNU Lesser General Public License as published by |
12 | | * the Free Software Foundation; either version 2, or (at your option) |
13 | | * any later version. |
14 | | * |
15 | | * GPAC is distributed in the hope that it will be useful, |
16 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
18 | | * GNU Lesser General Public License for more details. |
19 | | * |
20 | | * You should have received a copy of the GNU Lesser General Public |
21 | | * License along with this library; see the file COPYING. If not, write to |
22 | | * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. |
23 | | * |
24 | | */ |
25 | | |
26 | | |
27 | | #include <gpac/internal/bifs_dev.h> |
28 | | #include "quant.h" |
29 | | |
30 | | #ifndef GPAC_DISABLE_BIFS_ENC |
31 | | |
32 | | GF_Err BE_EncProtoList(GF_BifsEncoder *codec, GF_List *protoList, GF_BitStream *bs); |
33 | | |
34 | | |
35 | | void gf_bifs_enc_name(GF_BifsEncoder *codec, GF_BitStream *bs, char *name) |
36 | 0 | { |
37 | 0 | u32 i = 0; |
38 | 0 | if (!name) { |
39 | 0 | GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[BIFS] Coding IDs using names but no name is specified\n")); |
40 | 0 | i = 1; |
41 | 0 | } else { |
42 | 0 | while (name[i]) { |
43 | 0 | gf_bs_write_int(bs, name[i], 8); |
44 | 0 | i++; |
45 | 0 | } |
46 | 0 | } |
47 | 0 | gf_bs_write_int(bs, 0, 8); |
48 | 0 | GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] DEF\t\t%d\t\t%s\n", 8*i, name)); |
49 | 0 | } |
50 | | |
51 | | static GF_Err BE_XReplace(GF_BifsEncoder * codec, GF_Command *com, GF_BitStream *bs) |
52 | 0 | { |
53 | 0 | u32 i,nbBits; |
54 | 0 | GF_FieldInfo field; |
55 | 0 | GF_Err e; |
56 | 0 | GF_CommandField *inf; |
57 | 0 | if (!gf_list_count(com->command_fields)) return GF_BAD_PARAM; |
58 | 0 | inf = (GF_CommandField *)gf_list_get(com->command_fields, 0); |
59 | | |
60 | |
|
61 | 0 | gf_bs_write_int(bs, gf_node_get_id(com->node)-1, codec->info->config.NodeIDBits); |
62 | 0 | nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(com->node, GF_SG_FIELD_CODING_IN)-1); |
63 | 0 | gf_bifs_field_index_by_mode(com->node, inf->fieldIndex, GF_SG_FIELD_CODING_IN, &i); |
64 | 0 | GF_BIFS_WRITE_INT(codec, bs, i, nbBits, "field", NULL); |
65 | |
|
66 | 0 | gf_node_get_field(com->node, inf->fieldIndex, &field); |
67 | 0 | if (!gf_sg_vrml_is_sf_field(field.fieldType)) { |
68 | 0 | if ((inf->pos != -2) || com->toNodeID) { |
69 | 0 | GF_BIFS_WRITE_INT(codec, bs, 1, 1, "indexedReplacement", NULL); |
70 | 0 | if (com->toNodeID) { |
71 | 0 | GF_Node *n = gf_bifs_enc_find_node(codec, com->toNodeID); |
72 | 0 | GF_BIFS_WRITE_INT(codec, bs, 1, 1, "dynamicIndex", NULL); |
73 | 0 | GF_BIFS_WRITE_INT(codec, bs, com->toNodeID-1, codec->info->config.NodeIDBits, "idxNodeID", NULL); |
74 | 0 | nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(n, GF_SG_FIELD_CODING_DEF)-1); |
75 | 0 | gf_bifs_field_index_by_mode(n, com->toFieldIndex, GF_SG_FIELD_CODING_DEF, &i); |
76 | 0 | GF_BIFS_WRITE_INT(codec, bs, i, nbBits, "idxField", NULL); |
77 | 0 | } else { |
78 | 0 | GF_BIFS_WRITE_INT(codec, bs, 0, 1, "dynamicIndex", NULL); |
79 | 0 | if (inf->pos==-1) { |
80 | 0 | GF_BIFS_WRITE_INT(codec, bs, 3, 2, "replacementPosition", NULL); |
81 | 0 | } else if (inf->pos==0) { |
82 | 0 | GF_BIFS_WRITE_INT(codec, bs, 2, 2, "replacementPosition", NULL); |
83 | 0 | } else { |
84 | 0 | GF_BIFS_WRITE_INT(codec, bs, 0, 2, "replacementPosition", NULL); |
85 | 0 | GF_BIFS_WRITE_INT(codec, bs, inf->pos, 16, "position", NULL); |
86 | 0 | } |
87 | 0 | } |
88 | 0 | } else { |
89 | 0 | GF_BIFS_WRITE_INT(codec, bs, 0, 1, "indexedReplacement", NULL); |
90 | 0 | } |
91 | 0 | } |
92 | 0 | if (field.fieldType==GF_SG_VRML_MFNODE) { |
93 | 0 | if (com->ChildNodeTag) { |
94 | 0 | GF_Node *n; |
95 | 0 | if (com->ChildNodeTag>0) { |
96 | 0 | n = gf_node_new(codec->scene_graph, com->ChildNodeTag); |
97 | 0 | } else { |
98 | 0 | GF_Proto *proto = gf_sg_find_proto(codec->scene_graph, -com->ChildNodeTag , NULL); |
99 | 0 | if (!proto) return GF_SG_UNKNOWN_NODE; |
100 | 0 | n = gf_sg_proto_create_instance(codec->scene_graph, proto); |
101 | 0 | } |
102 | 0 | if (!n) return GF_SG_UNKNOWN_NODE; |
103 | 0 | gf_node_register(n, NULL); |
104 | |
|
105 | 0 | GF_BIFS_WRITE_INT(codec, bs, 1, 1, "childField", NULL); |
106 | |
|
107 | 0 | nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(n, GF_SG_FIELD_CODING_IN)-1); |
108 | 0 | gf_bifs_field_index_by_mode(n, com->child_field, GF_SG_FIELD_CODING_IN, &i); |
109 | 0 | GF_BIFS_WRITE_INT(codec, bs, i, nbBits, "childField", NULL); |
110 | 0 | gf_node_unregister(n, NULL); |
111 | 0 | } else { |
112 | 0 | GF_BIFS_WRITE_INT(codec, bs, 0, 1, "childField", NULL); |
113 | 0 | } |
114 | 0 | } |
115 | 0 | if (com->fromNodeID) { |
116 | 0 | GF_Node *n = gf_bifs_enc_find_node(codec, com->fromNodeID); |
117 | 0 | GF_BIFS_WRITE_INT(codec, bs, 1, 1, "valueFromNode", NULL); |
118 | |
|
119 | 0 | GF_BIFS_WRITE_INT(codec, bs, com->fromNodeID-1, codec->info->config.NodeIDBits, "sourceNodeID", NULL); |
120 | 0 | nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(n, GF_SG_FIELD_CODING_DEF)-1); |
121 | 0 | gf_bifs_field_index_by_mode(n, com->fromFieldIndex, GF_SG_FIELD_CODING_DEF, &i); |
122 | 0 | GF_BIFS_WRITE_INT(codec, bs, i, nbBits, "sourceField", NULL); |
123 | |
|
124 | 0 | return GF_OK; |
125 | 0 | } |
126 | | |
127 | 0 | GF_BIFS_WRITE_INT(codec, bs, 0, 1, "valueFromNode", NULL); |
128 | |
|
129 | 0 | field.far_ptr = inf->field_ptr; |
130 | 0 | field.fieldType = inf->fieldType; |
131 | 0 | e = gf_bifs_enc_field(codec, bs, com->node, &field); |
132 | 0 | return e; |
133 | 0 | } |
134 | | |
135 | | static GF_Err BE_MultipleIndexedReplace(GF_BifsEncoder * codec, GF_Command *com, GF_BitStream *bs) |
136 | 0 | { |
137 | 0 | u32 i,nbBits, count, maxPos, nbBitsPos; |
138 | 0 | GF_FieldInfo field; |
139 | 0 | GF_Err e; |
140 | 0 | GF_CommandField *inf; |
141 | 0 | if (!gf_list_count(com->command_fields)) return GF_OK; |
142 | 0 | inf = (GF_CommandField *)gf_list_get(com->command_fields, 0); |
143 | | |
144 | |
|
145 | 0 | gf_bs_write_int(bs, gf_node_get_id(com->node)-1, codec->info->config.NodeIDBits); |
146 | 0 | nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(com->node, GF_SG_FIELD_CODING_IN)-1); |
147 | 0 | gf_bifs_field_index_by_mode(com->node, inf->fieldIndex, GF_SG_FIELD_CODING_IN, &i); |
148 | 0 | GF_BIFS_WRITE_INT(codec, bs, i, nbBits, "field", NULL); |
149 | |
|
150 | 0 | gf_node_get_field(com->node, inf->fieldIndex, &field); |
151 | 0 | field.fieldType = inf->fieldType; |
152 | |
|
153 | 0 | count = gf_list_count(com->command_fields); |
154 | 0 | maxPos = 0; |
155 | 0 | for (i=0; i<count; i++) { |
156 | 0 | inf = (GF_CommandField *)gf_list_get(com->command_fields, i); |
157 | 0 | if (maxPos < (u32) inf->pos) maxPos = inf->pos; |
158 | 0 | } |
159 | 0 | nbBitsPos = gf_get_bit_size(maxPos); |
160 | 0 | GF_BIFS_WRITE_INT(codec, bs, nbBitsPos, 5, "nbBitsPos", NULL); |
161 | |
|
162 | 0 | nbBits = gf_get_bit_size(count); |
163 | 0 | GF_BIFS_WRITE_INT(codec, bs, nbBits, 5, "nbBits", NULL); |
164 | 0 | GF_BIFS_WRITE_INT(codec, bs, count, nbBits, "count", NULL); |
165 | |
|
166 | 0 | for (i=0; i<count; i++) { |
167 | 0 | inf = (GF_CommandField *)gf_list_get(com->command_fields, i); |
168 | 0 | GF_BIFS_WRITE_INT(codec, bs, inf->pos, nbBitsPos, "idx", NULL); |
169 | 0 | field.far_ptr = inf->field_ptr; |
170 | 0 | e = gf_bifs_enc_field(codec, bs, com->node, &field); |
171 | 0 | if (e) return e; |
172 | 0 | } |
173 | 0 | return GF_OK; |
174 | 0 | } |
175 | | |
176 | | static GF_Err BE_MultipleReplace(GF_BifsEncoder * codec, GF_Command *com, GF_BitStream *bs) |
177 | 0 | { |
178 | 0 | u32 i, j, nbBits, count, numFields, allField; |
179 | 0 | Bool use_list; |
180 | 0 | GF_FieldInfo field; |
181 | 0 | GF_Err e; |
182 | |
|
183 | 0 | gf_bs_write_int(bs, gf_node_get_id(com->node)-1, codec->info->config.NodeIDBits); |
184 | |
|
185 | 0 | count = gf_list_count(com->command_fields); |
186 | 0 | use_list = GF_TRUE; |
187 | 0 | numFields = gf_node_get_num_fields_in_mode(com->node, GF_SG_FIELD_CODING_DEF); |
188 | 0 | nbBits = gf_get_bit_size(numFields - 1); |
189 | 0 | if (count < 1+count*(1+nbBits)) use_list = GF_FALSE; |
190 | 0 | GF_BIFS_WRITE_INT(codec, bs, use_list ? 0 : 1, 1, "isMask", NULL); |
191 | |
|
192 | 0 | for (i=0; i<numFields; i++) { |
193 | 0 | GF_CommandField *inf = NULL; |
194 | 0 | gf_bifs_get_field_index(com->node, i, GF_SG_FIELD_CODING_DEF, &allField); |
195 | 0 | for (j=0; j<count; j++) { |
196 | 0 | inf = (GF_CommandField *)gf_list_get(com->command_fields, j); |
197 | 0 | if (inf->fieldIndex==allField) break; |
198 | 0 | inf = NULL; |
199 | 0 | } |
200 | 0 | if (!inf) { |
201 | 0 | if (!use_list) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "Mask", NULL); |
202 | 0 | continue; |
203 | 0 | } |
204 | | /*common case*/ |
205 | 0 | gf_node_get_field(com->node, inf->fieldIndex, &field); |
206 | 0 | if (use_list) { |
207 | | /*not end flag*/ |
208 | 0 | GF_BIFS_WRITE_INT(codec, bs, 0, 1, "end", NULL); |
209 | 0 | } else { |
210 | | /*mask flag*/ |
211 | 0 | GF_BIFS_WRITE_INT(codec, bs, 1, 1, "Mask", NULL); |
212 | 0 | } |
213 | 0 | if (use_list) GF_BIFS_WRITE_INT(codec, bs, i, nbBits, "field", (char*)field.name); |
214 | 0 | field.far_ptr = inf->field_ptr; |
215 | 0 | e = gf_bifs_enc_field(codec, bs, com->node, &field); |
216 | 0 | if (e) return e; |
217 | 0 | } |
218 | | /*end flag*/ |
219 | 0 | if (use_list) GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL); |
220 | 0 | return GF_OK; |
221 | 0 | } |
222 | | |
223 | | static GF_Err BE_GlobalQuantizer(GF_BifsEncoder * codec, GF_Command *com, GF_BitStream *bs) |
224 | 0 | { |
225 | 0 | GF_Err e; |
226 | 0 | GF_CommandField *inf; |
227 | 0 | if (!gf_list_count(com->command_fields)) return GF_OK; |
228 | 0 | inf = (GF_CommandField *)gf_list_get(com->command_fields, 0); |
229 | 0 | if (inf->new_node) ((M_QuantizationParameter *)inf->new_node)->isLocal = 0; |
230 | 0 | e = gf_bifs_enc_node(codec, inf->new_node, NDT_SFWorldNode, bs, NULL); |
231 | 0 | if (e) return e; |
232 | | |
233 | | /*reset global QP*/ |
234 | 0 | if (codec->scene_graph->global_qp) { |
235 | 0 | gf_node_unregister(codec->scene_graph->global_qp, NULL); |
236 | 0 | codec->scene_graph->global_qp = NULL; |
237 | 0 | } |
238 | 0 | codec->ActiveQP = NULL; |
239 | | |
240 | | /*no QP*/ |
241 | 0 | if (!inf->new_node) return GF_OK; |
242 | | |
243 | | /*register global QP*/ |
244 | 0 | codec->scene_graph->global_qp = inf->new_node; |
245 | 0 | gf_node_register(inf->new_node, NULL); |
246 | 0 | codec->ActiveQP = (M_QuantizationParameter *) inf->new_node; |
247 | 0 | codec->ActiveQP->isLocal = 0; |
248 | 0 | return GF_OK; |
249 | 0 | } |
250 | | |
251 | | static GF_Err BE_EncProtoDelete(GF_BifsEncoder * codec, GF_Command *com, GF_BitStream *bs) |
252 | 0 | { |
253 | 0 | u32 nbBits, i; |
254 | 0 | Bool use_list = GF_FALSE; |
255 | 0 | nbBits = gf_get_bit_size(com->del_proto_list_size); |
256 | 0 | if (nbBits+5>com->del_proto_list_size) use_list = GF_TRUE; |
257 | 0 | GF_BIFS_WRITE_INT(codec, bs, use_list, 1, "isList", NULL); |
258 | 0 | if (!use_list) { |
259 | 0 | GF_BIFS_WRITE_INT(codec, bs, nbBits, 5, "len", NULL); |
260 | 0 | GF_BIFS_WRITE_INT(codec, bs, com->del_proto_list_size, nbBits, "len", NULL); |
261 | 0 | } |
262 | 0 | for (i=0; i<com->del_proto_list_size; i++) { |
263 | 0 | if (use_list) GF_BIFS_WRITE_INT(codec, bs, 1, 1, "moreProto", NULL); |
264 | 0 | GF_BIFS_WRITE_INT(codec, bs, com->del_proto_list[i], codec->info->config.ProtoIDBits, "protoID", NULL); |
265 | 0 | } |
266 | 0 | if (use_list) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "moreProto", NULL); |
267 | 0 | return GF_OK; |
268 | 0 | } |
269 | | |
270 | | static GF_Err BE_ExtendedUpdate(GF_BifsEncoder * codec, GF_Command *com, GF_BitStream *bs) |
271 | 0 | { |
272 | 0 | GF_BIFS_WRITE_INT(codec, bs, 0, 2, "Insert", NULL); |
273 | 0 | GF_BIFS_WRITE_INT(codec, bs, 1, 2, "ExtendedUpdate", NULL); |
274 | 0 | switch (com->tag) { |
275 | 0 | case GF_SG_PROTO_INSERT: |
276 | 0 | GF_BIFS_WRITE_INT(codec, bs, 0, 8, "MultipleReplace", NULL); |
277 | 0 | return BE_EncProtoList(codec, com->new_proto_list, bs); |
278 | 0 | case GF_SG_PROTO_DELETE: |
279 | 0 | GF_BIFS_WRITE_INT(codec, bs, 1, 8, "ProtoDelete", NULL); |
280 | 0 | return BE_EncProtoDelete(codec, com, bs); |
281 | 0 | case GF_SG_PROTO_DELETE_ALL: |
282 | 0 | GF_BIFS_WRITE_INT(codec, bs, 2, 8, "DeleteAllProtos", NULL); |
283 | 0 | return GF_OK; |
284 | 0 | case GF_SG_MULTIPLE_INDEXED_REPLACE: |
285 | 0 | GF_BIFS_WRITE_INT(codec, bs, 3, 8, "MultipleReplace", NULL); |
286 | 0 | return BE_MultipleIndexedReplace(codec, com, bs); |
287 | 0 | case GF_SG_MULTIPLE_REPLACE: |
288 | 0 | GF_BIFS_WRITE_INT(codec, bs, 4, 8, "MultipleReplace", NULL); |
289 | 0 | return BE_MultipleReplace(codec, com, bs); |
290 | 0 | case GF_SG_GLOBAL_QUANTIZER: |
291 | 0 | GF_BIFS_WRITE_INT(codec, bs, 5, 8, "GlobalQuantizer", NULL); |
292 | 0 | return BE_GlobalQuantizer(codec, com, bs); |
293 | 0 | case GF_SG_NODE_DELETE_EX: |
294 | 0 | GF_BIFS_WRITE_INT(codec, bs, 6, 8, "MultipleReplace", NULL); |
295 | 0 | GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(com->node) - 1, codec->info->config.NodeIDBits, "NodeID", NULL); |
296 | 0 | return GF_OK; |
297 | 0 | case GF_SG_XREPLACE: |
298 | 0 | GF_BIFS_WRITE_INT(codec, bs, 7, 8, "XReplace", NULL); |
299 | 0 | return BE_XReplace(codec, com, bs); |
300 | 0 | default: |
301 | 0 | return GF_BAD_PARAM; |
302 | 0 | } |
303 | 0 | } |
304 | | |
305 | | /*inserts a node in a container (node.children)*/ |
306 | | GF_Err BE_NodeInsert(GF_BifsEncoder *codec, GF_Command *com, GF_BitStream *bs) |
307 | 0 | { |
308 | 0 | u32 NDT; |
309 | 0 | GF_CommandField *inf; |
310 | 0 | if (!gf_list_count(com->command_fields)) return GF_OK; |
311 | 0 | inf = (GF_CommandField *)gf_list_get(com->command_fields, 0); |
312 | |
|
313 | 0 | GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(com->node) - 1, codec->info->config.NodeIDBits, "NodeID", NULL); |
314 | |
|
315 | 0 | NDT = gf_bifs_get_child_table(com->node); |
316 | |
|
317 | 0 | switch (inf->pos) { |
318 | 0 | case 0: |
319 | 0 | GF_BIFS_WRITE_INT(codec, bs, 2, 2, "FIRST", "idx"); |
320 | 0 | break; |
321 | 0 | case -1: |
322 | 0 | GF_BIFS_WRITE_INT(codec, bs, 3, 2, "LAST", "idx"); |
323 | 0 | break; |
324 | 0 | default: |
325 | 0 | GF_BIFS_WRITE_INT(codec, bs, 0, 2, "pos", "idx"); |
326 | 0 | GF_BIFS_WRITE_INT(codec, bs, inf->pos, 8, "pos", NULL); |
327 | 0 | break; |
328 | 0 | } |
329 | 0 | return gf_bifs_enc_node(codec, inf->new_node, NDT, bs, NULL); |
330 | 0 | } |
331 | | |
332 | | GF_Err BE_IndexInsert(GF_BifsEncoder *codec, GF_Command *com, GF_BitStream *bs) |
333 | 0 | { |
334 | 0 | GF_Err e; |
335 | 0 | u32 NumBits, ind; |
336 | 0 | GF_FieldInfo field, sffield; |
337 | 0 | GF_CommandField *inf; |
338 | 0 | if (!gf_list_count(com->command_fields)) return GF_OK; |
339 | 0 | inf = (GF_CommandField *)gf_list_get(com->command_fields, 0); |
340 | |
|
341 | 0 | GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(com->node) - 1, codec->info->config.NodeIDBits, "NodeID", NULL); |
342 | | |
343 | | /*index insertion uses IN mode for field index*/ |
344 | 0 | NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(com->node, GF_SG_FIELD_CODING_IN)-1); |
345 | 0 | gf_bifs_field_index_by_mode(com->node, inf->fieldIndex, GF_SG_FIELD_CODING_IN, &ind); |
346 | 0 | GF_BIFS_WRITE_INT(codec, bs, ind, NumBits, "field", NULL); |
347 | |
|
348 | 0 | switch (inf->pos) { |
349 | 0 | case 0: |
350 | 0 | GF_BIFS_WRITE_INT(codec, bs, 2, 2, "FIRST", "idx"); |
351 | 0 | break; |
352 | 0 | case -1: |
353 | 0 | GF_BIFS_WRITE_INT(codec, bs, 3, 2, "LAST", "idx"); |
354 | 0 | break; |
355 | 0 | default: |
356 | 0 | GF_BIFS_WRITE_INT(codec, bs, 0, 2, "pos", "idx"); |
357 | 0 | GF_BIFS_WRITE_INT(codec, bs, inf->pos, 16, "pos", NULL); |
358 | 0 | break; |
359 | 0 | } |
360 | 0 | e = gf_node_get_field(com->node, inf->fieldIndex, &field); |
361 | 0 | if (e) return e; |
362 | 0 | if (gf_sg_vrml_is_sf_field(field.fieldType)) |
363 | 0 | return GF_NON_COMPLIANT_BITSTREAM; |
364 | | |
365 | 0 | memcpy(&sffield, &field, sizeof(GF_FieldInfo)); |
366 | 0 | sffield.fieldType = gf_sg_vrml_get_sf_type(field.fieldType); |
367 | 0 | sffield.far_ptr = inf->field_ptr; |
368 | | |
369 | | /*rescale the MFField and parse the SFField*/ |
370 | 0 | if (field.fieldType==GF_SG_VRML_MFNODE) { |
371 | 0 | return gf_bifs_enc_node(codec, inf->new_node, field.NDTtype, bs, com->node); |
372 | 0 | } else { |
373 | 0 | return gf_bifs_enc_sf_field(codec, bs, com->node, &sffield); |
374 | 0 | } |
375 | 0 | } |
376 | | |
377 | | |
378 | | GF_Err BE_IndexDelete(GF_BifsEncoder *codec, GF_Command *com, GF_BitStream *bs) |
379 | 0 | { |
380 | 0 | u32 NumBits, ind; |
381 | 0 | GF_Err e; |
382 | 0 | GF_CommandField *inf; |
383 | 0 | if (!gf_list_count(com->command_fields)) return GF_OK; |
384 | 0 | inf = (GF_CommandField *)gf_list_get(com->command_fields, 0); |
385 | |
|
386 | 0 | GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(com->node) - 1, codec->info->config.NodeIDBits, "NodeID", NULL); |
387 | |
|
388 | 0 | NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(com->node, GF_SG_FIELD_CODING_IN) - 1); |
389 | 0 | e = gf_bifs_field_index_by_mode(com->node, inf->fieldIndex, GF_SG_FIELD_CODING_IN, &ind); |
390 | 0 | if (e) return e; |
391 | 0 | GF_BIFS_WRITE_INT(codec, bs, ind, NumBits, "field", NULL); |
392 | |
|
393 | 0 | switch (inf->pos) { |
394 | 0 | case 0: |
395 | 0 | GF_BIFS_WRITE_INT(codec, bs, 2, 2, "FIRST", "idw"); |
396 | 0 | break; |
397 | 0 | case -1: |
398 | 0 | GF_BIFS_WRITE_INT(codec, bs, 3, 2, "LAST", "idx"); |
399 | 0 | break; |
400 | 0 | default: |
401 | 0 | GF_BIFS_WRITE_INT(codec, bs, 0, 2, "pos", "idx"); |
402 | 0 | GF_BIFS_WRITE_INT(codec, bs, inf->pos, 16, "pos", NULL); |
403 | 0 | break; |
404 | 0 | } |
405 | 0 | return GF_OK; |
406 | 0 | } |
407 | | |
408 | | |
409 | | GF_Err BE_NodeReplace(GF_BifsEncoder *codec, GF_Command *com, GF_BitStream *bs) |
410 | 0 | { |
411 | 0 | GF_Node *new_node = NULL; |
412 | 0 | if (gf_list_count(com->command_fields)) { |
413 | 0 | GF_CommandField *inf = (GF_CommandField *)gf_list_get(com->command_fields, 0); |
414 | 0 | if (inf) new_node = inf->new_node; |
415 | 0 | } |
416 | 0 | GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(com->node) - 1, codec->info->config.NodeIDBits, "NodeID", NULL); |
417 | 0 | return gf_bifs_enc_node(codec, new_node, NDT_SFWorldNode, bs, NULL); |
418 | 0 | } |
419 | | |
420 | | GF_Err BE_FieldReplace(GF_BifsEncoder *codec, GF_Command *com, GF_BitStream *bs) |
421 | 0 | { |
422 | 0 | GF_Err e; |
423 | 0 | u32 ind, NumBits; |
424 | 0 | GF_FieldInfo field; |
425 | 0 | GF_CommandField *inf; |
426 | 0 | if (!gf_list_count(com->command_fields)) return GF_OK; |
427 | 0 | inf = (GF_CommandField *)gf_list_get(com->command_fields, 0); |
428 | |
|
429 | 0 | GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(com->node) - 1, codec->info->config.NodeIDBits, "NodeID", NULL); |
430 | |
|
431 | 0 | NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(com->node, GF_SG_FIELD_CODING_IN)-1); |
432 | 0 | gf_bifs_field_index_by_mode(com->node, inf->fieldIndex, GF_SG_FIELD_CODING_IN, &ind); |
433 | 0 | GF_BIFS_WRITE_INT(codec, bs, ind, NumBits, "field", NULL); |
434 | |
|
435 | 0 | e = gf_node_get_field(com->node, inf->fieldIndex, &field); |
436 | 0 | if (e) return e; |
437 | 0 | field.far_ptr = inf->field_ptr; |
438 | | |
439 | | /* Warning: To be changed when proper solution is found */ |
440 | 0 | if (gf_sg_vrml_get_sf_type(field.fieldType) == GF_SG_VRML_SFSCRIPT) codec->is_encoding_command = GF_TRUE; |
441 | |
|
442 | 0 | e = gf_bifs_enc_field(codec, bs, com->node, &field); |
443 | |
|
444 | 0 | codec->is_encoding_command = GF_FALSE; |
445 | 0 | return e; |
446 | 0 | } |
447 | | |
448 | | GF_Err BE_IndexFieldReplace(GF_BifsEncoder *codec, GF_Command *com, GF_BitStream *bs) |
449 | 0 | { |
450 | 0 | u32 ind, NumBits; |
451 | 0 | GF_Err e; |
452 | 0 | GF_FieldInfo field, sffield; |
453 | 0 | GF_CommandField *inf; |
454 | 0 | if (!gf_list_count(com->command_fields)) return GF_OK; |
455 | 0 | inf = (GF_CommandField *)gf_list_get(com->command_fields, 0); |
456 | |
|
457 | 0 | GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(com->node) - 1, codec->info->config.NodeIDBits, "NodeID", NULL); |
458 | 0 | NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(com->node, GF_SG_FIELD_CODING_IN)-1); |
459 | 0 | gf_bifs_field_index_by_mode(com->node, inf->fieldIndex, GF_SG_FIELD_CODING_IN, &ind); |
460 | 0 | GF_BIFS_WRITE_INT(codec, bs, ind, NumBits, "field", NULL); |
461 | |
|
462 | 0 | e = gf_node_get_field(com->node, inf->fieldIndex, &field); |
463 | 0 | if (e) return e; |
464 | 0 | if (gf_sg_vrml_is_sf_field(field.fieldType)) |
465 | 0 | return GF_NON_COMPLIANT_BITSTREAM; |
466 | | |
467 | 0 | switch (inf->pos) { |
468 | 0 | case 0: |
469 | 0 | GF_BIFS_WRITE_INT(codec, bs, 2, 2, "FIRST", "idx"); |
470 | 0 | break; |
471 | 0 | case -1: |
472 | 0 | GF_BIFS_WRITE_INT(codec, bs, 3, 2, "LAST", "idx"); |
473 | 0 | break; |
474 | 0 | default: |
475 | 0 | GF_BIFS_WRITE_INT(codec, bs, 0, 2, "pos", "idx"); |
476 | 0 | GF_BIFS_WRITE_INT(codec, bs, inf->pos, 16, "pos", NULL); |
477 | 0 | break; |
478 | 0 | } |
479 | | |
480 | 0 | if (field.fieldType == GF_SG_VRML_MFNODE) { |
481 | 0 | e = gf_bifs_enc_node(codec, inf->new_node, field.NDTtype, bs, com->node); |
482 | 0 | } else { |
483 | 0 | memcpy(&sffield, &field, sizeof(GF_FieldInfo)); |
484 | 0 | sffield.fieldType = gf_sg_vrml_get_sf_type(field.fieldType); |
485 | 0 | sffield.far_ptr = inf->field_ptr; |
486 | 0 | e = gf_bifs_enc_sf_field(codec, bs, com->node, &sffield); |
487 | 0 | } |
488 | 0 | return e; |
489 | 0 | } |
490 | | |
491 | | GF_Err BE_RouteReplace(GF_BifsEncoder *codec, GF_Command *com, GF_BitStream *bs, Bool isInsert) |
492 | 0 | { |
493 | 0 | GF_Err e; |
494 | 0 | GF_Node *n; |
495 | 0 | u32 numBits, ind; |
496 | |
|
497 | 0 | if (isInsert) { |
498 | 0 | GF_BIFS_WRITE_INT(codec, bs, com->RouteID ? 1 : 0, 1, "isDEF", NULL); |
499 | 0 | if (com->RouteID) { |
500 | 0 | GF_BIFS_WRITE_INT(codec, bs, com->RouteID-1, codec->info->config.RouteIDBits, "RouteID", NULL); |
501 | 0 | if (codec->UseName) gf_bifs_enc_name(codec, bs, com->def_name); |
502 | 0 | } |
503 | 0 | } else { |
504 | 0 | GF_BIFS_WRITE_INT(codec, bs, com->RouteID - 1, codec->info->config.RouteIDBits, "RouteID", NULL); |
505 | 0 | } |
506 | | |
507 | | /*origin*/ |
508 | 0 | GF_BIFS_WRITE_INT(codec, bs, com->fromNodeID - 1, codec->info->config.NodeIDBits, "outNodeID", NULL); |
509 | 0 | n = gf_bifs_enc_find_node(codec, com->fromNodeID); |
510 | 0 | numBits = gf_node_get_num_fields_in_mode(n, GF_SG_FIELD_CODING_OUT) - 1; |
511 | 0 | numBits = gf_get_bit_size(numBits); |
512 | 0 | e = gf_bifs_field_index_by_mode(n, com->fromFieldIndex, GF_SG_FIELD_CODING_OUT, &ind); |
513 | 0 | if (e) return e; |
514 | 0 | GF_BIFS_WRITE_INT(codec, bs, ind, numBits, "outField", NULL); |
515 | | |
516 | | /*target*/ |
517 | 0 | GF_BIFS_WRITE_INT(codec, bs, com->toNodeID - 1, codec->info->config.NodeIDBits, "inNodeID", NULL); |
518 | 0 | n = gf_bifs_enc_find_node(codec, com->toNodeID); |
519 | 0 | numBits = gf_node_get_num_fields_in_mode(n, GF_SG_FIELD_CODING_IN) - 1; |
520 | 0 | numBits = gf_get_bit_size(numBits); |
521 | 0 | e = gf_bifs_field_index_by_mode(n, com->toFieldIndex, GF_SG_FIELD_CODING_IN, &ind); |
522 | 0 | GF_BIFS_WRITE_INT(codec, bs, ind, numBits, "inField", NULL); |
523 | 0 | return e; |
524 | 0 | } |
525 | | |
526 | | |
527 | | GF_Err BE_EncProtoList(GF_BifsEncoder *codec, GF_List *protoList, GF_BitStream *bs) |
528 | 0 | { |
529 | 0 | u8 useQuant, useAnim; |
530 | 0 | u32 i, j, nbRoutes, nbBits, numProtos, numFields, count; |
531 | 0 | GF_Node *node; |
532 | 0 | GF_ProtoFieldInterface *proto_field; |
533 | 0 | GF_Proto *proto, *prev_proto; |
534 | 0 | GF_Route *r; |
535 | 0 | GF_Err e; |
536 | 0 | GF_SceneGraph *rootSG; |
537 | 0 | GF_FieldInfo field; |
538 | |
|
539 | 0 | e = GF_OK; |
540 | 0 | if (!protoList || !gf_list_count(protoList)) { |
541 | 0 | GF_BIFS_WRITE_INT(codec, bs, 0, 1, "moreProto", NULL); |
542 | 0 | return GF_OK; |
543 | 0 | } |
544 | 0 | if (!codec->info->config.ProtoIDBits) |
545 | 0 | return GF_NON_COMPLIANT_BITSTREAM; |
546 | | |
547 | | /*store state*/ |
548 | 0 | rootSG = codec->current_proto_graph; |
549 | 0 | prev_proto = codec->encoding_proto; |
550 | |
|
551 | 0 | numProtos = gf_list_count(protoList); |
552 | 0 | for (i=0; i<numProtos; i++) { |
553 | 0 | proto = (GF_Proto*)gf_list_get(protoList, i); |
554 | 0 | useQuant = useAnim = 0; |
555 | | /*set current proto state*/ |
556 | 0 | codec->encoding_proto = proto; |
557 | 0 | codec->current_proto_graph = proto->sub_graph; |
558 | |
|
559 | 0 | GF_BIFS_WRITE_INT(codec, bs, 1, 1, "moreProto", NULL); |
560 | | |
561 | | /*1- proto interface declaration*/ |
562 | 0 | GF_BIFS_WRITE_INT(codec, bs, proto->ID, codec->info->config.ProtoIDBits, "protoID", NULL); |
563 | |
|
564 | 0 | if (codec->UseName) gf_bifs_enc_name(codec, bs, proto->Name); |
565 | |
|
566 | 0 | numFields = gf_list_count(proto->proto_fields); |
567 | 0 | for (j=0; j<numFields; j++) { |
568 | 0 | proto_field = (GF_ProtoFieldInterface*)gf_list_get(proto->proto_fields, j); |
569 | |
|
570 | 0 | GF_BIFS_WRITE_INT(codec, bs, 1, 1, "moreField", NULL); |
571 | 0 | GF_BIFS_WRITE_INT(codec, bs, proto_field->EventType, 2, "eventType", NULL); |
572 | 0 | GF_BIFS_WRITE_INT(codec, bs, proto_field->FieldType, 6, "fieldType", NULL); |
573 | |
|
574 | 0 | if (codec->UseName) gf_bifs_enc_name(codec, bs, proto_field->FieldName); |
575 | 0 | switch (proto_field->EventType) { |
576 | 0 | case GF_SG_EVENT_EXPOSED_FIELD: |
577 | 0 | case GF_SG_EVENT_FIELD: |
578 | 0 | gf_sg_proto_field_get_field(proto_field, &field); |
579 | 0 | if (gf_sg_vrml_is_sf_field(field.fieldType)) { |
580 | 0 | e = gf_bifs_enc_sf_field(codec, bs, NULL, &field); |
581 | 0 | } else { |
582 | 0 | if (codec->info->config.UsePredictiveMFField) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "usePredictive", NULL); |
583 | 0 | e = gf_bifs_enc_mf_field(codec, bs, NULL, &field); |
584 | 0 | } |
585 | 0 | if (e) goto exit; |
586 | 0 | break; |
587 | 0 | } |
588 | 0 | if (proto_field->QP_Type) useQuant = 1; |
589 | 0 | if (proto_field->Anim_Type) useAnim = 1; |
590 | 0 | } |
591 | 0 | GF_BIFS_WRITE_INT(codec, bs, 0, 1, "moreField", NULL); |
592 | |
|
593 | 0 | GF_BIFS_WRITE_INT(codec, bs, proto->ExternProto.count ? 1 : 0, 1, "externProto", NULL); |
594 | | /*externProto*/ |
595 | 0 | if (proto->ExternProto.count) { |
596 | 0 | memset(&field, 0, sizeof(GF_FieldInfo)); |
597 | 0 | field.far_ptr = &proto->ExternProto; |
598 | 0 | field.fieldType = GF_SG_VRML_MFURL; |
599 | 0 | field.name = "ExternProto"; |
600 | |
|
601 | 0 | if (codec->info->config.UsePredictiveMFField) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "usePredictive", NULL); |
602 | 0 | e = gf_bifs_enc_mf_field(codec, bs, NULL, &field); |
603 | 0 | if (e) goto exit; |
604 | 0 | } else { |
605 | | /*encode sub-proto list*/ |
606 | 0 | e = BE_EncProtoList(codec, proto->sub_graph->protos, bs); |
607 | 0 | if (e) goto exit; |
608 | | |
609 | 0 | count = gf_list_count(proto->node_code); |
610 | | /*BIFS cannot encode empty protos ! We therefore encode a NULL node instead*/ |
611 | 0 | if (!count) { |
612 | 0 | gf_bifs_enc_node(codec, NULL, NDT_SFWorldNode, bs, NULL); |
613 | 0 | GF_BIFS_WRITE_INT(codec, bs, 0, 1, "moreNodes", NULL); |
614 | 0 | } else { |
615 | 0 | for (j=0; j<count; j++) { |
616 | | /*parse all nodes in SFWorldNode table*/ |
617 | 0 | node = (GF_Node*)gf_list_get(proto->node_code, j); |
618 | 0 | e = gf_bifs_enc_node(codec, node, NDT_SFWorldNode, bs, NULL); |
619 | 0 | if (e) goto exit; |
620 | 0 | GF_BIFS_WRITE_INT(codec, bs, (j+1==count) ? 0 : 1, 1, "moreNodes", NULL); |
621 | 0 | } |
622 | 0 | } |
623 | | |
624 | | /*encode routes routes*/ |
625 | 0 | nbRoutes = count = gf_list_count(proto->sub_graph->Routes); |
626 | 0 | for (j=0; j<count; j++) { |
627 | 0 | r = (GF_Route*)gf_list_get(proto->sub_graph->Routes, j); |
628 | 0 | if (r->IS_route) nbRoutes--; |
629 | 0 | } |
630 | |
|
631 | 0 | GF_BIFS_WRITE_INT(codec, bs, nbRoutes ? 1 : 0, 1, "hasRoute", NULL); |
632 | 0 | if (nbRoutes) { |
633 | 0 | nbBits = gf_get_bit_size(nbRoutes); |
634 | 0 | if (nbBits + 5 > nbRoutes) { |
635 | 0 | GF_BIFS_WRITE_INT(codec, bs, 1, 1, "isList", NULL); |
636 | | /*list*/ |
637 | 0 | for (j=0; j<count; j++) { |
638 | 0 | r = (GF_Route*)gf_list_get(proto->sub_graph->Routes, j); |
639 | 0 | if (r->IS_route) continue; |
640 | 0 | e = gf_bifs_enc_route(codec, r, bs); |
641 | 0 | if (e) goto exit; |
642 | 0 | nbRoutes--; |
643 | 0 | GF_BIFS_WRITE_INT(codec, bs, nbRoutes ? 1 : 0, 1, "moreRoute", NULL); |
644 | 0 | } |
645 | 0 | } else { |
646 | 0 | GF_BIFS_WRITE_INT(codec, bs, 0, 1, "isList", NULL); |
647 | 0 | GF_BIFS_WRITE_INT(codec, bs, nbBits, 5, "nbBits", NULL); |
648 | 0 | GF_BIFS_WRITE_INT(codec, bs, nbRoutes, nbBits, "length", NULL); |
649 | 0 | for (j=0; j<count; j++) { |
650 | 0 | r = (GF_Route*)gf_list_get(proto->sub_graph->Routes, j); |
651 | 0 | if (r->IS_route) continue; |
652 | 0 | e = gf_bifs_enc_route(codec, r, bs); |
653 | 0 | if (e) goto exit; |
654 | 0 | } |
655 | 0 | } |
656 | 0 | } |
657 | 0 | } |
658 | | |
659 | | /*anim and Quantization stuff*/ |
660 | 0 | GF_BIFS_WRITE_INT(codec, bs, useQuant, 1, "useQuant", NULL); |
661 | 0 | GF_BIFS_WRITE_INT(codec, bs, useAnim, 1, "useAnim", NULL); |
662 | |
|
663 | 0 | if (!useAnim && !useQuant) continue; |
664 | | |
665 | 0 | count = gf_sg_proto_get_field_count(proto); |
666 | 0 | for (j=0; j<count; j++) { |
667 | 0 | proto_field = gf_sg_proto_field_find(proto, j); |
668 | 0 | gf_sg_proto_field_get_field(proto_field, &field); |
669 | | |
670 | | /*quant*/ |
671 | 0 | if (useQuant && ( (field.eventType == GF_SG_EVENT_FIELD) || (field.eventType == GF_SG_EVENT_EXPOSED_FIELD) )) { |
672 | 0 | GF_BIFS_WRITE_INT(codec, bs, proto_field->QP_Type, 4, "QPType", NULL); |
673 | 0 | if (proto_field->QP_Type==QC_LINEAR_SCALAR) GF_BIFS_WRITE_INT(codec, bs, proto_field->NumBits, 5, "nbBits", NULL); |
674 | 0 | GF_BIFS_WRITE_INT(codec, bs, proto_field->hasMinMax, 1, "hasMinMax", NULL); |
675 | 0 | if (proto_field->hasMinMax) { |
676 | 0 | field.fieldType = gf_sg_vrml_get_sf_type(field.fieldType); |
677 | 0 | switch (field.fieldType) { |
678 | 0 | case GF_SG_VRML_SFINT32: |
679 | 0 | case GF_SG_VRML_SFTIME: |
680 | 0 | break; |
681 | 0 | default: |
682 | 0 | field.fieldType = GF_SG_VRML_SFFLOAT; |
683 | 0 | break; |
684 | 0 | } |
685 | 0 | field.name = "QPMinValue"; |
686 | 0 | field.far_ptr = proto_field->qp_min_value; |
687 | 0 | gf_bifs_enc_sf_field(codec, bs, NULL, &field); |
688 | |
|
689 | 0 | field.name = "QPMaxValue"; |
690 | 0 | field.far_ptr = proto_field->qp_max_value; |
691 | 0 | gf_bifs_enc_sf_field(codec, bs, NULL, &field); |
692 | 0 | } |
693 | 0 | } |
694 | | |
695 | | /*anim - not supported yet*/ |
696 | 0 | if (useAnim && ( (field.eventType == GF_SG_EVENT_IN) || (field.eventType == GF_SG_EVENT_EXPOSED_FIELD) )) { |
697 | 0 | e = GF_NOT_SUPPORTED; |
698 | 0 | goto exit; |
699 | 0 | } |
700 | 0 | } |
701 | 0 | } |
702 | 0 | GF_BIFS_WRITE_INT(codec, bs, 0, 1, "moreProto", NULL); |
703 | |
|
704 | 0 | exit: |
705 | | /*restore scene graph state*/ |
706 | 0 | codec->encoding_proto = prev_proto; |
707 | 0 | codec->current_proto_graph = rootSG; |
708 | 0 | return e; |
709 | 0 | } |
710 | | |
711 | | |
712 | | |
713 | | GF_Err gf_bifs_enc_route(GF_BifsEncoder *codec, GF_Route *r, GF_BitStream *bs) |
714 | 0 | { |
715 | 0 | GF_Err e; |
716 | 0 | u32 numBits, ind; |
717 | |
|
718 | 0 | if (!r) return GF_BAD_PARAM; |
719 | | |
720 | 0 | GF_BIFS_WRITE_INT(codec, bs, r->ID ? 1: 0, 1, "isDEF", NULL); |
721 | | /*def'ed route*/ |
722 | 0 | if (r->ID) { |
723 | 0 | GF_BIFS_WRITE_INT(codec, bs, r->ID-1, codec->info->config.RouteIDBits, "routeID", NULL); |
724 | 0 | if (codec->UseName) gf_bifs_enc_name(codec, bs, r->name); |
725 | 0 | } |
726 | | /*origin*/ |
727 | 0 | GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(r->FromNode) - 1, codec->info->config.NodeIDBits, "outNodeID", NULL); |
728 | 0 | numBits = gf_node_get_num_fields_in_mode(r->FromNode, GF_SG_FIELD_CODING_OUT) - 1; |
729 | 0 | numBits = gf_get_bit_size(numBits); |
730 | 0 | e = gf_bifs_field_index_by_mode(r->FromNode, r->FromField.fieldIndex, GF_SG_FIELD_CODING_OUT, &ind); |
731 | 0 | if (e) return e; |
732 | 0 | GF_BIFS_WRITE_INT(codec, bs, ind, numBits, "outField", NULL); |
733 | | |
734 | | /*target*/ |
735 | 0 | GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(r->ToNode) - 1, codec->info->config.NodeIDBits, "inNodeID", NULL); |
736 | 0 | numBits = gf_node_get_num_fields_in_mode(r->ToNode, GF_SG_FIELD_CODING_IN) - 1; |
737 | 0 | numBits = gf_get_bit_size(numBits); |
738 | 0 | e = gf_bifs_field_index_by_mode(r->ToNode, r->ToField.fieldIndex, GF_SG_FIELD_CODING_IN, &ind); |
739 | 0 | GF_BIFS_WRITE_INT(codec, bs, ind, numBits, "inField", NULL); |
740 | 0 | return e; |
741 | 0 | } |
742 | | |
743 | | GF_Err BE_SceneReplaceEx(GF_BifsEncoder *codec, GF_Command *com, GF_BitStream *bs, GF_List *routes) |
744 | 0 | { |
745 | 0 | u32 i, nbR, nbBits; |
746 | 0 | GF_Err e; |
747 | | |
748 | | /*reserved*/ |
749 | 0 | GF_BIFS_WRITE_INT(codec, bs, 0, 6, "reserved", NULL); |
750 | 0 | GF_BIFS_WRITE_INT(codec, bs, codec->UseName ? 1 : 0, 1, "useName", NULL); |
751 | |
|
752 | 0 | if (gf_list_count(com->new_proto_list)) { |
753 | 0 | e = BE_EncProtoList(codec, com->new_proto_list, bs); |
754 | 0 | if (e) goto exit; |
755 | 0 | } else { |
756 | 0 | e = BE_EncProtoList(codec, com->in_scene->protos, bs); |
757 | 0 | if (e) goto exit; |
758 | 0 | } |
759 | | |
760 | | /*NULL root is valid for ProtoLibraries*/ |
761 | 0 | e = gf_bifs_enc_node(codec, com->node, NDT_SFTopNode, bs, NULL); |
762 | 0 | if (e || !gf_list_count(routes) ) { |
763 | 0 | GF_BIFS_WRITE_INT(codec, bs, 0, 1, "hasRoute", NULL); |
764 | 0 | return codec->LastError = e; |
765 | 0 | } |
766 | 0 | GF_BIFS_WRITE_INT(codec, bs, 1, 1, "hasRoute", NULL); |
767 | 0 | nbR = gf_list_count(routes); |
768 | 0 | nbBits = gf_get_bit_size(nbR); |
769 | 0 | if (nbBits + 5 > nbR) { |
770 | 0 | GF_BIFS_WRITE_INT(codec, bs, 1, 1, "isList", NULL); |
771 | | /*list*/ |
772 | 0 | for (i=0; i<nbR; i++) { |
773 | 0 | e = gf_bifs_enc_route(codec, (GF_Route*)gf_list_get(routes, i), bs); |
774 | 0 | if (e) goto exit; |
775 | 0 | GF_BIFS_WRITE_INT(codec, bs, (i+1==nbR) ? 0 : 1, 1, "moreRoute", NULL); |
776 | 0 | } |
777 | 0 | } else { |
778 | 0 | GF_BIFS_WRITE_INT(codec, bs, 0, 1, "isList", NULL); |
779 | 0 | GF_BIFS_WRITE_INT(codec, bs, nbBits, 5, "nbBits", NULL); |
780 | 0 | GF_BIFS_WRITE_INT(codec, bs, nbR, nbBits, "nbRoutes", NULL); |
781 | 0 | for (i=0; i<nbR; i++) { |
782 | 0 | e = gf_bifs_enc_route(codec, (GF_Route*)gf_list_get(routes, i), bs); |
783 | 0 | if (e) goto exit; |
784 | 0 | } |
785 | 0 | } |
786 | | |
787 | 0 | exit: |
788 | 0 | return codec->LastError = e; |
789 | 0 | } |
790 | | |
791 | | |
792 | | GF_Err BE_SceneReplace(GF_BifsEncoder *codec, GF_SceneGraph *graph, GF_BitStream *bs) |
793 | 0 | { |
794 | 0 | u32 i, nbR, nbBits; |
795 | 0 | GF_Err e; |
796 | | |
797 | | /*reserved*/ |
798 | 0 | GF_BIFS_WRITE_INT(codec, bs, 0, 6, "reserved", NULL); |
799 | 0 | GF_BIFS_WRITE_INT(codec, bs, codec->UseName ? 1 : 0, 1, "useName", NULL); |
800 | | |
801 | | /*assign current graph*/ |
802 | 0 | codec->scene_graph = graph; |
803 | |
|
804 | 0 | e = BE_EncProtoList(codec, codec->scene_graph ? codec->scene_graph->protos : NULL, bs); |
805 | 0 | if (e) goto exit; |
806 | | |
807 | | /*NULL root is valid for ProtoLibraries*/ |
808 | 0 | e = gf_bifs_enc_node(codec, graph ? graph->RootNode : NULL, NDT_SFTopNode, bs, NULL); |
809 | 0 | if (e || !graph || !gf_list_count(graph->Routes) ) { |
810 | 0 | GF_BIFS_WRITE_INT(codec, bs, 0, 1, "hasRoute", NULL); |
811 | 0 | return codec->LastError = e; |
812 | 0 | } |
813 | 0 | GF_BIFS_WRITE_INT(codec, bs, 1, 1, "hasRoute", NULL); |
814 | 0 | nbR = gf_list_count(graph->Routes); |
815 | 0 | nbBits = gf_get_bit_size(nbR); |
816 | 0 | if (nbBits + 5 > nbR) { |
817 | 0 | GF_BIFS_WRITE_INT(codec, bs, 1, 1, "isList", NULL); |
818 | | /*list*/ |
819 | 0 | for (i=0; i<nbR; i++) { |
820 | 0 | e = gf_bifs_enc_route(codec, (GF_Route*)gf_list_get(graph->Routes, i), bs); |
821 | 0 | if (e) goto exit; |
822 | 0 | GF_BIFS_WRITE_INT(codec, bs, (i+1==nbR) ? 0 : 1, 1, "moreRoute", NULL); |
823 | 0 | } |
824 | 0 | } else { |
825 | 0 | GF_BIFS_WRITE_INT(codec, bs, 0, 1, "isList", NULL); |
826 | 0 | GF_BIFS_WRITE_INT(codec, bs, nbBits, 5, "nbBits", NULL); |
827 | 0 | GF_BIFS_WRITE_INT(codec, bs, nbR, nbBits, "nbRoutes", NULL); |
828 | 0 | for (i=0; i<nbR; i++) { |
829 | 0 | e = gf_bifs_enc_route(codec, (GF_Route*)gf_list_get(graph->Routes, i), bs); |
830 | 0 | if (e) goto exit; |
831 | 0 | } |
832 | 0 | } |
833 | | |
834 | 0 | exit: |
835 | 0 | return codec->LastError = e; |
836 | 0 | } |
837 | | |
838 | | |
839 | | GF_Err gf_bifs_enc_commands(GF_BifsEncoder *codec, GF_List *comList, GF_BitStream *bs) |
840 | 0 | { |
841 | 0 | u32 i; |
842 | 0 | u32 count; |
843 | 0 | GF_List *routes; |
844 | 0 | GF_Err e = GF_OK; |
845 | |
|
846 | 0 | routes = NULL; |
847 | |
|
848 | 0 | codec->LastError = GF_OK; |
849 | 0 | count = gf_list_count(comList); |
850 | |
|
851 | 0 | for (i=0; i<count; i++) { |
852 | 0 | GF_Command *com = (GF_Command*)gf_list_get(comList, i); |
853 | 0 | switch (com->tag) { |
854 | 0 | case GF_SG_SCENE_REPLACE: |
855 | 0 | { |
856 | | /*reset node context*/ |
857 | 0 | while (gf_list_count(codec->encoded_nodes)) gf_list_rem(codec->encoded_nodes, 0); |
858 | 0 | GF_BIFS_WRITE_INT(codec, bs, 3, 2, "SceneReplace", NULL); |
859 | |
|
860 | 0 | if (!com->aggregated) { |
861 | 0 | routes = gf_list_new(); |
862 | | /*now the trick: get all following InsertRoutes and convert as routes*/ |
863 | 0 | for (; i<count-1; i++) { |
864 | 0 | GF_Route *r; |
865 | 0 | GF_Command *rcom = (GF_Command*)gf_list_get(comList, i+1); |
866 | 0 | if (rcom->tag!=GF_SG_ROUTE_INSERT) break; |
867 | 0 | GF_SAFEALLOC(r, GF_Route); |
868 | 0 | if (!r) { |
869 | 0 | GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[BIFS] Cannot allocate route\n")); |
870 | 0 | continue; |
871 | 0 | } |
872 | 0 | r->FromField.fieldIndex = rcom->fromFieldIndex; |
873 | 0 | r->FromNode = gf_sg_find_node(codec->scene_graph, rcom->fromNodeID); |
874 | 0 | r->ToField.fieldIndex = rcom->toFieldIndex; |
875 | 0 | r->ToNode = gf_sg_find_node(codec->scene_graph, rcom->toNodeID); |
876 | 0 | r->ID = rcom->RouteID; |
877 | 0 | r->name = rcom->def_name; |
878 | 0 | gf_list_add(routes, r); |
879 | 0 | } |
880 | 0 | e = BE_SceneReplaceEx(codec, com, bs, routes); |
881 | |
|
882 | 0 | while (gf_list_count(routes)) { |
883 | 0 | GF_Route *r = (GF_Route*)gf_list_get(routes, 0); |
884 | 0 | gf_list_rem(routes, 0); |
885 | 0 | gf_free(r); |
886 | 0 | } |
887 | 0 | gf_list_del(routes); |
888 | 0 | } else { |
889 | 0 | e = BE_SceneReplaceEx(codec, com, bs, codec->scene_graph->Routes); |
890 | 0 | } |
891 | 0 | } |
892 | 0 | break; |
893 | | /*replace commands*/ |
894 | 0 | case GF_SG_NODE_REPLACE: |
895 | 0 | GF_BIFS_WRITE_INT(codec, bs, 2, 2, "Replace", NULL); |
896 | 0 | GF_BIFS_WRITE_INT(codec, bs, 0, 2, "Node", NULL); |
897 | 0 | e = BE_NodeReplace(codec, com, bs); |
898 | 0 | break; |
899 | 0 | case GF_SG_FIELD_REPLACE: |
900 | 0 | GF_BIFS_WRITE_INT(codec, bs, 2, 2, "Replace", NULL); |
901 | 0 | GF_BIFS_WRITE_INT(codec, bs, 1, 2, "Field", NULL); |
902 | 0 | e = BE_FieldReplace(codec, com, bs); |
903 | 0 | break; |
904 | 0 | case GF_SG_INDEXED_REPLACE: |
905 | 0 | GF_BIFS_WRITE_INT(codec, bs, 2, 2, "Replace", NULL); |
906 | 0 | GF_BIFS_WRITE_INT(codec, bs, 2, 2, "FieldIndex", NULL); |
907 | 0 | e = BE_IndexFieldReplace(codec, com, bs); |
908 | 0 | break; |
909 | 0 | case GF_SG_ROUTE_REPLACE: |
910 | 0 | GF_BIFS_WRITE_INT(codec, bs, 2, 2, "Replace", NULL); |
911 | 0 | GF_BIFS_WRITE_INT(codec, bs, 3, 2, "Route", NULL); |
912 | 0 | e = BE_RouteReplace(codec, com, bs, GF_FALSE); |
913 | 0 | break; |
914 | 0 | case GF_SG_NODE_INSERT: |
915 | 0 | GF_BIFS_WRITE_INT(codec, bs, 0, 2, "Insert", NULL); |
916 | 0 | GF_BIFS_WRITE_INT(codec, bs, 0, 2, "Node", NULL); |
917 | 0 | e = BE_NodeInsert(codec, com, bs); |
918 | 0 | break; |
919 | 0 | case GF_SG_INDEXED_INSERT: |
920 | 0 | GF_BIFS_WRITE_INT(codec, bs, 0, 2, "Insert", NULL); |
921 | 0 | GF_BIFS_WRITE_INT(codec, bs, 2, 2, "FieldIndex", NULL); |
922 | 0 | e = BE_IndexInsert(codec, com, bs); |
923 | 0 | break; |
924 | 0 | case GF_SG_ROUTE_INSERT: |
925 | 0 | GF_BIFS_WRITE_INT(codec, bs, 0, 2, "Insert", NULL); |
926 | 0 | GF_BIFS_WRITE_INT(codec, bs, 3, 2, "Route", NULL); |
927 | 0 | e = BE_RouteReplace(codec, com, bs, GF_TRUE); |
928 | 0 | break; |
929 | 0 | case GF_SG_NODE_DELETE: |
930 | 0 | GF_BIFS_WRITE_INT(codec, bs, 1, 2, "Delete", NULL); |
931 | 0 | GF_BIFS_WRITE_INT(codec, bs, 0, 2, "Node", NULL); |
932 | 0 | GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(com->node) - 1, codec->info->config.NodeIDBits, "NodeID", NULL); |
933 | 0 | break; |
934 | 0 | case GF_SG_INDEXED_DELETE: |
935 | 0 | GF_BIFS_WRITE_INT(codec, bs, 1, 2, "Delete", NULL); |
936 | 0 | GF_BIFS_WRITE_INT(codec, bs, 2, 2, "FieldIndex", NULL); |
937 | 0 | e = BE_IndexDelete(codec, com, bs); |
938 | 0 | break; |
939 | 0 | case GF_SG_ROUTE_DELETE: |
940 | 0 | GF_BIFS_WRITE_INT(codec, bs, 1, 2, "Delete", NULL); |
941 | 0 | GF_BIFS_WRITE_INT(codec, bs, 3, 2, "Route", NULL); |
942 | 0 | GF_BIFS_WRITE_INT(codec, bs, com->RouteID - 1, codec->info->config.RouteIDBits, "RouteID", NULL); |
943 | 0 | break; |
944 | | |
945 | 0 | default: |
946 | 0 | e = BE_ExtendedUpdate(codec, com, bs); |
947 | 0 | break; |
948 | 0 | } |
949 | 0 | if (e) break; |
950 | | |
951 | 0 | GF_BIFS_WRITE_INT(codec, bs, (i+1==count) ? 0 : 1, 1, "moreCommands", NULL); |
952 | 0 | } |
953 | | |
954 | 0 | while (gf_list_count(codec->QPs)) gf_bifs_enc_qp_remove(codec, GF_TRUE); |
955 | 0 | return e; |
956 | 0 | } |
957 | | |
958 | | |
959 | | GF_EXPORT |
960 | | GF_Err gf_bifs_encoder_get_rap(GF_BifsEncoder *codec, u8 **out_data, u32 *out_data_length) |
961 | 0 | { |
962 | 0 | GF_BitStream *bs; |
963 | 0 | GF_Err e; |
964 | 0 | GF_List *ctx_bck; |
965 | | |
966 | | /*reset context for RAP encoding*/ |
967 | 0 | ctx_bck = codec->encoded_nodes; |
968 | 0 | codec->encoded_nodes = gf_list_new(); |
969 | |
|
970 | 0 | if (!codec->info) codec->info = (BIFSStreamInfo*)gf_list_get(codec->streamInfo, 0); |
971 | |
|
972 | 0 | bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); |
973 | 0 | GF_BIFS_WRITE_INT(codec, bs, 3, 2, "SceneReplace", NULL); |
974 | 0 | e = BE_SceneReplace(codec, codec->scene_graph, bs); |
975 | 0 | if (e == GF_OK) { |
976 | 0 | GF_BIFS_WRITE_INT(codec, bs, 0, 1, "moreCommands", NULL); |
977 | 0 | gf_bs_get_content(bs, out_data, out_data_length); |
978 | 0 | } |
979 | 0 | gf_bs_del(bs); |
980 | | |
981 | | /*restore context*/ |
982 | 0 | gf_list_del(codec->encoded_nodes); |
983 | 0 | codec->encoded_nodes = ctx_bck; |
984 | |
|
985 | 0 | return e; |
986 | 0 | } |
987 | | |
988 | | #endif /*GPAC_DISABLE_BIFS_ENC*/ |