summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x[-rw-r--r--]device.c23
-rwxr-xr-x[-rw-r--r--]device.h1
-rwxr-xr-x[-rw-r--r--]pvrinput.c2
-rwxr-xr-x[-rw-r--r--]reader.c61
4 files changed, 72 insertions, 15 deletions
diff --git a/device.c b/device.c
index 049f553..c707fa2 100644..100755
--- a/device.c
+++ b/device.c
@@ -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]);
diff --git a/device.h b/device.h
index a62f382..75daa71 100644..100755
--- a/device.h
+++ b/device.h
@@ -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");
diff --git a/reader.c b/reader.c
index debed07..9d4e152 100644..100755
--- a/reader.c
+++ b/reader.c
@@ -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;