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.
This commit is contained in:
Adam Sutton 2013-04-26 16:25:27 +01:00
parent 378b3a6b63
commit 1abb1f7736
6 changed files with 183 additions and 13 deletions

View file

@ -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);

View file

@ -21,6 +21,41 @@
#include "queue.h"
#include "input/mpegts.h"
#include <assert.h>
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;
}

View file

@ -18,6 +18,8 @@
#include "input/mpegts.h"
#include <assert.h>
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

View file

@ -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);

View file

@ -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;
}

View file

@ -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;
}