implement TSS_TUNING message for late tuning error notification (SAT>IP)

This commit is contained in:
Jaroslav Kysela 2014-12-12 11:19:26 +01:00
parent 0b416b3e29
commit d760c4cb7c
10 changed files with 97 additions and 31 deletions

View file

@ -576,11 +576,10 @@ dvr_thread(void *aux)
case SMT_SERVICE_STATUS:
if(sm->sm_code & TSS_PACKETS) {
} else if(sm->sm_code & (TSS_GRACEPERIOD | TSS_ERRORS)) {
} else if(sm->sm_code & TSS_ERRORS) {
int code = SM_CODE_UNDEFINED_ERROR;
if(sm->sm_code & TSS_NO_DESCRAMBLER)
code = SM_CODE_NO_DESCRAMBLER;

View file

@ -3184,7 +3184,7 @@ htsp_subscription_service_status(htsp_subscription_t *hs, int status)
{
if(status & TSS_PACKETS) {
htsp_subscription_status(hs, NULL);
} else if(status & (TSS_GRACEPERIOD | TSS_ERRORS)) {
} else if(status & TSS_ERRORS) {
htsp_subscription_status(hs, service_tss2text(status));
}
}

View file

@ -631,6 +631,7 @@ struct mpegts_input
void (*mi_stopping_mux) (mpegts_input_t*,mpegts_mux_instance_t*);
void (*mi_stopped_mux) (mpegts_input_t*,mpegts_mux_instance_t*);
int (*mi_has_subscription) (mpegts_input_t*, mpegts_mux_t *mm);
void (*mi_tuning_error) (mpegts_input_t*,mpegts_mux_t *);
idnode_set_t *(*mi_network_list) (mpegts_input_t*);
};
@ -748,6 +749,8 @@ void mpegts_mux_delete ( mpegts_mux_t *mm, int delconf );
void mpegts_mux_save ( mpegts_mux_t *mm, htsmsg_t *c );
void mpegts_mux_tuning_error( mpegts_mux_t *mm );
mpegts_mux_instance_t *mpegts_mux_instance_create0
( mpegts_mux_instance_t *mmi, const idclass_t *class, const char *uuid,
mpegts_input_t *mi, mpegts_mux_t *mm );

View file

@ -544,7 +544,7 @@ mpegts_input_stopped_mux
( mpegts_input_t *mi, mpegts_mux_instance_t *mmi )
{
char buf[256];
service_t *s;
service_t *s, *s_next;
/* no longer active */
LIST_REMOVE(mmi, mmi_active_link);
@ -555,11 +555,10 @@ mpegts_input_stopped_mux
mi->mi_display_name(mi, buf, sizeof(buf));
tvhtrace("mpegts", "%s - flush subscribers", buf);
s = LIST_FIRST(&mi->mi_transports);
while (s) {
for (s = LIST_FIRST(&mi->mi_transports); s; s = s_next) {
s_next = LIST_NEXT(s, s_active_link);
if (((mpegts_service_t*)s)->s_dvb_mux == mmi->mmi_mux)
service_remove_subscriber(s, NULL, SM_CODE_SUBSCRIPTION_OVERRIDDEN);
s = LIST_NEXT(s, s_active_link);
}
notify_reload("input_status");
mpegts_input_dbus_notify(mi, 0);
@ -597,6 +596,22 @@ mpegts_input_has_subscription ( mpegts_input_t *mi, mpegts_mux_t *mm )
return ret;
}
static void
mpegts_input_tuning_error ( mpegts_input_t *mi, mpegts_mux_t *mm )
{
service_t *t, *t_next;
pthread_mutex_lock(&mi->mi_output_lock);
for (t = LIST_FIRST(&mi->mi_transports); t; t = t_next) {
t_next = LIST_NEXT(t, s_active_link);
if (((mpegts_service_t*)t)->s_dvb_mux == mm) {
pthread_mutex_lock(&t->s_stream_mutex);
service_set_streaming_status_flags(t, TSS_TUNING);
pthread_mutex_unlock(&t->s_stream_mutex);
}
}
pthread_mutex_unlock(&mi->mi_output_lock);
}
/* **************************************************************************
* Data processing
* *************************************************************************/
@ -867,9 +882,6 @@ mpegts_input_process
goto done;
}
/* Remove in future or move it outside this loop */
lock_assert(&mi->mi_output_lock);
/* Find PID */
if ((mp = mpegts_mux_find_pid(mm, pid, 0))) {
@ -1259,6 +1271,7 @@ mpegts_input_create0
mi->mi_stopping_mux = mpegts_input_stopping_mux;
mi->mi_stopped_mux = mpegts_input_stopped_mux;
mi->mi_has_subscription = mpegts_input_has_subscription;
mi->mi_tuning_error = mpegts_input_tuning_error;
mi->ti_get_streams = mpegts_input_get_streams;
/* Index */
@ -1405,7 +1418,8 @@ mpegts_input_set_networks ( mpegts_input_t *mi, htsmsg_t *msg )
return save;
}
int mpegts_input_grace( mpegts_input_t *mi, mpegts_mux_t *mm )
int
mpegts_input_grace( mpegts_input_t *mi, mpegts_mux_t *mm )
{
/* Get timeout */
int t = 0;

View file

@ -21,6 +21,7 @@
#include "queue.h"
#include "input.h"
#include "subscriptions.h"
#include "streaming.h"
#include "channels.h"
#include "access.h"
#include "profile.h"
@ -1111,12 +1112,31 @@ mpegts_mux_unsubscribe_by_name
}
}
void
mpegts_mux_tuning_error ( mpegts_mux_t *mm )
{
th_subscription_t *sub;
mpegts_mux_instance_t *mmi;
streaming_message_t *sm;
lock_assert(&global_lock);
if ((mmi = mm->mm_active) != NULL) {
LIST_FOREACH(sub, &mmi->mmi_subs, ths_mmi_link) {
sm = streaming_msg_create_code(SMT_SERVICE_STATUS, TSS_TUNING);
streaming_target_deliver(sub->ths_output, sm);
}
if (mmi->mmi_input)
mmi->mmi_input->mi_tuning_error(mmi->mmi_input, mm);
}
}
/* **************************************************************************
* Search
* *************************************************************************/
mpegts_service_t *
mpegts_mux_find_service ( mpegts_mux_t *mm, uint16_t sid)
mpegts_mux_find_service ( mpegts_mux_t *mm, uint16_t sid )
{
mpegts_service_t *ms;
LIST_FOREACH(ms, &mm->mm_services, s_dvb_mux_link)

View file

@ -999,6 +999,18 @@ satip_frontend_pid_changed( http_client_t *rtsp,
return r;
}
static void
satip_frontend_tuning_error ( satip_frontend_t *lfe, satip_tune_req_t *tr )
{
pthread_mutex_lock(&global_lock);
pthread_mutex_lock(&lfe->sf_dvr_lock);
if (lfe->sf_running && lfe->sf_req == tr &&
tr->sf_mmi && tr->sf_mmi->mmi_mux)
mpegts_mux_tuning_error(tr->sf_mmi->mmi_mux);
pthread_mutex_unlock(&lfe->sf_dvr_lock);
pthread_mutex_unlock(&global_lock);
}
static void *
satip_frontend_input_thread ( void *aux )
{
@ -1086,7 +1098,7 @@ new_tune:
mmi = tr->sf_mmi;
changing = 0;
ms = -1;
ms = 500;
fatal = 0;
running = 1;
seq = -1;
@ -1096,8 +1108,10 @@ new_tune:
if (udp_bind_double(&rtp, &rtcp,
"satip", "rtp", "rtpc",
satip_frontend_bindaddr(lfe), lfe->sf_udp_rtp_port,
NULL, SATIP_BUF_SIZE, 16384) < 0)
NULL, SATIP_BUF_SIZE, 16384) < 0) {
satip_frontend_tuning_error(lfe, tr);
goto done;
}
rtp_port = ntohs(IP_PORT(rtp->ip));
@ -1106,8 +1120,10 @@ new_tune:
ntohs(IP_PORT(rtp->ip)),
ntohs(IP_PORT(rtcp->ip)));
if (rtp == NULL || rtcp == NULL || mmi == NULL)
if (rtp == NULL || rtcp == NULL || mmi == NULL) {
satip_frontend_tuning_error(lfe, tr);
goto done;
}
lm = (dvb_mux_t *)mmi->mmi_mux;
@ -1176,8 +1192,10 @@ new_tune:
rtsp = http_client_connect(lfe, RTSP_VERSION_1_0, "rstp",
lfe->sf_device->sd_info.addr, 554,
satip_frontend_bindaddr(lfe));
if (rtsp == NULL)
if (rtsp == NULL) {
satip_frontend_tuning_error(lfe, tr);
goto done;
}
/* Setup poll */
memset(ev, 0, sizeof(ev));
@ -1198,7 +1216,7 @@ new_tune:
rtsp_flags |= SATIP_SETUP_PIDS0;
if (lfe->sf_device->sd_pilot_on)
rtsp_flags |= SATIP_SETUP_PILOT_ON;
r = 0xa59234;
r = -12345678;
pthread_mutex_lock(&lfe->sf_dvr_lock);
if (lfe->sf_req == lfe->sf_req_thread)
r = satip_rtsp_setup(rtsp,
@ -1207,15 +1225,15 @@ new_tune:
rtsp_flags);
pthread_mutex_unlock(&lfe->sf_dvr_lock);
if (r < 0) {
if (r != 0xa59234)
tvherror("satip", "%s - failed to tune", buf);
tvherror("satip", "%s - failed to tune", buf);
satip_frontend_tuning_error(lfe, tr);
goto done;
}
reply = 1;
udp_multirecv_init(&um, RTP_PKTS, RTP_PKT_SIZE);
sbuf_init_fixed(&sb, RTP_PKTS * RTP_PKT_SIZE);
while ((reply || running) && !fatal) {
nfds = tvhpoll_wait(efd, ev, 1, ms);
@ -1247,7 +1265,7 @@ new_tune:
}
if (changing && rtsp->hc_cmd == HTTP_CMD_NONE) {
ms = -1;
ms = 500;
changing = 0;
if (satip_frontend_pid_changed(rtsp, lfe, buf) > 0)
reply = 1;
@ -1261,6 +1279,7 @@ new_tune:
if (r < 0) {
tvhlog(LOG_ERR, "satip", "%s - RTSP error %d (%s) [%i-%i]",
buf, r, strerror(-r), rtsp->hc_cmd, rtsp->hc_code);
satip_frontend_tuning_error(lfe, tr);
fatal = 1;
} else if (r == HTTP_CON_DONE) {
reply = 0;
@ -1272,6 +1291,7 @@ new_tune:
if (r < 0) {
tvhlog(LOG_ERR, "satip", "%s - RTSP OPTIONS error %d (%s) [%i-%i]",
buf, r, strerror(-r), rtsp->hc_cmd, rtsp->hc_code);
satip_frontend_tuning_error(lfe, tr);
fatal = 1;
}
break;
@ -1283,13 +1303,14 @@ new_tune:
rtsp->hc_rtpc_port != rtp_port + 1) {
tvhlog(LOG_ERR, "satip", "%s - RTSP SETUP error %d (%s) [%i-%i]",
buf, r, strerror(-r), rtsp->hc_cmd, rtsp->hc_code);
satip_frontend_tuning_error(lfe, tr);
fatal = 1;
} else {
tvhdebug("satip", "%s #%i - new session %s stream id %li",
rtsp->hc_host, lfe->sf_number,
rtsp->hc_rtsp_session, rtsp->hc_rtsp_stream_id);
if (lfe->sf_play2) {
r = 0xa59234;
r = -12345678;
pthread_mutex_lock(&lfe->sf_dvr_lock);
if (lfe->sf_req == lfe->sf_req_thread)
r = satip_rtsp_setup(rtsp, position, lfe->sf_number,
@ -1297,8 +1318,8 @@ new_tune:
rtsp_flags | SATIP_SETUP_PLAY);
pthread_mutex_unlock(&lfe->sf_dvr_lock);
if (r < 0) {
if (r != 0xa59234)
tvherror("satip", "%s - failed to tune2", buf);
tvherror("satip", "%s - failed to tune2", buf);
satip_frontend_tuning_error(lfe, tr);
fatal = 1;
}
reply = 1;
@ -1326,6 +1347,7 @@ new_tune:
if (rtsp->hc_code >= 400) {
tvhlog(LOG_ERR, "satip", "%s - RTSP cmd error %d (%s) [%i-%i]",
buf, r, strerror(-r), rtsp->hc_cmd, rtsp->hc_code);
satip_frontend_tuning_error(lfe, tr);
fatal = 1;
}
break;

View file

@ -1168,7 +1168,7 @@ service_set_streaming_status_flags_(service_t *t, int set)
t->s_streaming_status = set;
tvhlog(LOG_DEBUG, "service", "%s: Status changed to %s%s%s%s%s%s%s%s",
tvhlog(LOG_DEBUG, "service", "%s: Status changed to %s%s%s%s%s%s%s%s%s",
service_nicename(t),
set & TSS_INPUT_HARDWARE ? "[Hardware input] " : "",
set & TSS_INPUT_SERVICE ? "[Input on service] " : "",
@ -1176,6 +1176,7 @@ service_set_streaming_status_flags_(service_t *t, int set)
set & TSS_PACKETS ? "[Reassembled packets] " : "",
set & TSS_NO_DESCRAMBLER ? "[No available descrambler] " : "",
set & TSS_NO_ACCESS ? "[No access] " : "",
set & TSS_TUNING ? "[Tuning failed] " : "",
set & TSS_GRACEPERIOD ? "[Graceperiod expired] " : "",
set & TSS_TIMEOUT ? "[Data timeout] " : "");
@ -1448,6 +1449,9 @@ service_tss2text(int flags)
if(flags & TSS_NO_ACCESS)
return "No access";
if(flags & TSS_TUNING)
return "Tuning failed";
if(flags & TSS_NO_DESCRAMBLER)
return "No descrambler";
@ -1482,6 +1486,9 @@ tss2errcode(int tss)
if(tss & TSS_NO_ACCESS)
return SM_CODE_NO_ACCESS;
if(tss & TSS_TUNING)
return SM_CODE_TUNING_FAILED;
if(tss & TSS_NO_DESCRAMBLER)
return SM_CODE_NO_DESCRAMBLER;

View file

@ -406,11 +406,12 @@ typedef struct service {
#define TSS_PACKETS 0x8
#define TSS_NO_ACCESS 0x10
#define TSS_GRACEPERIOD 0x8000
// Errors
#define TSS_NO_DESCRAMBLER 0x10000
#define TSS_TIMEOUT 0x20000
#define TSS_GRACEPERIOD 0x10000
#define TSS_NO_DESCRAMBLER 0x20000
#define TSS_TIMEOUT 0x40000
#define TSS_TUNING 0x80000
#define TSS_ERRORS 0xffff0000

View file

@ -414,7 +414,7 @@ service_mapper_thread ( void *aux )
} else if (sm->sm_type == SMT_SERVICE_STATUS) {
int status = sm->sm_code;
if(status & (TSS_GRACEPERIOD | TSS_ERRORS)) {
if(status & TSS_ERRORS) {
run = 0;
err = service_tss2text(status);
}

View file

@ -464,7 +464,7 @@ subscription_input(void *opauqe, streaming_message_t *sm)
}
if(sm->sm_type == SMT_SERVICE_STATUS &&
sm->sm_code & (TSS_GRACEPERIOD | TSS_ERRORS)) {
sm->sm_code & TSS_ERRORS) {
// No, mark our subscription as bad_service
// the scheduler will take care of things
error = tss2errcode(sm->sm_code);
@ -493,7 +493,7 @@ subscription_input(void *opauqe, streaming_message_t *sm)
}
if (sm->sm_type == SMT_SERVICE_STATUS &&
sm->sm_code & TSS_TIMEOUT) {
sm->sm_code & (TSS_TUNING|TSS_TIMEOUT)) {
error = tss2errcode(sm->sm_code);
if (error > s->ths_testing_error)
s->ths_testing_error = error;