Fix dvr input if sync is lost, also minor efficiency improvement.

This commit is contained in:
Adam Sutton 2012-08-31 23:12:07 +01:00
parent f88892bd67
commit ae0b0965d6
3 changed files with 64 additions and 13 deletions

View file

@ -701,7 +701,7 @@ static void *
dvb_adapter_input_dvr(void *aux)
{
th_dvb_adapter_t *tda = aux;
int fd, i, r, efd, nfds;
int fd, i, r, c, efd, nfds;
uint8_t tsb[188 * 10];
service_t *t;
struct epoll_event ev;
@ -720,34 +720,68 @@ dvb_adapter_input_dvr(void *aux)
ev.data.fd = tda->tda_dvr_pipe[0];
epoll_ctl(efd, EPOLL_CTL_ADD, tda->tda_dvr_pipe[0], &ev);
while(1){
r = i = 0;
while(1) {
/* Wait for input */
nfds = epoll_wait(efd, &ev, 1, -1);
if (nfds < 1) continue;
if (ev.data.fd != fd) break;
r = read(fd, tsb, sizeof(tsb));
c = read(fd, tsb+r, sizeof(tsb)-r);
if (c < 0) {
if (errno == EAGAIN || errno == EINTR)
continue;
else
break;
}
r += c;
/* not enough data */
if (r < 188) continue;
pthread_mutex_lock(&tda->tda_delivery_mutex);
for(i = 0; i < r; i += 188) {
LIST_FOREACH(t, &tda->tda_transports, s_active_link)
if(t->s_dvb_mux_instance == tda->tda_mux_current)
ts_recv_packet1(t, tsb + i, NULL);
}
/* debug */
if(tda->tda_dump_fd != -1) {
if(write(tda->tda_dump_fd, tsb, r) != r) {
tvhlog(LOG_ERR, "dvb",
"\"%s\" unable to write to mux dump file -- %s",
tda->tda_identifier, strerror(errno));
close(tda->tda_dump_fd);
tda->tda_dump_fd = -1;
"\"%s\" unable to write to mux dump file -- %s",
tda->tda_identifier, strerror(errno));
close(tda->tda_dump_fd);
tda->tda_dump_fd = -1;
}
}
/* find mux */
LIST_FOREACH(t, &tda->tda_transports, s_active_link)
if(t->s_dvb_mux_instance == tda->tda_mux_current)
break;
/* Process */
while (r >= 188) {
/* sync */
if (tsb[i] == 0x47) {
if(t) ts_recv_packet1(t, tsb + i, NULL);
i += 188;
r -= 188;
/* no sync */
} else {
tvhlog(LOG_DEBUG, "dvb", "\"%s\" ts sync lost", tda->tda_identifier);
if (ts_resync(tsb, &r, &i)) break;
tvhlog(LOG_DEBUG, "dvb", "\"%s\" ts sync found", tda->tda_identifier);
}
}
pthread_mutex_unlock(&tda->tda_delivery_mutex);
/* reset buffer */
if (r && r < i) {
memcpy(tsb, tsb+i, r);
i = 0;
}
}
close(efd);

View file

@ -286,3 +286,18 @@ ts_remux(service_t *t, const uint8_t *src)
sm.sm_data = tsb;
streaming_pad_deliver(&t->s_streaming_pad, &sm);
}
/*
* Attempt to re-sync a ts stream (3 valid sync's in a row)
*/
int
ts_resync ( const uint8_t *tsb, int *len, int *idx )
{
int err = 1;
while (err && (*len > 376)) {
(*idx)++; (*len)--;
err = (tsb[*idx] != 0x47) || (tsb[*idx+188] != 0x47) ||
(tsb[*idx+376] != 0x47);
}
return err;
}

View file

@ -19,6 +19,8 @@
#ifndef TSDEMUX_H
#define TSDEMUX_H
int ts_resync ( const uint8_t *tsb, int *len, int *idx );
void ts_recv_packet1(struct service *t, const uint8_t *tsb, int64_t *pcrp);
void ts_recv_packet2(struct service *t, const uint8_t *tsb);