diff --git a/src/dvr/dvr.h b/src/dvr/dvr.h index a8a12583..4a996c3e 100644 --- a/src/dvr/dvr.h +++ b/src/dvr/dvr.h @@ -194,6 +194,11 @@ typedef struct dvr_entry { */ uint32_t de_errors; + /** + * Number of data errors (only to be modified by the recording thread) + */ + uint32_t de_data_errors; + /** * Last error, see SM_CODE_ defines */ diff --git a/src/dvr/dvr_db.c b/src/dvr/dvr_db.c index f05ca86b..59a83325 100644 --- a/src/dvr/dvr_db.c +++ b/src/dvr/dvr_db.c @@ -1887,6 +1887,13 @@ const idclass_t dvr_entry_class = { .off = offsetof(dvr_entry_t, de_errors), .opts = PO_RDONLY, }, + { + .type = PT_U32, + .id = "data_errors", + .name = "Data Errors", + .off = offsetof(dvr_entry_t, de_data_errors), + .opts = PO_RDONLY, + }, { .type = PT_U16, .id = "dvb_eid", diff --git a/src/dvr/dvr_rec.c b/src/dvr/dvr_rec.c index 7101f2a0..16c5ca53 100644 --- a/src/dvr/dvr_rec.c +++ b/src/dvr/dvr_rec.c @@ -483,6 +483,7 @@ dvr_thread(void *aux) profile_chain_t *prch = de->de_chain; streaming_queue_t *sq = &prch->prch_sq; streaming_message_t *sm; + th_subscription_t *ts; th_pkt_t *pkt; int run = 1; int started = 0; @@ -498,14 +499,19 @@ dvr_thread(void *aux) continue; } - if (de->de_s && started) { + if ((ts = de->de_s) != NULL && started) { pktbuf_t *pb = NULL; if (sm->sm_type == SMT_PACKET) pb = ((th_pkt_t*)sm->sm_data)->pkt_payload; else if (sm->sm_type == SMT_MPEGTS) pb = sm->sm_data; - if (pb) - atomic_add(&de->de_s->ths_bytes_out, pktbuf_len(pb)); + if (pb) { + atomic_add(&ts->ths_bytes_out, pktbuf_len(pb)); + if (ts->ths_total_err != de->de_data_errors) { + de->de_data_errors = ts->ths_total_err; + idnode_notify_simple(&de->de_id); + } + } } TAILQ_REMOVE(&sq->sq_queue, sm, sm_link); diff --git a/src/webui/static/app/dvr.js b/src/webui/static/app/dvr.js index 960dc252..de071e37 100644 --- a/src/webui/static/app/dvr.js +++ b/src/webui/static/app/dvr.js @@ -216,7 +216,7 @@ tvheadend.dvr_upcoming = function(panel, index) { del: true, list: 'disp_title,episode,pri,start_real,stop_real,' + 'duration,channel,owner,creator,config_name,' + - 'sched_status,comment', + 'sched_status,errors,data_errors,comment', sort: { field: 'start_real', direction: 'ASC' @@ -279,7 +279,7 @@ tvheadend.dvr_finished = function(panel, index) { 'The associated file will be removed from the storage.', list: 'disp_title,episode,start_real,stop_real,' + 'duration,filesize,channelname,owner,creator,' + - 'sched_status,url,comment', + 'sched_status,errors,data_errors,url,comment', columns: { filesize: { renderer: tvheadend.filesizeRenderer() @@ -359,7 +359,7 @@ tvheadend.dvr_failed = function(panel, index) { 'The associated file will be removed from the storage.', list: 'disp_title,episode,start_real,stop_real,' + 'duration,filesize,channelname,owner,creator,' + - 'status,sched_status,url,comment', + 'status,sched_status,errors,data_errors,url,comment', columns: { filesize: { renderer: tvheadend.filesizeRenderer()