Commit 7e34273a authored by Laurent Aimar's avatar Laurent Aimar

Added DVB scan capability.

Only DVB-T tuner is supported (but it would be easy to add DVB-S/C).
The files scan.c/h are strictly independant of the DVB access and could
be reused for the DBA access if wanted.
parent 66715267
SOURCES_dvb = \
access.c \
scan.c \
linux_dvb.c \
en50221.c \
http.c \
......
This diff is collapsed.
......@@ -24,6 +24,8 @@
*****************************************************************************/
#include "scan.h"
/*****************************************************************************
* Devices location
*****************************************************************************/
......@@ -43,6 +45,19 @@ typedef struct demux_handle_t
} demux_handle_t;
typedef struct frontend_t frontend_t;
typedef struct
{
int i_snr; /**< Signal Noise ratio */
int i_ber; /**< Bitrate error ratio */
int i_signal_strenth; /**< Signal strength */
} frontend_statistic_t;
typedef struct
{
bool b_has_signal;
bool b_has_carrier;
bool b_has_lock;
} frontend_status_t;
typedef struct en50221_session_t
{
......@@ -138,6 +153,7 @@ struct access_sys_t
demux_handle_t p_demux_handles[MAX_DEMUX];
frontend_t *p_frontend;
bool b_budget_mode;
bool b_scan_mode;
/* CA management */
int i_ca_handle;
......@@ -168,6 +184,9 @@ struct access_sys_t
char *psz_frontend_info, *psz_mmi_info;
char *psz_request;
#endif
/* Scan */
scan_t scan;
};
#define VIDEO0_TYPE 1
......@@ -181,6 +200,7 @@ struct access_sys_t
/*****************************************************************************
* Prototypes
*****************************************************************************/
int FrontendOpen( access_t * );
void FrontendPoll( access_t *p_access );
int FrontendSet( access_t * );
......@@ -189,6 +209,10 @@ void FrontendClose( access_t * );
void FrontendStatus( access_t * );
#endif
int FrontendGetStatistic( access_t *, frontend_statistic_t * );
void FrontendGetStatus( access_t *, frontend_status_t * );
int FrontendGetScanParameter( access_t *, scan_parameter_t * );
int DMXSetFilter( access_t *, int i_pid, int * pi_fd, int i_type );
int DMXUnsetFilter( access_t *, int i_fd );
......@@ -214,6 +238,8 @@ void en50221_SendMMIObject( access_t * p_access, int i_slot,
en50221_mmi_object_t *p_object );
void en50221_End( access_t * );
char *dvbsi_to_utf8( char *psz_instring, size_t i_length );
#ifdef ENABLE_HTTPD
int HTTPOpen( access_t *p_access );
void HTTPClose( access_t *p_access );
......@@ -225,3 +251,4 @@ char *HTTPExtractValue( char *psz_uri, const char *psz_name,
*****************************************************************************/
#define STRINGIFY( z ) UGLY_KLUDGE( z )
#define UGLY_KLUDGE( z ) #z
......@@ -55,6 +55,9 @@
# include <dvbpsi/pmt.h>
# include <dvbpsi/dr.h>
# include <dvbpsi/psi.h>
# include <dvbpsi/demux.h>
# include <dvbpsi/sdt.h>
# include <dvbpsi/nit.h>
#else
# include "dvbpsi.h"
# include "descriptor.h"
......@@ -62,6 +65,9 @@
# include "tables/pmt.h"
# include "descriptors/dr.h"
# include "psi.h"
# include "demux.h"
# include "sdt.h"
# include "nit.h"
#endif
#ifdef ENABLE_HTTPD
......@@ -81,7 +87,6 @@ static void ApplicationInformationOpen( access_t * p_access, int i_session_id );
static void ConditionalAccessOpen( access_t * p_access, int i_session_id );
static void DateTimeOpen( access_t * p_access, int i_session_id );
static void MMIOpen( access_t * p_access, int i_session_id );
static char *dvbsi_to_utf8( char *psz_instring, size_t i_length );
/*****************************************************************************
* Utility functions
......@@ -174,6 +179,8 @@ static void Dump( bool b_outgoing, uint8_t *p_data, int i_size )
for ( i = 0; i < i_size && i < MAX_DUMP; i++)
fprintf(stderr, "%02X ", p_data[i]);
fprintf(stderr, "%s\n", i_size >= MAX_DUMP ? "..." : "");
#else
VLC_UNUSED(b_outgoing); VLC_UNUSED(p_data); VLC_UNUSED(i_size);
#endif
}
......@@ -2318,7 +2325,7 @@ static inline void *FixUTF8( char *p )
return p;
}
static char *dvbsi_to_utf8( char *psz_instring, size_t i_length )
char *dvbsi_to_utf8( char *psz_instring, size_t i_length )
{
const char *psz_encoding, *psz_stringstart;
char *psz_outstring, *psz_tmp;
......
......@@ -48,6 +48,9 @@
# include <dvbpsi/pmt.h>
# include <dvbpsi/dr.h>
# include <dvbpsi/psi.h>
# include <dvbpsi/demux.h>
# include <dvbpsi/sdt.h>
# include <dvbpsi/nit.h>
#else
# include "dvbpsi.h"
# include "descriptor.h"
......@@ -55,6 +58,9 @@
# include "tables/pmt.h"
# include "descriptors/dr.h"
# include "psi.h"
# include "demux.h"
# include "sdt.h"
# include "nit.h"
#endif
#ifdef ENABLE_HTTPD
......
......@@ -55,6 +55,9 @@
# include <dvbpsi/pmt.h>
# include <dvbpsi/dr.h>
# include <dvbpsi/psi.h>
# include <dvbpsi/demux.h>
# include <dvbpsi/sdt.h>
# include <dvbpsi/nit.h>
#else
# include "dvbpsi.h"
# include "descriptor.h"
......@@ -62,6 +65,9 @@
# include "tables/pmt.h"
# include "descriptors/dr.h"
# include "psi.h"
# include "demux.h"
# include "sdt.h"
# include "nit.h"
#endif
#ifdef ENABLE_HTTPD
......@@ -339,17 +345,21 @@ void FrontendPoll( access_t *p_access )
IF_UP( FE_HAS_LOCK )
{
int32_t i_value = 0;
frontend_statistic_t stat;
msg_Dbg( p_access, "frontend has acquired lock" );
p_sys->i_frontend_timeout = 0;
/* Read some statistics */
if( ioctl( p_sys->i_frontend_handle, FE_READ_BER, &i_value ) >= 0 )
msg_Dbg( p_access, "- Bit error rate: %d", i_value );
if( ioctl( p_sys->i_frontend_handle, FE_READ_SIGNAL_STRENGTH, &i_value ) >= 0 )
msg_Dbg( p_access, "- Signal strength: %d", i_value );
if( ioctl( p_sys->i_frontend_handle, FE_READ_SNR, &i_value ) >= 0 )
msg_Dbg( p_access, "- SNR: %d", i_value );
if( !FrontendGetStatistic( p_access, &stat ) )
{
if( stat.i_ber >= 0 )
msg_Dbg( p_access, "- Bit error rate: %d", stat.i_ber );
if( stat.i_signal_strenth >= 0 )
msg_Dbg( p_access, "- Signal strength: %d", stat.i_signal_strenth );
if( stat.i_snr >= 0 )
msg_Dbg( p_access, "- SNR: %d", stat.i_snr );
}
}
else
{
......@@ -367,6 +377,66 @@ void FrontendPoll( access_t *p_access )
#undef IF_UP
}
}
int FrontendGetStatistic( access_t *p_access, frontend_statistic_t *p_stat )
{
access_sys_t *p_sys = p_access->p_sys;
frontend_t * p_frontend = p_sys->p_frontend;
if( (p_frontend->i_last_status & FE_HAS_LOCK) == 0 )
return VLC_EGENERIC;
memset( p_stat, 0, sizeof(*p_stat) );
if( ioctl( p_sys->i_frontend_handle, FE_READ_BER, &p_stat->i_ber ) < 0 )
p_stat->i_ber = -1;
if( ioctl( p_sys->i_frontend_handle, FE_READ_SIGNAL_STRENGTH, &p_stat->i_signal_strenth ) < 0 )
p_stat->i_signal_strenth = -1;
if( ioctl( p_sys->i_frontend_handle, FE_READ_SNR, &p_stat->i_snr ) < 0 )
p_stat->i_snr = -1;
return VLC_SUCCESS;
}
void FrontendGetStatus( access_t *p_access, frontend_status_t *p_status )
{
access_sys_t *p_sys = p_access->p_sys;
frontend_t * p_frontend = p_sys->p_frontend;
p_status->b_has_signal = (p_frontend->i_last_status & FE_HAS_SIGNAL) != 0;
p_status->b_has_carrier = (p_frontend->i_last_status & FE_HAS_CARRIER) != 0;
p_status->b_has_lock = (p_frontend->i_last_status & FE_HAS_LOCK) != 0;
}
static int ScanParametersDvbT( access_t *p_access, scan_parameter_t *p_scan )
{
const frontend_t *p_frontend = p_access->p_sys->p_frontend;
memset( p_scan, 0, sizeof(*p_scan) );
p_scan->type = SCAN_DVB_T;
p_scan->b_exhaustive = false;
/* */
p_scan->frequency.i_min = p_frontend->info.frequency_min;
p_scan->frequency.i_max = p_frontend->info.frequency_max;
p_scan->frequency.i_step = p_frontend->info.frequency_stepsize;
p_scan->frequency.i_count = (p_scan->frequency.i_max-p_scan->frequency.i_min)/p_scan->frequency.i_step;
/* */
p_scan->bandwidth.i_min = 6;
p_scan->bandwidth.i_max = 8;
p_scan->bandwidth.i_step = 1;
p_scan->bandwidth.i_count = 3;
return VLC_SUCCESS;
}
int FrontendGetScanParameter( access_t *p_access, scan_parameter_t *p_scan )
{
access_sys_t *p_sys = p_access->p_sys;
const frontend_t *p_frontend = p_sys->p_frontend;
if( p_frontend->info.type == FE_OFDM ) // DVB-T
return ScanParametersDvbT( p_access, p_scan );
msg_Err( p_access, "Frontend type not supported for scanning" );
return VLC_EGENERIC;
}
#ifdef ENABLE_HTTPD
/*****************************************************************************
......
This diff is collapsed.
/*****************************************************************************
* scan.h : functions to ease DVB scanning
*****************************************************************************
* Copyright (C) 2008 the VideoLAN team
*
* Authors: Laurent Aimar <fenrir@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
typedef enum
{
SCAN_NONE,
SCAN_DVB_T,
SCAN_DVB_S,
SCAN_DVB_C,
} scan_type_t;
typedef struct
{
scan_type_t type;
bool b_exhaustive;
struct
{
int i_min;
int i_max;
int i_step;
int i_count; /* Number of frequency test to do */
} frequency;
struct
{
/* Bandwidth should be 6, 7 or 8 */
int i_min;
int i_max;
int i_step;
int i_count;
} bandwidth;
} scan_parameter_t;
typedef struct
{
int i_frequency;
int i_bandwidth;
} scan_configuration_t;
typedef enum
{
SERVICE_UNKNOWN = 0,
SERVICE_DIGITAL_RADIO,
SERVICE_DIGITAL_TELEVISION,
SERVICE_DIGITAL_TELEVISION_AC_SD,
SERVICE_DIGITAL_TELEVISION_AC_HD,
} scan_service_type_t;
typedef struct
{
int i_program; /* program number (service id) */
scan_configuration_t cfg;
int i_snr;
scan_service_type_t type;
char *psz_name; /* channel name in utf8 or NULL */
int i_channel; /* -1 if unknown */
bool b_crypted; /* True if potentially crypted */
int i_network_id;
int i_nit_version;
int i_sdt_version;
} scan_service_t;
typedef struct
{
vlc_object_t *p_obj;
scan_configuration_t cfg;
int i_snr;
dvbpsi_handle pat;
dvbpsi_pat_t *p_pat;
int i_nit_pid;
dvbpsi_handle sdt;
dvbpsi_sdt_t *p_sdt;
dvbpsi_handle nit;
dvbpsi_nit_t *p_nit;
} scan_session_t;
typedef struct
{
vlc_object_t *p_obj;
int64_t i_index;
int i_dialog_id;
scan_parameter_t parameter;
int64_t i_time_start;
int i_service;
scan_service_t **pp_service;
} scan_t;
scan_service_t *scan_service_New( int i_program, const scan_configuration_t *p_cfg );
void scan_service_Delete( scan_service_t *p_srv );
int scan_Init( vlc_object_t *p_obj, scan_t *p_scan, const scan_parameter_t *p_parameter );
void scan_Clean( scan_t *p_scan );
int scan_Next( scan_t *p_scan, scan_configuration_t *p_cfg );
block_t *scan_GetM3U( scan_t *p_scan );
bool scan_IsCancelled( scan_t *p_scan );
int scan_session_Init( vlc_object_t *p_obj, scan_session_t *p_session, const scan_configuration_t *p_cfg );
void scan_session_Clean( scan_t *p_scan, scan_session_t *p_session );
bool scan_session_Push( scan_session_t *p_scan, block_t *p_block );
void scan_service_SetSNR( scan_session_t *p_scan, int i_snr );
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment