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:
parent
378b3a6b63
commit
1abb1f7736
6 changed files with 183 additions and 13 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue