[mythtv] [PATCH] Beginning radio pvr support

Jeremy Palenchar jeremyp at mindspring.com
Sat Jan 10 21:06:40 EST 2004


My .02 -  

There was some discussion a while back about having a screen saver or no
signal sent to the video card if the OSD was left up. This prevents burn-in
and can allow EntergyStar devices to StandBy.

Something like that feels appropriate here.

I have a macro on my current reciever to turn off the TV while I am
listening to CD's from the CD changer.

It would be nice if we could display some kind of screen saver or blank the
screen when we're listening to sources that do not have a video component.

Pressing a key on the remote would, of course, bring the OSD back.


-J

 

-----Original Message-----
From: mythtv-dev-bounces at mythtv.org [mailto:mythtv-dev-bounces at mythtv.org]
On Behalf Of Dan Sheridan
Sent: Saturday, January 10, 2004 10:22 AM
To: Development of mythtv
Subject: [mythtv] [PATCH] Beginning radio pvr support


This is a very hacky first attempt (which doesn't work!) at radio support
within mythtv. I am aiming to support radio as another input:
channels can be selected and recorded as if they were TV channels. I have
tuning and input selection sorted out, using an extra column in the
cardinput table to indicate a radio input (though the device name should
probably be in the capturecard table).

My problems are:

o  Notifying the various threads that the current stream is
   audio-only. At the moment I have a call to a function in
   ChannelBase, but this feels messy.

o  NuppelVideoRecorder, when setting up, can select a channel. I think
   for symmetry that it should use the Channel class instead of
   calling the ioctl itself -- is there any reason why it doesn't at
   the moment?

o  I need to stop the video thread while allowing the audio thread to
   continue. You can see my failed attempt below. Any ideas on how I 
   should be going about this? 

When backend support is complete, I'd like to modify the frontend to simply
keep all of the OSDs switch on, with a black bacground, when a stream
without video is played. 

       Dan.

--
Dan Sheridan -- Research Student -- LFCS, Division of Informatics
University of Edinburgh, King's Buildings, Mayfield Road EH9 3JZ


Index: mythtv/libs/libmythtv/NuppelVideoRecorder.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/NuppelVideoRecorder.cpp,v
retrieving revision 1.152
diff -u -r1.152 NuppelVideoRecorder.cpp
--- mythtv/libs/libmythtv/NuppelVideoRecorder.cpp	7 Jan 2004 06:14:04
-0000	1.152
+++ mythtv/libs/libmythtv/NuppelVideoRecorder.cpp	10 Jan 2004 18:11:05
-0000
@@ -366,6 +366,7 @@
 
 void NuppelVideoRecorder::Unpause(void)
 {
+    isradio = channelObj->GetCurrentInputRadio();
     pausewritethread = false;
     paused = false;
 }
@@ -1027,6 +1028,13 @@
                gettimeofday(&stm, &tzone);
            continue;
         }
+        if (isradio)
+        {
+           usleep(500);
+           if (cleartimeonpause)
+               gettimeofday(&stm, &tzone);
+           continue;
+        }
 
         frame = 0;
         mm.frame = 0;
@@ -2433,7 +2441,7 @@
         } action = ACTION_NONE;
         int firsttimecode = -1;
 
-        if (videobuffer[act_video_encode]->freeToEncode)
+        if (!isradio && videobuffer[act_video_encode]->freeToEncode)
         {
             action = ACTION_VIDEO;
             firsttimecode = videobuffer[act_video_encode]->timecode;
Index: mythtv/libs/libmythtv/NuppelVideoRecorder.h
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/NuppelVideoRecorder.h,v
retrieving revision 1.66
diff -u -r1.66 NuppelVideoRecorder.h
--- mythtv/libs/libmythtv/NuppelVideoRecorder.h	7 Jan 2004 06:14:04 -0000
1.66
+++ mythtv/libs/libmythtv/NuppelVideoRecorder.h	10 Jan 2004 18:11:05 -0000
@@ -262,6 +262,8 @@
     ChannelBase *channelObj;
 
     bool setorigaudio;
+
+    bool isradio;
 };
 
 #endif
Index: mythtv/libs/libmythtv/channel.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/channel.cpp,v
retrieving revision 1.60
diff -u -r1.60 channel.cpp
--- mythtv/libs/libmythtv/channel.cpp	9 Jan 2004 21:02:12 -0000	1.60
+++ mythtv/libs/libmythtv/channel.cpp	10 Jan 2004 18:11:05 -0000
@@ -22,6 +22,7 @@
 {
     device = videodevice;
     isopen = false;
+    isradio = false;
     videofd = -1;
     curList = 0;
     defaultFreqTable = 1;
@@ -117,11 +118,26 @@
             inputChannel[vin.index] = "";
             inputTuneTo[vin.index] = "";
             externalChanger[vin.index] = "";
+            inputRadio[vin.index] = "";
             vin.index++;
 
             capchannels = vin.index;
         }
 
+	// if there is a radio on this card
+	{
+	    QString msg = QString("Probed: %1 - Radio").arg(device);
+            VERBOSE(VB_CHANNEL, msg);
+            channelnames[vin.index] = "Radio";
+            inputChannel[vin.index] = "";
+            inputTuneTo[vin.index] = "";
+            externalChanger[vin.index] = "";
+            inputRadio[vin.index] = ""; // Will be filled in later
+            vin.index++;
+
+            capchannels = vin.index;
+	}
+
         if (fmt == "NTSC")
             videomode = V4L2_STD_NTSC;
         else if (fmt == "ATSC")
@@ -140,7 +156,7 @@
             videomode = V4L2_STD_NTSC_M_JP;
 
         pParent->RetrieveInputChannels(inputChannel, inputTuneTo, 
-                                       externalChanger);
+                                       externalChanger, inputRadio);
         return;
     }
  
@@ -189,8 +205,20 @@
         inputChannel[i] = "";
         inputTuneTo[i] = "";
         externalChanger[i] = "";
+        inputRadio[i] = "";
     }
 
+    // if there is a radio on this card
+    {
+        QString msg = QString("Probed: %1 - Radio").arg(device);
+        VERBOSE(VB_CHANNEL, msg);
+        channelnames[capchannels] = "Radio";
+        inputChannel[capchannels] = "";
+        inputTuneTo[capchannels] = "";
+        externalChanger[capchannels] = "";
+        inputRadio[capchannels] = ""; // Will be filled in later
+        capchannels++;
+    }
     struct video_channel vc;
     memset(&vc, 0, sizeof(vc));
     ioctl(videofd, VIDIOCGCHAN, &vc);
@@ -199,7 +227,7 @@
 
     videomode = mode;
 
-    pParent->RetrieveInputChannels(inputChannel, inputTuneTo,
externalChanger);
+    pParent->RetrieveInputChannels(inputChannel, inputTuneTo,
externalChanger, inputRadio);
 }
 
 int Channel::SetDefaultFreqTable(const QString &name)
@@ -254,6 +282,11 @@
     return -1;
 }
 
+bool Channel::GetCurrentInputRadio(void)
+{
+  return isradio;
+}
+
 bool Channel::ChannelUp(void)
 {
     if (ChannelBase::ChannelUp())
@@ -369,6 +402,7 @@
     // Tune
     if (externalChanger[currentcapchannel].isEmpty())
     {
+        cerr << "Requesting " << freqid << "\n";
         if (!TuneTo(freqid, finetune))
             return false;
     }
@@ -392,18 +426,29 @@
 
 bool Channel::TuneTo(const QString &channum, int finetune)
 {
-    int i = GetCurrentChannelNum(channum);
-    if (i == -1)
-        return false;
-
-    int frequency = curList[i].freq * 16 / 1000 + finetune;
+    int frequency;
+    if (isradio)
+    {
+        frequency = channum.toInt() * 16;
+	cerr << "Tuning to " << frequency << "\n";
+    }
+    else
+    {
+	int i = GetCurrentChannelNum(channum);
+	if (i == -1)
+	    return false;
+        frequency = curList[i].freq * 16 / 1000 + finetune;
+    }
 
     if (usingv4l2)
     {
         struct v4l2_frequency vf;
         memset(&vf, 0, sizeof(vf));
         vf.frequency = frequency;
-        vf.type = V4L2_TUNER_ANALOG_TV;
+	if (isradio)
+	    vf.type = V4L2_TUNER_RADIO;
+        else
+            vf.type = V4L2_TUNER_ANALOG_TV;
 
         if (ioctl(videofd, VIDIOC_S_FREQUENCY, &vf) < 0)
         {
@@ -424,23 +469,53 @@
 
 void Channel::SwitchToInput(int newcapchannel, bool setstarting)
 {
-    if (usingv4l2)
+    if (!inputRadio[newcapchannel].isEmpty())
     {
-        if (ioctl(videofd, VIDIOC_S_INPUT, &newcapchannel) < 0)
-            perror("VIDIOC_S_INPUT");
-   
-        if (ioctl(videofd, VIDIOC_S_STD, &videomode) < 0)
-            perror("VIDIOC_S_STD");
+        close(videofd);
+        videofd = open(inputRadio[newcapchannel].ascii(), O_RDWR);
+        if (videofd > 0)
+            isradio = true;
+        else
+        {
+            cerr << "Channel::SwitchToInput(): Can't open: " <<
inputRadio[newcapchannel] << endl;
+            perror(inputRadio[newcapchannel].ascii());
+            return;
+        }
+    } else 
+    if (isradio)
+    {
+        close(videofd);
+	videofd = open(device.ascii(), O_RDWR);
+        if (videofd > 0)
+            isradio = false;
+        else
+        {
+             cerr << "Channel::SwitchToInput(): Can't open: " << device <<
endl;
+             perror(device.ascii());
+             return;
+        }
     }
-    else
+
+    if (!isradio)
     {
-        struct video_channel set;
-        memset(&set, 0, sizeof(set));
-        ioctl(videofd, VIDIOCGCHAN, &set);
-        set.channel = newcapchannel;
-        set.norm = videomode;
-        if (ioctl(videofd, VIDIOCSCHAN, &set) < 0)
-           perror("VIDIOCSCHAN");
+        if (usingv4l2)
+        {
+            if (ioctl(videofd, VIDIOC_S_INPUT, &newcapchannel) < 0)
+                perror("VIDIOC_S_INPUT");
+   
+            if (ioctl(videofd, VIDIOC_S_STD, &videomode) < 0)
+                perror("VIDIOC_S_STD");
+        }
+        else
+        {
+            struct video_channel set;
+            memset(&set, 0, sizeof(set));
+            ioctl(videofd, VIDIOCGCHAN, &set);
+            set.channel = newcapchannel;
+            set.norm = videomode;
+            if (ioctl(videofd, VIDIOCSCHAN, &set) < 0)
+               perror("VIDIOCSCHAN");
+        }
     }
 
     currentcapchannel = newcapchannel;
@@ -476,6 +551,9 @@
     QString field_name = name;
     int field = pParent->GetChannelValue(field_name, this, curchannelname);
 
+    if (isradio)
+        return;
+
     if (usingv4l2)
     {
         struct v4l2_control ctrl;
Index: mythtv/libs/libmythtv/channel.h
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/channel.h,v
retrieving revision 1.26
diff -u -r1.26 channel.h
--- mythtv/libs/libmythtv/channel.h	9 Jan 2004 21:02:12 -0000	1.26
+++ mythtv/libs/libmythtv/channel.h	10 Jan 2004 18:11:05 -0000
@@ -41,8 +41,9 @@
     void SetHue();
 
     void SwitchToInput(int newcapchannel, bool setstarting);
-
+    
     void SetFd(int fd); 
+    bool GetCurrentInputRadio(void);
 
   private:
     int GetCurrentChannelNum(const QString &channame);
@@ -53,6 +54,7 @@
 
     QString device;
     bool isopen;  
+    bool isradio;  
     int videofd;
 
     struct CHANLIST *curList;  
Index: mythtv/libs/libmythtv/channelbase.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/channelbase.cpp,v
retrieving revision 1.6
diff -u -r1.6 channelbase.cpp
--- mythtv/libs/libmythtv/channelbase.cpp	12 Sep 2003 16:49:53 -0000
1.6
+++ mythtv/libs/libmythtv/channelbase.cpp	10 Jan 2004 18:11:05 -0000
@@ -70,6 +70,11 @@
     return currentcapchannel;
 }
 
+bool ChannelBase::GetCurrentInputRadio(void)
+{
+  return false;
+}
+
 void ChannelBase::ToggleInputs(void)
 {
     int newcapchannel = currentcapchannel;
Index: mythtv/libs/libmythtv/channelbase.h
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/channelbase.h,v
retrieving revision 1.3
diff -u -r1.3 channelbase.h
--- mythtv/libs/libmythtv/channelbase.h	7 Aug 2003 17:37:41 -0000	1.3
+++ mythtv/libs/libmythtv/channelbase.h	10 Jan 2004 18:11:05 -0000
@@ -55,6 +55,7 @@
     virtual QString GetCurrentInput(void);
 
     virtual int GetCurrentInputNum(void);
+    virtual bool GetCurrentInputRadio(void);
 
     virtual void SetFd(int fd) { (void)fd; }
 
@@ -69,6 +70,7 @@
     map<int, QString> inputChannel;
     map<int, QString> inputTuneTo;
     map<int, QString> externalChanger;
+    map<int, QString> inputRadio;
     // returns index of channame (channel.channum) in curList
 
     QString channelorder;
Index: mythtv/libs/libmythtv/tv_rec.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/tv_rec.cpp,v
retrieving revision 1.126
diff -u -r1.126 tv_rec.cpp
--- mythtv/libs/libmythtv/tv_rec.cpp	9 Jan 2004 21:02:13 -0000
1.126
+++ mythtv/libs/libmythtv/tv_rec.cpp	10 Jan 2004 18:11:06 -0000
@@ -2072,14 +2072,16 @@
 
 void TVRec::RetrieveInputChannels(map<int, QString> &inputChannel,
                                   map<int, QString> &inputTuneTo,
-                                  map<int, QString> &externalChanger)
+                                  map<int, QString> &externalChanger,
+                                  map<int, QString> &inputRadio)
 {
     pthread_mutex_lock(&db_lock);
     MythContext::KickDatabase(db_conn);
 
     QString query = QString("SELECT inputname, trim(externalcommand), "
                             "if(tunechan='', 'Undefined', tunechan), "
-                            "if(startchan, startchan, '') "
+                            "if(startchan, startchan, ''), "
+                            "radiodevice "
                             "FROM capturecard, cardinput "
                             "WHERE capturecard.cardid = %1 "
                             "AND capturecard.cardid = cardinput.cardid;")
@@ -2104,6 +2106,7 @@
             externalChanger[cap] = result.value(1).toString();
             inputTuneTo[cap] = result.value(2).toString();
             inputChannel[cap] = result.value(3).toString();
+            inputRadio[cap] = result.value(4).toString();
         }
     }
 
Index: mythtv/libs/libmythtv/tv_rec.h
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/tv_rec.h,v
retrieving revision 1.47
diff -u -r1.47 tv_rec.h
--- mythtv/libs/libmythtv/tv_rec.h	30 Dec 2003 07:05:23 -0000	1.47
+++ mythtv/libs/libmythtv/tv_rec.h	10 Jan 2004 18:11:06 -0000
@@ -75,7 +75,8 @@
 
     void RetrieveInputChannels(map<int, QString> &inputChannel,
                                map<int, QString> &inputTuneTo,
-                               map<int, QString> &externalChanger);
+                               map<int, QString> &externalChanger,
+                               map<int, QString> &inputRadio);
     void StoreInputChannels(map<int, QString> &inputChannel);
 
     bool IsBusy(void);




More information about the mythtv-dev mailing list