diff --git a/src/input/mpegts/linuxdvb/linuxdvb_device.c b/src/input/mpegts/linuxdvb/linuxdvb_device.c index 8ac6f68c..e94c80ea 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_device.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_device.c @@ -236,7 +236,6 @@ linuxdvb_device_create0 ( const char *uuid, htsmsg_t *conf ) /* Create */ ld = calloc(1, sizeof(linuxdvb_device_t)); -printf("create device %p\n", ld); if (idnode_insert(&ld->mi_id, uuid, &linuxdvb_device_class)) { free(ld); return NULL; @@ -277,9 +276,6 @@ linuxdvb_device_find_by_hwid ( const char *hwid ) { linuxdvb_hardware_t *lh; LIST_FOREACH(lh, &linuxdvb_device_all, lh_parent_link) { - printf("hwid = %s\n", hwid); - printf("lh = %p\n", lh); - printf("devid = %s\n", ((linuxdvb_device_t*)lh)->ld_devid.di_id); if (!strcmp(hwid, ((linuxdvb_device_t*)lh)->ld_devid.di_id)) return (linuxdvb_device_t*)lh; } @@ -306,7 +302,6 @@ linuxdvb_device_find_by_adapter ( int a ) } /* Copy device info */ - printf("added dev info to %p\n", ld); memcpy(&ld->ld_devid, &dev, sizeof(dev)); ld->lh_displayname = strdup(dev.di_id); return ld; @@ -325,7 +320,6 @@ void linuxdvb_device_init ( int adapter_mask ) if (!(e = htsmsg_get_map_by_field(f))) continue; if (!(e = htsmsg_get_map(e, "config"))) continue; (void)linuxdvb_device_create0(f->hmf_name, e); - printf("created from config\n"); } } diff --git a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c index afbdc207..dee1a793 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c @@ -20,7 +20,14 @@ #include "tvheadend.h" #include "linuxdvb_private.h" +#include +#include +#include +#include +#include +#include #include +#include /* ************************************************************************** * Class definitions @@ -123,6 +130,7 @@ linuxdvb_frontend_save ( linuxdvb_frontend_t *lfe, htsmsg_t *m ) htsmsg_add_str(m, "dvr_path", lfe->lfe_dvr_path); } +#if 0 static int linuxdvb_frontend_is_free ( mpegts_input_t *mi ) { @@ -144,6 +152,7 @@ linuxdvb_frontend_current_weight ( mpegts_input_t *mi ) #endif return 0; } +#endif static void linuxdvb_frontend_stop_mux @@ -151,15 +160,131 @@ linuxdvb_frontend_stop_mux { } -#if 0 +static void * +linuxdvb_frontend_input_thread ( void *aux ) +{ + linuxdvb_frontend_t *lfe = aux; + mpegts_mux_instance_t *mmi; + int dmx = -1, dvr = -1; + uint8_t tsb[18800]; + int pos = 0, nfds, efd; + ssize_t c; + struct epoll_event ev; + struct dmx_pes_filter_params dmx_param; + + /* Get MMI */ + pthread_mutex_lock(&global_lock); + mmi = LIST_FIRST(&lfe->mi_mux_active); + pthread_mutex_unlock(&global_lock); + if (mmi == NULL) return NULL; + + /* Open DMX */ + dmx = tvh_open(lfe->lfe_dmx_path, O_RDWR, 0); + if (dmx < 0) { + tvhlog(LOG_ERR, "linuxdvb", "failed to open %s", lfe->lfe_dmx_path); + return NULL; + } + 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) == -1) { + tvhlog(LOG_ERR, "dvb", + "Unable to configure demuxer \"%s\" for all PIDs -- %s", + lfe->lfe_dmx_path, strerror(errno)); + close(dmx); + return NULL; + } + + /* Open DVR */ + dvr = tvh_open(lfe->lfe_dvr_path, O_RDONLY | O_NONBLOCK, 0); + if (dvr < 0) { + close(dmx); + tvhlog(LOG_ERR, "linuxdvb", "failed to open %s", lfe->lfe_dvr_path); + return NULL; + } + + /* Setup poll */ + efd = epoll_create(2); + memset(&ev, 0, sizeof(ev)); + ev.events = EPOLLIN; + ev.data.fd = dvr; + epoll_ctl(efd, EPOLL_CTL_ADD, ev.data.fd, &ev); + + /* Read */ + while (1) { + nfds = epoll_wait(efd, &ev, 1, 10); + if (nfds < 1) continue; + if (ev.data.fd != dvr) break; + + /* Read */ + c = read(dvr, tsb+pos, sizeof(tsb)-pos); + if (c < 0) { + if ((errno == EAGAIN) || (errno == EINTR)) + continue; + if (errno == EOVERFLOW) { + tvhlog(LOG_WARNING, "linuxdvb", "read() EOVERFLOW"); + continue; + } + tvhlog(LOG_ERR, "linuxdvb", "read() error %d (%s)", + errno, strerror(errno)); + break; + } + + /* Process */ + pos = mpegts_input_recv_packets((mpegts_input_t*)lfe, mmi, tsb, c, + NULL, NULL); + } + +//exit: + close(dmx); + close(dvr); + return NULL; +} + +static void +linuxdvb_frontend_monitor ( void *aux ) +{ + linuxdvb_frontend_t *lfe = aux; + mpegts_mux_instance_t *mmi = LIST_FIRST(&lfe->mi_mux_active); + mpegts_mux_t *mm; + pthread_t tid; + + if (!mmi) return; + mm = mmi->mmi_mux; + + fe_status_t fe_status; + + if (!ioctl(lfe->lfe_fe_fd, FE_READ_STATUS, &fe_status)) + tvhtrace("mpegts", "fe_status = %02X", fe_status); + else + tvhtrace("mpegts", "fe_status = unknown"); + + if (fe_status & FE_HAS_LOCK) { + // Note: the lock + // Open pending services + pthread_create(&tid, NULL, linuxdvb_frontend_input_thread, lfe); + mpegts_table_add(mm, DVB_PAT_BASE, DVB_PAT_MASK, dvb_pat_callback, + NULL, "pat", MT_QUICKREQ | MT_CRC, DVB_PAT_PID); + mpegts_table_add(mm, DVB_SDT_BASE, DVB_SDT_MASK, dvb_sdt_callback, + NULL, "sdt", MT_QUICKREQ | MT_CRC, DVB_SDT_PID); + mpegts_table_add(mm, DVB_BAT_BASE, DVB_BAT_MASK, dvb_bat_callback, + NULL, "bat", MT_CRC, DVB_BAT_PID); + } else { + gtimer_arm_ms(&lfe->lfe_monitor_timer, linuxdvb_frontend_monitor, lfe, 1000); + } +} + #if DVB_API_VERSION >= 5 static int linuxdvb_frontend_tune - ( linuxdvb_frontend_t *lfe, mpegts_mux_instance_t *mmi ) + ( linuxdvb_frontend_t *lfe, linuxdvb_mux_t *lm ) { -#if 0 struct dvb_frontend_event ev; + dvb_mux_conf_t *dmc = &lm->lm_tuning; struct dvb_frontend_parameters *p = &dmc->dmc_fe_params; int r; @@ -171,62 +296,60 @@ linuxdvb_frontend_tune .num = 1, .props = clear_p }; - if ((ioctl(tda->tda_fe_fd, FE_SET_PROPERTY, &clear_cmdseq)) != 0) + if ((ioctl(lfe->lfe_fe_fd, FE_SET_PROPERTY, &clear_cmdseq)) != 0) return -1; /* Tune */ struct dtv_property _dvbs_cmdargs[] = { - { .cmd = DTV_DELIVERY_SYSTEM, .u.data = dmc->dmc_fe_delsys }, - { .cmd = DTV_FREQUENCY, .u.data = p->frequency }, - { .cmd = DTV_MODULATION, .u.data = dmc->dmc_fe_modulation }, - { .cmd = DTV_SYMBOL_RATE, .u.data = p->u.qpsk.symbol_rate }, - { .cmd = DTV_INNER_FEC, .u.data = p->u.qpsk.fec_inner }, - { .cmd = DTV_INVERSION, .u.data = INVERSION_AUTO }, - { .cmd = DTV_ROLLOFF, .u.data = dmc->dmc_fe_rolloff }, - { .cmd = DTV_PILOT, .u.data = PILOT_AUTO }, + { .cmd = DTV_DELIVERY_SYSTEM, .u.data = SYS_DVBT /*TODO: fix this*/ }, + { .cmd = DTV_FREQUENCY, .u.data = p->frequency }, + { .cmd = DTV_INVERSION, .u.data = p->inversion }, + { .cmd = DTV_BANDWIDTH_HZ, .u.data = 8000000 },// TODO: fix this + { .cmd = DTV_CODE_RATE_HP, .u.data = p->u.ofdm.code_rate_HP }, + { .cmd = DTV_CODE_RATE_LP, .u.data = p->u.ofdm.code_rate_LP }, + { .cmd = DTV_MODULATION, .u.data = p->u.ofdm.constellation }, + { .cmd = DTV_TRANSMISSION_MODE, .u.data = p->u.ofdm.transmission_mode }, + { .cmd = DTV_GUARD_INTERVAL, .u.data = p->u.ofdm.guard_interval }, + { .cmd = DTV_HIERARCHY, .u.data = p->u.ofdm.hierarchy_information }, { .cmd = DTV_TUNE }, }; struct dtv_properties _dvbs_cmdseq = { - .num = 9, + .num = 11, .props = _dvbs_cmdargs }; /* discard stale QPSK events */ while (1) { - if (ioctl(tda->tda_fe_fd, FE_GET_EVENT, &ev) == -1) + if (ioctl(lfe->lfe_fe_fd, FE_GET_EVENT, &ev) == -1) break; } /* do tuning now */ - r = ioctl(tda->tda_fe_fd, FE_SET_PROPERTY, &_dvbs_cmdseq); + r = ioctl(lfe->lfe_fe_fd, FE_SET_PROPERTY, &_dvbs_cmdseq); return r; -#endif - return 0; } #else static int linuxdvb_frontend_tune ( linuxdvb_frontend_t *lfe, mpegts_mux_instance_t *mmi ) -{ + } -#endif #endif static int linuxdvb_frontend_start_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi ) { - printf("fe_start(%p, %p)\n", mi, mmi); - return SM_CODE_TUNING_FAILED; -#if 0 int r; linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi; mpegts_mux_instance_t *cur = LIST_FIRST(&mi->mi_mux_active); + tvhtrace("mpegts", "linuxdvb_frontend_start_mux(%p, %p)", mi, mmi); + // Not sure if this is right place? /* Currently active */ if (cur != NULL) { @@ -239,8 +362,16 @@ linuxdvb_frontend_start_mux } assert(LIST_FIRST(&mi->mi_mux_active) == NULL); + /* Open FE */ + if (lfe->lfe_fe_fd <= 0) { + lfe->lfe_fe_fd = tvh_open(lfe->lfe_fe_path, O_RDWR | O_NONBLOCK, 0); + if (lfe->lfe_fe_fd <= 0) { + return SM_CODE_TUNING_FAILED; + } + } + /* Tune */ - r = 0;//linuxdvb_frontend_tune(lfe, (linuxdvb_mux_t*)mmi); + r = linuxdvb_frontend_tune(lfe, (linuxdvb_mux_t*)mmi->mmi_mux); /* Failed */ if (r != 0) { @@ -254,12 +385,11 @@ linuxdvb_frontend_start_mux /* Start monitor */ time(&lfe->lfe_monitor); lfe->lfe_monitor += 4; - //gtimer_arm_ms(&lfe->lfe_monitor_timer, linuxdvb_frontend_monitor, lfe, 50); + gtimer_arm_ms(&lfe->lfe_monitor_timer, linuxdvb_frontend_monitor, lfe, 50); /* Send alert */ // TODO: should this be moved elsewhere? - -#endif + return r; } static void @@ -281,6 +411,7 @@ linuxdvb_frontend_create0 uint32_t u32; const char *str; const idclass_t *idc; + pthread_t tid; /* Get type */ if (conf) { @@ -313,12 +444,17 @@ linuxdvb_frontend_create0 lfe->mi_stop_mux = linuxdvb_frontend_stop_mux; lfe->mi_open_service = linuxdvb_frontend_open_service; lfe->mi_close_service = linuxdvb_frontend_close_service; +#if 0 lfe->mi_is_free = linuxdvb_frontend_is_free; lfe->mi_current_weight = linuxdvb_frontend_current_weight; +#endif /* Adapter link */ lfe->lh_parent = (linuxdvb_hardware_t*)la; LIST_INSERT_HEAD(&la->lh_children, (linuxdvb_hardware_t*)lfe, lh_parent_link); + + /* Start table thread */ + pthread_create(&tid, NULL, mpegts_input_table_thread, lfe); /* No conf */ if (!conf) diff --git a/src/input/mpegts/linuxdvb/linuxdvb_mux.c b/src/input/mpegts/linuxdvb/linuxdvb_mux.c index 4b7cbd2f..2bdbe974 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_mux.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_mux.c @@ -122,6 +122,7 @@ linuxdvb_mux_create_instances ( mpegts_mux_t *mm ) } } +#if 0 static void linuxdvb_mux_open_table ( mpegts_mux_t *mm, mpegts_table_t *mt ) { @@ -131,68 +132,69 @@ static void linuxdvb_mux_close_table ( mpegts_mux_t *mm, mpegts_table_t *mt ) { } +#endif static const char * dvb_mux_conf_load ( fe_type_t type, dvb_mux_conf_t *dmc, htsmsg_t *m ) { - //const char *s; + int r; + const char *s; dmc->dmc_fe_params.inversion = INVERSION_AUTO; htsmsg_get_u32(m, "frequency", &dmc->dmc_fe_params.frequency); -#if 0 - switch(tda->tda_type) { + switch(type) { case FE_OFDM: s = htsmsg_get_str(m, "bandwidth"); - if(s == NULL || (r = str2val(s, bwtab)) < 0) + if(s == NULL || (r = dvb_str2bw(s)) < 0) return "Invalid bandwidth"; dmc->dmc_fe_params.u.ofdm.bandwidth = r; s = htsmsg_get_str(m, "constellation"); - if(s == NULL || (r = str2val(s, qamtab)) < 0) + if(s == NULL || (r = dvb_str2qam(s)) < 0) return "Invalid QAM constellation"; dmc->dmc_fe_params.u.ofdm.constellation = r; s = htsmsg_get_str(m, "transmission_mode"); - if(s == NULL || (r = str2val(s, modetab)) < 0) + if(s == NULL || (r = dvb_str2mode(s)) < 0) return "Invalid transmission mode"; dmc->dmc_fe_params.u.ofdm.transmission_mode = r; s = htsmsg_get_str(m, "guard_interval"); - if(s == NULL || (r = str2val(s, guardtab)) < 0) + if(s == NULL || (r = dvb_str2guard(s)) < 0) return "Invalid guard interval"; dmc->dmc_fe_params.u.ofdm.guard_interval = r; s = htsmsg_get_str(m, "hierarchy"); - if(s == NULL || (r = str2val(s, hiertab)) < 0) + if(s == NULL || (r = dvb_str2hier(s)) < 0) return "Invalid heirarchy information"; dmc->dmc_fe_params.u.ofdm.hierarchy_information = r; s = htsmsg_get_str(m, "fec_hi"); - if(s == NULL || (r = str2val(s, fectab)) < 0) + if(s == NULL || (r = dvb_str2fec(s)) < 0) return "Invalid hi-FEC"; dmc->dmc_fe_params.u.ofdm.code_rate_HP = r; s = htsmsg_get_str(m, "fec_lo"); - if(s == NULL || (r = str2val(s, fectab)) < 0) + if(s == NULL || (r = dvb_str2fec(s)) < 0) return "Invalid lo-FEC"; dmc->dmc_fe_params.u.ofdm.code_rate_LP = r; break; + default: + return "Not yet supported"; } -#endif - return "Not yet supported"; + return NULL; } linuxdvb_mux_t * linuxdvb_mux_create0 - ( linuxdvb_network_t *ln, const char *uuid, htsmsg_t *conf ) + ( linuxdvb_network_t *ln, + uint16_t onid, uint16_t tsid, const dvb_mux_conf_t *dmc, + const char *uuid ) { - uint32_t u32; - const char *str; - htsmsg_t *c, *e; - htsmsg_field_t *f; - mpegts_mux_t *mm; - linuxdvb_mux_t *lm; const idclass_t *idc; + mpegts_mux_t *mm; + + /* Search for existing */ /* Class */ if (ln->ln_type == FE_QPSK) @@ -210,16 +212,44 @@ linuxdvb_mux_create0 /* Create */ if (!(mm = mpegts_mux_create0(calloc(1, sizeof(linuxdvb_mux_t)), idc, uuid, - (mpegts_network_t*)ln, - MPEGTS_ONID_NONE, - MPEGTS_TSID_NONE))) + (mpegts_network_t*)ln, onid, tsid))) return NULL; - lm = (linuxdvb_mux_t*)mm; + memcpy(&((linuxdvb_mux_t*)mm)->lm_tuning, dmc, sizeof(dvb_mux_conf_t)); + + return (linuxdvb_mux_t*)mm; +} + +linuxdvb_mux_t * +linuxdvb_mux_create1 + ( linuxdvb_network_t *ln, const char *uuid, htsmsg_t *conf ) +{ + uint32_t u32; + const char *str; + htsmsg_t *c, *e; + htsmsg_field_t *f; + linuxdvb_mux_t *lm; + dvb_mux_conf_t dmc; + + /* Check tuning */ + memset(&dmc, 0, sizeof(dmc)); + if (conf) { + if ((str = dvb_mux_conf_load(ln->ln_type, &dmc, conf))) { + tvhlog(LOG_ERR, "linuxdvb", "failed to load mux config [%s]", str); + return NULL; + } + } + + lm = linuxdvb_mux_create0(ln, MPEGTS_ONID_NONE, + MPEGTS_TSID_NONE, &dmc, uuid); + if (!lm) printf("OH DEAR\n"); + if (!lm) return NULL; /* Callbacks */ lm->mm_config_save = linuxdvb_mux_config_save; +#if 0 lm->mm_open_table = linuxdvb_mux_open_table; lm->mm_close_table = linuxdvb_mux_close_table; +#endif lm->mm_create_instances = linuxdvb_mux_create_instances; /* No config */ @@ -236,10 +266,7 @@ linuxdvb_mux_create0 lm->mm_tsid = u32; if ((str = htsmsg_get_str(conf, "default_authority"))) lm->mm_dvb_default_authority = strdup(str); - - /* Tuning info */ - if ((e = htsmsg_get_map(conf, "tuning"))) - (void)dvb_mux_conf_load(ln->ln_type, &lm->lm_tuning, e); + memcpy(&lm->lm_tuning, &dmc, sizeof(dmc)); /* Services */ if ((c = hts_settings_load_r(1, "input/linuxdvb/networks/%s/muxes/%s/services", diff --git a/src/input/mpegts/linuxdvb/linuxdvb_network.c b/src/input/mpegts/linuxdvb/linuxdvb_network.c index 8a47d3dd..1079193e 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_network.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_network.c @@ -50,7 +50,8 @@ static mpegts_mux_t * linuxdvb_network_create_mux ( mpegts_mux_t *mm, uint16_t onid, uint16_t tsid, dvb_mux_conf_t *conf ) { - return NULL; + linuxdvb_network_t *ln = (linuxdvb_network_t*)mm->mm_network; + return (mpegts_mux_t*)linuxdvb_mux_create0(ln, onid, tsid, conf, NULL); } static mpegts_service_t * @@ -96,15 +97,12 @@ linuxdvb_network_create0 if (!htsmsg_get_u32(conf, "nid", &u32)) ln->mn_nid = u32; - printf("network created %s / %s / %d\n", dvb_type2str(ln->ln_type), - ln->mn_network_name, ln->mn_nid); - /* Load muxes */ if ((c = hts_settings_load_r(1, "input/linuxdvb/networks/%s/muxes", uuid))) { HTSMSG_FOREACH(f, c) { if (!(e = htsmsg_get_map_by_field(f))) continue; if (!(e = htsmsg_get_map(e, "config"))) continue; - (void)linuxdvb_mux_create0(ln, f->hmf_name, e); + (void)linuxdvb_mux_create1(ln, f->hmf_name, e); } } diff --git a/src/input/mpegts/linuxdvb/linuxdvb_private.h b/src/input/mpegts/linuxdvb/linuxdvb_private.h index 985602e3..5e2a80d0 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_private.h +++ b/src/input/mpegts/linuxdvb/linuxdvb_private.h @@ -132,6 +132,9 @@ struct linuxdvb_frontend char *lfe_dmx_path; char *lfe_dvr_path; + int lfe_fe_fd; + int lfe_dvr_fd; + /* * Tuning */ @@ -177,6 +180,9 @@ struct linuxdvb_mux }; linuxdvb_mux_t *linuxdvb_mux_create0 + (linuxdvb_network_t *ln, uint16_t onid, uint16_t tsid, + const dvb_mux_conf_t *dmc, const char *uuid); +linuxdvb_mux_t *linuxdvb_mux_create1 (linuxdvb_network_t *ln, const char *uuid, htsmsg_t *conf); #endif /* __TVH_LINUXDVB_PRIVATE_H__ */ diff --git a/src/input/mpegts/mpegts_input.c b/src/input/mpegts/mpegts_input.c index 955e166d..ae0d587e 100644 --- a/src/input/mpegts/mpegts_input.c +++ b/src/input/mpegts/mpegts_input.c @@ -76,7 +76,6 @@ mpegts_input_recv_packets /* Process */ while ( len >= 188 ) { - //printf("tsb[%d] = %02X\n", i, tsb[i]); /* Sync */ if ( tsb[i] == 0x47 ) { diff --git a/src/input/mpegts/mpegts_mux.c b/src/input/mpegts/mpegts_mux.c index 2cee578d..06473114 100644 --- a/src/input/mpegts/mpegts_mux.c +++ b/src/input/mpegts/mpegts_mux.c @@ -120,6 +120,7 @@ void mpegts_mux_initial_scan_done ( mpegts_mux_t *mm ) { mpegts_network_t *mn = mm->mm_network; + tvhlog(LOG_DEBUG, "mpegts", "initial scan complete for mm %p", mm); gtimer_disarm(&mm->mm_initial_scan_timeout); assert(mm->mm_initial_scan_status == MM_SCAN_CURRENT); mn->mn_initial_scan_num--; @@ -145,7 +146,7 @@ mpegts_mux_start ( mpegts_mux_t *mm, const char *reason, int weight ) } /* Create mux instances (where needed) */ - //mm->mm_create_instances(mm); + mm->mm_create_instances(mm); /* Find */ // TODO: don't like this is unbounded, if for some reason mi_start_mux() @@ -159,9 +160,12 @@ mpegts_mux_start ( mpegts_mux_t *mm, const char *reason, int weight ) break; if (mmi) tvhtrace("mpegts", "found free mmi %p", mmi); + else + tvhtrace("mpegts", "no input is free"); /* Try and remove a lesser instance */ if (!mmi) { +#if 0 LIST_FOREACH(mmi, &mm->mm_instances, mmi_mux_link) { /* Bad - skip */ @@ -175,6 +179,7 @@ mpegts_mux_start ( mpegts_mux_t *mm, const char *reason, int weight ) if (mmi) tvhtrace("mpegts", "found mmi %p to boot", mmi); +#endif /* No free input */ if (!mmi) { @@ -184,13 +189,17 @@ mpegts_mux_start ( mpegts_mux_t *mm, const char *reason, int weight ) } /* Tune */ - if (!mmi->mmi_input->mi_start_mux(mmi->mmi_input, mmi)) + if (!mmi->mmi_input->mi_start_mux(mmi->mmi_input, mmi)) { + LIST_INSERT_HEAD(&mmi->mmi_input->mi_mux_active, mmi, mmi_active_link); + mm->mm_active = mmi; break; + } tvhtrace("mpegts", "failed to run mmi %p", mmi); } /* Initial scanning */ if (mm->mm_initial_scan_status == MM_SCAN_PENDING) { + tvhtrace("mpegts", "adding mm %p to current scan Q", mm); TAILQ_REMOVE(&mn->mn_initial_scan_pending_queue, mm, mm_initial_scan_link); mm->mm_initial_scan_status = MM_SCAN_CURRENT; TAILQ_INSERT_TAIL(&mn->mn_initial_scan_current_queue, mm, mm_initial_scan_link); @@ -207,6 +216,9 @@ mpegts_mux_stop ( mpegts_mux_t *mm ) mpegts_mux_instance_t *mmi = mm->mm_active; mpegts_input_t *mi; + tvhtrace("mpegts", "stopping mux %p", mm); + assert(0); + /* Flush all subscribers */ if (mmi) { mi = mmi->mmi_input;