diff options
Diffstat (limited to 'src/input/input_dvb.c')
-rw-r--r-- | src/input/input_dvb.c | 189 |
1 files changed, 79 insertions, 110 deletions
diff --git a/src/input/input_dvb.c b/src/input/input_dvb.c index 9077c221b..6b791d355 100644 --- a/src/input/input_dvb.c +++ b/src/input/input_dvb.c @@ -71,7 +71,10 @@ #endif /* pthread.h must be included first so rest of the headers are imported - thread safely (on some systems). */ + thread safely (on some systems). + However, including it before config.h causes problems with asprintf not + being declared (glibc 2.3.6) +*/ #include <pthread.h> #include <assert.h> @@ -97,9 +100,17 @@ #endif #include <ctype.h> -/* These will eventually be #include <linux/dvb/...> */ -#include "dvb/dmx.h" -#include "dvb/frontend.h" +#ifdef HAVE_FFMPEG_AVUTIL_H +# include <crc.h> +#else +# include <libavutil/crc.h> +#endif + +/* XDG */ +#include <basedir.h> + +#include <linux/dvb/dmx.h> +#include <linux/dvb/frontend.h> #define LOG_MODULE "input_dvb" #define LOG_VERBOSE @@ -108,9 +119,9 @@ #define LOG_READS */ -#include "xine_internal.h" -#include "xineutils.h" -#include "input_plugin.h" +#include <xine/xine_internal.h> +#include <xine/xineutils.h> +#include <xine/input_plugin.h> #include "net_buf_ctrl.h" #define BUFSIZE 16384 @@ -229,9 +240,8 @@ typedef struct { int adapter_num; - char frontend_device[100]; - char dvr_device[100]; - char demux_device[100]; + char *dvr_device; + char *demux_device; struct dmx_pes_filter_params pesFilterParams[MAX_FILTERS]; struct dmx_pes_filter_params subFilterParams[MAX_SUBTITLES]; @@ -286,12 +296,13 @@ typedef struct { xine_t *xine; - char *mrls[6]; + const char *mrls[6]; int numchannels; char *autoplaylist[MAX_AUTOCHANNELS]; - char *default_channels_conf_filename; + + const AVCRC *av_crc; } dvb_input_class_t; typedef struct { @@ -326,15 +337,12 @@ typedef struct { osd_object_t *background; xine_event_queue_t *event_queue; - /* CRC table for PAT rebuilding */ - unsigned long crc32_table[256]; /* scratch buffer for forward seeking */ char seek_buf[BUFSIZE]; /* Is the GUI enabled at all? */ int dvb_gui_enabled; - /* simple vcr-like functionality */ int record_fd; int record_paused; @@ -358,7 +366,7 @@ typedef struct { } dvb_input_plugin_t; typedef struct { - char *name; + const char *name; int value; } Param; @@ -436,7 +444,7 @@ static const Param transmissionmode_list [] = { }; -time_t dvb_mjdtime (char *buf); +static time_t dvb_mjdtime (uint8_t *buf); static void load_epg_data(dvb_input_plugin_t *this); static void show_eit(dvb_input_plugin_t *this); @@ -452,28 +460,6 @@ static void print_info(const char* estring) { } #endif -static void ts_build_crc32_table(dvb_input_plugin_t *this) { - uint32_t i, j, k; - - for( i = 0 ; i < 256 ; i++ ) { - k = 0; - for (j = (i << 24) | 0x800000 ; j != 0x80000000 ; j <<= 1) { - k = (k << 1) ^ (((k ^ j) & 0x80000000) ? 0x04c11db7 : 0); - } - this->crc32_table[i] = k; - } -} - -static uint32_t ts_compute_crc32(dvb_input_plugin_t *this, uint8_t *data, - uint32_t length, uint32_t crc32) { - uint32_t i; - - for(i = 0; i < length; i++) { - crc32 = (crc32 << 8) ^ this->crc32_table[(crc32 >> 24) ^ data[i]]; - } - return crc32; -} - static unsigned int getbits(unsigned char *buffer, unsigned int bitpos, unsigned int bitcount) { @@ -517,7 +503,7 @@ static int find_descriptor(uint8_t tag, const unsigned char *buf, int descriptor /* Extract UTC time and date encoded in modified julian date format and return it as a time_t. */ -time_t dvb_mjdtime (char *buf) +static time_t dvb_mjdtime (uint8_t *buf) { int i; unsigned int year, month, day, hour, min, sec; @@ -575,8 +561,9 @@ static void tuner_dispose(tuner_t * this) if (this->fd_subfilter[x] >= 0) close(this->fd_subfilter[x]); - if(this) - free(this); + free(this->dvr_device); + free(this->demux_device); + free(this); } @@ -586,11 +573,10 @@ static tuner_t *XINE_MALLOC tuner_init(xine_t * xine, int adapter) tuner_t *this; int x; int test_video; - char *video_device=malloc(100); + char *video_device = NULL; + char *frontend_device = NULL; - _x_assert(video_device != NULL); - - this = calloc(1, sizeof(tuner_t)); + this = (tuner_t *) xine_xmalloc(sizeof(tuner_t)); _x_assert(this != NULL); @@ -601,21 +587,24 @@ static tuner_t *XINE_MALLOC tuner_init(xine_t * xine, int adapter) this->xine = xine; this->adapter_num = adapter; - snprintf(this->frontend_device,100,"/dev/dvb/adapter%i/frontend0",this->adapter_num); - snprintf(this->demux_device,100,"/dev/dvb/adapter%i/demux0",this->adapter_num); - snprintf(this->dvr_device,100,"/dev/dvb/adapter%i/dvr0",this->adapter_num); - snprintf(video_device,100,"/dev/dvb/adapter%i/video0",this->adapter_num); + this->demux_device = _x_asprintf("/dev/dvb/adapter%i/demux0",this->adapter_num); + this->dvr_device = _x_asprintf("/dev/dvb/adapter%i/dvr0",this->adapter_num); + video_device = _x_asprintf("/dev/dvb/adapter%i/video0",this->adapter_num); - if ((this->fd_frontend = xine_open_cloexec(this->frontend_device, O_RDWR)) < 0) { + frontend_device = _x_asprintf("/dev/dvb/adapter%i/frontend0",this->adapter_num); + if ((this->fd_frontend = xine_open_cloexec(frontend_device, O_RDWR)) < 0) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "FRONTEND DEVICE: %s\n", strerror(errno)); tuner_dispose(this); - return NULL; + this = NULL; + goto exit; } + free(frontend_device); frontend_device = NULL; if ((ioctl(this->fd_frontend, FE_GET_INFO, &this->feinfo)) < 0) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "FE_GET_INFO: %s\n", strerror(errno)); tuner_dispose(this); - return NULL; + this = NULL; + goto exit; } for (x = 0; x < MAX_FILTERS; x++) { @@ -623,7 +612,8 @@ static tuner_t *XINE_MALLOC tuner_init(xine_t * xine, int adapter) if (this->fd_pidfilter[x] < 0) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "DEMUX DEVICE PIDfilter: %s\n", strerror(errno)); tuner_dispose(this); - return NULL; + this = NULL; + goto exit; } } for (x = 0; x < MAX_SUBTITLES; x++) { @@ -655,7 +645,9 @@ static tuner_t *XINE_MALLOC tuner_init(xine_t * xine, int adapter) close(test_video); } + exit: free(video_device); + free(frontend_device); return this; } @@ -889,15 +881,13 @@ static channel_t *load_channels(xine_t *xine, xine_stream_t *stream, int *num_ch FILE *f; char str[BUFSIZE]; + char filename[BUFSIZE]; channel_t *channels = NULL; int num_channels = 0; int num_alloc = 0; struct stat st; - xine_cfg_entry_t channels_conf; - char *filename; - xine_config_lookup_entry(xine, "media.dvb.channels_conf", &channels_conf); - filename = channels_conf.str_value; + snprintf(filename, BUFSIZE, "%s/"PACKAGE"/channels.conf", xdgConfigHome(&xine->basedir_handle)); f = fopen(filename, "r"); if (!f) { @@ -1152,8 +1142,6 @@ static void parse_pmt(dvb_input_plugin_t *this, const unsigned char *buf, int se switch (buf[0]) { case 0x01: case 0x02: - case 0x10: - case 0x1b: if(!has_video) { xprintf(this->stream->xine,XINE_VERBOSITY_LOG,"input_dvb: Adding VIDEO : PID 0x%04x\n", elementary_pid); dvb_set_pidfilter(this, VIDFILTER, elementary_pid, DMX_PES_VIDEO, DMX_OUT_TS_TAP); @@ -1163,8 +1151,6 @@ static void parse_pmt(dvb_input_plugin_t *this, const unsigned char *buf, int se case 0x03: case 0x04: - case 0x0f: - case 0x11: if(!has_audio) { xprintf(this->stream->xine,XINE_VERBOSITY_LOG,"input_dvb: Adding AUDIO : PID 0x%04x\n", elementary_pid); dvb_set_pidfilter(this, AUDFILTER, elementary_pid, DMX_PES_AUDIO, DMX_OUT_TS_TAP); @@ -1232,8 +1218,8 @@ static void parse_pmt(dvb_input_plugin_t *this, const unsigned char *buf, int se static void dvb_parse_si(dvb_input_plugin_t *this) { - char *tmpbuffer; - char *bufptr; + uint8_t *tmpbuffer; + uint8_t *bufptr; int service_id; int result; int section_len; @@ -1341,8 +1327,8 @@ done: /* Helper function for finding the channel index in the channels struct given the service_id. If channel is not found, -1 is returned. */ -static int channel_index(dvb_input_plugin_t* this, unsigned int service_id) { - unsigned int n; +static int channel_index(dvb_input_plugin_t* this, int service_id) { + int n; for (n=0; n < this->num_channels; n++) if (this->channels[n].service_id == service_id) return n; @@ -1432,8 +1418,8 @@ static void load_epg_data(dvb_input_plugin_t *this) int section_len = 0; unsigned int service_id=-1; int n; - char *eit = NULL; - char *foo = NULL; + uint8_t *eit = NULL; + uint8_t *foo = NULL; char *seen_channels = NULL; int text_len; struct pollfd fd; @@ -1617,7 +1603,7 @@ static void load_epg_data(dvb_input_plugin_t *this) case 0x54: { /* Content Descriptor, riveting stuff */ int content_bits = getbits(eit, 8, 4); - char *content[] = { + static const char *const content[] = { "UNKNOWN","MOVIE","NEWS","ENTERTAINMENT","SPORT", "CHILDRENS","MUSIC","ARTS/CULTURE","CURRENT AFFAIRS", "EDUCATIONAL","INFOTAINMENT","SPECIAL","COMEDY","DRAMA", @@ -2482,12 +2468,12 @@ static void ts_rewrite_packets (dvb_input_plugin_t *this, unsigned char * origin originalPkt[11]=(this->channels[this->channel].pmtpid >> 8) & 0xff; originalPkt[12]=this->channels[this->channel].pmtpid & 0xff; - crc= ts_compute_crc32 (this, originalPkt+1, 12, 0xffffffff); + crc = av_crc(this->class->av_crc, 0xffffffff, originalPkt+1, 12); - originalPkt[13]=(crc>>24) & 0xff; - originalPkt[14]=(crc>>16) & 0xff; - originalPkt[15]=(crc>>8) & 0xff; - originalPkt[16]=crc & 0xff; + originalPkt[13]=(crc ) & 0xff; + originalPkt[14]=(crc>> 8) & 0xff; + originalPkt[15]=(crc>>16) & 0xff; + originalPkt[16]=(crc>>24) & 0xff; memset(originalPkt+17,0xFF,PKT_SIZE-21); /* stuff the remainder */ } @@ -2500,8 +2486,10 @@ static void ts_rewrite_packets (dvb_input_plugin_t *this, unsigned char * origin } static off_t dvb_plugin_read (input_plugin_t *this_gen, - char *buf, off_t len) { + void *buf_gen, off_t len) { dvb_input_plugin_t *this = (dvb_input_plugin_t *) this_gen; + uint8_t *buf = buf_gen; + off_t n=0, total=0; int have_mutex=0; struct pollfd pfd; @@ -2845,7 +2833,7 @@ static int dvb_plugin_open(input_plugin_t * this_gen) * by numbers... */ size_t chanlen = strlen(channame); - int offset = 0; + size_t offset = 0; xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("input_dvb: exact match for %s not found: trying partial matches\n"), channame); @@ -2862,7 +2850,7 @@ static int dvb_plugin_open(input_plugin_t * this_gen) idx++; } offset++; - xprintf(this->class->xine,XINE_VERBOSITY_LOG,"%d,%d,%d\n", offset, idx, num_channels); + xprintf(this->class->xine,XINE_VERBOSITY_LOG,"%zd,%d,%d\n", offset, idx, num_channels); } while ((offset < 6) && (idx == num_channels)); if (idx < num_channels) { @@ -3104,8 +3092,6 @@ static int dvb_plugin_open(input_plugin_t * this_gen) snprintf(str, 256, "%s", this->channels[this->channel].name); _x_meta_info_set(this->stream, XINE_META_INFO_TITLE, str); - /* compute CRC table for rebuilding pat */ - ts_build_crc32_table(this); /* Clear all pids, the pmt will tell us which to use */ for (x = 0; x < MAX_FILTERS; x++){ @@ -3176,22 +3162,11 @@ static input_plugin_t *dvb_class_get_instance (input_class_t *class_gen, * dvb input plugin class stuff */ -static const char *dvb_class_get_description (input_class_t *this_gen) { - return _("DVB (Digital TV) input plugin"); -} - -static const char *dvb_class_get_identifier (input_class_t *this_gen) { - return "dvb"; -} - - static void dvb_class_dispose(input_class_t * this_gen) { dvb_input_class_t *class = (dvb_input_class_t *) this_gen; int x; - free(class->default_channels_conf_filename); - for(x=0;x<class->numchannels;x++) free(class->autoplaylist[x]); @@ -3203,7 +3178,7 @@ static int dvb_class_eject_media (input_class_t *this_gen) { } -static char **dvb_class_get_autoplay_list(input_class_t * this_gen, +static const char * const *dvb_class_get_autoplay_list(input_class_t * this_gen, int *num_files) { dvb_input_class_t *class = (dvb_input_class_t *) this_gen; @@ -3272,7 +3247,7 @@ static char **dvb_class_get_autoplay_list(input_class_t * this_gen, *num_files = num_channels + lastchannel_enable.num_value; class->numchannels = *num_files; - return class->autoplaylist; + return (const char * const *)class->autoplaylist; } static void *init_class (xine_t *xine, void *data) { @@ -3286,8 +3261,8 @@ static void *init_class (xine_t *xine, void *data) { this->xine = xine; this->input_class.get_instance = dvb_class_get_instance; - this->input_class.get_identifier = dvb_class_get_identifier; - this->input_class.get_description = dvb_class_get_description; + this->input_class.identifier = "dvb"; + this->input_class.description = N_("DVB (Digital TV) input plugin"); this->input_class.get_dir = NULL; this->input_class.get_autoplay_list = dvb_class_get_autoplay_list; this->input_class.dispose = dvb_class_dispose; @@ -3300,8 +3275,7 @@ static void *init_class (xine_t *xine, void *data) { this->mrls[4] = "dvba://"; this->mrls[5] = 0; - this->default_channels_conf_filename = _x_asprintf("%s/.xine/channels.conf", - xine_get_homedir()); + this->av_crc = av_crc_get_table(AV_CRC_32_IEEE); xprintf(this->xine,XINE_VERBOSITY_DEBUG,"init class succeeded\n"); @@ -3327,6 +3301,13 @@ static void *init_class (xine_t *xine, void *data) { "Greater than 0 means wait that many seconds to get a lock. Minimum is 5 seconds."), 0, NULL, (void *) this); + /* set to 0 to turn off the GUI built into this input plugin */ + config->register_bool(config, "media.dvb.gui_enabled", + 1, + _("Enable the DVB GUI"), + _("Enable the DVB GUI, mouse controlled recording and channel switching."), + 21, NULL, NULL); + config->register_num(config, "media.dvb.adapter", 0, _("Number of dvb card to use."), @@ -3335,19 +3316,7 @@ static void *init_class (xine_t *xine, void *data) { "in your system."), 0, NULL, (void *) this); - /* set to 0 to turn off the GUI built into this input plugin */ - config->register_bool(config, "media.dvb.gui_enabled", - 1, - _("Enable the DVB GUI"), - _("Enable the DVB GUI, mouse controlled recording and channel switching."), - 21, NULL, NULL); - /* Override the default channels file */ - config->register_filename(config, "media.dvb.channels_conf", - this->default_channels_conf_filename, - XINE_CONFIG_STRING_IS_FILENAME, - _("DVB Channels config file"), - _("DVB Channels config file to use instead of the ~/.xine/channels.conf file."), - 21, NULL, NULL); + return this; } @@ -3358,6 +3327,6 @@ static void *init_class (xine_t *xine, void *data) { const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_INPUT | PLUGIN_MUST_PRELOAD, 17, "DVB", XINE_VERSION_CODE, NULL, init_class }, + { PLUGIN_INPUT | PLUGIN_MUST_PRELOAD, 18, "DVB", XINE_VERSION_CODE, NULL, init_class }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; |