LIST_ENTRY(tvh_input_instance) tii_input_link;
+ pthread_mutex_t tii_stats_mutex;
tvh_input_stream_stats_t tii_stats;
void (*tii_delete) (tvh_input_instance_t *tii);
im->mm_iptv_rtp_seq = seq;
if (im->mm_active)
- im->mm_active->tii_stats.unc += unc;
+ atomic_add(&im->mm_active->tii_stats.unc, unc);
return res;
}
lfe->lfe_monitor = mclk() + ms2mono(period);
}
+
+ pthread_mutex_lock(&mmi->tii_stats_mutex);
+
/* Statistics - New API */
#if DVB_VER_ATLEAST(5,10)
memset(&fe_properties, 0, sizeof(fe_properties));
gotprop = 0;
if(ioctl_check(lfe, 8) && fe_properties[4].u.st.len > 0) {
if(fe_properties[4].u.st.stat[0].scale == FE_SCALE_COUNTER) {
- mmi->tii_stats.unc = mmi->tii_stats.ec_block = fe_properties[4].u.st.stat[0].uvalue;
+ atomic_set(&mmi->tii_stats.unc, fe_properties[4].u.st.stat[0].uvalue);
+ mmi->tii_stats.ec_block = fe_properties[4].u.st.stat[0].uvalue;
gotprop = 1;
}
else {
}
else {
ioctl_bad(lfe, 9);
- mmi->tii_stats.ec_block = mmi->tii_stats.unc = 0; /* both values or none */
+ /* both values to none */
+ mmi->tii_stats.ec_block = 0;
+ atomic_set(&mmi->tii_stats.unc, 0);
if (logit)
tvhlog(LOG_WARNING, "linuxdvb", "Unhandled TOTAL_BLOCK_COUNT scale: %d",
fe_properties[5].u.st.stat[0].scale);
if(!gotprop && ioctl_check(lfe, 10)) {
/* try old API */
if (!ioctl(lfe->lfe_fe_fd, FE_READ_UNCORRECTED_BLOCKS, &u32)) {
- mmi->tii_stats.unc = u32;
+ atomic_set(&mmi->tii_stats.unc, u32);
gotprop = 1;
}
else {
tvhlog(LOG_WARNING, "linuxdvb", "Unable to provide SNR value.");
}
if (ioctl_check(lfe, 4) && !ioctl(lfe->lfe_fe_fd, FE_READ_UNCORRECTED_BLOCKS, &u32))
- mmi->tii_stats.unc = u32;
+ atomic_set(&mmi->tii_stats.unc, u32);
else {
ioctl_bad(lfe, 4);
if (logit)
sigstat.snr = mmi->tii_stats.snr;
sigstat.signal = mmi->tii_stats.signal;
sigstat.ber = mmi->tii_stats.ber;
- sigstat.unc = mmi->tii_stats.unc;
+ sigstat.unc = atomic_get(&mmi->tii_stats.unc);
sigstat.signal_scale = mmi->tii_stats.signal_scale;
sigstat.snr_scale = mmi->tii_stats.snr_scale;
sigstat.ec_bit = mmi->tii_stats.ec_bit;
sigstat.tc_block = mmi->tii_stats.tc_block;
sm.sm_type = SMT_SIGNAL_STATUS;
sm.sm_data = &sigstat;
+
+ pthread_mutex_unlock(&mmi->tii_stats_mutex);
+
LIST_FOREACH(s, &mmi->mmi_mux->mm_transports, s_active_link) {
pthread_mutex_lock(&s->s_stream_mutex);
streaming_pad_deliver(&s->s_streaming_pad, streaming_msg_clone(&sm));
/* Check for sync */
while ( (len >= MIN_TS_SYN) &&
((len2 = ts_sync_count(tsb, len)) < MIN_TS_SYN) ) {
- mmi->tii_stats.unc++;
+ atomic_add(&mmi->tii_stats.unc, 1);
--len;
++tsb;
++off;
/* Transport error */
if (pid & 0x8000) {
if ((pid & 0x1FFF) != 0x1FFF)
- ++mmi->tii_stats.te;
+ atomic_add(&mmi->tii_stats.te, 1);
}
pid &= 0x1FFF;
cc = tsb2[3] & 0x0f;
if (cc2 != 0xff && cc2 != cc) {
tvhtrace("mpegts", "%s: pid %04X cc err %2d != %2d", muxname, pid, cc, cc2);
- ++mmi->tii_stats.cc;
+ atomic_add(&mmi->tii_stats.cc, 1);
}
cc2 = (cc + 1) & 0xF;
}
st->stream_name = strdup(buf);
st->subs_count = s;
st->max_weight = w;
- st->stats = mmi->tii_stats;
+ pthread_mutex_lock(&mmi->tii_stats_mutex);
+ st->stats.signal = mmi->tii_stats.signal;
+ st->stats.snr = mmi->tii_stats.snr;
+ st->stats.ber = mmi->tii_stats.ber;
+ st->stats.signal_scale = mmi->tii_stats.signal_scale;
+ st->stats.snr_scale = mmi->tii_stats.snr_scale;
+ st->stats.ec_bit = mmi->tii_stats.ec_bit;
+ st->stats.tc_bit = mmi->tii_stats.tc_bit;
+ st->stats.ec_block = mmi->tii_stats.ec_block;
+ st->stats.tc_block = mmi->tii_stats.tc_block;
+ pthread_mutex_unlock(&mmi->tii_stats_mutex);
+ st->stats.unc = atomic_get(&mmi->tii_stats.unc);
+ st->stats.cc = atomic_get(&mmi->tii_stats.cc);
+ st->stats.te = atomic_get(&mmi->tii_stats.te);
st->stats.bps = atomic_exchange(&mmi->tii_stats.bps, 0) * 8;
}
st->input_name = strdup(buf);
LIST_FOREACH(mmi_, &mi->mi_mux_instances, tii_input_link) {
mmi = (mpegts_mux_instance_t *)mmi_;
- st->stats.unc += mmi->tii_stats.unc;
- st->stats.cc += mmi->tii_stats.cc;
+ st->stats.unc += atomic_get(&mmi->tii_stats.unc);
+ st->stats.cc += atomic_get(&mmi->tii_stats.cc);
+ pthread_mutex_lock(&mmi->tii_stats_mutex);
st->stats.te += mmi->tii_stats.te;
st->stats.ec_block += mmi->tii_stats.ec_block;
st->stats.tc_block += mmi->tii_stats.tc_block;
+ pthread_mutex_unlock(&mmi->tii_stats_mutex);
}
}
pthread_mutex_lock(&mi->mi_output_lock);
LIST_FOREACH(mmi_, &mi->mi_mux_instances, tii_input_link) {
mmi = (mpegts_mux_instance_t *)mmi_;
- mmi->tii_stats.unc = 0;
- mmi->tii_stats.cc = 0;
+ atomic_set(&mmi->tii_stats.unc, 0);
+ atomic_set(&mmi->tii_stats.cc, 0);
+ pthread_mutex_lock(&mmi->tii_stats_mutex);
mmi->tii_stats.te = 0;
mmi->tii_stats.ec_block = 0;
mmi->tii_stats.tc_block = 0;
+ pthread_mutex_unlock(&mmi->tii_stats_mutex);
}
pthread_mutex_unlock(&mi->mi_output_lock);
notify_reload("input_status");
idnode_unlink(&tii->tii_id);
LIST_REMOVE(mmi, mmi_mux_link);
LIST_REMOVE(tii, tii_input_link);
+ pthread_mutex_destroy(&mmi->tii_stats_mutex);
free(mmi);
}
return NULL;
}
+ pthread_mutex_init(&mmi->tii_stats_mutex, NULL);
+
/* Setup links */
mmi->mmi_mux = mm;
mmi->mmi_input = mi;
lfe->sf_tables = 1;
}
sigstat.status_text = signal2str(lfe->sf_status);
+ pthread_mutex_lock(&mmi->tii_stats_mutex);
sigstat.snr = mmi->tii_stats.snr;
sigstat.signal = mmi->tii_stats.signal;
sigstat.ber = mmi->tii_stats.ber;
- sigstat.unc = mmi->tii_stats.unc;
+ sigstat.unc = atomic_get(&mmi->tii_stats.unc);
sigstat.signal_scale = mmi->tii_stats.signal_scale;
sigstat.snr_scale = mmi->tii_stats.snr_scale;
sigstat.ec_bit = mmi->tii_stats.ec_bit;
sigstat.tc_bit = mmi->tii_stats.tc_bit;
sigstat.ec_block = mmi->tii_stats.ec_block;
sigstat.tc_block = mmi->tii_stats.tc_block;
+ pthread_mutex_unlock(&mmi->tii_stats_mutex);
sm.sm_type = SMT_SIGNAL_STATUS;
sm.sm_data = &sigstat;
LIST_FOREACH(svc, &mmi->mmi_mux->mm_transports, s_active_link) {
* -a BER lower than 2x10-4 after Viterbi for DVB-S
* -a PER lower than 10-7 for DVB-S2
*/
+ pthread_mutex_lock(&mmi->tii_stats_mutex);
while (len >= 12) {
if ((rtcp[0] & 0xc0) != 0x80) /* protocol version: v2 */
return;
strncmp(s, "ver=1.2;tuner=", 14) == 0) {
n = http_tokenize(s + 14, argv, 4, ',');
if (n < 4)
- return;
+ goto fail;
if (atoi(argv[0]) != lfe->sf_number)
- return;
+ goto fail;
mmi->tii_stats.signal =
atoi(argv[1]) * 0xffff / lfe->sf_device->sd_sig_scale;
mmi->tii_stats.signal_scale =
goto ok;
} else if (strncmp(s, "ver=1.0;", 8) == 0) {
if ((s = strstr(s + 8, ";tuner=")) == NULL)
- return;
+ goto fail;
s += 7;
n = http_tokenize(s, argv, 4, ',');
if (n < 4)
- return;
+ goto fail;
if (atoi(argv[0]) != lfe->sf_number)
- return;
+ goto fail;
mmi->tii_stats.signal =
atoi(argv[1]) * 0xffff / lfe->sf_device->sd_sig_scale;
mmi->tii_stats.signal_scale =
} else if (strncmp(s, "ver=1.1;tuner=", 14) == 0) {
n = http_tokenize(s + 14, argv, 4, ',');
if (n < 4)
- return;
+ goto fail;
if (atoi(argv[0]) != lfe->sf_number)
- return;
+ goto fail;
mmi->tii_stats.signal =
atoi(argv[1]) * 0xffff / lfe->sf_device->sd_sig_scale;
mmi->tii_stats.signal_scale =
rtcp += l;
len -= l;
}
- return;
+ goto fail;
ok:
if (mmi->tii_stats.snr < 2 && status == SIGNAL_GOOD)
else if (mmi->tii_stats.snr < 4 && status == SIGNAL_GOOD)
status = SIGNAL_FAINT;
lfe->sf_status = status;
+fail:
+ pthread_mutex_unlock(&mmi->tii_stats_mutex);
}
static int
pthread_mutex_lock(&lfe->sf_dvr_lock);
if (lfe->sf_req == lfe->sf_req_thread) {
mmi = lfe->sf_req->sf_mmi;
- mmi->tii_stats.unc += unc;
+ atomic_add(&mmi->tii_stats.unc, unc);
mpegts_input_recv_packets((mpegts_input_t*)lfe, mmi,
&lfe->sf_sbuf, 0, NULL);
}
}
pthread_mutex_lock(&lfe->sf_dvr_lock);
if (lfe->sf_req == lfe->sf_req_thread) {
- mmi->tii_stats.unc += unc;
+ atomic_add(&mmi->tii_stats.unc, unc);
mpegts_input_recv_packets((mpegts_input_t*)lfe, mmi, sb, 0, NULL);
} else
fatal = 1;
}
}
+ pthread_mutex_lock(&mmi->tii_stats_mutex);
+
if(tuner_status.signal_present) {
/* TODO: totaly stupid conversion from 0-100 scale to 0-655.35 */
mmi->tii_stats.snr = tuner_status.signal_to_noise_quality * 655.35;
sigstat.signal = mmi->tii_stats.signal;
sigstat.signal_scale = mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_RELATIVE;
sigstat.ber = mmi->tii_stats.ber;
- sigstat.unc = mmi->tii_stats.unc;
+ sigstat.unc = atomic_get(&mmi->tii_stats.unc);
sm.sm_type = SMT_SIGNAL_STATUS;
sm.sm_data = &sigstat;
+ pthread_mutex_unlock(&mmi->tii_stats_mutex);
+
LIST_FOREACH(svc, &mmi->mmi_mux->mm_transports, s_active_link) {
pthread_mutex_lock(&svc->s_stream_mutex);
streaming_pad_deliver(&svc->s_streaming_pad, streaming_msg_clone(&sm));