diff options
| author | Lars Hanisch <dvb@flensrocker.de> | 2010-08-12 18:21:59 +0200 |
|---|---|---|
| committer | Lars Hanisch <dvb@flensrocker.de> | 2010-08-12 18:21:59 +0200 |
| commit | 2c3fec5ac120b88c17633ff8a0dfae0091a4964a (patch) | |
| tree | cc8bd2a0a64db3a97f549b432dc924d828035369 /reader.c | |
| parent | b856f4fb464607fe195f34cb3523429d7d3f4d2f (diff) | |
| parent | 643ebe816466891354cf511e9a570236a8884d7e (diff) | |
| download | vdr-plugin-pvrinput-2c3fec5ac120b88c17633ff8a0dfae0091a4964a.tar.gz vdr-plugin-pvrinput-2c3fec5ac120b88c17633ff8a0dfae0091a4964a.tar.bz2 | |
Merge branch 'reader-with-select'
Use select before read with timeout and reopen v4l2-device if
select reports an error.
Reading from the Hauppauge HD PVR hangs sometimes on bad video input
and forces vdr to restart.
With this workaround the vdr doesn't stop and there's
only a few seconds missing in the recording.
Diffstat (limited to 'reader.c')
| -rwxr-xr-x[-rw-r--r--] | reader.c | 61 |
1 files changed, 47 insertions, 14 deletions
@@ -500,6 +500,10 @@ void cPvrReadThread::Action(void) uint8_t *buffer = new uint8_t[bufferSize]; int r; int retries = 3; + int reopen_retries = 5; + struct timeval selTimeout; + fd_set selSet; + log(pvrDEBUG1,"cPvrReadThread::Action(): Entering Action()"); // A derived cThread class must check Running() // repeatedly to see whether it's time to stop. @@ -543,21 +547,50 @@ void cPvrReadThread::Action(void) } retry: while (Running() && parent->readThreadRunning) { - r = read(parent->v4l2_fd, buffer, bufferSize); - if (r < 0) { - log(pvrERROR, "cPvrReadThread::Action():error reading from /dev/video%d: %d:%s %s", - parent->number, errno, strerror(errno), (--retries > 0) ? " - retrying" : ""); - if (retries > 0) { - usleep(100); - goto retry; + selTimeout.tv_sec = 0; + selTimeout.tv_usec = 200000; + FD_ZERO(&selSet); + FD_SET(parent->v4l2_fd, &selSet); + r = select(parent->v4l2_fd + 1, &selSet, 0, 0, &selTimeout); + if ((r == 0) && (errno == 0)) { + log(pvrDEBUG1, "cPvrReadThread::Action():timeout on select from /dev/video%d: %d:%s %s", + parent->number, errno, strerror(errno), (retries > 0) ? " - retrying" : ""); + } + else if ((r < 0) || (errno != 0)) { + log(pvrERROR, "cPvrReadThread::Action():error on select from /dev/video%d: %d:%s %s", + parent->number, errno, strerror(errno), (retries > 0) ? " - retrying" : ""); + retries--; + if (retries > 0) { + usleep(100); + goto retry; + } + while (reopen_retries > 0) { + reopen_retries--; + if (parent->ReOpen() > 0) { + retries = 3; + goto retry; + } + } + break; + } + else if (FD_ISSET(parent->v4l2_fd, &selSet)) { + r = read(parent->v4l2_fd, buffer, bufferSize); + if (r < 0) { + log(pvrERROR, "cPvrReadThread::Action():error reading from /dev/video%d: %d:%s %s", + parent->number, errno, strerror(errno), (retries > 0) ? " - retrying" : ""); + retries--; + if (retries > 0) { + usleep(100); + goto retry; + } + break; + } + if (r > 0) { + if (parent->streamType == V4L2_MPEG_STREAM_TYPE_MPEG2_TS) + PutData(buffer, r); + else + ParseProgramStream(buffer, r); } - break; - } - if (r > 0) { - if (parent->streamType == V4L2_MPEG_STREAM_TYPE_MPEG2_TS) - PutData(buffer, r); - else - ParseProgramStream(buffer, r); } } delete [] buffer; |
