diff options
| -rwxr-xr-x[-rw-r--r--] | device.c | 23 | ||||
| -rwxr-xr-x[-rw-r--r--] | device.h | 1 | ||||
| -rwxr-xr-x[-rw-r--r--] | pvrinput.c | 2 | ||||
| -rwxr-xr-x[-rw-r--r--] | reader.c | 61 |
4 files changed, 72 insertions, 15 deletions
@@ -345,6 +345,29 @@ cPvrDevice *cPvrDevice::Get(int index) return NULL; } +int cPvrDevice::ReOpen(void) +{ + log(pvrDEBUG1, "cPvrDevice::ReOpen /dev/video%d = %s (%s)", number, CARDNAME[cardname], DRIVERNAME[driver]); + int retry_count = 5; + cString devName = cString::sprintf("/dev/video%d", number); + retry: + close(v4l2_fd); + v4l2_fd = open(devName, O_RDWR); + if (v4l2_fd < 0) { + log(pvrERROR, "cPvrDevice::ReOpen: error reopening %s (%s): %d:%s", + CARDNAME[cardname], *devName, errno, strerror(errno)); + retry_count--; + if (retry_count > 0) { + usleep(1000000); + goto retry; + } + } + else { + log(pvrDEBUG2, "cPvrDevice::ReOpen: %s (%s) successfully re-opened", *devName, CARDNAME[cardname]); + } + return v4l2_fd; +} + void cPvrDevice::ReInit(void) { log(pvrDEBUG1, "cPvrDevice::ReInit /dev/video%d = %s (%s)", number, CARDNAME[cardname], DRIVERNAME[driver]); @@ -133,6 +133,7 @@ public: virtual int NumProvidedSystems(void) const; bool ParseChannel(const cChannel *Channel, int *input, uint64_t *norm, int *LinesPerFrame, int *card, eInputType *inputType, int *apid, int *vpid, int *tpid) const; + int ReOpen(void); void ReInit(void); void StopReadThread(void); void GetStandard(void); diff --git a/pvrinput.c b/pvrinput.c index 8e24eb9..f89b054 100644..100755 --- a/pvrinput.c +++ b/pvrinput.c @@ -6,7 +6,7 @@ #endif #endif -static const char *VERSION = "2010-04-14"; +static const char *VERSION = "2010-08-12"; static const char *DESCRIPTION = tr("use Hauppauge PVR as input device"); static const char *MAINMENUENTRY = tr("PVR picture settings"); @@ -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; |
