Use flags to signal transport status
This commit is contained in:
parent
7ae41b62ce
commit
62008fcb9d
10 changed files with 114 additions and 122 deletions
|
@ -435,9 +435,12 @@ dvr_thread(void *aux)
|
|||
break;
|
||||
|
||||
case SMT_TRANSPORT_STATUS:
|
||||
if(sm->sm_code != TRANSPORT_FEED_VALID_PACKETS)
|
||||
if(sm->sm_code & TSS_PACKETS) {
|
||||
|
||||
} else if(sm->sm_code & (TSS_GRACEPERIOD | TSS_ERRORS)) {
|
||||
dvr_rec_fatal_error(de, "Source problems: %s",
|
||||
transport_feed_status_to_text(sm->sm_code));
|
||||
transport_tss2text(sm->sm_code));
|
||||
}
|
||||
break;
|
||||
|
||||
case SMT_NOSOURCE:
|
||||
|
|
15
src/htsp.c
15
src/htsp.c
|
@ -1478,17 +1478,14 @@ htsp_subscription_status(htsp_subscription_t *hs, const char *err)
|
|||
*
|
||||
*/
|
||||
static void
|
||||
htsp_subscription_transport_status(htsp_subscription_t *hs,
|
||||
transport_feed_status_t status)
|
||||
htsp_subscription_transport_status(htsp_subscription_t *hs, int status)
|
||||
{
|
||||
const char *err = NULL;
|
||||
|
||||
if(status != TRANSPORT_FEED_VALID_PACKETS)
|
||||
err = transport_feed_status_to_text(status);
|
||||
|
||||
htsp_subscription_status(hs, err);
|
||||
if(status & TSS_PACKETS) {
|
||||
htsp_subscription_status(hs, NULL);
|
||||
} else if(status & (TSS_GRACEPERIOD | TSS_ERRORS)) {
|
||||
htsp_subscription_status(hs, transport_tss2text(status));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
@ -1095,7 +1095,7 @@ parser_deliver(th_transport_t *t, th_stream_t *st, th_pkt_t *pkt,
|
|||
/**
|
||||
* Input is ok
|
||||
*/
|
||||
transport_set_feed_status(t, TRANSPORT_FEED_VALID_PACKETS);
|
||||
transport_set_streaming_status_flags(t, TSS_PACKETS);
|
||||
|
||||
/* Forward packet */
|
||||
pkt->pkt_componentindex = st->st_index;
|
||||
|
|
|
@ -365,7 +365,7 @@ psi_parse_pmt(th_transport_t *t, const uint8_t *ptr, int len, int chksvcid,
|
|||
len -= 5;
|
||||
|
||||
frameduration = 0;
|
||||
hts_stream_type = 0;
|
||||
hts_stream_type = SCT_UNKNOWN;
|
||||
memset(lang, 0, 4);
|
||||
composition_id = -1;
|
||||
ancillary_id = -1;
|
||||
|
@ -452,7 +452,7 @@ psi_parse_pmt(th_transport_t *t, const uint8_t *ptr, int len, int chksvcid,
|
|||
len -= dlen; ptr += dlen; dllen -= dlen;
|
||||
}
|
||||
|
||||
if(hts_stream_type != 0) {
|
||||
if(hts_stream_type != SCT_UNKNOWN) {
|
||||
|
||||
if((st = transport_stream_find(t, pid)) == NULL) {
|
||||
update |= PMT_UPDATE_NEW_STREAM;
|
||||
|
|
|
@ -84,7 +84,7 @@ serviceprobe_thread(void *aux)
|
|||
int was_doing_work = 0;
|
||||
streaming_queue_t sq;
|
||||
streaming_message_t *sm;
|
||||
transport_feed_status_t status;
|
||||
// transport_feed_status_t status;
|
||||
int run;
|
||||
const char *err;
|
||||
channel_t *ch;
|
||||
|
@ -136,14 +136,14 @@ serviceprobe_thread(void *aux)
|
|||
pthread_mutex_unlock(&sq.sq_mutex);
|
||||
|
||||
if(sm->sm_type == SMT_TRANSPORT_STATUS) {
|
||||
status = sm->sm_code;
|
||||
int status = sm->sm_code;
|
||||
|
||||
run = 0;
|
||||
|
||||
if(status == TRANSPORT_FEED_VALID_PACKETS) {
|
||||
if(status & TSS_PACKETS) {
|
||||
run = 0;
|
||||
err = NULL;
|
||||
} else {
|
||||
err = transport_feed_status_to_text(status);
|
||||
} else if(status & (TSS_GRACEPERIOD | TSS_ERRORS)) {
|
||||
run = 0;
|
||||
err = transport_tss2text(status);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -68,11 +68,10 @@ static void
|
|||
subscription_link_transport(th_subscription_t *s, th_transport_t *t)
|
||||
{
|
||||
streaming_message_t *sm;
|
||||
|
||||
|
||||
s->ths_transport = t;
|
||||
LIST_INSERT_HEAD(&t->tht_subscriptions, s, ths_transport_link);
|
||||
|
||||
|
||||
pthread_mutex_lock(&t->tht_stream_mutex);
|
||||
|
||||
// Link to transport output
|
||||
|
@ -87,10 +86,12 @@ subscription_link_transport(th_subscription_t *s, th_transport_t *t)
|
|||
streaming_target_deliver(s->ths_output, sm);
|
||||
|
||||
// Send a TRANSPORT_STATUS message to the subscription client
|
||||
if(t->tht_feed_status != TRANSPORT_FEED_UNKNOWN) {
|
||||
sm = streaming_msg_create_code(SMT_TRANSPORT_STATUS, t->tht_feed_status);
|
||||
if(t->tht_streaming_status) {
|
||||
sm = streaming_msg_create_code(SMT_TRANSPORT_STATUS,
|
||||
t->tht_streaming_status);
|
||||
streaming_target_deliver(s->ths_output, sm);
|
||||
}
|
||||
|
||||
}
|
||||
pthread_mutex_unlock(&t->tht_stream_mutex);
|
||||
}
|
||||
|
@ -334,8 +335,7 @@ dummy_callback(void *opauqe, streaming_message_t *sm)
|
|||
break;
|
||||
|
||||
case SMT_TRANSPORT_STATUS:
|
||||
fprintf(stderr, "dummsubscription: %s\n",
|
||||
transport_feed_status_to_text(sm->sm_code));
|
||||
fprintf(stderr, "dummsubscription: %x\n", sm->sm_code);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
100
src/transports.c
100
src/transports.c
|
@ -265,9 +265,7 @@ transport_start(th_transport_t *t, unsigned int weight, int force_start)
|
|||
lock_assert(&global_lock);
|
||||
|
||||
assert(t->tht_status != TRANSPORT_RUNNING);
|
||||
|
||||
t->tht_feed_status = TRANSPORT_FEED_UNKNOWN;
|
||||
t->tht_input_status = TRANSPORT_FEED_NO_INPUT;
|
||||
t->tht_streaming_status = 0;
|
||||
t->tht_dts_start = AV_NOPTS_VALUE;
|
||||
t->tht_pcr_drift = 0;
|
||||
|
||||
|
@ -713,7 +711,6 @@ transport_map_channel(th_transport_t *t, channel_t *ch, int save)
|
|||
t->tht_config_save(t);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -724,13 +721,11 @@ transport_data_timeout(void *aux)
|
|||
|
||||
pthread_mutex_lock(&t->tht_stream_mutex);
|
||||
|
||||
if(t->tht_feed_status == TRANSPORT_FEED_UNKNOWN)
|
||||
transport_set_feed_status(t, t->tht_input_status);
|
||||
transport_set_streaming_status_flags(t, TSS_GRACEPERIOD);
|
||||
|
||||
pthread_mutex_unlock(&t->tht_stream_mutex);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -766,17 +761,33 @@ transport_is_tv(th_transport_t *t)
|
|||
*
|
||||
*/
|
||||
void
|
||||
transport_set_feed_status(th_transport_t *t, transport_feed_status_t newstatus)
|
||||
transport_set_streaming_status_flags(th_transport_t *t, int set)
|
||||
{
|
||||
int n;
|
||||
streaming_message_t *sm;
|
||||
lock_assert(&t->tht_stream_mutex);
|
||||
|
||||
n = t->tht_streaming_status;
|
||||
|
||||
n |= set;
|
||||
|
||||
if(t->tht_feed_status == newstatus)
|
||||
return;
|
||||
if(n == t->tht_streaming_status)
|
||||
return; // Already set
|
||||
|
||||
t->tht_feed_status = newstatus;
|
||||
t->tht_streaming_status = n;
|
||||
|
||||
streaming_message_t *sm = streaming_msg_create_code(SMT_TRANSPORT_STATUS,
|
||||
newstatus);
|
||||
tvhlog(LOG_DEBUG, "Transport", "%s: Status changed to %s%s%s%s%s%s%s",
|
||||
transport_nicename(t),
|
||||
n & TSS_INPUT_HARDWARE ? "[Hardware input] " : "",
|
||||
n & TSS_INPUT_SERVICE ? "[Input on service] " : "",
|
||||
n & TSS_MUX_PACKETS ? "[Demuxed packets] " : "",
|
||||
n & TSS_PACKETS ? "[Reassembled packets] " : "",
|
||||
n & TSS_NO_DESCRAMBLER ? "[No available descrambler] " : "",
|
||||
n & TSS_NO_ACCESS ? "[No access] " : "",
|
||||
n & TSS_GRACEPERIOD ? "[Graceperiod expired] " : "");
|
||||
|
||||
sm = streaming_msg_create_code(SMT_TRANSPORT_STATUS,
|
||||
t->tht_streaming_status);
|
||||
streaming_pad_deliver(&t->tht_streaming_pad, sm);
|
||||
streaming_msg_free(sm);
|
||||
}
|
||||
|
@ -848,42 +859,6 @@ transport_build_stream_start(th_transport_t *t)
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Table for status -> text conversion
|
||||
*/
|
||||
static struct strtab transportstatustab[] = {
|
||||
{ "Unknown",
|
||||
TRANSPORT_FEED_UNKNOWN },
|
||||
|
||||
{ "No data input from adapter detected",
|
||||
TRANSPORT_FEED_NO_INPUT},
|
||||
|
||||
{"No mux packets for this service",
|
||||
TRANSPORT_FEED_NO_DEMUXED_INPUT},
|
||||
|
||||
{"Data received for service, but no packets could be reassembled",
|
||||
TRANSPORT_FEED_RAW_INPUT},
|
||||
|
||||
{"No descrambler available for service",
|
||||
TRANSPORT_FEED_NO_DESCRAMBLER},
|
||||
|
||||
{"Access denied",
|
||||
TRANSPORT_FEED_NO_ACCESS},
|
||||
|
||||
{"OK",
|
||||
TRANSPORT_FEED_VALID_PACKETS},
|
||||
};
|
||||
|
||||
|
||||
const char *
|
||||
transport_feed_status_to_text(transport_feed_status_t status)
|
||||
{
|
||||
return val2str(status, transportstatustab) ?: "Unknown";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -1013,3 +988,30 @@ transport_component_nicename(th_stream_t *st)
|
|||
{
|
||||
return st->st_nicename;
|
||||
}
|
||||
|
||||
const char *
|
||||
transport_tss2text(int flags)
|
||||
{
|
||||
if(flags & TSS_NO_ACCESS)
|
||||
return "No access";
|
||||
|
||||
if(flags & TSS_NO_DESCRAMBLER)
|
||||
return "No descrambler";
|
||||
|
||||
if(flags & TSS_PACKETS)
|
||||
return "Got valid packets";
|
||||
|
||||
if(flags & TSS_MUX_PACKETS)
|
||||
return "Got multiplexed packets but could not decode further";
|
||||
|
||||
if(flags & TSS_INPUT_SERVICE)
|
||||
return "Got packets for this service but could not decode further";
|
||||
|
||||
if(flags & TSS_INPUT_HARDWARE)
|
||||
return "Sensed input from hardware but nothing for the service";
|
||||
|
||||
if(flags & TSS_GRACEPERIOD)
|
||||
return "No input detected";
|
||||
|
||||
return "No status";
|
||||
}
|
||||
|
|
|
@ -65,13 +65,10 @@ int transport_is_tv(th_transport_t *t);
|
|||
|
||||
void transport_destroy(th_transport_t *t);
|
||||
|
||||
void transport_set_feed_status(th_transport_t *t,
|
||||
transport_feed_status_t newstatus);
|
||||
|
||||
const char *transport_feed_status_to_text(transport_feed_status_t status);
|
||||
|
||||
void transport_remove_subscriber(th_transport_t *t, th_subscription_t *s);
|
||||
|
||||
void transport_set_streaming_status_flags(th_transport_t *t, int flag);
|
||||
|
||||
static inline th_stream_t *
|
||||
transport_find_stream_by_pid(th_transport_t *t, int pid)
|
||||
{
|
||||
|
@ -107,4 +104,11 @@ const char *transport_component_nicename(th_stream_t *st);
|
|||
|
||||
const char *transport_nostart2txt(int code);
|
||||
|
||||
const char *transport_tss2text(int flags);
|
||||
|
||||
static inline int transport_tss_is_error(int flags)
|
||||
{
|
||||
return flags & TSS_ERRORS ? 1 : 0;
|
||||
}
|
||||
|
||||
#endif /* TRANSPORTS_H */
|
||||
|
|
|
@ -73,6 +73,8 @@ ts_recv_packet0(th_transport_t *t, th_stream_t *st, uint8_t *tsb)
|
|||
{
|
||||
int off, len, pusi, cc, err = 0;
|
||||
|
||||
transport_set_streaming_status_flags(t, TSS_MUX_PACKETS);
|
||||
|
||||
if(streaming_pad_probe_type(&t->tht_streaming_pad, SMT_MPEGTS))
|
||||
ts_remux(t, tsb);
|
||||
|
||||
|
@ -204,19 +206,20 @@ ts_recv_packet1(th_transport_t *t, uint8_t *tsb, int64_t *pcrp)
|
|||
int pid, n, m, r;
|
||||
th_descrambler_t *td;
|
||||
|
||||
t->tht_input_status = TRANSPORT_FEED_NO_DEMUXED_INPUT;
|
||||
pthread_mutex_lock(&t->tht_stream_mutex);
|
||||
|
||||
transport_set_streaming_status_flags(t, TSS_INPUT_HARDWARE);
|
||||
|
||||
if(tsb[1] & 0x80) {
|
||||
/* Transport Error Indicator */
|
||||
limitedlog(&t->tht_loglimit_tei, "TS", transport_nicename(t),
|
||||
"Transport error indicator");
|
||||
pthread_mutex_unlock(&t->tht_stream_mutex);
|
||||
return;
|
||||
}
|
||||
t->tht_input_status = TRANSPORT_FEED_RAW_INPUT;
|
||||
|
||||
pid = (tsb[1] & 0x1f) << 8 | tsb[2];
|
||||
|
||||
pthread_mutex_lock(&t->tht_stream_mutex);
|
||||
st = transport_find_stream_by_pid(t, pid);
|
||||
|
||||
/* Extract PCR */
|
||||
|
@ -228,6 +231,8 @@ ts_recv_packet1(th_transport_t *t, uint8_t *tsb, int64_t *pcrp)
|
|||
return;
|
||||
}
|
||||
|
||||
transport_set_streaming_status_flags(t, TSS_INPUT_SERVICE);
|
||||
|
||||
avgstat_add(&t->tht_rate, 188, dispatch_clock);
|
||||
|
||||
if((tsb[3] & 0xc0) ||
|
||||
|
@ -253,9 +258,9 @@ ts_recv_packet1(th_transport_t *t, uint8_t *tsb, int64_t *pcrp)
|
|||
}
|
||||
|
||||
if(n == 0) {
|
||||
transport_set_feed_status(t, TRANSPORT_FEED_NO_DESCRAMBLER);
|
||||
transport_set_streaming_status_flags(t, TSS_NO_DESCRAMBLER);
|
||||
} else if(m == n) {
|
||||
transport_set_feed_status(t, TRANSPORT_FEED_NO_ACCESS);
|
||||
transport_set_streaming_status_flags(t, TSS_NO_ACCESS);
|
||||
}
|
||||
} else {
|
||||
ts_recv_packet0(t, st, tsb);
|
||||
|
|
53
src/tvhead.h
53
src/tvhead.h
|
@ -134,6 +134,7 @@ void limitedlog(loglimiter_t *ll, const char *sys,
|
|||
* Stream component types
|
||||
*/
|
||||
typedef enum {
|
||||
SCT_UNKNOWN = 0,
|
||||
SCT_MPEG2VIDEO = 1,
|
||||
SCT_MPEG2AUDIO,
|
||||
SCT_H264,
|
||||
|
@ -176,7 +177,7 @@ typedef enum {
|
|||
SMT_START, // sm_data is a stream_start,
|
||||
// see transport_build_stream_start()
|
||||
SMT_STOP , // no extra payload right now
|
||||
SMT_TRANSPORT_STATUS, // sm_code is TRANSPORT_STATUS_
|
||||
SMT_TRANSPORT_STATUS, // sm_code is TSS_ ...something
|
||||
SMT_EXIT, // Used to signal exit to threads
|
||||
SMT_NOSOURCE,
|
||||
SMT_MPEGTS, // sm_data is raw MPEG TS
|
||||
|
@ -367,35 +368,6 @@ typedef struct th_stream {
|
|||
} th_stream_t;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
|
||||
/** No status known */
|
||||
TRANSPORT_FEED_UNKNOWN,
|
||||
|
||||
/** No packets are received from source at all */
|
||||
TRANSPORT_FEED_NO_INPUT,
|
||||
|
||||
/** No input is received from source destined for this transport */
|
||||
TRANSPORT_FEED_NO_DEMUXED_INPUT,
|
||||
|
||||
/** Raw input seen but nothing has really been decoded */
|
||||
TRANSPORT_FEED_RAW_INPUT,
|
||||
|
||||
/** No descrambler is able to decrypt the stream */
|
||||
TRANSPORT_FEED_NO_DESCRAMBLER,
|
||||
|
||||
/** Potential descrambler is available, but access is denied */
|
||||
TRANSPORT_FEED_NO_ACCESS,
|
||||
|
||||
/** Packet are being parsed. */
|
||||
TRANSPORT_FEED_VALID_PACKETS,
|
||||
|
||||
} transport_feed_status_t;
|
||||
|
||||
|
||||
/**
|
||||
* A Transport (or in MPEG TS terms: a 'service')
|
||||
*/
|
||||
|
@ -626,14 +598,23 @@ typedef struct th_transport {
|
|||
pthread_mutex_t tht_stream_mutex;
|
||||
|
||||
/**
|
||||
* Last known data status (or error)
|
||||
*
|
||||
*/
|
||||
transport_feed_status_t tht_feed_status;
|
||||
int tht_streaming_status;
|
||||
|
||||
/**
|
||||
* Set as soon as we get some kind of activity
|
||||
*/
|
||||
transport_feed_status_t tht_input_status;
|
||||
// Progress
|
||||
#define TSS_INPUT_HARDWARE 0x1
|
||||
#define TSS_INPUT_SERVICE 0x2
|
||||
#define TSS_MUX_PACKETS 0x4
|
||||
#define TSS_PACKETS 0x8
|
||||
|
||||
#define TSS_GRACEPERIOD 0x8000
|
||||
|
||||
// Errors
|
||||
#define TSS_NO_DESCRAMBLER 0x10000
|
||||
#define TSS_NO_ACCESS 0x20000
|
||||
|
||||
#define TSS_ERRORS 0xffff0000
|
||||
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Reference in a new issue