[mythtv-commits] Ticket #1502: DVB API requires usleep after certain calls to get reliable tuning on certain drivers (esp Nova-T).
MythTV
mythtv at cvs.mythtv.org
Mon Mar 13 00:10:01 UTC 2006
#1502: DVB API requires usleep after certain calls to get reliable tuning on
certain drivers (esp Nova-T).
--------------------------------+-------------------------------------------
Reporter: dscoular at cisco.com | Owner: ijr
Type: patch | Status: new
Priority: minor | Milestone:
Component: mythtv | Version:
Severity: medium |
--------------------------------+-------------------------------------------
Hi Danielk et al,
The dvb api v3 authors contend that certain api calls require a usleep to
wait
for the low-level driver to complete the operation. They also hint that
the
dvb api event mechanism is flawed and shouldn't really be relied upon.
This is, indeed, a sorry state of affairs for would-be dvb api users.
Manu Abraham, of linuxtv fame, suggests that user-space applications mimic
the techniques used by the linuxtv-apps util/scan/scan.c which works
across the broadest range of supported cards.
{{{
1470 if (ioctl(frontend_fd, FE_SET_FRONTEND, &p) == -1) {
1471 errorn("Setting frontend parameters failed");
1472 return -1;
1473 }
1474
1475 for (i = 0; i < 10; i++) {
1476 usleep (200000);
1477
1478 if (ioctl(frontend_fd, FE_READ_STATUS, &s) == -1) {
1479 errorn("FE_READ_STATUS failed");
1480 return -1;
1481 }
1482
1483 verbose(">>> tuning status == 0x%02x\n", s);
1484
1485 if (s & FE_HAS_LOCK) {
1486 t->last_tuning_failed = 0;
1487 return 0;
1488 }
1489 }
1490
1491 warning(">>> tuning failed!!!\n");
1492
}}}
My interpretation of the above is that we should implement a
usleep(200000)
after a FE_SET_FRONTEND and FE_READ_STATUS to mimic the core scan.c
behaviour.
Daniel suggested that this should be optional and the usleep configurable.
Perhaps,
combined with the detection of the card type. However, I would suggest
that since
more than just the Nova-T may be affected here, coupled with the fact that
the
frontend "name" field varies between revisions of the actual Nova-T
hardware - that
making this specific to the "!DiBcom 3000P/M-C DVB-T" might be a bad idea.
Especially, since Manu's point is that scan.c has to work across the
broadest range of cards.
All DVB driver authors will be primarily testing their implementations
using the scan.c code.
So if mythtv uses this dumb usleep method it has the best chance of
working against the
widest range of dvb drivers.
Contrary to the above, my first attempt at a patch uses a hardwired usleep
of 200000
microseconds and only operates when the dbi api card name is "!DiBcom
3000P/M-C DVB-T".
Instead I think it could probably use the "channel_timeout" from mythtv-
setup/videosource.cpp
and work across all cards IMHO.
Anyway, here's the initial, possibly, dumb patch...
{{{
Index: libs/libmythtv/dvbsignalmonitor.h
===================================================================
--- libs/libmythtv/dvbsignalmonitor.h (revision 9336)
+++ libs/libmythtv/dvbsignalmonitor.h (working copy)
@@ -48,6 +48,10 @@
int GetDVBCardNum(void) const;
bool SupportsTSMonitoring(void);
+
+ DVBChannel *GetDVBChannel(void) const { return(channel); };
+ void SetDVBChannel(DVBChannel *_channel) { channel = _channel; };
+
protected:
SignalMonitorValue signalToNoise;
SignalMonitorValue bitErrorRate;
@@ -58,6 +62,7 @@
pthread_t table_monitor_thread;
FilterMap filters; ///< PID filters for table monitoring
+ DVBChannel *channel;
};
#endif // DVBSIGNALMONITOR_H
Index: libs/libmythtv/dvbchannel.cpp
===================================================================
--- libs/libmythtv/dvbchannel.cpp (revision 9336)
+++ libs/libmythtv/dvbchannel.cpp (working copy)
@@ -633,6 +633,11 @@
"Setting Frontend tuning parameters failed.");
return false;
}
+
+ // Special case for Nova-T. Should use configurable timeout.
+ if (GetFrontendName() == "DiBcom 3000P/M-C DVB-T") {
+ usleep(2000000);
+ }
wait_for_backend(fd_frontend, 5 /* msec */);
prev_tuning.params = params;
Index: libs/libmythtv/dvbsignalmonitor.cpp
===================================================================
--- libs/libmythtv/dvbsignalmonitor.cpp (revision 9336)
+++ libs/libmythtv/dvbsignalmonitor.cpp (working copy)
@@ -83,6 +83,8 @@
QString msg = QString("DVBSignalMonitor(%1)::constructor(%2,%3): %4")
.arg(channel->GetDevice()).arg(capturecardnum);
+ SetDVBChannel(_channel);
+
#define DVB_IO(WHAT,WHERE,ERRMSG,FLAG) \
if (ioctl(_channel->GetFd(), WHAT, WHERE)) \
VERBOSE(VB_IMPORTANT, msg.arg(ERRMSG).arg(strerror(errno))); \
@@ -542,10 +544,16 @@
uint32_t ber = 0, ublocks = 0;
fe_status_t status;
bzero(&status, sizeof(status));
+ DVBChannel *channel = GetDVBChannel();
// Get info from card
int fd_frontend = channel->GetFd();
ioctl(fd_frontend, FE_READ_STATUS, &status);
+ // Special case for Nova-T. Should use configurable timeout.
+ if (channel->GetFrontendName() == "DiBcom 3000P/M-C DVB-T") {
+ usleep(2000000);
+ }
+
if (HasFlags(kDTVSigMon_WaitForSig))
ioctl(fd_frontend, FE_READ_SIGNAL_STRENGTH, &sig);
if (HasFlags(kDVBSigMon_WaitForSNR))
}}}
Also, note that since my C++ is incredibly lame and rusty that I put the
setDVBChannel(_channel) into the DVBSignalMonitor constructor... this may
not be an
appropriate place for it... especially if the constructor is not called on
each card
change initiated via the 'Y' key.
For even more background on this ticket please refer to the rather lengthy
discussion thread on mythtv-users:
http://www.gossamer-threads.com/lists/mythtv/users/187725#1state87725
AtDhVaAnNkCsE
Doug
----
"The big print giveth and the small print taketh away"
--
Ticket URL: <http://cvs.mythtv.org/trac/ticket/1502>
MythTV <http://www.mythtv.org/>
MythTV
More information about the mythtv-commits
mailing list