LCOV - code coverage report
Current view: top level - bifs - conditional.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 69 71 97.2 %
Date: 2021-04-29 23:48:07 Functions: 7 7 100.0 %

          Line data    Source code
       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             : 
      28             : #include <gpac/internal/bifs_dev.h>
      29             : 
      30             : 
      31             : #ifndef GPAC_DISABLE_BIFS
      32             : 
      33             : /*private stack for conditional*/
      34             : typedef struct
      35             : {
      36             :         /*BIFS decoder*/
      37             :         GF_BifsDecoder *codec;
      38             :         /*BIFS config of original stream carrying the conditional*/
      39             :         BIFSStreamInfo *info;
      40             : } ConditionalStack;
      41             : 
      42         345 : void Conditional_PreDestroy(GF_Node *n, void *eff, Bool is_destroy)
      43             : {
      44         345 :         if (is_destroy) {
      45         102 :                 ConditionalStack *priv = (ConditionalStack*)gf_node_get_private(n);
      46         102 :                 if (priv) gf_free(priv);
      47             :         }
      48         345 : }
      49             : 
      50          65 : void Conditional_BufferReplaced(GF_BifsDecoder *codec, GF_Node *n)
      51             : {
      52          65 :         ConditionalStack *priv = (ConditionalStack*)gf_node_get_private(n);
      53          65 :         if (!priv || (gf_node_get_tag(n) != TAG_MPEG4_Conditional)) return;
      54           0 :         priv->info = codec->info;
      55             : }
      56             : 
      57           9 : static void Conditional_execute(M_Conditional *node)
      58             : {
      59             :         char *buffer;
      60             :         u32 len;
      61             :         GF_BitStream *bs;
      62             :         GF_BifsDecoder *codec;
      63             :         GF_Proto *prevproto;
      64             :         GF_SceneGraph *prev_graph;
      65           9 :         ConditionalStack *priv = (ConditionalStack*)gf_node_get_private((GF_Node*)node);
      66           9 :         if (!priv) return;
      67             : 
      68             :         /*set the codec working graph to the node one (to handle conditional in protos)*/
      69           9 :         prev_graph = priv->codec->current_graph;
      70           9 :         priv->codec->current_graph = gf_node_get_graph((GF_Node*)node);
      71             :         assert(priv->codec->current_graph);
      72             : 
      73           9 :         priv->codec->info = priv->info;
      74           9 :         prevproto = priv->codec->pCurrentProto;
      75           9 :         priv->codec->pCurrentProto = NULL;
      76           9 :         if (priv->codec->current_graph->pOwningProto) priv->codec->pCurrentProto = priv->codec->current_graph->pOwningProto->proto_interface;
      77             : 
      78             :         /*set isActive - to clarify in the specs*/
      79           9 :         node->isActive = 1;
      80           9 :         gf_node_event_out((GF_Node *)node, 3/*"isActive"*/);
      81           9 :         if (!node->buffer.bufferSize) return;
      82             : 
      83             :         /*we may replace ourselves*/
      84           6 :         buffer = (char*)node->buffer.buffer;
      85             :         len = node->buffer.bufferSize;
      86           6 :         node->buffer.buffer = NULL;
      87           6 :         node->buffer.bufferSize = 0;
      88           6 :         bs = gf_bs_new(buffer, len, GF_BITSTREAM_READ);
      89           6 :         codec = priv->codec;
      90           6 :         codec->cts_offset = gf_node_get_scene_time((GF_Node*)node);
      91             :         /*a conditional may destroy/replace itself - to prevent that, protect node by a register/unregister ...*/
      92           6 :         gf_node_register((GF_Node*)node, NULL);
      93             : #ifdef GF_SELF_REPLACE_ENABLE
      94             :         /*and a conditional may destroy the entire scene!*/
      95             :         cur_graph->graph_has_been_reset = 0;
      96             : #endif
      97           6 :         gf_bifs_dec_command(codec, bs);
      98           6 :         gf_bs_del(bs);
      99             : #ifdef GF_SELF_REPLACE_ENABLE
     100             :         if (cur_graph->graph_has_been_reset) {
     101             :                 return;
     102             :         }
     103             : #endif
     104           6 :         if (node->buffer.buffer) {
     105           0 :                 gf_free(buffer);
     106             :         } else {
     107           6 :                 node->buffer.buffer = (u8*)buffer;
     108           6 :                 node->buffer.bufferSize = len;
     109             :         }
     110             :         //set isActive - to clarify in the specs
     111             : //      node->isActive = 0;
     112           6 :         gf_node_unregister((GF_Node*)node, NULL);
     113           6 :         codec->cts_offset = 0;
     114           6 :         codec->pCurrentProto = prevproto;
     115           6 :         codec->current_graph = prev_graph;
     116             : }
     117             : 
     118           9 : void Conditional_OnActivate(GF_Node *n, GF_Route *route)
     119             : {
     120             :         M_Conditional *node = (M_Conditional *)n;
     121           9 :         if (! node->activate) return;
     122           3 :         Conditional_execute(node);
     123             : }
     124             : 
     125           6 : void Conditional_OnReverseActivate(GF_Node *n, GF_Route *route)
     126             : {
     127             :         M_Conditional *node = (M_Conditional *)n;
     128           6 :         if (node->reverseActivate) return;
     129           6 :         Conditional_execute(node);
     130             : }
     131             : 
     132          90 : void SetupConditional(GF_BifsDecoder *codec, GF_Node *node)
     133             : {
     134             :         ConditionalStack *priv;
     135          90 :         if (gf_node_get_tag(node) != TAG_MPEG4_Conditional) return;
     136          90 :         priv = (ConditionalStack*)gf_malloc(sizeof(ConditionalStack));
     137             : 
     138             :         /*needed when initializing extern protos*/
     139          90 :         if (!codec->info) codec->info = (BIFSStreamInfo*)gf_list_get(codec->streamInfo, 0);
     140          90 :         if (!codec->info) return;
     141             : 
     142          90 :         priv->info = codec->info;
     143          90 :         priv->codec = codec;
     144          90 :         codec->has_conditionnals = GF_TRUE;
     145          90 :         gf_node_set_callback_function(node, Conditional_PreDestroy);
     146          90 :         gf_node_set_private(node, priv);
     147          90 :         ((M_Conditional *)node)->on_activate = Conditional_OnActivate;
     148          90 :         ((M_Conditional *)node)->on_reverseActivate = Conditional_OnReverseActivate;
     149             : }
     150             : 
     151             : #endif  /*GPAC_DISABLE_BIFS*/
     152             : 
     153             : 
     154             : /*this is ugly but we have no choice, we need to clone the conditional stack because of externProto*/
     155          39 : void BIFS_SetupConditionalClone(GF_Node *node, GF_Node *orig)
     156             : {
     157             : #ifndef GPAC_DISABLE_BIFS
     158             :         M_Conditional *ptr;
     159             :         ConditionalStack *priv_orig, *priv;
     160          39 :         priv_orig = (ConditionalStack*)gf_node_get_private(orig);
     161             :         /*looks we're not in BIFS*/
     162          39 :         if (!priv_orig) {
     163             : #else
     164             :         {
     165             : #endif
     166             : 
     167             : #ifndef GPAC_DISABLE_VRML
     168             :                 u32 i;
     169             :                 GF_Command *ori_com;
     170             :                 M_Conditional *c_orig, *c_dest;
     171             :                 c_orig = (M_Conditional *)orig;
     172             :                 c_dest = (M_Conditional *)node;
     173          27 :                 gf_node_init(node);
     174             :                 /*and clone all commands*/
     175          27 :                 i=0;
     176          83 :                 while ((ori_com = (GF_Command*)gf_list_enum(c_orig->buffer.commandList, &i))) {
     177          29 :                         GF_Command *dest_com = gf_sg_vrml_command_clone(ori_com, gf_node_get_graph(node), GF_TRUE);
     178          29 :                         if (dest_com) gf_list_add(c_dest->buffer.commandList, dest_com);
     179             :                 }
     180             : #endif
     181             :                 return;
     182             :         }
     183             : 
     184             : #ifndef GPAC_DISABLE_BIFS
     185          12 :         priv = (ConditionalStack*)gf_malloc(sizeof(ConditionalStack));
     186          12 :         priv->codec = priv_orig->codec;
     187          12 :         priv->info = priv_orig->info;
     188          12 :         gf_node_set_callback_function(node, Conditional_PreDestroy);
     189          12 :         gf_node_set_private(node, priv);
     190             :         ptr = (M_Conditional *)node;
     191          12 :         ptr->on_activate = Conditional_OnActivate;
     192          12 :         ptr->on_reverseActivate = Conditional_OnReverseActivate;
     193             : #endif
     194             : 
     195             : }

Generated by: LCOV version 1.13