From 1abb1f77362e12bc45fea3091ec4c86635479b83 Mon Sep 17 00:00:00 2001 From: Adam Sutton Date: Fri, 26 Apr 2013 16:25:27 +0100 Subject: [PATCH] tsfile: started to get muxes linked for initial scan at the moment there is a problem when a mux cannot be tuned, I don't think its correctly removed from the lists. --- src/input/mpegts.h | 15 +++ src/input/mpegts/mpegts_mux.c | 137 ++++++++++++++++++++++++- src/input/mpegts/mpegts_network.c | 23 +++++ src/input/mpegts/tsfile/tsfile.c | 6 +- src/input/mpegts/tsfile/tsfile_input.c | 7 +- src/input/mpegts/tsfile/tsfile_mux.c | 8 +- 6 files changed, 183 insertions(+), 13 deletions(-) diff --git a/src/input/mpegts.h b/src/input/mpegts.h index a6758b56..9aafa9be 100644 --- a/src/input/mpegts.h +++ b/src/input/mpegts.h @@ -177,6 +177,12 @@ struct mpegts_mux */ LIST_HEAD(, mpegts_mux_instance) mm_instances; + + /* + * Functions + */ + + int (*mm_start) ( mpegts_mux_t *mm, const char *reason, int weight ); #if 0 dvb_mux_conf_t dm_conf; @@ -302,6 +308,7 @@ struct mpegts_mux_instance mpegts_mux_t *mmi_mux; mpegts_input_t *mmi_input; + // TODO: remove this int mmi_tune_failed; // this is really DVB }; @@ -344,9 +351,17 @@ mpegts_input_t *mpegts_input_create0 mpegts_network_t *mpegts_network_create0 ( const char *uuid, const char *name ); +void mpegts_network_schedule_initial_scan + ( mpegts_network_t *mm ); + mpegts_mux_t *mpegts_mux_create0 ( const char *uuid, mpegts_network_t *net, uint16_t onid, uint16_t tsid ); +mpegts_mux_instance_t *mpegts_mux_instance_create0 + ( size_t alloc, const char *uuid, mpegts_input_t *mi, mpegts_mux_t *mm ); + +void mpegts_mux_initial_scan_done ( mpegts_mux_t *mm ); + void mpegts_input_recv_packets (mpegts_input_t *mi, const uint8_t *tsb, size_t len, int64_t *pcr, uint16_t *pcr_pid); diff --git a/src/input/mpegts/mpegts_mux.c b/src/input/mpegts/mpegts_mux.c index 3a5ee3d7..efceaf30 100644 --- a/src/input/mpegts/mpegts_mux.c +++ b/src/input/mpegts/mpegts_mux.c @@ -21,6 +21,41 @@ #include "queue.h" #include "input/mpegts.h" +#include + +const idclass_t mpegts_mux_instance_class = +{ + .ic_class = "mpegts_mux_instance", + .ic_caption = "MPEGTS Multiplex Phy", + .ic_properties = (const property_t[]){ + } +}; + +static int +mpegts_mux_instance_weight ( mpegts_mux_instance_t *mmi ) +{ + return 0; +} + +mpegts_mux_instance_t * +mpegts_mux_instance_create0 + ( size_t alloc, const char *uuid, mpegts_input_t *mi, mpegts_mux_t *mm ) +{ + mpegts_mux_instance_t *mmi; + + /* Create */ + mmi = (mpegts_mux_instance_t*)idnode_create0(alloc, &mpegts_mux_instance_class, uuid); + + /* Setup links */ + mmi->mmi_mux = mm; + mmi->mmi_input = mi; // TODO: is this required? + + LIST_INSERT_HEAD(&mm->mm_instances, mmi, mmi_mux_link); + printf("added to mm_instances\n"); + + return mmi; +} + const idclass_t mpegts_mux_class = { .ic_class = "mpegts_mux", @@ -29,6 +64,103 @@ const idclass_t mpegts_mux_class = } }; +static void +mpegts_mux_initial_scan_link ( mpegts_mux_t *mm ) +{ + mpegts_network_t *mn = mm->mm_network; + + assert(mn != NULL); + assert(mm->mm_initial_scan_status == MM_SCAN_DONE); + + mm->mm_initial_scan_status = MM_SCAN_PENDING; + TAILQ_INSERT_TAIL(&mn->mn_initial_scan_pending_queue, mm, + mm_initial_scan_link); + mn->mn_initial_scan_num++; + printf("initial_scan_num = %d\n", mn->mn_initial_scan_num); + mpegts_network_schedule_initial_scan(mn); +} + +static void +mpegts_mux_initial_scan_timeout ( void *aux ) +{ + mpegts_mux_t *mm = aux; + tvhlog(LOG_DEBUG, "mpegts", "Initial scan timed out for %s", "TODO"); + mpegts_mux_initial_scan_done(mm); +} + +void +mpegts_mux_initial_scan_done ( mpegts_mux_t *mm ) +{ + mpegts_network_t *mn = mm->mm_network; + gtimer_disarm(&mm->mm_initial_scan_timeout); + assert(mm->mm_initial_scan_status == MM_SCAN_CURRENT); + mn->mn_initial_scan_num--; + mm->mm_initial_scan_status = MM_SCAN_DONE; + TAILQ_REMOVE(&mn->mn_initial_scan_current_queue, mm, mm_initial_scan_link); + mpegts_network_schedule_initial_scan(mn); + // TODO: save +} + +static int +mpegts_mux_start ( mpegts_mux_t *mm, const char *reason, int weight ) +{ + mpegts_network_t *mn = mm->mm_network; + mpegts_mux_instance_t *mmi; + + printf("mpegts_mux_start(%p, %s, %d)\n", mm, reason, weight); + + /* Already tuned */ + LIST_FOREACH(mmi, &mm->mm_instances, mmi_mux_link) + if (mmi->mmi_input->mi_mux_current == mmi) + return 0; + printf("not already tuned\n"); + + /* Find */ + // TODO: don't like this is unbounded, if for some reason mi_start_mux() + // constantly fails this will lock + while (1) { + + /* Find free input */ + LIST_FOREACH(mmi, &mm->mm_instances, mmi_mux_link) + if (!mmi->mmi_tune_failed && + !mmi->mmi_input->mi_mux_current) + break; + printf("free input = %p\n", mmi); + + /* Try and remove a lesser instance */ + if (!mmi) { + LIST_FOREACH(mmi, &mm->mm_instances, mmi_mux_link) { + + /* Bad */ + if (mmi->mmi_tune_failed) + continue; + + /* Found */ + if (mpegts_mux_instance_weight(mmi->mmi_input->mi_mux_current) < weight) + break; + } + + /* No free input */ + if (!mmi) + return SM_CODE_NO_FREE_ADAPTER; + } + + /* Tune */ + if (!mmi->mmi_input->mi_start_mux(mmi->mmi_input, mmi)) + break; + } + + /* Initial scanning */ + if (mm->mm_initial_scan_status == MM_SCAN_PENDING) { + 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); + gtimer_arm(&mm->mm_initial_scan_timeout, mpegts_mux_initial_scan_timeout, mm, 10); + } + + return 0; +} + mpegts_mux_t * mpegts_mux_create0 ( const char *uuid, mpegts_network_t *net, uint16_t onid, uint16_t tsid ) @@ -41,9 +173,8 @@ mpegts_mux_create0 /* Add to network */ mm->mm_network = net; - mm->mm_initial_scan_status = MM_SCAN_PENDING; - TAILQ_INSERT_TAIL(&net->mn_initial_scan_pending_queue, mm, - mm_initial_scan_link); + mm->mm_start = mpegts_mux_start; + mpegts_mux_initial_scan_link(mm); return mm; } diff --git a/src/input/mpegts/mpegts_network.c b/src/input/mpegts/mpegts_network.c index 9c60425e..b14b13b0 100644 --- a/src/input/mpegts/mpegts_network.c +++ b/src/input/mpegts/mpegts_network.c @@ -18,6 +18,8 @@ #include "input/mpegts.h" +#include + const idclass_t mpegts_network_class = { .ic_class = "mpegts_network", @@ -26,6 +28,27 @@ const idclass_t mpegts_network_class = } }; +static void +mpegts_network_initial_scan(void *aux) +{ + mpegts_network_t *mn = aux; + mpegts_mux_t *mm; + + printf("mpegts_network_initial_scan(%p)\n", aux); + while((mm = TAILQ_FIRST(&mn->mn_initial_scan_pending_queue)) != NULL) { + assert(mm->mm_initial_scan_status == MM_SCAN_PENDING); + if (mm->mm_start(mm, "initial scan", 1)) + break; + assert(mm->mm_initial_scan_status == MM_SCAN_CURRENT); + } + gtimer_arm(&mn->mn_initial_scan_timer, mpegts_network_initial_scan, mn, 10); +} + +void +mpegts_network_schedule_initial_scan ( mpegts_network_t *mn ) +{ + gtimer_arm(&mn->mn_initial_scan_timer, mpegts_network_initial_scan, mn, 0); +} mpegts_network_t * mpegts_network_create0 diff --git a/src/input/mpegts/tsfile/tsfile.c b/src/input/mpegts/tsfile/tsfile.c index b86ce65a..2fe9669c 100644 --- a/src/input/mpegts/tsfile/tsfile.c +++ b/src/input/mpegts/tsfile/tsfile.c @@ -30,17 +30,15 @@ void tsfile_init ( int tuners ) { int i; mpegts_input_t *mi; -printf("tsfile_init(%d)\n", tuners); /* Shared network */ -printf("create network\n"); tsfile_network = mpegts_network_create0(NULL, "tsfile network"); /* Create inputs */ -printf("create inputs\n"); for (i = 0; i < tuners; i++) { mi = tsfile_input_create(); mi->mi_network = tsfile_network; + LIST_INSERT_HEAD(&tsfile_inputs, mi, mi_global_link); } } @@ -54,10 +52,8 @@ void tsfile_add_file ( const char *path ) printf("tsfile_add_file(%s)\n", path); /* Create logical instance */ -printf("create logical mux\n"); mm = mpegts_mux_create0(NULL, tsfile_network, MM_ONID_NONE, MM_TSID_NONE); -printf("create physical mux\n"); /* Create physical instance (for each tuner) */ LIST_FOREACH(mi, &tsfile_inputs, mi_global_link) tsfile_mux_instance_create(path, mi, mm); diff --git a/src/input/mpegts/tsfile/tsfile_input.c b/src/input/mpegts/tsfile/tsfile_input.c index 432f1755..2365041b 100644 --- a/src/input/mpegts/tsfile/tsfile_input.c +++ b/src/input/mpegts/tsfile/tsfile_input.c @@ -152,14 +152,19 @@ tsfile_input_start_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *t ) { struct stat st; tsfile_mux_instance_t *mmi = (tsfile_mux_instance_t*)t; + printf("tsfile_input_start_mux(%p, %p)\n", mi, t); /* Check file is accessible */ - if (lstat(mmi->mmi_tsfile_path, &st)) + if (lstat(mmi->mmi_tsfile_path, &st)) { + printf("could not stat %s\n", mmi->mmi_tsfile_path); + mmi->mmi_tune_failed = 1; return SM_CODE_TUNING_FAILED; + } /* Start thread */ if (mi->mi_thread_pipe.rd == -1) { if (tvh_pipe(O_NONBLOCK, &mi->mi_thread_pipe)) { + mmi->mmi_tune_failed = 1; tvhlog(LOG_ERR, "tsfile", "failed to create thread pipe"); return SM_CODE_TUNING_FAILED; } diff --git a/src/input/mpegts/tsfile/tsfile_mux.c b/src/input/mpegts/tsfile/tsfile_mux.c index d4cc2f7c..923f8eba 100644 --- a/src/input/mpegts/tsfile/tsfile_mux.c +++ b/src/input/mpegts/tsfile/tsfile_mux.c @@ -23,11 +23,11 @@ tsfile_mux_instance_t * tsfile_mux_instance_create ( const char *path, mpegts_input_t *mi, mpegts_mux_t *mm ) { - tsfile_mux_instance_t *mmi = NULL; - // super constructor -#if 0 + tsfile_mux_instance_t *mmi = (tsfile_mux_instance_t*) + mpegts_mux_instance_create0(sizeof(tsfile_mux_instance_t), + NULL, mi, mm); mmi->mmi_tsfile_path = strdup(path); -#endif + printf("mmi craeated %p path %s\n", mmi, mmi->mmi_tsfile_path); return mmi; }