From 8387b4da092ae4e0621ab807c9aac0193f9fd71d Mon Sep 17 00:00:00 2001 From: Adam Sutton Date: Fri, 11 Apr 2014 23:46:38 +0100 Subject: [PATCH] tsfile: updated to use new mpegts_input API --- src/input/mpegts/tsfile.h | 3 ++ src/input/mpegts/tsfile/tsfile.c | 31 ++++++++++++---- src/input/mpegts/tsfile/tsfile_input.c | 46 ++++++++++++++---------- src/input/mpegts/tsfile/tsfile_private.h | 28 +++++++++++---- 4 files changed, 75 insertions(+), 33 deletions(-) diff --git a/src/input/mpegts/tsfile.h b/src/input/mpegts/tsfile.h index 6a9e0f7b..87ed5ec4 100644 --- a/src/input/mpegts/tsfile.h +++ b/src/input/mpegts/tsfile.h @@ -28,6 +28,9 @@ struct mpegts_network; /* Initialise system (with N tuners) */ void tsfile_init ( int tuners ); +/* Shutdown */ +void tsfile_done ( void ); + /* Add a new file (multiplex) */ void tsfile_add_file ( const char *path ); diff --git a/src/input/mpegts/tsfile/tsfile.c b/src/input/mpegts/tsfile/tsfile.c index 15013e3c..f6b1d4e4 100644 --- a/src/input/mpegts/tsfile/tsfile.c +++ b/src/input/mpegts/tsfile/tsfile.c @@ -28,7 +28,7 @@ */ pthread_mutex_t tsfile_lock; mpegts_network_t tsfile_network; -mpegts_input_list_t tsfile_inputs; +tsfile_input_list_t tsfile_inputs; extern const idclass_t mpegts_service_class; extern const idclass_t mpegts_network_class; @@ -58,7 +58,7 @@ tsfile_network_create_service void tsfile_init ( int tuners ) { int i; - mpegts_input_t *mi; + tsfile_input_t *mi; /* Mutex - used for minor efficiency in service processing */ pthread_mutex_init(&tsfile_lock, NULL); @@ -71,21 +71,38 @@ void tsfile_init ( int tuners ) /* IPTV like setup */ if (tuners <= 0) { mi = tsfile_input_create(0); - mpegts_input_add_network(mi, &tsfile_network); + mpegts_input_add_network((mpegts_input_t*)mi, &tsfile_network); } else { for (i = 0; i < tuners; i++) { mi = tsfile_input_create(i+1); - mpegts_input_add_network(mi, &tsfile_network); + mpegts_input_add_network((mpegts_input_t*)mi, &tsfile_network); } } } +/* + * Shutdown + */ +void +tsfile_done ( void ) +{ + tsfile_input_t *mi; + pthread_mutex_lock(&global_lock); + while ((mi = LIST_FIRST(&tsfile_inputs))) { + LIST_REMOVE(mi, tsi_link); + mpegts_input_stop_all((mpegts_input_t*)mi); + mpegts_input_delete((mpegts_input_t*)mi, 0); + // doesn't close the pipe! + } + pthread_mutex_unlock(&global_lock); +} + /* * Add multiplex */ void tsfile_add_file ( const char *path ) { - mpegts_input_t *mi; + tsfile_input_t *mi; mpegts_mux_t *mm; tvhtrace("tsfile", "add file %s", path); @@ -93,8 +110,8 @@ void tsfile_add_file ( const char *path ) mm = tsfile_mux_create(&tsfile_network); /* Create physical instance (for each tuner) */ - LIST_FOREACH(mi, &tsfile_inputs, mi_global_link) - tsfile_mux_instance_create(path, mi, mm); + LIST_FOREACH(mi, &tsfile_inputs, tsi_link) + tsfile_mux_instance_create(path, (mpegts_input_t*)mi, mm); } /****************************************************************************** diff --git a/src/input/mpegts/tsfile/tsfile_input.c b/src/input/mpegts/tsfile/tsfile_input.c index 29105d10..f6023ca7 100644 --- a/src/input/mpegts/tsfile/tsfile_input.c +++ b/src/input/mpegts/tsfile/tsfile_input.c @@ -37,21 +37,23 @@ extern const idclass_t mpegts_input_class; static void * tsfile_input_thread ( void *aux ) { - int pos = 0, fd = -1, nfds; + int fd = -1, nfds; size_t len, rem; ssize_t c; tvhpoll_t *efd; tvhpoll_event_t ev; struct stat st; - uint8_t tsb[188*10]; + sbuf_t buf; int64_t pcr, pcr_last = PTS_UNSET; #if PLATFORM_LINUX int64_t pcr_last_realtime = 0; #endif - mpegts_input_t *mi = aux; + tsfile_input_t *mi = aux; mpegts_mux_instance_t *mmi; tsfile_mux_instance_t *tmi; + sbuf_init_fixed(&buf, 18800); + /* Open file */ pthread_mutex_lock(&global_lock); @@ -71,7 +73,7 @@ tsfile_input_thread ( void *aux ) memset(&ev, 0, sizeof(ev)); efd = tvhpoll_create(2); ev.events = TVHPOLL_IN; - ev.fd = ev.data.fd = mi->mi_thread_pipe.rd; + ev.fd = ev.data.fd = mi->ti_thread_pipe.rd; tvhpoll_add(efd, &ev, 1); /* Get file length */ @@ -106,7 +108,7 @@ tsfile_input_thread ( void *aux ) if (nfds == 1) break; /* Read */ - c = read(fd, tsb+pos, sizeof(tsb)-pos); + c = sbuf_read(&buf, fd); if (c < 0) { if (errno == EAGAIN || errno == EINTR) continue; @@ -128,8 +130,8 @@ tsfile_input_thread ( void *aux ) /* Process */ if (c >= 0) { pcr = PTS_UNSET; - pos = mpegts_input_recv_packets(mi, mmi, tsb, c+pos, &pcr, - &tmi->mmi_tsfile_pcr_pid, "tsfile"); + mpegts_input_recv_packets((mpegts_input_t*)mi, mmi, &buf, 0, + &pcr, &tmi->mmi_tsfile_pcr_pid); /* Delay */ if (pcr != PTS_UNSET) { @@ -175,14 +177,15 @@ static void tsfile_input_stop_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi ) { int err; + tsfile_input_t *ti = (tsfile_input_t*)mi; /* Stop thread */ - if (mi->mi_thread_pipe.rd != -1) { + if (ti->ti_thread_pipe.rd != -1) { tvhtrace("tsfile", "adapter %d stopping thread", mi->mi_instance); - err = tvh_write(mi->mi_thread_pipe.wr, "", 1); + err = tvh_write(ti->ti_thread_pipe.wr, "", 1); assert(err != -1); - pthread_join(mi->mi_thread_id, NULL); - tvh_pipe_close(&mi->mi_thread_pipe); + pthread_join(ti->ti_thread_id, NULL); + tvh_pipe_close(&ti->ti_thread_pipe); tvhtrace("tsfile", "adapter %d stopped thread", mi->mi_instance); } @@ -196,6 +199,7 @@ tsfile_input_start_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *t ) struct stat st; mpegts_mux_t *mm = t->mmi_mux; tsfile_mux_instance_t *mmi = (tsfile_mux_instance_t*)t; + tsfile_input_t *ti = (tsfile_input_t*)mi; tvhtrace("tsfile", "adapter %d starting mmi %p", mi->mi_instance, mmi); /* Already tuned */ @@ -215,14 +219,14 @@ tsfile_input_start_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *t ) } /* Start thread */ - if (mi->mi_thread_pipe.rd == -1) { - if (tvh_pipe(O_NONBLOCK, &mi->mi_thread_pipe)) { + if (ti->ti_thread_pipe.rd == -1) { + if (tvh_pipe(O_NONBLOCK, &ti->ti_thread_pipe)) { mmi->mmi_tune_failed = 1; tvhlog(LOG_ERR, "tsfile", "failed to create thread pipe"); return SM_CODE_TUNING_FAILED; } tvhtrace("tsfile", "adapter %d starting thread", mi->mi_instance); - tvhthread_create(&mi->mi_thread_id, NULL, tsfile_input_thread, mi, 0); + tvhthread_create(&ti->ti_thread_id, NULL, tsfile_input_thread, mi, 0); } /* Current */ @@ -237,23 +241,27 @@ tsfile_input_start_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *t ) return 0; } -mpegts_input_t * +tsfile_input_t * tsfile_input_create ( int idx ) { - mpegts_input_t *mi; + tsfile_input_t *mi; /* Create object */ - mi = mpegts_input_create1(NULL, NULL); + mi = (tsfile_input_t*) + mpegts_input_create0(calloc(1, sizeof(tsfile_input_t)), + &mpegts_input_class, + NULL, NULL); mi->mi_instance = idx; mi->mi_enabled = 1; mi->mi_start_mux = tsfile_input_start_mux; mi->mi_stop_mux = tsfile_input_stop_mux; - LIST_INSERT_HEAD(&tsfile_inputs, mi, mi_global_link); + LIST_INSERT_HEAD(&tsfile_inputs, mi, tsi_link); if (!mi->mi_name) mi->mi_name = strdup("TSFile"); + mi->ti_thread_pipe.rd = mi->ti_thread_pipe.wr = -1; + /* Start table thread */ - mpegts_input_table_thread_start(mi); return mi; } diff --git a/src/input/mpegts/tsfile/tsfile_private.h b/src/input/mpegts/tsfile/tsfile_private.h index 1c45a38c..7186955d 100644 --- a/src/input/mpegts/tsfile/tsfile_private.h +++ b/src/input/mpegts/tsfile/tsfile_private.h @@ -22,17 +22,20 @@ #include "input.h" +/* + * Typedefs + */ +typedef struct tsfile_input tsfile_input_t; +typedef struct tsfile_mux_instance tsfile_mux_instance_t; +typedef LIST_HEAD(,tsfile_input) tsfile_input_list_t; + /* * Globals */ extern mpegts_network_t tsfile_network; -extern mpegts_input_list_t tsfile_inputs; +extern tsfile_input_list_t tsfile_inputs; extern pthread_mutex_t tsfile_lock; -/* - * Typedefs - */ -typedef struct tsfile_mux_instance tsfile_mux_instance_t; /* * Mux instance @@ -51,14 +54,25 @@ struct tsfile_mux_instance */ char *mmi_tsfile_path; ///< Source file path - th_pipe_t mmi_tsfile_pipe; ///< Thread control pipe uint16_t mmi_tsfile_pcr_pid; ///< Timing control }; +/* + * TS file input + */ +struct tsfile_input +{ + mpegts_input_t; + + LIST_ENTRY(tsfile_input) tsi_link; + th_pipe_t ti_thread_pipe; + pthread_t ti_thread_id; +}; + /* * Prototypes */ -mpegts_input_t *tsfile_input_create ( int idx ); +tsfile_input_t *tsfile_input_create ( int idx ); tsfile_mux_instance_t *tsfile_mux_instance_create ( const char *path, mpegts_input_t *mi, mpegts_mux_t *mm );