Line data Source code
1 : /*
2 : * GPAC - Multimedia Framework C SDK
3 : *
4 : * Authors: Jean Le Feuvre
5 : * Copyright (c) Telecom ParisTech 2000-2020
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 :
28 : #include <gpac/internal/bifs_dev.h>
29 : #include <gpac/internal/bifs_tables.h>
30 : #include <gpac/network.h>
31 : #include "quant.h"
32 : #include "script.h"
33 :
34 : #ifndef GPAC_DISABLE_BIFS_ENC
35 :
36 4791 : GF_Err gf_bifs_field_index_by_mode(GF_Node *node, u32 all_ind, u8 indexMode, u32 *outField)
37 : {
38 : GF_Err e;
39 : u32 i, count, temp;
40 4791 : count = gf_node_get_num_fields_in_mode(node, indexMode);
41 13523 : for (i=0; i<count; i++) {
42 13523 : e = gf_bifs_get_field_index(node, i, indexMode, &temp);
43 13523 : if (e) return e;
44 13523 : if (temp==all_ind) {
45 4791 : *outField = i;
46 4791 : return GF_OK;
47 : }
48 : }
49 : return GF_BAD_PARAM;
50 : }
51 :
52 :
53 148196 : void BE_WriteSFFloat(GF_BifsEncoder *codec, Fixed val, GF_BitStream *bs, char *com)
54 : {
55 148196 : if (codec->ActiveQP && codec->ActiveQP->useEfficientCoding) {
56 120 : gf_bifs_enc_mantissa_float(codec, val, bs);
57 : } else {
58 148076 : gf_bs_write_float(bs, FIX2FLT(val));
59 148076 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] SFFloat\t\t32\t\t%g\t\t%s\n", FIX2FLT(val), com ? com : "") );
60 : }
61 148196 : }
62 :
63 :
64 151921 : GF_Err gf_bifs_enc_sf_field(GF_BifsEncoder *codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field)
65 : {
66 : GF_Err e;
67 :
68 151921 : if (node) {
69 151511 : e = gf_bifs_enc_quant_field(codec, bs, node, field);
70 151511 : if (e != GF_EOS) return e;
71 : }
72 149799 : switch (field->fieldType) {
73 1552 : case GF_SG_VRML_SFBOOL:
74 1552 : GF_BIFS_WRITE_INT(codec, bs, * ((SFBool *)field->far_ptr), 1, "SFBool", NULL);
75 : break;
76 1980 : case GF_SG_VRML_SFCOLOR:
77 1980 : BE_WriteSFFloat(codec, ((SFColor *)field->far_ptr)->red, bs, "color.red");
78 1980 : BE_WriteSFFloat(codec, ((SFColor *)field->far_ptr)->green, bs, "color.green");
79 1980 : BE_WriteSFFloat(codec, ((SFColor *)field->far_ptr)->blue, bs, "color.blue");
80 1980 : break;
81 19534 : case GF_SG_VRML_SFFLOAT:
82 19534 : BE_WriteSFFloat(codec, * ((SFFloat *)field->far_ptr), bs, NULL);
83 19534 : break;
84 54909 : case GF_SG_VRML_SFINT32:
85 54909 : GF_BIFS_WRITE_INT(codec, bs, * ((SFInt32 *)field->far_ptr), 32, "SFInt32", NULL);
86 : break;
87 12 : case GF_SG_VRML_SFROTATION:
88 12 : BE_WriteSFFloat(codec, ((SFRotation *)field->far_ptr)->x, bs, "rot.x");
89 12 : BE_WriteSFFloat(codec, ((SFRotation *)field->far_ptr)->y, bs, "rot.y");
90 12 : BE_WriteSFFloat(codec, ((SFRotation *)field->far_ptr)->z, bs, "rot.z");
91 12 : BE_WriteSFFloat(codec, ((SFRotation *)field->far_ptr)->q, bs, "rot.theta");
92 12 : break;
93 :
94 534 : case GF_SG_VRML_SFSTRING:
95 534 : if (node && (node->sgprivate->tag==TAG_MPEG4_CacheTexture) && (field->fieldIndex<=2)) {
96 : u32 size, val;
97 : char buf[4096];
98 : char *res_src = NULL;
99 0 : const char *src = ((SFString*)field->far_ptr)->buffer;
100 : FILE *f;
101 0 : if (codec->src_url) res_src = gf_url_concatenate(codec->src_url, src);
102 :
103 0 : f = gf_fopen(res_src ? res_src : src, "rb");
104 0 : if (!f) {
105 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[BIFS] Cannot open source file %s for encoding CacheTexture\n", res_src ? res_src : src));
106 0 : return GF_URL_ERROR;
107 : }
108 0 : if (res_src) gf_free(res_src);
109 0 : size = (u32) gf_fsize(f);
110 0 : val = gf_get_bit_size(size);
111 0 : GF_BIFS_WRITE_INT(codec, bs, val, 5, "nbBits", NULL);
112 0 : GF_BIFS_WRITE_INT(codec, bs, size, val, "length", NULL);
113 :
114 0 : while (size) {
115 0 : u32 read = (u32) gf_fread(buf, 4096, f);
116 0 : gf_bs_write_data(bs, buf, read);
117 0 : size -= read;
118 : }
119 0 : gf_fclose(f);
120 : } else {
121 : u32 i, val, len;
122 : char *dump_str = NULL;
123 534 : char *str = (char *) ((SFString*)field->far_ptr)->buffer;
124 534 : if (node && (node->sgprivate->tag==TAG_MPEG4_BitWrapper) ) {
125 21 : len = ((M_BitWrapper*)node)->buffer_len;
126 : } else {
127 513 : len = str ? (u32) strlen(str) : 0;
128 : dump_str = str;
129 : }
130 534 : val = gf_get_bit_size(len);
131 534 : GF_BIFS_WRITE_INT(codec, bs, val, 5, "nbBits", NULL);
132 534 : GF_BIFS_WRITE_INT(codec, bs, len, val, "length", NULL);
133 107164 : for (i=0; i<len; i++) gf_bs_write_int(bs, str[i], 8);
134 534 : if (dump_str) {
135 481 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] string\t\t%d\t\t%s\n", 8*len, str) );
136 : } else {
137 53 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] string\t\t%d\n", 8*len) );
138 : }
139 : }
140 : break;
141 :
142 56 : case GF_SG_VRML_SFTIME:
143 56 : gf_bs_write_double(bs, *((SFTime *)field->far_ptr));
144 56 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] SFTime\t\t%d\t\t%g\n", 64, *((SFTime *)field->far_ptr)));
145 : break;
146 :
147 60137 : case GF_SG_VRML_SFVEC2F:
148 60137 : BE_WriteSFFloat(codec, ((SFVec2f *)field->far_ptr)->x, bs, "vec2f.x");
149 60137 : BE_WriteSFFloat(codec, ((SFVec2f *)field->far_ptr)->y, bs, "vec2f.y");
150 60137 : break;
151 :
152 800 : case GF_SG_VRML_SFVEC3F:
153 800 : BE_WriteSFFloat(codec, ((SFVec3f *)field->far_ptr)->x, bs, "vec3f.x");
154 800 : BE_WriteSFFloat(codec, ((SFVec3f *)field->far_ptr)->y, bs, "vec3f.y");
155 800 : BE_WriteSFFloat(codec, ((SFVec3f *)field->far_ptr)->z, bs, "vec3f.z");
156 800 : break;
157 :
158 175 : case GF_SG_VRML_SFURL:
159 : {
160 175 : SFURL *url = (SFURL *) field->far_ptr;
161 175 : GF_BIFS_WRITE_INT(codec, bs, (url->OD_ID>0) ? 1 : 0, 1, "hasODID", "SFURL");
162 175 : if (url->OD_ID>0) {
163 133 : GF_BIFS_WRITE_INT(codec, bs, url->OD_ID, 10, "ODID", "SFURL");
164 : } else {
165 42 : u32 i, len = url->url ? (u32) strlen(url->url) : 0;
166 42 : u32 val = gf_get_bit_size(len);
167 42 : GF_BIFS_WRITE_INT(codec, bs, val, 5, "nbBits", NULL);
168 42 : GF_BIFS_WRITE_INT(codec, bs, len, val, "length", NULL);
169 1460 : for (i=0; i<len; i++) gf_bs_write_int(bs, url->url[i], 8);
170 42 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] string\t\t%d\t\t%s\t\t//SFURL\n", 8*len, url->url));
171 : }
172 : }
173 : break;
174 20 : case GF_SG_VRML_SFIMAGE:
175 : {
176 : u32 size, i;
177 20 : SFImage *img = (SFImage *)field->far_ptr;
178 20 : GF_BIFS_WRITE_INT(codec, bs, img->width, 12, "width", "SFImage");
179 20 : GF_BIFS_WRITE_INT(codec, bs, img->height, 12, "height", "SFImage");
180 20 : GF_BIFS_WRITE_INT(codec, bs, img->numComponents - 1, 2, "nbComp", "SFImage");
181 20 : size = img->width * img->height * img->numComponents;
182 20 : for (i=0; i<size; i++) gf_bs_write_int(bs, img->pixels[i], 8);
183 20 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] pixels\t\t%d\t\tnot dumped\t\t//SFImage\n", 8*size));
184 : }
185 : break;
186 :
187 141 : case GF_SG_VRML_SFCOMMANDBUFFER:
188 : {
189 141 : SFCommandBuffer *cb = (SFCommandBuffer *) field->far_ptr;
190 141 : if (cb->buffer) gf_free(cb->buffer);
191 141 : cb->buffer = NULL;
192 141 : cb->bufferSize = 0;
193 141 : if (gf_list_count(cb->commandList)) {
194 : u32 i, nbBits;
195 141 : GF_BitStream *bs_cond = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
196 141 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] /*SFCommandBuffer*/\n" ));
197 141 : e = gf_bifs_enc_commands(codec, cb->commandList, bs_cond);
198 141 : if (!e) gf_bs_get_content(bs_cond, &cb->buffer, &cb->bufferSize);
199 141 : gf_bs_del(bs_cond);
200 141 : if (e) return e;
201 141 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] /*End SFCommandBuffer*/\n"));
202 141 : nbBits = gf_get_bit_size(cb->bufferSize);
203 141 : GF_BIFS_WRITE_INT(codec, bs, nbBits, 5, "NbBits", NULL);
204 141 : GF_BIFS_WRITE_INT(codec, bs, cb->bufferSize, nbBits, "BufferSize", NULL);
205 1824 : for (i=0; i<cb->bufferSize; i++) GF_BIFS_WRITE_INT(codec, bs, cb->buffer[i], 8, "buffer byte", NULL);
206 : }
207 : /*empty command buffer*/
208 : else {
209 0 : GF_BIFS_WRITE_INT(codec, bs, 0, 5, "NbBits", NULL);
210 : }
211 : }
212 : break;
213 :
214 9929 : case GF_SG_VRML_SFNODE:
215 9929 : return gf_bifs_enc_node(codec, *((GF_Node **)field->far_ptr), field->NDTtype, bs, node);
216 :
217 20 : case GF_SG_VRML_SFSCRIPT:
218 : #ifdef GPAC_HAS_QJS
219 20 : codec->LastError = SFScript_Encode(codec, (SFScript *)field->far_ptr, bs, node);
220 : #else
221 : return GF_NOT_SUPPORTED;
222 : #endif
223 20 : break;
224 0 : case GF_SG_VRML_SFATTRREF:
225 : {
226 0 : u32 idx=0;
227 0 : SFAttrRef *ar = (SFAttrRef *)field->far_ptr;
228 0 : u32 nbBitsDEF = gf_get_bit_size(gf_node_get_num_fields_in_mode(ar->node, GF_SG_FIELD_CODING_DEF) - 1);
229 0 : GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(ar->node) - 1, codec->info->config.NodeIDBits, "NodeID", NULL);
230 :
231 0 : gf_bifs_field_index_by_mode(ar->node, ar->fieldIndex, GF_SG_FIELD_CODING_DEF, &idx);
232 0 : GF_BIFS_WRITE_INT(codec, bs, idx, nbBitsDEF, "field", NULL);
233 : }
234 0 : break;
235 : default:
236 : return GF_NOT_SUPPORTED;
237 : }
238 139870 : return codec->LastError;
239 : }
240 :
241 :
242 9384 : GF_Err gf_bifs_enc_mf_field(GF_BifsEncoder *codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field)
243 : {
244 : GF_ChildNodeItem *list = NULL;
245 : GF_Err e;
246 : u32 nbBits, qp_local;
247 : Bool use_list, qp_on, initial_qp;
248 : u32 nbF, i;
249 : GF_FieldInfo sffield;
250 :
251 : nbF = 0;
252 9384 : if (field->fieldType != GF_SG_VRML_MFNODE) {
253 4540 : nbF = field->far_ptr ? ((GenMFField *)field->far_ptr)->count : 0;
254 4540 : if (!nbF && (field->fieldType == GF_SG_VRML_MFSCRIPT))
255 : nbF = 1;
256 4844 : } else if (field->far_ptr) {
257 4844 : list = *((GF_ChildNodeItem **)field->far_ptr);
258 4844 : nbF = gf_node_list_get_count(list);
259 : }
260 : /*reserved*/
261 9384 : GF_BIFS_WRITE_INT(codec, bs, 0, 1, "reserved", NULL);
262 9384 : if (!nbF) {
263 : /*is list*/
264 2 : GF_BIFS_WRITE_INT(codec, bs, 1, 1, "isList", NULL);
265 : /*end flag*/
266 2 : GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL);
267 : return GF_OK;
268 : }
269 :
270 : /*do we work in list or vector*/
271 : use_list = GF_FALSE;
272 9382 : nbBits = gf_get_bit_size(nbF);
273 9382 : if (nbBits + 5 > nbF + 1) use_list = GF_TRUE;
274 :
275 9382 : GF_BIFS_WRITE_INT(codec, bs, use_list, 1, "isList", NULL);
276 9382 : if (!use_list) {
277 2900 : GF_BIFS_WRITE_INT(codec, bs, nbBits, 5, "nbBits", NULL);
278 2900 : GF_BIFS_WRITE_INT(codec, bs, nbF, nbBits, "length", NULL);
279 : }
280 :
281 : memset(&sffield, 0, sizeof(GF_FieldInfo));
282 9382 : sffield.fieldIndex = field->fieldIndex;
283 9382 : sffield.fieldType = gf_sg_vrml_get_sf_type(field->fieldType);
284 9382 : sffield.NDTtype = field->NDTtype;
285 :
286 : qp_on = GF_FALSE;
287 : qp_local = 0;
288 9382 : initial_qp = codec->ActiveQP ? GF_TRUE : GF_FALSE;
289 138393 : for (i=0; i<nbF; i++) {
290 :
291 129011 : if (use_list) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "end", NULL);
292 :
293 129011 : if (field->fieldType != GF_SG_VRML_MFNODE) {
294 120199 : gf_sg_vrml_mf_get_item(field->far_ptr, field->fieldType, &sffield.far_ptr, i);
295 120199 : e = gf_bifs_enc_sf_field(codec, bs, node, &sffield);
296 : } else {
297 : assert(list);
298 8812 : e = gf_bifs_enc_node(codec, list->node, field->NDTtype, bs, node);
299 :
300 : /*activate QP*/
301 8812 : if (list->node->sgprivate->tag == TAG_MPEG4_QuantizationParameter) {
302 49 : qp_local = ((M_QuantizationParameter *)list->node)->isLocal;
303 49 : if (qp_on) gf_bifs_enc_qp_remove(codec, GF_FALSE);
304 49 : e = gf_bifs_enc_qp_set(codec, list->node);
305 49 : if (e) return e;
306 : qp_on = GF_TRUE;
307 49 : if (qp_local) qp_local = 2;
308 : }
309 8812 : list = list->next;
310 : }
311 :
312 129011 : if (e) return e;
313 :
314 129011 : if (qp_on && qp_local) {
315 40 : if (qp_local == 2) qp_local -= 1;
316 : else {
317 20 : gf_bifs_enc_qp_remove(codec, initial_qp);
318 : qp_local = qp_on = GF_FALSE;
319 : }
320 : }
321 : }
322 :
323 9382 : if (use_list) GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL);
324 9382 : if (qp_on) gf_bifs_enc_qp_remove(codec, initial_qp);
325 : /*for QP14*/
326 9382 : gf_bifs_enc_qp14_set_length(codec, nbF);
327 9382 : return GF_OK;
328 : }
329 :
330 :
331 40676 : GF_Err gf_bifs_enc_field(GF_BifsEncoder * codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field)
332 : {
333 : assert(node);
334 40676 : if (field->fieldType == GF_SG_VRML_UNKNOWN)
335 : return GF_NON_COMPLIANT_BITSTREAM;
336 :
337 40676 : if (gf_sg_vrml_is_sf_field(field->fieldType)) {
338 31316 : return gf_bifs_enc_sf_field(codec, bs, node, field);
339 : }
340 :
341 : /*TO DO : PMF support*/
342 :
343 9360 : if (codec->info->config.UsePredictiveMFField) {
344 0 : GF_BIFS_WRITE_INT(codec, bs, 0, 1, "usePredictive", NULL);
345 : }
346 9360 : return gf_bifs_enc_mf_field(codec, bs, node, field);
347 : }
348 :
349 : /*we assume a node field is not ISed several times (that's stated as "undefined behavior" in VRML*/
350 1988 : GF_Route *gf_bifs_enc_is_field_ised(GF_BifsEncoder *codec, GF_Node *node, u32 fieldIndex)
351 : {
352 : GF_Route *r;
353 : u32 i;
354 1988 : if (!codec->encoding_proto) return NULL;
355 :
356 1988 : if (node->sgprivate->interact && node->sgprivate->interact->routes) {
357 863 : i=0;
358 2722 : while ((r = (GF_Route*)gf_list_enum(node->sgprivate->interact->routes, &i))) {
359 1394 : if (!r->IS_route) continue;
360 1346 : if ((r->ToNode == node) && (r->ToField.fieldIndex==fieldIndex)) return r;
361 1346 : else if ((r->FromNode == node) && (r->FromField.fieldIndex==fieldIndex)) return r;
362 : }
363 : }
364 :
365 1590 : i=0;
366 25488 : while ((r = (GF_Route*)gf_list_enum(codec->encoding_proto->sub_graph->Routes, &i))) {
367 22388 : if (!r->IS_route) continue;
368 21228 : if ((r->ToNode == node) && (r->ToField.fieldIndex==fieldIndex)) return r;
369 21148 : else if ((r->FromNode == node) && (r->FromField.fieldIndex==fieldIndex)) return r;
370 : }
371 : return NULL;
372 : }
373 :
374 : /**/
375 16737 : GF_Err EncNodeFields(GF_BifsEncoder * codec, GF_BitStream *bs, GF_Node *node)
376 : {
377 : u8 mode;
378 : GF_Route *isedField;
379 : GF_Node *clone;
380 : GF_Err e;
381 : s32 *enc_fields;
382 : u32 numBitsALL, numBitsDEF, allInd, count, i, nbBitsProto, nbFinal;
383 : Bool use_list, nodeIsFDP = GF_FALSE;
384 : GF_FieldInfo field, clone_field;
385 :
386 : e = GF_OK;
387 :
388 16737 : if (codec->encoding_proto) {
389 : mode = GF_SG_FIELD_CODING_ALL;
390 350 : nbBitsProto = gf_get_bit_size(gf_sg_proto_get_field_count(codec->encoding_proto) - 1);
391 350 : numBitsALL = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_ALL) - 1);
392 : } else {
393 : mode = GF_SG_FIELD_CODING_DEF;
394 : nbBitsProto = 0;
395 : numBitsALL = 0;
396 : }
397 16737 : count = gf_node_get_num_fields_in_mode(node, mode);
398 16737 : if (node->sgprivate->tag==TAG_MPEG4_Script) count = 3;
399 :
400 16717 : if (!count) {
401 0 : GF_BIFS_WRITE_INT(codec, bs, 0, 1, "isMask", NULL);
402 0 : GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL);
403 : return GF_OK;
404 : }
405 :
406 16737 : if (node->sgprivate->tag == TAG_ProtoNode) {
407 333 : clone = gf_sg_proto_create_instance(node->sgprivate->scenegraph, ((GF_ProtoInstance *)node)->proto_interface);
408 : } else {
409 16404 : clone = gf_node_new(node->sgprivate->scenegraph, node->sgprivate->tag);
410 : }
411 16737 : if (clone) gf_node_register(clone, NULL);
412 :
413 16737 : numBitsDEF = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_DEF) - 1);
414 :
415 16737 : enc_fields = (s32*)gf_malloc(sizeof(s32) * count);
416 : nbFinal = 0;
417 87026 : for (i=0; i<count; i++) {
418 70289 : enc_fields[i] = -1;
419 : /*get field in ALL mode*/
420 70289 : if (mode == GF_SG_FIELD_CODING_ALL) {
421 1292 : allInd = i;
422 : } else {
423 68997 : gf_bifs_get_field_index(node, i, GF_SG_FIELD_CODING_DEF, &allInd);
424 : }
425 :
426 : /*encode proto code*/
427 70289 : if (codec->encoding_proto) {
428 1292 : isedField = gf_bifs_enc_is_field_ised(codec, node, allInd);
429 1292 : if (isedField) {
430 239 : enc_fields[i] = allInd;
431 239 : nbFinal ++;
432 239 : continue;
433 : }
434 : }
435 : /*common case*/
436 70050 : gf_node_get_field(node, allInd, &field);
437 : /*if event don't encode (happens when encoding protos)*/
438 70050 : if ((field.eventType == GF_SG_EVENT_IN) || (field.eventType == GF_SG_EVENT_OUT)) continue;
439 : /*if field is default skip*/
440 69820 : switch (field.fieldType) {
441 14991 : case GF_SG_VRML_SFNODE:
442 14991 : if (* (GF_Node **) field.far_ptr) {
443 9849 : enc_fields[i] = allInd;
444 9849 : nbFinal++;
445 : }
446 : break;
447 5221 : case GF_SG_VRML_MFNODE:
448 5221 : if (* (GF_ChildNodeItem **) field.far_ptr) {
449 4838 : enc_fields[i] = allInd;
450 4838 : nbFinal++;
451 : }
452 : break;
453 165 : case GF_SG_VRML_SFCOMMANDBUFFER:
454 : {
455 165 : SFCommandBuffer *cb = (SFCommandBuffer *)field.far_ptr;
456 165 : if (gf_list_count(cb->commandList)) {
457 141 : enc_fields[i] = allInd;
458 141 : nbFinal++;
459 : }
460 : }
461 : break;
462 20 : case GF_SG_VRML_MFSCRIPT:
463 20 : enc_fields[i] = allInd;
464 20 : nbFinal++;
465 20 : break;
466 49423 : default:
467 49423 : gf_node_get_field(clone, allInd, &clone_field);
468 49423 : if (!gf_sg_vrml_field_equal(clone_field.far_ptr, field.far_ptr, field.fieldType)) {
469 25322 : enc_fields[i] = allInd;
470 25322 : nbFinal++;
471 : }
472 : break;
473 : }
474 : }
475 16737 : if (clone) gf_node_unregister(clone, NULL);
476 :
477 : use_list = GF_TRUE;
478 : /* patch for FDP node : */
479 : /* cannot use default field sorting due to spec "mistake", so use list to imply inversion between field 2 and field 3 of FDP*/
480 16737 : if (node->sgprivate->tag == TAG_MPEG4_FDP) {
481 0 : s32 s4SwapValue = enc_fields[2];
482 0 : enc_fields[2] = enc_fields[3];
483 0 : enc_fields[3] = s4SwapValue;
484 : nodeIsFDP = GF_TRUE;
485 : use_list = GF_TRUE;
486 : }
487 : /*number of bits in mask node is count*1, in list node is 1+nbFinal*(1+numBitsDEF) */
488 16737 : else if (count < 1+nbFinal*(1+numBitsDEF))
489 : use_list = GF_FALSE;
490 :
491 16737 : GF_BIFS_WRITE_INT(codec, bs, use_list ? 0 : 1, 1, "isMask", NULL);
492 :
493 70289 : for (i=0; i<count; i++) {
494 70289 : if (enc_fields[i] == -1) {
495 29880 : if (!use_list) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "Mask", NULL);
496 29880 : continue;
497 : }
498 40409 : allInd = (u32) enc_fields[i];
499 :
500 : /*encode proto code*/
501 40409 : if (codec->encoding_proto) {
502 696 : isedField = gf_bifs_enc_is_field_ised(codec, node, allInd);
503 696 : if (isedField) {
504 239 : if (use_list) {
505 40 : GF_BIFS_WRITE_INT(codec, bs, 0, 1, "end", NULL);
506 : } else {
507 199 : GF_BIFS_WRITE_INT(codec, bs, 1, 1, "Mask", NULL);
508 : }
509 239 : GF_BIFS_WRITE_INT(codec, bs, 1, 1, "isedField", NULL);
510 239 : if (use_list) GF_BIFS_WRITE_INT(codec, bs, allInd, numBitsALL, "nodeField", NULL);
511 :
512 239 : if (isedField->ToNode == node) {
513 40 : GF_BIFS_WRITE_INT(codec, bs, isedField->FromField.fieldIndex, nbBitsProto, "protoField", NULL);
514 : } else {
515 199 : GF_BIFS_WRITE_INT(codec, bs, isedField->ToField.fieldIndex, nbBitsProto, "protoField", NULL);
516 : }
517 239 : continue;
518 : }
519 : }
520 : /*common case*/
521 40170 : gf_node_get_field(node, allInd, &field);
522 40170 : if (use_list) {
523 : /*not end flag*/
524 1541 : GF_BIFS_WRITE_INT(codec, bs, 0, 1, "end", NULL);
525 : } else {
526 : /*mask flag*/
527 38629 : GF_BIFS_WRITE_INT(codec, bs, 1, 1, "Mask", NULL);
528 : }
529 : /*not ISed field*/
530 40170 : if (codec->encoding_proto) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "isedField", NULL);
531 40170 : if (use_list) {
532 1592 : if (codec->encoding_proto || nodeIsFDP) {
533 51 : u32 ind=0;
534 : /*for proto, we're in ALL mode and we need DEF mode*/
535 : /*for FDP, encoding requires to get def id from all id as fields 2 and 3 are reversed*/
536 51 : gf_bifs_field_index_by_mode(node, allInd, GF_SG_FIELD_CODING_DEF, &ind);
537 51 : GF_BIFS_WRITE_INT(codec, bs, ind, numBitsDEF, "field", (char*)field.name);
538 : } else {
539 1490 : GF_BIFS_WRITE_INT(codec, bs, i, numBitsDEF, "field", (char*)field.name);
540 : }
541 : }
542 40170 : e = gf_bifs_enc_field(codec, bs, node, &field);
543 40170 : if (e) goto exit;
544 : }
545 : /*end flag*/
546 18741 : if (use_list) GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL);
547 33278 : exit:
548 16737 : gf_free(enc_fields);
549 16737 : return e;
550 : }
551 :
552 22810 : Bool BE_NodeIsUSE(GF_BifsEncoder * codec, GF_Node *node)
553 : {
554 : u32 i, count;
555 22810 : if (!node || !gf_node_get_id(node) ) return GF_FALSE;
556 8310 : count = gf_list_count(codec->encoded_nodes);
557 739478 : for (i=0; i<count; i++) {
558 737241 : if (gf_list_get(codec->encoded_nodes, i) == node) return GF_TRUE;
559 : }
560 2237 : gf_list_add(codec->encoded_nodes, node);
561 2237 : return GF_FALSE;
562 : }
563 :
564 22905 : GF_Err gf_bifs_enc_node(GF_BifsEncoder * codec, GF_Node *node, u32 NDT_Tag, GF_BitStream *bs, GF_Node *parent_node)
565 : {
566 : u32 NDTBits, node_type, node_tag, BVersion, node_id;
567 : const char *node_name;
568 : Bool flag, reset_qp14;
569 : GF_Err e;
570 :
571 : assert(codec->info);
572 22905 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[BIFS] Encode node %s\n", gf_node_get_class_name(node) ));
573 :
574 : /*NULL node is a USE of maxID*/
575 22905 : if (!node) {
576 95 : GF_BIFS_WRITE_INT(codec, bs, 1, 1, "USE", NULL);
577 95 : GF_BIFS_WRITE_INT(codec, bs, (1<<codec->info->config.NodeIDBits) - 1 , codec->info->config.NodeIDBits, "NodeID", "NULL");
578 : return GF_OK;
579 : }
580 :
581 22810 : flag = BE_NodeIsUSE(codec, node);
582 22810 : GF_BIFS_WRITE_INT(codec, bs, flag ? 1 : 0, 1, "USE", (char*)gf_node_get_class_name(node));
583 :
584 22810 : if (flag) {
585 : GF_Node *new_node;
586 6073 : gf_bs_write_int(bs, gf_node_get_id(node) - 1, codec->info->config.NodeIDBits);
587 6073 : new_node = gf_bifs_enc_find_node(codec, gf_node_get_id(node) );
588 6073 : if (!new_node)
589 0 : return codec->LastError = GF_SG_UNKNOWN_NODE;
590 :
591 : /*restore QP14 length*/
592 6073 : switch (gf_node_get_tag(new_node)) {
593 0 : case TAG_MPEG4_Coordinate:
594 : {
595 0 : u32 nbCoord = ((M_Coordinate *)new_node)->point.count;
596 0 : gf_bifs_enc_qp14_enter(codec, GF_TRUE);
597 0 : gf_bifs_enc_qp14_set_length(codec, nbCoord);
598 0 : gf_bifs_enc_qp14_enter(codec, GF_FALSE);
599 : }
600 0 : break;
601 96 : case TAG_MPEG4_Coordinate2D:
602 : {
603 96 : u32 nbCoord = ((M_Coordinate2D *)new_node)->point.count;
604 96 : gf_bifs_enc_qp14_enter(codec, GF_TRUE);
605 96 : gf_bifs_enc_qp14_set_length(codec, nbCoord);
606 96 : gf_bifs_enc_qp14_enter(codec, GF_FALSE);
607 : }
608 96 : break;
609 : }
610 : return GF_OK;
611 : }
612 :
613 : BVersion = GF_BIFS_V1;
614 16737 : node_tag = node->sgprivate->tag;
615 : while (1) {
616 37479 : node_type = gf_bifs_get_node_type(NDT_Tag, node_tag, BVersion);
617 37479 : NDTBits = gf_bifs_get_ndt_bits(NDT_Tag, BVersion);
618 37479 : if (BVersion==2 && (node_tag==TAG_ProtoNode)) node_type = 1;
619 37479 : GF_BIFS_WRITE_INT(codec, bs, node_type, NDTBits, "ndt", NULL);
620 37479 : if (node_type) break;
621 :
622 20742 : BVersion += 1;
623 20742 : if (BVersion > GF_BIFS_NUM_VERSION) {
624 0 : if (parent_node) {
625 0 : 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) ));
626 : } else {
627 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[BIFS] Cannot encode node %s in the SFWorldNode context\n", gf_node_get_class_name(node) ));
628 : }
629 0 : return codec->LastError = GF_BIFS_UNKNOWN_VERSION;
630 : }
631 : }
632 16737 : if (BVersion==2 && node_type==1) {
633 333 : GF_Proto *proto = ((GF_ProtoInstance *)node)->proto_interface;
634 333 : GF_BIFS_WRITE_INT(codec, bs, proto->ID, codec->info->config.ProtoIDBits, "protoID", NULL);
635 : }
636 :
637 : /*special handling of 3D mesh*/
638 :
639 : /*DEF'd node*/
640 16737 : node_name = gf_node_get_name_and_id(node, &node_id);
641 16737 : GF_BIFS_WRITE_INT(codec, bs, node_id ? 1 : 0, 1, "DEF", NULL);
642 16737 : if (node_id) {
643 2237 : GF_BIFS_WRITE_INT(codec, bs, node_id - 1, codec->info->config.NodeIDBits, "NodeID", NULL);
644 2237 : if (codec->UseName) gf_bifs_enc_name(codec, bs, (char*) node_name );
645 : }
646 :
647 : /*no updates of time fields for now - NEEDED FOR A LIVE ENCODER*/
648 :
649 : /*if coords were not stored for QP14 before coding this node, reset QP14 it when leaving*/
650 16737 : reset_qp14 = !codec->coord_stored;
651 :
652 : /*QP14 case*/
653 16737 : switch (node_tag) {
654 1677 : case TAG_MPEG4_Coordinate:
655 : case TAG_MPEG4_Coordinate2D:
656 1677 : gf_bifs_enc_qp14_enter(codec, GF_TRUE);
657 : }
658 :
659 16737 : e = EncNodeFields(codec, bs, node);
660 16737 : if (e) return e;
661 :
662 16737 : if (codec->coord_stored && reset_qp14)
663 116 : gf_bifs_enc_qp14_reset(codec);
664 :
665 16737 : switch (node_tag) {
666 1677 : case TAG_MPEG4_Coordinate:
667 : case TAG_MPEG4_Coordinate2D:
668 1677 : gf_bifs_enc_qp14_enter(codec, GF_FALSE);
669 1677 : break;
670 : }
671 : return GF_OK;
672 : }
673 :
674 :
675 : #endif /*GPAC_DISABLE_BIFS_ENC*/
|