LCOV - code coverage report
Current view: top level - src/lib/signals.c (source / functions) Coverage Total Hit
Test: coverage.filtered.info Lines: 84.1 % 63 53
Test Date: 2025-09-18 00:43:48 Functions: 100.0 % 4 4

            Line data    Source code
       1              : /*
       2              :  *                      GPAC - Multimedia Framework C SDK
       3              :  *
       4              :  *                      Authors: Deniz Ugur, Romain Bouqueau, Sohaib Larbi
       5              :  *                      Copyright (c) Motion Spell
       6              :  *                              All rights reserved
       7              :  *
       8              :  *  This file is part of the GPAC/GStreamer wrapper
       9              :  *
      10              :  *  This GPAC/GStreamer wrapper is free software; you can redistribute it
      11              :  *  and/or modify it under the terms of the GNU Affero General Public License
      12              :  *  as published by the Free Software Foundation; either version 3, or (at
      13              :  *  your option) any later version.
      14              :  *
      15              :  *  This GPAC/GStreamer wrapper is distributed in the hope that it will be
      16              :  *  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
      17              :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18              :  *  GNU Affero General Public License for more details.
      19              :  *
      20              :  *  You should have received a copy of the GNU Affero General Public
      21              :  *  License along with this library; see the file LICENSE.  If not, write to
      22              :  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
      23              :  *
      24              :  */
      25              : 
      26              : #include "lib/signals.h"
      27              : #include "elements/common.h"
      28              : 
      29              : typedef struct
      30              : {
      31              :   const gchar* preset_name;
      32              :   union
      33              :   {
      34              :     struct
      35              :     {
      36              :       guint32 from_id;
      37              :       guint32 to_id;
      38              :     };
      39              :     guint32* ids;
      40              :   };
      41              : } signal_info;
      42              : 
      43              : #define GPAC_SIGNAL_ID_ARRAY(...) (guint32[]){ __VA_ARGS__, 0 }
      44              : #define GPAC_SIGNAL_PRESET_RANGE(name, from, to)              \
      45              :   { .preset_name = (name), .from_id = (from), .to_id = (to) }
      46              : #define GPAC_SIGNAL_PRESET(name, ...)                                 \
      47              :   { .preset_name = (name), .ids = GPAC_SIGNAL_ID_ARRAY(__VA_ARGS__) }
      48              : 
      49              : static signal_info signal_presets[] = {
      50              :   GPAC_SIGNAL_PRESET_RANGE("dasher_all",
      51              :                            GPAC_SIGNAL_DASHER_MANIFEST,
      52              :                            GPAC_SIGNAL_DASHER_DELETE_SEGMENT),
      53              : };
      54              : 
      55              : void
      56           25 : register_signal(GObjectClass* klass, GPAC_SignalId id)
      57              : {
      58           25 :   g_assert(klass != NULL);
      59           25 :   g_assert(id < GPAC_SIGNAL_LAST);
      60           25 :   GstGpacParams* params = GST_GPAC_GET_PARAMS(klass);
      61           25 :   guint* registered_signals = params->registered_signals;
      62              : 
      63           25 :   if (registered_signals[id])
      64            0 :     return; // Already registered
      65              : 
      66           25 :   switch (id) {
      67           20 :     case GPAC_SIGNAL_DASHER_MANIFEST:
      68              :     case GPAC_SIGNAL_DASHER_MANIFEST_VARIANT:
      69              :     case GPAC_SIGNAL_DASHER_SEGMENT_INIT:
      70              :     case GPAC_SIGNAL_DASHER_SEGMENT:
      71           40 :       registered_signals[id] = g_signal_new(
      72           20 :         gpac_signal_names[id - 1], // Adjusted index for 0-based array
      73              :         G_TYPE_FROM_CLASS(klass),
      74              :         G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE,
      75              :         0,
      76              :         NULL,
      77              :         NULL,
      78              :         NULL,
      79              :         G_TYPE_OUTPUT_STREAM,
      80              :         1,
      81              :         G_TYPE_STRING);
      82           20 :       break;
      83              : 
      84            5 :     case GPAC_SIGNAL_DASHER_DELETE_SEGMENT:
      85           10 :       registered_signals[id] = g_signal_new(
      86            5 :         gpac_signal_names[id - 1], // Adjusted index for 0-based array
      87              :         G_TYPE_FROM_CLASS(klass),
      88              :         G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE,
      89              :         0,
      90              :         NULL,
      91              :         NULL,
      92              :         NULL,
      93              :         G_TYPE_BOOLEAN, // Whether the segment was deleted
      94              :         1,
      95              :         G_TYPE_STRING);
      96            5 :       break;
      97              : 
      98            0 :     default:
      99            0 :       break;
     100              :   };
     101              : }
     102              : 
     103              : void
     104            2 : gpac_install_signals_by_presets(GObjectClass* gobject_class,
     105              :                                 const gchar* presets)
     106              : {
     107            2 :   g_assert(gobject_class != NULL);
     108            2 :   g_assert(presets != NULL);
     109              : 
     110            2 :   gchar** preset_list = g_strsplit(presets, ",", -1);
     111            4 :   for (gint i = 0; preset_list[i] != NULL; i++) {
     112            2 :     const gchar* preset_name = g_strstrip(preset_list[i]);
     113            2 :     for (guint j = 0; j < G_N_ELEMENTS(signal_presets); j++) {
     114            2 :       if (g_strcmp0(signal_presets[j].preset_name, preset_name) == 0) {
     115            2 :         guint32 from = signal_presets[j].from_id;
     116            2 :         guint32 to = signal_presets[j].to_id;
     117            2 :         if (!from)
     118            0 :           from = GPAC_SIGNAL_START;
     119            2 :         if (!to)
     120            0 :           to = GPAC_SIGNAL_END;
     121              : 
     122           12 :         for (guint32 id = from; id <= to && id < GPAC_SIGNAL_LAST; id++) {
     123           10 :           register_signal(gobject_class, id);
     124              :         }
     125            2 :         break;
     126              :       }
     127              :     }
     128              :   }
     129            2 :   g_strfreev(preset_list);
     130            2 : }
     131              : 
     132              : void
     133            3 : gpac_install_all_signals(GObjectClass* gobject_class)
     134              : {
     135            3 :   g_assert(gobject_class != NULL);
     136              : 
     137           18 :   for (guint32 id = GPAC_SIGNAL_START; id < GPAC_SIGNAL_LAST; id++) {
     138           15 :     register_signal(gobject_class, id);
     139              :   }
     140            3 : }
     141              : 
     142              : gboolean
     143           82 : gpac_signal_try_emit(GstElement* element,
     144              :                      GPAC_SignalId id,
     145              :                      const gchar* location,
     146              :                      GOutputStream** output_stream)
     147              : {
     148           82 :   g_assert(element != NULL);
     149           82 :   g_assert(id < GPAC_SIGNAL_LAST);
     150              : 
     151           82 :   GstObject* parent = GST_OBJECT(element);
     152              :   do {
     153          164 :     GObjectClass* klass = G_OBJECT_GET_CLASS(parent);
     154          164 :     GstGpacParams* params = GST_GPAC_GET_PARAMS(klass);
     155          164 :     guint* registered_signals = params->registered_signals;
     156              : 
     157              :     // We may not have registered this signal
     158          164 :     if (!registered_signals[id])
     159           82 :       continue;
     160              : 
     161           82 :     guint signal_id = registered_signals[id];
     162           82 :     if (signal_id) {
     163           82 :       if (output_stream) {
     164           82 :         *output_stream = NULL;
     165           82 :         g_signal_emit(parent, signal_id, 0, location, output_stream);
     166           82 :         return (*output_stream != NULL);
     167              :       }
     168              : 
     169            0 :       gboolean deleted = FALSE;
     170            0 :       g_signal_emit(parent, signal_id, 0, location, &deleted);
     171            0 :       return deleted;
     172              :     }
     173           82 :   } while ((parent = gst_element_get_parent(parent)));
     174              : 
     175            0 :   GST_DEBUG_OBJECT(element,
     176              :                    "Signal %s not registered for element %s",
     177              :                    gpac_signal_names[id - 1],
     178              :                    GST_OBJECT_NAME(element));
     179              : 
     180            0 :   return FALSE;
     181              : }
        

Generated by: LCOV version 2.0-1