From patchwork Sun Feb 18 11:51:20 2007 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reinhard Nissl X-Patchwork-Id: 12438 Received: from mail.gmx.net ([213.165.64.20]) by www.linuxtv.org with smtp (Exim 4.50) id 1HIkbF-0004Mm-PQ for vdr@linuxtv.org; Sun, 18 Feb 2007 12:53:01 +0100 Received: (qmail invoked by alias); 18 Feb 2007 11:51:39 -0000 X-Provags-ID: V01U2FsdGVkX19nvoxeZuxngru17DKzvH0/x+ktA3gldWZpPvdiK4 vGrg== Message-ID: <45D83DB8.9030800@gmx.de> Date: Sun, 18 Feb 2007 12:51:20 +0100 From: Reinhard Nissl User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.9) Gecko/20060911 SUSE/1.5.0.9-0.1 Thunderbird/1.5.0.9 Mnenhy/0.7.4.666 MIME-Version: 1.0 To: VDR Mailing List Subject: Re: [vdr] ERROR: video data stream broken on second dvb card , but szap works (new findings!) References: <20070209121459.GC4364@bloms.de> <20070215060725.GA4204@bloms.de> <20070216124847.GA5148@bloms.de> <200702161443.11730.bastlir2@quick.cz> <20070217165935.GB5148@bloms.de> In-Reply-To: <20070217165935.GB5148@bloms.de> X-Y-GMX-Trusted: 0 X-BeenThere: vdr@linuxtv.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: VDR Mailing List List-Id: VDR Mailing List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 18 Feb 2007 11:53:02 -0000 Status: O X-Status: X-Keywords: X-UID: 12212 Hi, Dieter Bloms wrote: > my primary dvb card works fine on both of my Twin-LNB connectors. > I can switch the second card via szap and get a video stream via > "cat /dev/dvb/adapter1/dvr0 > /tmp/bla" on H and V channels. > VDR doesn't get data any data from H channels, but gets data from V > channels. > I will try to strace vdr and szap to get any difference, maybe they do > it in a different way. I've had a further look into szap's source how it detects the status FE_LOCKED. Attached is an updated tuner patch which now also reports details for FE_READ_STATUS. One difference between VDR and szap regarding FE_READ_STATUS is, that VDR only honors the read status when ioctl() returns 0 while szap prints just an error when ioctl() returns -1. Furthermore, VDR's handling of errno == EINTR seems to be wrong due to the do {} while (0); loop. BTW: I still assume, that your logfile reports a tuning timeout. If this is no longer the case, then you may want to experiment with WAIT_FOR_TUNER_LOCK in device.c. Bye. --- ../vdr-1.4.5-orig/dvbdevice.c 2006-08-14 11:38:32.000000000 +0200 +++ dvbdevice.c 2007-02-18 12:23:47.000000000 +0100 @@ -147,6 +147,15 @@ bool cDvbTuner::Locked(int TimeoutMs) return tunerStatus >= tsLocked; } +#include +static double now() { int e = errno; timeval t; gettimeofday(&t, 0); errno = e; return t.tv_sec + t.tv_usec / 1e6; } +static int check(int c, int r, char *a, double t) { int e = errno; fprintf(stderr, "t: %.3lf, c: %d, r: %d, a: %s\n", t, c, r, a); errno = e; return r; } +static int check5(int status, int c, int r, char *a, double t) { int e = errno; fprintf(stderr, "t: %.3lf, c: %d, r: %d, a: %s => Status: %02x\n", t, c, r, a, status); errno = e; return r; } +#define CHECK5(s) ::check5(Status, cardIndex, s, #s, ::now()) +#define CHECK4(s) ::check(cardIndex, 0, s, ::now()) +#define CHECK3(s) ::check(cardIndex, s, #s, ::now()) +#define CHECK2(s) CHECK(::check(cardIndex, s, #s, ::now())) + bool cDvbTuner::GetFrontendStatus(fe_status_t &Status, int TimeoutMs) { if (TimeoutMs) { @@ -157,15 +166,16 @@ bool cDvbTuner::GetFrontendStatus(fe_sta ; // just to clear the event queue - we'll read the actual status below } } - do { - int stat = ioctl(fd_frontend, FE_READ_STATUS, &Status); - if (stat == 0) - return true; - if (stat < 0) { - if (errno == EINTR) - continue; + while (1) { + int stat = CHECK5(ioctl(fd_frontend, FE_READ_STATUS, &Status)); + if (stat == 0) + return true; + if (stat < 0) { + if (errno == EINTR) + continue; + } + break; } - } while (0); return false; } @@ -195,12 +205,12 @@ bool cDvbTuner::SetFrontend(void) for (char *CurrentAction = NULL; (da = diseqc->Execute(&CurrentAction)) != cDiseqc::daNone; ) { switch (da) { case cDiseqc::daNone: break; - case cDiseqc::daToneOff: CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF)); break; - case cDiseqc::daToneOn: CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_ON)); break; - case cDiseqc::daVoltage13: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); break; - case cDiseqc::daVoltage18: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_18)); break; - case cDiseqc::daMiniA: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A)); break; - case cDiseqc::daMiniB: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_B)); break; + case cDiseqc::daToneOff: CHECK2(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF)); break; + case cDiseqc::daToneOn: CHECK2(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_ON)); break; + case cDiseqc::daVoltage13: CHECK2(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); break; + case cDiseqc::daVoltage18: CHECK2(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_18)); break; + case cDiseqc::daMiniA: CHECK2(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A)); break; + case cDiseqc::daMiniB: CHECK2(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_B)); break; case cDiseqc::daCodes: { int n = 0; uchar *codes = diseqc->Codes(n); @@ -208,7 +218,7 @@ bool cDvbTuner::SetFrontend(void) struct dvb_diseqc_master_cmd cmd; memcpy(cmd.msg, codes, min(n, int(sizeof(cmd.msg)))); cmd.msg_len = n; - CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd)); + CHECK2(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd)); } } break; @@ -285,7 +295,7 @@ bool cDvbTuner::SetFrontend(void) esyslog("ERROR: attempt to set channel with unknown DVB frontend type"); return false; } - if (ioctl(fd_frontend, FE_SET_FRONTEND, &Frontend) < 0) { + if (CHECK3(ioctl(fd_frontend, FE_SET_FRONTEND, &Frontend)) < 0) { esyslog("ERROR: frontend %d: %m", cardIndex); return false; } @@ -306,11 +316,13 @@ void cDvbTuner::Action(void) case tsIdle: break; case tsSet: +CHECK4("----------------------------------------------"); tunerStatus = SetFrontend() ? tsTuned : tsIdle; Timer.Set(tuneTimeout); continue; case tsTuned: if (Timer.TimedOut()) { +CHECK4("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); tunerStatus = tsSet; diseqcCommands = NULL; if (time(NULL) - lastTimeoutReport > 60) { // let's not get too many of these @@ -328,6 +340,7 @@ void cDvbTuner::Action(void) continue; } else if (Status & FE_HAS_LOCK) { +if (tunerStatus != tsLocked) CHECK4("=============================================="); if (LostLock) { isyslog("frontend %d regained lock on channel %d, tp %d", cardIndex, channel.Number(), channel.Transponder()); LostLock = false;