Fix dvr input if sync is lost, also minor efficiency improvement.
This commit is contained in:
parent
f88892bd67
commit
ae0b0965d6
3 changed files with 64 additions and 13 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue