diff --git a/Makefile b/Makefile index b7953339..e8d3e37e 100644 --- a/Makefile +++ b/Makefile @@ -156,6 +156,7 @@ SRCS-${CONFIG_LINUXDVB} += \ src/dvb/dvb_preconf.c \ src/dvb/dvb_satconf.c \ src/dvb/dvb_input_filtered.c \ + src/dvb/dvb_input_raw.c \ src/webui/extjs_dvb.c \ # V4L diff --git a/src/dvb/dvb.h b/src/dvb/dvb.h index 8afe3ae5..4cdc7e4d 100644 --- a/src/dvb/dvb.h +++ b/src/dvb/dvb.h @@ -202,7 +202,6 @@ typedef struct th_dvb_adapter { char *tda_demux_path; - char *tda_dvr_path; pthread_t tda_dvr_thread; int tda_dvr_pipe[2]; @@ -223,11 +222,6 @@ typedef struct th_dvb_adapter { struct th_dvb_mux_instance_list tda_mux_list; - uint32_t tda_dump_muxes; - - int tda_allpids_dmx_fd; - int tda_dump_fd; - uint32_t tda_last_fec; int tda_unc_is_delta; /* 1 if we believe FE_READ_UNCORRECTED_BLOCKS @@ -240,6 +234,8 @@ typedef struct th_dvb_adapter { void (*tda_open_table)(struct th_dvb_mux_instance *tdmi, struct th_dvb_table *s); void (*tda_close_table)(struct th_dvb_mux_instance *tdmi, struct th_dvb_table *s); + int tda_rawmode; + } th_dvb_adapter_t; /** @@ -314,8 +310,6 @@ void dvb_adapter_set_skip_checksubscr(th_dvb_adapter_t *tda, int on); void dvb_adapter_set_qmon(th_dvb_adapter_t *tda, int on); -void dvb_adapter_set_dump_muxes(th_dvb_adapter_t *tda, int on); - void dvb_adapter_set_idleclose(th_dvb_adapter_t *tda, int on); void dvb_adapter_set_poweroff(th_dvb_adapter_t *tda, int on); @@ -349,6 +343,9 @@ void dvb_adapter_poweroff(th_dvb_adapter_t *tda); void dvb_input_filtered_setup(th_dvb_adapter_t *tda); +void dvb_input_raw_setup(th_dvb_adapter_t *tda); + + /** * DVB Multiplex diff --git a/src/dvb/dvb_adapter.c b/src/dvb/dvb_adapter.c index 8f136540..73c48b6b 100644 --- a/src/dvb/dvb_adapter.c +++ b/src/dvb/dvb_adapter.c @@ -64,10 +64,6 @@ tda_alloc(void) TAILQ_INIT(&tda->tda_scan_queues[i]); TAILQ_INIT(&tda->tda_initial_scan_queue); TAILQ_INIT(&tda->tda_satconfs); - - tda->tda_allpids_dmx_fd = -1; - tda->tda_dump_fd = -1; - return tda; } @@ -90,7 +86,6 @@ tda_save(th_dvb_adapter_t *tda) htsmsg_add_u32(m, "skip_checksubscr", tda->tda_skip_checksubscr); htsmsg_add_u32(m, "sidtochan", tda->tda_sidtochan); htsmsg_add_u32(m, "qmon", tda->tda_qmon); - htsmsg_add_u32(m, "dump_muxes", tda->tda_dump_muxes); htsmsg_add_u32(m, "poweroff", tda->tda_poweroff); htsmsg_add_u32(m, "nitoid", tda->tda_nitoid); htsmsg_add_u32(m, "diseqc_version", tda->tda_diseqc_version); @@ -274,25 +269,6 @@ dvb_adapter_set_poweroff(th_dvb_adapter_t *tda, int on) } -/** - * - */ -void -dvb_adapter_set_dump_muxes(th_dvb_adapter_t *tda, int on) -{ - if(tda->tda_dump_muxes == on) - return; - - lock_assert(&global_lock); - - tvhlog(LOG_NOTICE, "dvb", "Adapter \"%s\" dump of DVB mux input set to: %s", - tda->tda_displayname, on ? "On" : "Off"); - - tda->tda_dump_muxes = on; - tda_save(tda); -} - - /** * */ @@ -428,8 +404,6 @@ tda_add(int adapter_num) tda->tda_rootpath = strdup(path); tda->tda_demux_path = malloc(256); snprintf(tda->tda_demux_path, 256, "%s/demux0", path); - tda->tda_dvr_path = malloc(256); - snprintf(tda->tda_dvr_path, 256, "%s/dvr0", path); tda->tda_fe_path = strdup(fname); tda->tda_fe_fd = -1; tda->tda_dvr_pipe[0] = -1; @@ -588,7 +562,6 @@ dvb_adapter_init(uint32_t adapter_mask) htsmsg_get_u32(c, "skip_checksubscr", &tda->tda_skip_checksubscr); htsmsg_get_u32(c, "sidtochan", &tda->tda_sidtochan); htsmsg_get_u32(c, "qmon", &tda->tda_qmon); - htsmsg_get_u32(c, "dump_muxes", &tda->tda_dump_muxes); htsmsg_get_u32(c, "poweroff", &tda->tda_poweroff); htsmsg_get_u32(c, "nitoid", &tda->tda_nitoid); htsmsg_get_u32(c, "diseqc_version", &tda->tda_diseqc_version); @@ -750,17 +723,51 @@ static void * dvb_adapter_input_dvr(void *aux) { th_dvb_adapter_t *tda = aux; - int fd, i, r, c, efd, nfds; + int fd, i, r, c, efd, nfds, dmx = -1; uint8_t tsb[188 * 10]; service_t *t; struct epoll_event ev; + char path[256]; - fd = tvh_open(tda->tda_dvr_path, O_RDONLY | O_NONBLOCK, 0); + snprintf(path, sizeof(path), "%s/dvr0", tda->tda_rootpath); + + fd = tvh_open(path, O_RDONLY | O_NONBLOCK, 0); if(fd == -1) { - tvhlog(LOG_ALERT, "dvb", "%s: unable to open dvr", tda->tda_dvr_path); + tvhlog(LOG_ALERT, "dvb", "Unable to open %s -- %s", path, strerror(errno)); return NULL; } + if(tda->tda_rawmode) { + + // Receive unfiltered raw transport stream + + dmx = tvh_open(tda->tda_demux_path, O_RDWR, 0); + if(dmx == -1) { + tvhlog(LOG_ALERT, "dvb", "Unable to open %s -- %s", + tda->tda_demux_path, strerror(errno)); + close(fd); + return NULL; + } + + struct dmx_pes_filter_params dmx_param; + + memset(&dmx_param, 0, sizeof(dmx_param)); + dmx_param.pid = 0x2000; + dmx_param.input = DMX_IN_FRONTEND; + dmx_param.output = DMX_OUT_TS_TAP; + dmx_param.pes_type = DMX_PES_OTHER; + dmx_param.flags = DMX_IMMEDIATE_START; + + if(ioctl(dmx, DMX_SET_PES_FILTER, &dmx_param)) { + tvhlog(LOG_ERR, "dvb", + "Unable to configure demuxer \"%s\" for all PIDs -- %s", + tda->tda_demux_path, strerror(errno)); + close(dmx); + close(fd); + return NULL; + } + } + /* Create poll */ efd = epoll_create(2); ev.events = EPOLLIN; @@ -790,18 +797,6 @@ dvb_adapter_input_dvr(void *aux) if (r < 188) continue; pthread_mutex_lock(&tda->tda_delivery_mutex); - - /* debug */ - if(tda->tda_dump_fd != -1) { - if(write(tda->tda_dump_fd, tsb, r) != r) { - tvhlog(LOG_ERR, "dvb", - "\"%s\" unable to write to mux dump file -- %s", - tda->tda_identifier, strerror(errno)); - close(tda->tda_dump_fd); - tda->tda_dump_fd = -1; - } - } - /* Process */ while (r >= 188) { @@ -828,6 +823,8 @@ dvb_adapter_input_dvr(void *aux) i = 0; } + if(dmx != -1) + close(dmx); close(efd); close(fd); return NULL; diff --git a/src/dvb/dvb_fe.c b/src/dvb/dvb_fe.c index 4830e2fc..321ae860 100644 --- a/src/dvb/dvb_fe.c +++ b/src/dvb/dvb_fe.c @@ -229,16 +229,6 @@ dvb_fe_stop(th_dvb_mux_instance_t *tdmi, int retune) assert(tdmi == tda->tda_mux_current); tda->tda_mux_current = NULL; - if(tda->tda_allpids_dmx_fd != -1) { - close(tda->tda_allpids_dmx_fd); - tda->tda_allpids_dmx_fd = -1; - } - - if(tda->tda_dump_fd != -1) { - close(tda->tda_dump_fd); - tda->tda_dump_fd = -1; - } - if(tdmi->tdmi_table_initial) { tdmi->tdmi_table_initial = 0; tda->tda_initial_num_mux--; @@ -263,79 +253,6 @@ dvb_fe_stop(th_dvb_mux_instance_t *tdmi, int retune) } } - -/** - * Open a dump file which we write the entire mux output to - */ -static void -dvb_adapter_open_dump_file(th_dvb_adapter_t *tda) -{ - struct dmx_pes_filter_params dmx_param; - char fullname[1000]; - char path[500]; - const char *fname = tda->tda_mux_current->tdmi_identifier; - - int fd = tvh_open(tda->tda_demux_path, O_RDWR, 0); - if(fd == -1) - return; - - memset(&dmx_param, 0, sizeof(dmx_param)); - dmx_param.pid = 0x2000; - dmx_param.input = DMX_IN_FRONTEND; - dmx_param.output = DMX_OUT_TS_TAP; - dmx_param.pes_type = DMX_PES_OTHER; - dmx_param.flags = DMX_IMMEDIATE_START; - - if(ioctl(fd, DMX_SET_PES_FILTER, &dmx_param)) { - tvhlog(LOG_ERR, "dvb", - "\"%s\" unable to configure demuxer \"%s\" for all PIDs -- %s", - fname, tda->tda_demux_path, - strerror(errno)); - close(fd); - return; - } - - snprintf(path, sizeof(path), "%s/muxdumps", - dvr_config_find_by_name_default("")->dvr_storage); - - if(mkdir(path, 0777) && errno != EEXIST) { - tvhlog(LOG_ERR, "dvb", "\"%s\" unable to create mux dump dir %s -- %s", - fname, path, strerror(errno)); - close(fd); - return; - } - - int attempt = 1; - - while(1) { - struct stat st; - snprintf(fullname, sizeof(fullname), "%s/%s.dump%d.ts", - path, fname, attempt); - - if(stat(fullname, &st) == -1) - break; - - attempt++; - } - - int f = open(fullname, O_CREAT | O_TRUNC | O_WRONLY, 0777); - - if(f == -1) { - tvhlog(LOG_ERR, "dvb", "\"%s\" unable to create mux dump file %s -- %s", - fname, fullname, strerror(errno)); - close(fd); - return; - } - - tvhlog(LOG_WARNING, "dvb", "\"%s\" writing to mux dump file %s", - fname, fullname); - - tda->tda_allpids_dmx_fd = fd; - tda->tda_dump_fd = f; -} - - - #if DVB_API_VERSION >= 5 static int check_frontend (int fe_fd, int dvr, int human_readable) { @@ -553,9 +470,6 @@ dvb_fe_tune(th_dvb_mux_instance_t *tdmi, const char *reason) tda->tda_mux_current = tdmi; - if(tda->tda_dump_muxes) - dvb_adapter_open_dump_file(tda); - gtimer_arm(&tda->tda_fe_monitor_timer, dvb_fe_monitor, tda, 1); diff --git a/src/dvb/dvb_input_raw.c b/src/dvb/dvb_input_raw.c new file mode 100644 index 00000000..b1677805 --- /dev/null +++ b/src/dvb/dvb_input_raw.c @@ -0,0 +1,88 @@ +/* + * TV Input - Linux DVB interface + * Copyright (C) 2012 Andreas Ă–man + * + * 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 3 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, see . + */ + +/** + * DVB input from a raw transport stream + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tvheadend.h" +#include "dvb.h" +#include "service.h" + +/** + * Install filters for a service + * + * global_lock must be held + */ +static void +open_service(th_dvb_adapter_t *tda, service_t *s) +{ +} + + +/** + * Remove filters for a service + * + * global_lock must be held + */ +static void +close_service(th_dvb_adapter_t *tda, service_t *s) +{ +} + + +/** + * + */ +static void +open_table(th_dvb_mux_instance_t *tdmi, th_dvb_table_t *tdt) +{ +} + + +/** + * + */ +static void +close_table(th_dvb_mux_instance_t *tdmi, th_dvb_table_t *tdt) +{ +} + +/** + * + */ +void +dvb_input_raw_setup(th_dvb_adapter_t *tda) +{ + tda->tda_rawmode = 1; + tda->tda_open_service = open_service; + tda->tda_close_service = close_service; + tda->tda_open_table = open_table; + tda->tda_close_table = close_table; +} + diff --git a/src/webui/extjs_dvb.c b/src/webui/extjs_dvb.c index 6d4d2c04..4ae0d35d 100644 --- a/src/webui/extjs_dvb.c +++ b/src/webui/extjs_dvb.c @@ -153,7 +153,6 @@ extjs_dvbadapter(http_connection_t *hc, const char *remain, void *opaque) htsmsg_add_u32(r, "idleclose", tda->tda_idleclose); htsmsg_add_u32(r, "skip_checksubscr", tda->tda_skip_checksubscr); htsmsg_add_u32(r, "qmon", tda->tda_qmon); - htsmsg_add_u32(r, "dumpmux", tda->tda_dump_muxes); htsmsg_add_u32(r, "poweroff", tda->tda_poweroff); htsmsg_add_u32(r, "sidtochan", tda->tda_sidtochan); htsmsg_add_u32(r, "nitoid", tda->tda_nitoid); @@ -197,9 +196,6 @@ extjs_dvbadapter(http_connection_t *hc, const char *remain, void *opaque) s = http_arg_get(&hc->hc_req_args, "sidtochan"); dvb_adapter_set_sidtochan(tda, !!s); - s = http_arg_get(&hc->hc_req_args, "dumpmux"); - dvb_adapter_set_dump_muxes(tda, !!s); - s = http_arg_get(&hc->hc_req_args, "disable_pmt_monitor"); dvb_adapter_set_disable_pmt_monitor(tda, !!s); diff --git a/src/webui/static/app/dvb.js b/src/webui/static/app/dvb.js index 5667e6f1..48365610 100644 --- a/src/webui/static/app/dvb.js +++ b/src/webui/static/app/dvb.js @@ -1087,7 +1087,7 @@ tvheadend.dvb_adapter_general = function(adapterData, satConfStore) { var confreader = new Ext.data.JsonReader({ root : 'dvbadapters' }, [ 'name', 'automux', 'skip_initialscan', 'idlescan', 'diseqcversion', - 'diseqcrepeats', 'qmon', 'skip_checksubscr', 'dumpmux', + 'diseqcrepeats', 'qmon', 'skip_checksubscr', 'poweroff', 'sidtochan', 'nitoid', 'extrapriority', ,'disable_pmt_monitor', 'idleclose' ]); @@ -1138,16 +1138,6 @@ tvheadend.dvb_adapter_general = function(adapterData, satConfStore) { new Ext.form.Checkbox({ fieldLabel : 'Disable PMT monitoring', name : 'disable_pmt_monitor' - }), - new Ext.form.Checkbox({ - fieldLabel : 'Write full DVB MUX to disk', - name : 'dumpmux', - handler : function(s, v) { - if (v) Ext.MessageBox.alert('DVB Mux dump', - 'Please note that keeping this ' - + 'option enabled can consume a lot ' - + 'of diskspace. You have been warned'); - } }), { fieldLabel : 'Original Network ID', name : 'nitoid',