LCOV - code coverage report
Current view: top level - compositor - mpeg4_timesensor.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 83 84 98.8 %
Date: 2021-04-29 23:48:07 Functions: 4 4 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 / Scene Compositor 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             : #include "nodes_stacks.h"
      27             : 
      28             : #include <gpac/nodes_mpeg4.h>
      29             : #include <gpac/nodes_x3d.h>
      30             : 
      31             : 
      32             : #ifndef GPAC_DISABLE_VRML
      33             : 
      34             : typedef struct
      35             : {
      36             :         GF_TimeNode time_handle;
      37             :         Bool store_info;
      38             :         Double start_time, cycle_interval;
      39             :         u32 num_cycles;
      40             :         GF_Compositor *compositor;
      41             : #ifndef GPAC_DISABLE_X3D
      42             :         Bool is_x3d;
      43             : #endif
      44             : } TimeSensorStack;
      45             : 
      46       92464 : static void timesensor_destroy(GF_Node *ts, void *rs, Bool is_destroy)
      47             : {
      48       92464 :         if (is_destroy) {
      49         536 :                 TimeSensorStack *st = (TimeSensorStack *)gf_node_get_private(ts);
      50         536 :                 if (st->time_handle.is_registered) {
      51         139 :                         gf_sc_unregister_time_node(st->compositor, &st->time_handle);
      52             :                 }
      53         536 :                 gf_free(st);
      54             :         }
      55       92464 : }
      56             : 
      57             : 
      58             : static
      59             : void timesensor_deactivate(TimeSensorStack *stack, M_TimeSensor *ts)
      60             : {
      61          96 :         ts->isActive = 0;
      62          96 :         gf_node_event_out((GF_Node *) ts, 7);//"isActive"
      63             :         assert(stack->time_handle.is_registered);
      64          96 :         stack->time_handle.needs_unregister = 1;
      65          96 :         stack->num_cycles = 0;
      66             : }
      67             : 
      68             : static
      69       23090 : void timesensor_update_time(GF_TimeNode *st)
      70             : {
      71             :         Double currentTime, cycleTime;
      72             :         Fixed newFraction;
      73             :         u32 inc;
      74       23090 :         M_TimeSensor *TS = (M_TimeSensor *)st->udta;
      75       23090 :         TimeSensorStack *stack = (TimeSensorStack *)gf_node_get_private(st->udta);
      76             : 
      77       23090 :         if (! TS->enabled) {
      78         458 :                 if (TS->isActive) {
      79           6 :                         TS->cycleTime = gf_node_get_scene_time(st->udta);
      80           6 :                         gf_node_event_out(st->udta, 5);//"cycleTime"
      81             :                         timesensor_deactivate(stack, TS);
      82             :                 }
      83             :                 return;
      84             :         }
      85             : 
      86       22632 :         if (stack->store_info) {
      87         653 :                 stack->store_info = 0;
      88         653 :                 stack->start_time = TS->startTime;
      89         653 :                 stack->cycle_interval = TS->cycleInterval;
      90             :         }
      91             : 
      92       22632 :         currentTime = gf_node_get_scene_time(st->udta);
      93       22632 :         if (!TS->isActive) {
      94        2511 :                 if (currentTime < stack->start_time) return;
      95             :                 /*special case: if we're greater than both start and stop time don't activate*/
      96         797 :                 if (!TS->isActive && (TS->stopTime > stack->start_time) && (currentTime >= TS->stopTime)) {
      97         418 :                         stack->time_handle.needs_unregister = 1;
      98         418 :                         return;
      99             :                 }
     100             : #ifndef GPAC_DISABLE_X3D
     101         379 :                 if (stack->is_x3d && !TS->loop) {
     102         152 :                         if (!stack->start_time && !gf_sys_old_arch_compat() ) return;
     103         152 :                         if (currentTime >= TS->startTime+stack->cycle_interval) return;
     104             :                 }
     105             : #endif
     106             :         }
     107             : 
     108       20348 :         cycleTime = currentTime - stack->start_time - stack->num_cycles * stack->cycle_interval;
     109       20348 :         newFraction = FLT2FIX ( fmod(cycleTime, stack->cycle_interval) / stack->cycle_interval );
     110             : 
     111       20348 :         if (TS->isActive) {
     112       20121 :                 TS->time = currentTime;
     113       20121 :                 gf_node_event_out(st->udta, 8);//"time"
     114             : 
     115             :                 /*VRML:
     116             :                         "f = fmod( (now - startTime) , cycleInterval) / cycleInterval
     117             :                         if (f == 0.0 && now > startTime) fraction_changed = 1.0
     118             :                         else fraction_changed = f"
     119             :                 */
     120       20121 :                 if (!newFraction && (currentTime > stack->start_time ) ) newFraction = FIX_ONE;
     121             : 
     122             :                 /*check for deactivation - if so generate a fraction_changed AS IF NOW WAS EXACTLY STOPTIME*/
     123       20121 :                 if ((TS->stopTime > stack->start_time) && (currentTime >= TS->stopTime) ) {
     124          10 :                         cycleTime = TS->stopTime - stack->start_time - stack->num_cycles * stack->cycle_interval;
     125          10 :                         TS->fraction_changed = FLT2FIX( fmod(cycleTime, stack->cycle_interval) / stack->cycle_interval );
     126             :                         /*cf above*/
     127          10 :                         if (TS->fraction_changed < FIX_EPSILON) TS->fraction_changed = FIX_ONE;
     128          10 :                         gf_node_event_out(st->udta, 6);//"fraction_changed"
     129             :                         timesensor_deactivate(stack, TS);
     130             :                         return;
     131             :                 }
     132       20111 :                 if (! TS->loop) {
     133        2055 :                         if (cycleTime >= stack->cycle_interval) {
     134          80 :                                 TS->fraction_changed = FIX_ONE;
     135          80 :                                 gf_node_event_out(st->udta, 6);//"fraction_changed"
     136             :                                 timesensor_deactivate(stack, TS);
     137             :                                 return;
     138             :                         }
     139             :                 }
     140       20031 :                 if (newFraction != TS->fraction_changed) {
     141       19278 :                         TS->fraction_changed = newFraction;
     142       19278 :                         gf_node_event_out(st->udta, 6);//"fraction_changed"
     143             :                 }
     144             :         }
     145             : 
     146             :         /*we're (about to be) active: VRML:
     147             :         "A time-dependent node is inactive until its startTime is reached. When time now becomes greater than or
     148             :         equal to startTime, an isActive TRUE event is generated and the time-dependent node becomes active      */
     149             : 
     150       20258 :         if (!TS->isActive) {
     151         227 :                 st->needs_unregister = 0;
     152         227 :                 TS->isActive = 1;
     153         227 :                 gf_node_event_out(st->udta, 7); //"isActive"
     154         227 :                 TS->cycleTime = currentTime;
     155         227 :                 gf_node_event_out(st->udta, 5);//"cycleTime"
     156         227 :                 TS->fraction_changed = newFraction;
     157         227 :                 gf_node_event_out(st->udta, 6);//"fraction_changed"
     158             :         }
     159             : 
     160             :         //compute cycle time
     161       20258 :         if (TS->loop && (cycleTime >= stack->cycle_interval) ) {
     162         655 :                 inc = 1 + (u32) ( (cycleTime - stack->cycle_interval ) / stack->cycle_interval );
     163         655 :                 stack->num_cycles += inc;
     164         655 :                 cycleTime -= inc*stack->cycle_interval;
     165         655 :                 TS->cycleTime = currentTime - cycleTime;
     166         655 :                 gf_node_event_out(st->udta, 5);//"cycleTime"
     167             :         }
     168             : }
     169             : 
     170         536 : void compositor_init_timesensor(GF_Compositor *compositor, GF_Node *node)
     171             : {
     172             :         TimeSensorStack *st;
     173         536 :         GF_SAFEALLOC(st, TimeSensorStack);
     174         536 :         if (!st) {
     175           0 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_COMPOSE, ("[Compositor] Failed to allocate time  sensor 2d stack\n"));
     176             :                 return;
     177             :         }
     178         536 :         st->time_handle.UpdateTimeNode = timesensor_update_time;
     179         536 :         st->time_handle.udta = node;
     180         536 :         st->store_info = 1;
     181         536 :         st->compositor = compositor;
     182             : #ifndef GPAC_DISABLE_X3D
     183         536 :         st->is_x3d = (gf_node_get_tag(node)==TAG_X3D_TimeSensor) ? 1 : 0;
     184             : #endif
     185         536 :         gf_node_set_private(node, st);
     186         536 :         gf_node_set_callback_function(node, timesensor_destroy);
     187             :         /*time sensor needs to be run only if def'ed, otherwise it doesn't impact scene*/
     188             :         //if (gf_node_get_id(node))
     189         536 :         gf_sc_register_time_node(compositor, &st->time_handle);
     190             : }
     191             : 
     192             : 
     193         325 : void compositor_timesensor_modified(GF_Node *t)
     194             : {
     195             :         M_TimeSensor *ts = (M_TimeSensor *)t;
     196         325 :         TimeSensorStack *stack = (TimeSensorStack *) gf_node_get_private(t);
     197         325 :         if (!stack) return;
     198             : 
     199         325 :         if (ts->isActive) timesensor_update_time(&stack->time_handle);
     200             : 
     201         325 :         if (!ts->isActive) stack->store_info = 1;
     202             : 
     203         325 :         if (ts->enabled) {
     204         293 :                 stack->time_handle.needs_unregister = 0;
     205         293 :                 if (!stack->time_handle.is_registered) {
     206         110 :                         gf_sc_register_time_node(stack->compositor, &stack->time_handle);
     207             :                 }
     208             :         }
     209             : }
     210             : 
     211             : #endif /*GPAC_DISABLE_VRML*/

Generated by: LCOV version 1.13