[mythtv] [patch] hdtv signal check
Daniel Thor Kristjansson
danielk at cat.nyu.edu
Fri Feb 20 21:00:09 EST 2004
This patch adds a signal check to TuneTo calls in the Channel class if
you are using HDTV. I've changed the threshold to 65% from the 70% I was
using before after Doug's comment about his 68% channel looking fine.
I have a similar patch for DVBChannel which I'll send in later.
-- Daniel
-------------- next part --------------
Index: libs/libmythtv/channelbase.h
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/channelbase.h,v
retrieving revision 1.4
diff -u -r1.4 channelbase.h
--- libs/libmythtv/channelbase.h 27 Jan 2004 06:42:33 -0000 1.4
+++ libs/libmythtv/channelbase.h 21 Feb 2004 01:54:53 -0000
@@ -30,6 +30,9 @@
virtual bool SetChannelByString(const QString &chan) = 0;
virtual bool ChannelUp(void);
virtual bool ChannelDown(void);
+ virtual bool CheckSignal(int /*msecWait = 5000*/,
+ int /*requiredSignalPercentage = 70*/,
+ int /*input = 0*/) { return true; }
virtual bool NextFavorite(void);
virtual int ChangeColour(bool up) { (void)up; return 0; };
Index: libs/libmythtv/channel.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/channel.cpp,v
retrieving revision 1.64
diff -u -r1.64 channel.cpp
--- libs/libmythtv/channel.cpp 5 Feb 2004 22:50:38 -0000 1.64
+++ libs/libmythtv/channel.cpp 21 Feb 2004 01:54:54 -0000
@@ -17,7 +17,7 @@
#include <iostream>
using namespace std;
-Channel::Channel(TVRec *parent, const QString &videodevice)
+Channel::Channel(TVRec *parent, const QString &videodevice, bool strength)
: ChannelBase(parent)
{
device = videodevice;
@@ -29,6 +29,7 @@
usingv4l2 = false;
videomode = VIDEO_MODE_NTSC;
currentFormat = "";
+ usingstrength = strength;
}
Channel::~Channel(void)
@@ -46,7 +47,7 @@
isopen = true;
else
{
- cerr << "Channel::Open(): Can't open: " << device << endl;
+ VERBOSE(VB_IMPORTANT, QString("Channel::Open(): Can't open: %1").arg(device));
perror(device.ascii());
return false;
}
@@ -281,8 +282,8 @@
if (chancount > totalChannels)
{
- cerr << "Error, couldn't find any available channels.\n";
- cerr << "Your database is most likely setup incorrectly.\n";
+ VERBOSE(VB_IMPORTANT, "Error, couldn't find any available channels.");
+ VERBOSE(VB_IMPORTANT, "Your database is most likely setup incorrectly.");
break;
}
}
@@ -314,8 +315,8 @@
if (chancount > totalChannels)
{
- cerr << "Error, couldn't find any available channels.\n";
- cerr << "Your database is most likely setup incorrectly.\n";
+ VERBOSE(VB_IMPORTANT, "Error, couldn't find any available channels.");
+ VERBOSE(VB_IMPORTANT, "Your database is most likely setup incorrectly.");
break;
}
}
@@ -327,7 +328,7 @@
{
if (!Open())
{
- cerr << "channel object wasn't open, can't change channels\n";
+ VERBOSE(VB_IMPORTANT, "Channel object wasn't open, can't change channels");
return false;
}
@@ -401,6 +402,38 @@
return true;
}
+template<typename V>
+V clamp(V val, V minv, V maxv) { return std::min(maxv, std::max(minv, val)); }
+
+// Returns ATSC signal strength 0-100. >75 is good.
+int signalStrengthATSC(int device, int input) {
+ struct video_signal vsig;
+ int ioctlval = ioctl(device,VIDIOCGSIGNAL,&vsig);
+ if (-1==ioctlval) {
+ perror("VIDIOCGSIGNAL problem in channel.h's signalStrengthATSC()");
+ return 0;
+ }
+ int signal = (input==0) ? vsig.strength : vsig.aux;
+ if ((signal&0xff)!=0x43) return 0;
+ else return clamp(101-(signal>>9), 0, 100);
+}
+
+bool Channel::CheckSignal(int msecTotal, int reqSignal, int input) {
+ int msecSleep=100, maxSignal=0, i=0;
+ msecTotal=max(msecSleep, msecTotal);
+ if (usingstrength) {
+ for (i=0; i<(msecTotal/msecSleep)+1; i++) {
+ if (0!=i) usleep(msecSleep);
+ maxSignal=max(maxSignal, signalStrengthATSC(videofd, input));
+ if (maxSignal>=reqSignal) break;
+ }
+ VERBOSE(VB_IMPORTANT, QString("Maximum signal strength detected: %1\% after %2 msec wait").
+ arg(maxSignal).arg(i*msecSleep));
+ if (maxSignal<reqSignal) return false;
+ }
+ return true;
+}
+
bool Channel::TuneTo(const QString &channum, int finetune)
{
int i = GetCurrentChannelNum(channum);
@@ -408,6 +441,8 @@
return false;
int frequency = curList[i].freq * 16 / 1000 + finetune;
+ VERBOSE(VB_CHANNEL, QString("TuneTo(%1) curList[i].freq(%2) freq*16(%3)")
+ .arg(channum).arg(curList[i].freq).arg(frequency));
if (usingv4l2)
{
@@ -421,7 +456,7 @@
perror("VIDIOC_S_FREQUENCY");
return false;
}
- return true;
+ return CheckSignal();
}
if (ioctl(videofd, VIDIOCSFREQ, &frequency) == -1)
@@ -430,7 +465,7 @@
return false;
}
- return true;
+ return CheckSignal();
}
void Channel::SwitchToInput(int newcapchannel, bool setstarting)
Index: libs/libmythtv/channel.h
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/channel.h,v
retrieving revision 1.27
diff -u -r1.27 channel.h
--- libs/libmythtv/channel.h 5 Feb 2004 22:50:38 -0000 1.27
+++ libs/libmythtv/channel.h 21 Feb 2004 01:54:55 -0000
@@ -14,7 +14,7 @@
class Channel : public ChannelBase
{
public:
- Channel(TVRec *parent, const QString &videodevice);
+ Channel(TVRec *parent, const QString &videodevice, bool strength=false);
virtual ~Channel(void);
bool Open(void);
@@ -26,6 +26,9 @@
bool SetChannelByString(const QString &chan);
bool ChannelUp(void);
bool ChannelDown(void);
+ bool CheckSignal(int msecWait = 5000,
+ int requiredSignalPercentage = 65,
+ int input = 0);
unsigned short *Channel::GetV4L1Field(int attrib,
struct video_picture &vid_pic);
@@ -62,6 +65,7 @@
int videomode;
bool usingv4l2;
+ bool usingstrength;
QString currentFormat;
Index: libs/libmythtv/tv_rec.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/tv_rec.cpp,v
retrieving revision 1.139
diff -u -r1.139 tv_rec.cpp
--- libs/libmythtv/tv_rec.cpp 19 Feb 2004 08:26:04 -0000 1.139
+++ libs/libmythtv/tv_rec.cpp 21 Feb 2004 01:54:56 -0000
@@ -94,7 +94,7 @@
}
else // "V4L" or "MPEG", ie, analog TV, or "HDTV"
{
- Channel *achannel = new Channel(this, videodev);
+ Channel *achannel = new Channel(this, videodev, (cardtype == "HDTV"));
channel = achannel; // here for SetFormat()->RetrieveInputChannels()
channel->Open();
achannel->SetFormat(gContext->GetSetting("TVFormat"));
@@ -486,26 +486,48 @@
autoTranscode = profile.byName("autotranscode")->getValue().toInt();
SetupRecorder(profile);
- nvr->SetRecording(curRecording);
- nvr->SetDB(db_conn, &db_lock);
- if (channel != NULL)
- nvr->ChannelNameChanged(channel->GetCurrentName());
-
- SetVideoFiltersForChannel(channel, channel->GetCurrentName());
- if (channel->Open())
- {
- channel->SetBrightness();
- channel->SetContrast();
- channel->SetColour();
- channel->SetHue();
- channel->Close();
- }
-
- pthread_create(&encode, NULL, SpawnEncode, nvr);
-
- while (!nvr->IsRecording() && !nvr->IsErrored())
- usleep(50);
+ bool error=false;
+ if (channel != NULL)
+ {
+ // If there is a tuner make sure this is a valid station
+ // hdtv will block for a long time if we try to get
+ // mpeg ts packets from outer space.
+ bool success=channel->Open();
+ if (success)
+ {
+ success=channel->SetChannelByString(channel->GetCurrentName());
+ if (!success)
+ {
+ VERBOSE(VB_IMPORTANT, "Signal level too low?");
+ error = true;
+ }
+ channel->Close();
+ } else
+ error = true;
+ }
+ if (!error)
+ {
+ nvr->SetRecording(curRecording);
+ nvr->SetDB(db_conn, &db_lock);
+ if (channel != NULL)
+ nvr->ChannelNameChanged(channel->GetCurrentName());
+
+ SetVideoFiltersForChannel(channel, channel->GetCurrentName());
+ if (channel->Open())
+ {
+ channel->SetBrightness();
+ channel->SetContrast();
+ channel->SetColour();
+ channel->SetHue();
+ channel->Close();
+ }
+ pthread_create(&encode, NULL, SpawnEncode, nvr);
+
+ while (!nvr->IsRecording() && !nvr->IsErrored())
+ usleep(50);
+ } else
+ VERBOSE(VB_IMPORTANT, "Tuning Error -- aborting recording");
if (nvr->IsRecording())
{
// evil.
More information about the mythtv-dev
mailing list