LCOV - code coverage report
Current view: top level - filters - in_dvb4linux.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 5 163 3.1 %
Date: 2021-04-29 23:48:07 Functions: 2 9 22.2 %

          Line data    Source code
       1             : /*
       2             :  *                      GPAC - Multimedia Framework C SDK
       3             :  *
       4             :  *                      Authors: Jean Le Feuvre
       5             :  *                      Copyright (c) Telecom ParisTech 2017-2021
       6             :  *                                      All rights reserved
       7             :  *
       8             :  *  This file is part of GPAC / DVB4Linux input filter
       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             : #include <gpac/filters.h>
      28             : #include <gpac/constants.h>
      29             : #include <gpac/network.h>
      30             : 
      31             : #ifndef WIN32
      32             : //#define GPAC_HAS_LINUX_DVB
      33             : //#define GPAC_SIM_LINUX_DVB
      34             : #endif
      35             : 
      36             : 
      37             : #ifdef GPAC_HAS_LINUX_DVB
      38             : 
      39             : #include <fcntl.h>
      40             : #include <sys/ioctl.h>
      41             : #include <sys/stat.h>
      42             : #include <unistd.h>
      43             : 
      44             : #ifndef GPAC_SIM_LINUX_DVB
      45             : #include <linux/dvb/dmx.h>
      46             : #include <linux/dvb/frontend.h>
      47             : #endif
      48             : 
      49             : typedef struct
      50             : {
      51             :         //options
      52             :         const char *src;
      53             :         const char *chcfg;
      54             :         u32 block_size;
      55             : 
      56             :         //only one output pid declared
      57             :         GF_FilterPid *pid;
      58             : 
      59             :         u32 freq;
      60             :         u16 vpid;
      61             :         u16 apid;
      62             : 
      63             : #ifndef GPAC_SIM_LINUX_DVB
      64             :         fe_spectral_inversion_t specInv;
      65             :         fe_modulation_t modulation;
      66             :         fe_bandwidth_t bandwidth;
      67             :         fe_transmit_mode_t TransmissionMode;
      68             :         fe_guard_interval_t guardInterval;
      69             :         fe_code_rate_t HP_CodeRate;
      70             :         fe_code_rate_t LP_CodeRate;
      71             :         fe_hierarchy_t hierarchy;
      72             : #endif
      73             : 
      74             :         int demux_fd;
      75             : 
      76             :         char *block;
      77             : 
      78             : } GF_DVBLinuxCtx;
      79             : 
      80             : 
      81           0 : static GF_Err dvblin_tune(GF_DVBLinuxCtx *ctx)
      82             : {
      83             :         FILE *chanfile;
      84             :         char line[255];
      85             : #ifndef GPAC_SIM_LINUX_DVB
      86             :         int demux1, front1;
      87             :         struct dmx_pes_filter_params pesFilterParams;
      88             :         struct dvb_frontend_parameters frp;
      89             :         char chan_name_t[255];
      90             :         char freq_str[255], inv[255], bw[255], lcr[255], hier[255], cr[255],
      91             :              mod[255], transm[255], gi[255], apid_str[255], vpid_str[255];
      92             :         const char *chan_conf = ":%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:";
      93             : #endif
      94             :         char *chan_name;
      95             :         char *tmp;
      96             :         char frontend_name[100], demux_name[100], dvr_name[100];
      97             :         u32 adapter_num;
      98             : 
      99           0 :         if (!ctx->src) {
     100           0 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[DVB4Lin] Missing URL\n"));
     101             :                 return GF_BAD_PARAM;
     102             :         }
     103           0 :         if (!ctx->chcfg) {
     104           0 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[DVB4Lin] Missing channels config file\n"));
     105             :                 return GF_BAD_PARAM;
     106             :         }
     107           0 :         chanfile = gf_fopen(ctx->chcfg, "rb");
     108           0 :         if (!chanfile) return GF_BAD_PARAM;
     109             : 
     110           0 :         chan_name = (char *) ctx->src+6; // 6 = strlen("dvb://")
     111             : 
     112             :         // support for multiple frontends
     113           0 :         tmp = strchr(chan_name, '@');
     114           0 :         if (tmp) {
     115           0 :                 adapter_num = atoi(tmp+1);
     116           0 :                 tmp[0] = 0;
     117             :         } else {
     118             :                 adapter_num = 0;
     119             :         }
     120           0 :         GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("Channel name %s\n", chan_name));
     121             : 
     122           0 :         while(!gf_feof(chanfile)) {
     123           0 :                 if ( gf_fgets(line, 255, chanfile) != NULL) {
     124           0 :                         if (line[0]=='#') continue;
     125           0 :                         if (line[0]=='\r') continue;
     126           0 :                         if (line[0]=='\n') continue;
     127             : 
     128             : #ifndef GPAC_SIM_LINUX_DVB
     129           0 :                         strncpy(chan_name_t, line, index(line, ':')-line);
     130           0 :                         chan_name_t[254] = 0;
     131             : 
     132           0 :                         if (strncmp(chan_name,chan_name_t,strlen(chan_name))==0) {
     133           0 :                                 sscanf(strstr(line,":"), chan_conf, freq_str, inv, bw, lcr, cr, mod, transm, gi, hier, apid_str, vpid_str);
     134           0 :                                 ctx->freq = (uint32_t) atoi(freq_str);
     135           0 :                                 ctx->apid = (uint16_t) atoi(apid_str);
     136           0 :                                 ctx->vpid = (uint16_t) atoi(vpid_str);
     137             :                                 //Inversion
     138           0 :                                 if(! strcmp(inv, "INVERSION_ON")) ctx->specInv = INVERSION_ON;
     139           0 :                                 else if(! strcmp(inv, "INVERSION_OFF")) ctx->specInv = INVERSION_OFF;
     140           0 :                                 else ctx->specInv = INVERSION_AUTO;
     141             :                                 //LP Code Rate
     142           0 :                                 if(! strcmp(lcr, "FEC_1_2")) ctx->LP_CodeRate =FEC_1_2;
     143           0 :                                 else if(! strcmp(lcr, "FEC_2_3")) ctx->LP_CodeRate =FEC_2_3;
     144           0 :                                 else if(! strcmp(lcr, "FEC_3_4")) ctx->LP_CodeRate =FEC_3_4;
     145           0 :                                 else if(! strcmp(lcr, "FEC_4_5")) ctx->LP_CodeRate =FEC_4_5;
     146           0 :                                 else if(! strcmp(lcr, "FEC_6_7")) ctx->LP_CodeRate =FEC_6_7;
     147           0 :                                 else if(! strcmp(lcr, "FEC_8_9")) ctx->LP_CodeRate =FEC_8_9;
     148           0 :                                 else if(! strcmp(lcr, "FEC_5_6")) ctx->LP_CodeRate =FEC_5_6;
     149           0 :                                 else if(! strcmp(lcr, "FEC_7_8")) ctx->LP_CodeRate =FEC_7_8;
     150           0 :                                 else if(! strcmp(lcr, "FEC_NONE")) ctx->LP_CodeRate =FEC_NONE;
     151           0 :                                 else ctx->LP_CodeRate =FEC_AUTO;
     152             :                                 //HP Code Rate
     153           0 :                                 if(! strcmp(cr, "FEC_1_2")) ctx->HP_CodeRate =FEC_1_2;
     154           0 :                                 else if(! strcmp(cr, "FEC_2_3")) ctx->HP_CodeRate =FEC_2_3;
     155           0 :                                 else if(! strcmp(cr, "FEC_3_4")) ctx->HP_CodeRate =FEC_3_4;
     156           0 :                                 else if(! strcmp(cr, "FEC_4_5")) ctx->HP_CodeRate =FEC_4_5;
     157           0 :                                 else if(! strcmp(cr, "FEC_6_7")) ctx->HP_CodeRate =FEC_6_7;
     158           0 :                                 else if(! strcmp(cr, "FEC_8_9")) ctx->HP_CodeRate =FEC_8_9;
     159           0 :                                 else if(! strcmp(cr, "FEC_5_6")) ctx->HP_CodeRate =FEC_5_6;
     160           0 :                                 else if(! strcmp(cr, "FEC_7_8")) ctx->HP_CodeRate =FEC_7_8;
     161           0 :                                 else if(! strcmp(cr, "FEC_NONE")) ctx->HP_CodeRate =FEC_NONE;
     162           0 :                                 else ctx->HP_CodeRate =FEC_AUTO;
     163             :                                 //Modulation
     164           0 :                                 if(! strcmp(mod, "QAM_128")) ctx->modulation = QAM_128;
     165           0 :                                 else if(! strcmp(mod, "QAM_256")) ctx->modulation = QAM_256;
     166           0 :                                 else if(! strcmp(mod, "QAM_64")) ctx->modulation = QAM_64;
     167           0 :                                 else if(! strcmp(mod, "QAM_32")) ctx->modulation = QAM_32;
     168           0 :                                 else if(! strcmp(mod, "QAM_16")) ctx->modulation = QAM_16;
     169             :                                 //Bandwidth
     170           0 :                                 if(! strcmp(bw, "BANDWIDTH_6_MHZ")) ctx->bandwidth = BANDWIDTH_6_MHZ;
     171           0 :                                 else if(! strcmp(bw, "BANDWIDTH_7_MHZ")) ctx->bandwidth = BANDWIDTH_7_MHZ;
     172           0 :                                 else if(! strcmp(bw, "BANDWIDTH_8_MHZ")) ctx->bandwidth = BANDWIDTH_8_MHZ;
     173             :                                 //Transmission Mode
     174           0 :                                 if(! strcmp(transm, "TRANSMISSION_MODE_2K")) ctx->TransmissionMode = TRANSMISSION_MODE_2K;
     175           0 :                                 else if(! strcmp(transm, "TRANSMISSION_MODE_8K")) ctx->TransmissionMode = TRANSMISSION_MODE_8K;
     176             :                                 //Guard Interval
     177           0 :                                 if(! strcmp(gi, "GUARD_INTERVAL_1_32")) ctx->guardInterval = GUARD_INTERVAL_1_32;
     178           0 :                                 else if(! strcmp(gi, "GUARD_INTERVAL_1_16")) ctx->guardInterval = GUARD_INTERVAL_1_16;
     179           0 :                                 else if(! strcmp(gi, "GUARD_INTERVAL_1_8")) ctx->guardInterval = GUARD_INTERVAL_1_8;
     180           0 :                                 else ctx->guardInterval = GUARD_INTERVAL_1_4;
     181             :                                 //Hierarchy
     182           0 :                                 if(! strcmp(hier, "HIERARCHY_1")) ctx->hierarchy = HIERARCHY_1;
     183           0 :                                 else if(! strcmp(hier, "HIERARCHY_2")) ctx->hierarchy = HIERARCHY_2;
     184           0 :                                 else if(! strcmp(hier, "HIERARCHY_4")) ctx->hierarchy = HIERARCHY_4;
     185           0 :                                 else if(! strcmp(hier, "HIERARCHY_AUTO")) ctx->hierarchy = HIERARCHY_AUTO;
     186           0 :                                 else ctx->hierarchy = HIERARCHY_NONE;
     187             : 
     188             :                                 break;
     189             :                         }
     190             : #endif
     191             : 
     192             :                 }
     193             :         }
     194           0 :         gf_fclose(chanfile);
     195             : 
     196             :         sprintf(frontend_name, "/dev/dvb/adapter%d/frontend0", adapter_num);
     197             :         sprintf(demux_name, "/dev/dvb/adapter%d/demux0", adapter_num);
     198             :         sprintf(dvr_name, "/dev/dvb/adapter%d/dvr0", adapter_num);
     199             : 
     200             : #ifndef GPAC_SIM_LINUX_DVB
     201             :         // Open frontend
     202           0 :         if((front1 = open(frontend_name,O_RDWR|O_NONBLOCK)) < 0) {
     203           0 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("Cannot open frontend %s.\n", frontend_name));
     204             :                 return GF_IO_ERR;
     205             :         } else {
     206           0 :                 GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("Frontend %s opened.\n", frontend_name));
     207             :         }
     208             :         // Open demuxes
     209           0 :         if ((demux1=open(demux_name, O_RDWR|O_NONBLOCK)) < 0) {
     210           0 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("Cannot open demux %s\n", demux_name));
     211             :                 return GF_IO_ERR;
     212             :         } else {
     213           0 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("Demux %s opened.\n", demux_name));
     214             :         }
     215             :         // Set FrontendParameters - DVB-T
     216           0 :         frp.frequency = ctx->freq;
     217           0 :         frp.inversion = ctx->specInv;
     218           0 :         frp.u.ofdm.bandwidth = ctx->bandwidth;
     219           0 :         frp.u.ofdm.code_rate_HP = ctx->HP_CodeRate;
     220           0 :         frp.u.ofdm.code_rate_LP = ctx->LP_CodeRate;
     221           0 :         frp.u.ofdm.constellation = ctx->modulation;
     222           0 :         frp.u.ofdm.transmission_mode = ctx->TransmissionMode;
     223           0 :         frp.u.ofdm.guard_interval = ctx->guardInterval;
     224           0 :         frp.u.ofdm.hierarchy_information = ctx->hierarchy;
     225             :         // Set frontend
     226           0 :         if (ioctl(front1, FE_SET_FRONTEND, &frp) < 0) {
     227             :                 return GF_IO_ERR;
     228             :         }
     229             : 
     230             :         // Set dumex
     231           0 :         pesFilterParams.pid      = 0x2000;                              // Linux-DVB API take PID=2000 for FULL/RAW TS flag
     232           0 :         pesFilterParams.input    = DMX_IN_FRONTEND;
     233           0 :         pesFilterParams.output   = DMX_OUT_TS_TAP;
     234           0 :         pesFilterParams.pes_type = DMX_PES_OTHER;
     235           0 :         pesFilterParams.flags    = DMX_IMMEDIATE_START;
     236           0 :         if (ioctl(demux1, DMX_SET_PES_FILTER, &pesFilterParams) < 0) {
     237             :                 return GF_IO_ERR;
     238             :         }
     239             :         /* The following code differs from mplayer and alike because the device is opened in blocking mode */
     240           0 :         if ((ctx->demux_fd = open(dvr_name, O_RDONLY/*|O_NONBLOCK*/)) < 0) {
     241             :                 return GF_IO_ERR;
     242             :         }
     243             : #endif
     244             : 
     245           0 :         return GF_OK;
     246             : }
     247             : 
     248           0 : static u32 gf_dvblin_get_freq_from_url(GF_DVBLinuxCtx *ctx, const char *url)
     249             : {
     250             :         FILE *chcfgig_file;
     251             :         char line[255], *tmp, *channel_name;
     252             : 
     253             :         u32 freq;
     254             : 
     255             :         /* get rid of trailing @ */
     256           0 :         tmp = strchr(url, '@');
     257           0 :         if (tmp) tmp[0] = 0;
     258             : 
     259           0 :         channel_name = (char *)url+6;
     260             : 
     261           0 :         chcfgig_file = gf_fopen(ctx->chcfg, "rb");
     262           0 :         if (!chcfgig_file) return GF_BAD_PARAM;
     263             : 
     264             :         freq = 0;
     265           0 :         while(!gf_feof(chcfgig_file)) {
     266           0 :                 if ( gf_fgets(line, 255, chcfgig_file) != NULL) {
     267           0 :                         if (line[0]=='#') continue;
     268           0 :                         if (line[0]=='\r') continue;
     269           0 :                         if (line[0]=='\n') continue;
     270             : 
     271           0 :                         tmp = strchr(line, ':');
     272           0 :                         tmp[0] = 0;
     273           0 :                         if (!strcmp(line, channel_name)) {
     274             :                                 char *tmp2;
     275           0 :                                 tmp++;
     276           0 :                                 tmp2 = strchr(tmp, ':');
     277           0 :                                 if (tmp2) tmp2[0] = 0;
     278           0 :                                 freq = (u32)atoi(tmp);
     279             :                                 break;
     280             :                         }
     281             :                 }
     282             :         }
     283             :         return freq;
     284             : }
     285             : 
     286           0 : GF_Err dvblin_setup_demux(GF_DVBLinuxCtx *ctx)
     287             : {
     288             :         GF_Err e = GF_OK;
     289             : 
     290           0 :         if (!ctx->chcfg) {
     291           0 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[DVB4Lin] Missing channels config file\n"));
     292             :                 return GF_BAD_PARAM;
     293             :         }
     294           0 :         if (strnicmp(ctx->src, "dvb://", 6)) return GF_NOT_SUPPORTED;
     295             : 
     296           0 :         if ((ctx->freq != 0) && (ctx->freq == gf_dvblin_get_freq_from_url(ctx, ctx->src)) ) {
     297           0 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[M2TSDemux] Tuner already tuned to that frequency\n"));
     298             :                 return GF_OK;
     299             :         }
     300             : 
     301           0 :         e = dvblin_tune(ctx);
     302           0 :         if (e) {
     303           0 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[M2TSDemux] Unable to tune to frequency\n"));
     304             :                 return GF_SERVICE_ERROR;
     305             :         }
     306             :         return GF_OK;
     307             : }
     308             : 
     309             : 
     310             : 
     311             : 
     312           0 : GF_Err dvblin_initialize(GF_Filter *filter)
     313             : {
     314             :         GF_Err e = GF_OK;
     315           0 :         GF_DVBLinuxCtx *ctx = (GF_DVBLinuxCtx *) gf_filter_get_udta(filter);
     316             : 
     317           0 :         if (!ctx || !ctx->src) return GF_BAD_PARAM;
     318           0 :         e = dvblin_setup_demux(ctx);
     319             : 
     320           0 :         if (e) {
     321           0 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[DVBLinux] Failed to open %s\n", ctx->src));
     322           0 :                 gf_filter_setup_failure(filter, e);
     323           0 :                 return GF_URL_ERROR;
     324             :         }
     325           0 :         GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[DVBLinux] opening %s\n", ctx->src));
     326             : 
     327           0 :         ctx->block = gf_malloc(ctx->block_size +1);
     328           0 :         return GF_OK;
     329             : }
     330             : 
     331           0 : void dvblin_finalize(GF_Filter *filter)
     332             : {
     333           0 :         GF_DVBLinuxCtx *ctx = (GF_DVBLinuxCtx *) gf_filter_get_udta(filter);
     334             : #ifndef GPAC_SIM_LINUX_DVB
     335           0 :         if (ctx->demux_fd) close(ctx->demux_fd);
     336             : #endif
     337           0 :         if (ctx->block) gf_free(ctx->block);
     338           0 : }
     339             : 
     340        2939 : GF_FilterProbeScore dvblin_probe_url(const char *url, const char *mime_type)
     341             : {
     342        2939 :         if (!strnicmp(url, "dvb://", 6)) return GF_FPROBE_SUPPORTED;
     343        2939 :         return GF_FPROBE_NOT_SUPPORTED;
     344             : }
     345             : 
     346             : 
     347           0 : static Bool dvblin_process_event(GF_Filter *filter, const GF_FilterEvent *evt)
     348             : {
     349           0 :         GF_DVBLinuxCtx *ctx = (GF_DVBLinuxCtx *) gf_filter_get_udta(filter);
     350             : 
     351           0 :         if (!evt->base.on_pid) return GF_FALSE;
     352           0 :         if (evt->base.on_pid != ctx->pid) return GF_FALSE;
     353             : 
     354           0 :         switch (evt->base.type) {
     355           0 :         case GF_FEVT_PLAY:
     356           0 :                 dvblin_setup_demux(ctx);
     357           0 :                 return GF_TRUE;
     358           0 :         case GF_FEVT_STOP:
     359             : #ifndef GPAC_SIM_LINUX_DVB
     360           0 :                 if (ctx->demux_fd) close(ctx->demux_fd);
     361           0 :                 ctx->demux_fd = 0;
     362             : #endif
     363           0 :                 return GF_TRUE;
     364             :         default:
     365             :                 break;
     366             :         }
     367             :         return GF_FALSE;
     368             : }
     369             : 
     370           0 : static GF_Err dvblin_process(GF_Filter *filter)
     371             : {
     372             :         GF_FilterPacket *dst_pck;
     373             :         u8 *out_data;
     374           0 :         GF_DVBLinuxCtx *ctx = (GF_DVBLinuxCtx *) gf_filter_get_udta(filter);
     375             : 
     376           0 :         if (!ctx->freq) return GF_EOS;
     377             : 
     378             : #ifndef GPAC_SIM_LINUX_DVB
     379           0 :         u32 nb_read = read(ctx->demux_fd, ctx->block, ctx->block_size);
     380           0 :         if (!nb_read) return GF_OK;
     381             : #endif
     382             : 
     383           0 :         dst_pck = gf_filter_pck_new_alloc(ctx->pid, nb_read, &out_data);
     384           0 :         if (!dst_pck) return GF_OUT_OF_MEM;
     385           0 :         memcpy(out_data, ctx->block, nb_read);
     386           0 :         gf_filter_pck_set_framing(dst_pck, GF_TRUE, GF_TRUE);
     387           0 :         gf_filter_pck_send(dst_pck);
     388           0 :         return GF_OK;
     389             : }
     390             : 
     391             : #else
     392             : static GF_Err dvblin_process(GF_Filter *filter)
     393             : {
     394             :         return GF_EOS;
     395             : }
     396             : #endif //GPAC_HAS_LINUX_DVB
     397             : 
     398             : 
     399             : #ifdef GPAC_HAS_LINUX_DVB
     400             : #define OFFS(_n)        #_n, offsetof(GF_DVBLinuxCtx, _n)
     401             : #else
     402             : #define OFFS(_n)        #_n, -1
     403             : #endif
     404             : 
     405             : static const GF_FilterArgs DVBLinuxArgs[] =
     406             : {
     407             :         { OFFS(src), "URL of source content - see filter help", GF_PROP_NAME, NULL, NULL, 0},
     408             :         { OFFS(block_size), "block size used to read file", GF_PROP_UINT, "65536", NULL, GF_FS_ARG_HINT_ADVANCED},
     409             :         { OFFS(chcfg), "path to channels.conf file", GF_PROP_NAME, NULL, NULL, 0},
     410             :         {0}
     411             : };
     412             : 
     413             : GF_FilterRegister DVBLinuxRegister = {
     414             :         .name = "dvbin",
     415             :         GF_FS_SET_DESCRIPTION("DVB for Linux")
     416             :         GF_FS_SET_HELP("Experimental DVB support for linux, requires a channel config file through [-chcfg]()\n"
     417             :         "  \n"
     418             :         "The URL syntax is `dvb://CHANNAME[@FRONTEND]`, with:\n"
     419             :         " - CHANNAME: the channel name as listed in the channel config file\n"
     420             :         " - frontend: the index of the DVB adapter to use (optional, default is 0)\n"
     421             :         )
     422             :         .args = DVBLinuxArgs,
     423             : #ifdef GPAC_HAS_LINUX_DVB
     424             :         .private_size = sizeof(GF_DVBLinuxCtx),
     425             :         .initialize = dvblin_initialize,
     426             :         .finalize = dvblin_finalize,
     427             :         .process = dvblin_process,
     428             :         .process_event = dvblin_process_event,
     429             :         .probe_url = dvblin_probe_url
     430             : #else
     431             :         .process = dvblin_process,
     432             : #endif
     433             : };
     434             : 
     435        2877 : const GF_FilterRegister *dvblin_register(GF_FilterSession *session)
     436             : {
     437             : #if !defined(GPAC_HAS_LINUX_DVB) || defined(GPAC_SIM_LINUX_DVB)
     438             :         if (!gf_opts_get_bool("temp", "gendoc"))
     439             :                 return NULL;
     440             :         DVBLinuxRegister.version = "! Warning: DVB4Linux NOT AVAILABLE IN THIS BUILD !";
     441             : #endif
     442        2877 :         return &DVBLinuxRegister;
     443             : }
     444             : 

Generated by: LCOV version 1.13