--- /dev/null
+commit dc7de8d3d604426c7a6e628d90cb9fb88e7b4c2c
+Author: jeanlf <jeanlf@gpac.io>
+Date: Tue Jul 12 17:57:03 2022 +0200
+
+ fixed #2212
+
+diff --git a/src/bifs/field_decode.c b/src/bifs/field_decode.c
+index 5537da7d3..65d045b02 100644
+--- a/src/bifs/field_decode.c
++++ b/src/bifs/field_decode.c
+@@ -427,64 +427,71 @@ GF_Err BD_DecMFFieldVec(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node,
+ e = gf_bifs_dec_sf_field(codec, bs, node, &sffield, GF_FALSE);
+ if (e) return e;
+ }
+- } else {
+- last = NULL;
+- for (i=0; i<nbFields; i++) {
+- GF_Node *new_node = gf_bifs_dec_node(codec, bs, field->NDTtype);
+- if (new_node) {
+- e = gf_node_register(new_node, is_mem_com ? NULL : node);
+- if (e) return e;
+-
+- if (node) {
+- /*special case for QP, register as the current QP*/
+- if (gf_node_get_tag(new_node) == TAG_MPEG4_QuantizationParameter) {
+- qp_local = ((M_QuantizationParameter *)new_node)->isLocal;
+- /*we have a QP in the same scope, remove previous
+- NB: we assume this is the right behavior, the spec doesn't say
+- whether QP is cumulative or not*/
+- if (qp_on) gf_bifs_dec_qp_remove(codec, GF_FALSE);
++ return GF_OK;
++ }
+
+- e = gf_bifs_dec_qp_set(codec, new_node);
+- if (e) return e;
+- qp_on = 1;
+- if (qp_local) qp_local = 2;
+- if (codec->force_keep_qp) {
+- e = gf_node_list_add_child_last(field->far_ptr, new_node, &last);
+- if (e) return e;
+- } else {
+- gf_node_register(new_node, NULL);
+- gf_node_unregister(new_node, node);
+- }
+- } else {
++ e = GF_OK;
++ last = NULL;
++ for (i=0; i<nbFields; i++) {
++ GF_Node *new_node = gf_bifs_dec_node(codec, bs, field->NDTtype);
++ if (new_node) {
++ e = gf_node_register(new_node, is_mem_com ? NULL : node);
++ if (e) goto exit;
++
++ if (node) {
++ /*special case for QP, register as the current QP*/
++ if (gf_node_get_tag(new_node) == TAG_MPEG4_QuantizationParameter) {
++ qp_local = ((M_QuantizationParameter *)new_node)->isLocal;
++ /*we have a QP in the same scope, remove previous
++ NB: we assume this is the right behavior, the spec doesn't say
++ whether QP is cumulative or not*/
++ if (qp_on) gf_bifs_dec_qp_remove(codec, GF_FALSE);
++
++ e = gf_bifs_dec_qp_set(codec, new_node);
++ if (e) goto exit;
++ qp_on = 1;
++ if (qp_local) qp_local = 2;
++ if (codec->force_keep_qp) {
+ e = gf_node_list_add_child_last(field->far_ptr, new_node, &last);
+- if (e) return e;
++ if (e) goto exit;
++ } else {
++ gf_node_register(new_node, NULL);
++ gf_node_unregister(new_node, node);
+ }
++ } else {
++ e = gf_node_list_add_child_last(field->far_ptr, new_node, &last);
++ if (e) goto exit;
+ }
+- /*proto coding*/
+- else if (codec->pCurrentProto) {
+- /*TO DO: what happens if this is a QP node on the interface ?*/
+- e = gf_node_list_add_child_last( (GF_ChildNodeItem **)field->far_ptr, new_node, &last);
+- if (e) return e;
+- }
+- } else {
+- return codec->LastError ? codec->LastError : GF_NON_COMPLIANT_BITSTREAM;
+ }
++ /*proto coding*/
++ else if (codec->pCurrentProto) {
++ /*TO DO: what happens if this is a QP node on the interface ?*/
++ e = gf_node_list_add_child_last( (GF_ChildNodeItem **)field->far_ptr, new_node, &last);
++ if (e)goto exit;
++ }
++ } else {
++ e = codec->LastError ? codec->LastError : GF_NON_COMPLIANT_BITSTREAM;
++ goto exit;
+ }
+- /*according to the spec, the QP applies to the current node itself, not just children.
+- If IsLocal is TRUE remove the node*/
+- if (qp_on && qp_local) {
+- if (qp_local == 2) {
++ }
++
++exit:
++
++ /*according to the spec, the QP applies to the current node itself, not just children.
++ If IsLocal is TRUE remove the node*/
++ if (qp_on && qp_local) {
++ if (qp_local == 2) {
+ // qp_local = 1;
+- } else {
+- //ask to get rid of QP and reactivate if we had a QP when entering the node
+- gf_bifs_dec_qp_remove(codec, initial_qp);
++ } else {
++ //ask to get rid of QP and reactivate if we had a QP when entering the node
++ gf_bifs_dec_qp_remove(codec, initial_qp);
+ // qp_local = 0;
+- }
+ }
+ }
++
+ /*finally delete the QP if any (local or not) as we get out of this node*/
+ if (qp_on) gf_bifs_dec_qp_remove(codec, GF_TRUE);
+- return GF_OK;
++ return e;
+ }
+
+