Mailing List archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[vdr] Re: VDR Admin GRAB command
- To: vdr@linuxtv.org
- Subject: [vdr] Re: VDR Admin GRAB command
- From: Klaus Schmidinger <Klaus.Schmidinger@cadsoft.de>
- Date: Sat, 04 Oct 2003 14:41:37 +0200
- Content-type: text/plain; charset=us-ascii
- Organization: CadSoft Computer GmbH
- References: <20030914181012.4B2A.DE@floydworld.de> <20030914175736.GA5786@gw.akool.de> <3F678604.A66A5659@cadsoft.de> <20030916231239.GA27153@gw.akool.de>
- Reply-to: vdr@linuxtv.org
- Sender: vdr-bounce@linuxtv.org
Andreas Kool wrote:
>
> On Tue, Sep 16, 2003 at 11:52:04PM +0200, Klaus Schmidinger wrote:
> > Andreas Kool wrote:
> > >
> > > On Sun, Sep 14, 2003 at 06:20:51PM -0700, Dirk Essl wrote:
> > > >
> > > >
> > > > Hi everybody,
> > > >
> > > > I got a problem while using the "TV" Window in VDR Admin
> > > > it grabs a frame from my Hauppauge WinTV, and not from the DVB Card.
> > > > The bttv09 module is loaded before the DVB driver, because only this way
> > > > it works at my system.
> > >
> > > Use this patch:
> > >
> > > ---8<-----if--you--cut--here--you--will--probably--destroy--your--monitor---
> > > --- dvbdevice.c.orig 2003-08-26 18:15:51.000000000 +0200
> > > +++ dvbdevice.c 2003-08-26 18:13:50.000000000 +0200
> > > @@ -583,7 +583,35 @@
> > > bool cDvbDevice::GrabImage(const char *FileName, bool Jpeg, int Quality, int SizeX, int SizeY)
> > > {
> > > char buffer[PATH_MAX];
> > > - snprintf(buffer, sizeof(buffer), "%s%d", DEV_VIDEO, CardIndex());
> > > + static int ofs = -1;
> > > + FILE *f;
> > > +
> > > + if (ofs == -1) { // firsttime
> > > + while (1) {
> > > + snprintf(buffer, sizeof buffer, "/proc/video/dev/video%d", ++ofs);
> > > +
> > > + if ((f = fopen(buffer, "r")) == (FILE *)NULL) { // does not exist?
> > > + ofs = 0;
> > > + break;
> > > + }
> > > +
> > > + if (fgets(buffer, sizeof buffer, f)) {
> > > + if (strstr(buffer, "DVB Board")) // found the _first_ DVB card
> > > + break;
> > > + }
> > > + else {
> > > + ofs = 0;
> > > + break;
> > > + }
> > > +
> > > + fclose(f);
> > > + }
> > > +
> > > + fclose(f);
> > > +
> > > + }
> > > +
> > > + snprintf(buffer, sizeof(buffer), "%s%d", DEV_VIDEO, CardIndex() + ofs);
> > > isyslog("grabbing from %s", buffer);
> > > int videoDev = open(buffer, O_RDWR);
> > > if (videoDev < 0)
> > > ---8<-----if--you--cut--here--you--will--probably--destroy--your--monitor---
> >
> > I'm not sure whether this is a real _solution_ to the problem.
>
> No, it is'nt, but better than nothing/*wrong* functionality!
>
> > It _may_ work, if the primary device id the _first_ DVB card.
> > But what if it isn't?
>
> Sorry, Klaus, but my patch works in *any* combination (i can think about)!
>
> Lets think about a really big machine:
>
> /dev/video0 -> non DVB-card, maybe a WEBCAM
> /dev/video1 -> non DVB-card, a grabber card
> /dev/video2 -> non DVB-card, a analog tv-card
> /dev/video3 -> DVB-card
> /dev/video4 -> DVB-card
> /dev/video5 -> DVB-card
> /dev/video6 -> DVB-card
>
> -> my patch skips over the first 3 *non* DVB-cards : result correct
>
> Or a totally simple machine:
>
> /dev/video0 -> DVB-card
>
> -> my patch does nothing : result correct
>
> Your machine (i think):
>
> /dev/video0 -> DVB-card
> /dev/video1 -> DVB-card
> /dev/video2 -> DVB-card
> /dev/video3 -> MPEG-encoder-card
>
> -> my patch does nothing : result correct (for the first 3 cards for sure ...)
>
> My machine:
>
> /dev/video0 -> non DVB-card, a analogue tv-card
> /dev/video1 -> non DVB-card, a WEBCAM
> /dev/video2 -> DVB-card
>
> -> my patch skips over the first 2 *non* DVB-cards : result correct
>
> Are there *any* other combinations possible?
>
> OK, a *very* exotic combination could be
>
> /dev/video0 -> DVB-card
> /dev/video1 -> non DVB-card
> /dev/video2 -> DVB-card
>
> *here* my patch fails, but this combination is *only* possible with
> 2 different DVB-card-drivers, right?
>
> > The real problem is that the /dev/dvb/... devices can have completely
> > different numbers than the related /dev/video... devices. What we would
>
> Sorry, but *not* "completely" different numbers! Both numbers are simply
> incrementing (by 1) from 0 to n or x to n + x
>
> > need is a way of having the DVB device tell VDR which /dev/video device
> > belongs to it.
>
> Yes, sure, but up to now there simply dont exists such a table or whatever.
I'm afraid you forgot one possible scenario:
1. full featured DVB card (/dev/video0)
2. budget DVB card
3. full featured DVB card (/dev/video1)
Now if the "primary device" is set to '3' it won't work.
Actually this didn't work before, either, but while we're
at it I guess we should take care of this case, too.
I therefore have modified your patch a little and moved it
into the cDvbDevice constructor:
--- dvbdevice.h 2003/08/15 12:34:55 1.22
+++ dvbdevice.h 2003/10/04 11:54:50
@@ -73,6 +73,9 @@
// Image Grab facilities
+private:
+ static int devVideoOffset;
+ int devVideoIndex;
public:
virtual bool GrabImage(const char *FileName, bool Jpeg = true, int Quality = -1, int SizeX = -1, int SizeY = -1);
--- dvbdevice.c 2003/09/06 13:19:33 1.64
+++ dvbdevice.c 2003/10/04 12:31:15
@@ -307,6 +307,8 @@
// --- cDvbDevice ------------------------------------------------------------
+int cDvbDevice::devVideoOffset = -1;
+
cDvbDevice::cDvbDevice(int n)
{
dvbTuner = NULL;
@@ -317,8 +319,7 @@
// Devices that are present on all card types:
- int fd_frontend = DvbOpen(DEV_DVB_FRONTEND, n, O_RDWR | O_NONBLOCK);
-
+ int fd_frontend = DvbOpen(DEV_DVB_FRONTEND, n, O_RDWR | O_NONBLOCK);
// Devices that are only present on cards with decoders:
fd_osd = DvbOpen(DEV_DVB_OSD, n, O_RDWR);
@@ -329,6 +330,35 @@
fd_dvr = -1;
+ // The offset of the /dev/video devices:
+
+ if (devVideoOffset < 0) { // the first one checks this
+ FILE *f = NULL;
+ char buffer[PATH_MAX];
+ for (int ofs = 0; ofs < 100; ofs++) {
+ snprintf(buffer, sizeof(buffer), "/proc/video/dev/video%d", ofs);
+ if ((f = fopen(buffer, "r")) != NULL) {
+ if (fgets(buffer, sizeof(buffer), f)) {
+ if (strstr(buffer, "DVB Board")) { // found the _first_ DVB card
+ devVideoOffset = ofs;
+ dsyslog("video device offset is %d", devVideoOffset);
+ break;
+ }
+ }
+ else
+ break;
+ fclose(f);
+ }
+ else
+ break;
+ }
+ if (devVideoOffset < 0)
+ devVideoOffset = 0;
+ if (f)
+ fclose(f);
+ }
+ devVideoIndex = (devVideoOffset >= 0 && HasDecoder()) ? devVideoOffset++ : -1;
+
// Video format:
SetVideoFormat(Setup.VideoFormat ? VIDEO_FORMAT_16_9 : VIDEO_FORMAT_4_3);
@@ -427,8 +457,10 @@
bool cDvbDevice::GrabImage(const char *FileName, bool Jpeg, int Quality, int SizeX, int SizeY)
{
+ if (devVideoIndex < 0)
+ return false;
char buffer[PATH_MAX];
- snprintf(buffer, sizeof(buffer), "%s%d", DEV_VIDEO, CardIndex());
+ snprintf(buffer, sizeof(buffer), "%s%d", DEV_VIDEO, devVideoIndex);
int videoDev = open(buffer, O_RDWR);
if (videoDev < 0)
LOG_ERROR_STR(buffer);
Unfortunately this seems to trigger a driver bug, because with
the primary device set to 3 in my case it initiates the grab
correctly with /dev/video1, but gets stuck in the line
result |= ioctl(videoDev, VIDIOCSYNC, &vm.frame);
inside cDvbDevice::GrabImage(). Maybe somebody could do
some debugging here to see whether this really is a driver
issue or if something in VDR is done wrong in such a case.
Klaus
--
Info:
To unsubscribe send a mail to ecartis@linuxtv.org with "unsubscribe vdr" as subject.
Home |
Main Index |
Thread Index