[mythtv] Directv and channel changing problem

Andy Davidoff dert at pobox.com
Tue Mar 11 00:55:39 EST 2003


I'd greatly appreciate it if those with multiple inputs could test
this and let me know of anything fishy.  I'd like to eliminate the
DefaultTVChannel option by simply saving the last channel tuned to
in the new cardinput columns.


#if Isaac Richards /* Mar 06, 10:38 */
> Think you could resubmit this without the need for a separate setting?
> Should be fairly easy, just check to see if the input has an external
> channel change command set on startup and whenever it switches inputs..
#endif /* ijr at po.cwru.edu */
-------------- next part --------------
Index: MC/libs/libmythtv/channel.cpp
===================================================================
RCS file: /var/lib/cvs/MC/libs/libmythtv/channel.cpp,v
retrieving revision 1.29
diff -d -w -U6 -r1.29 channel.cpp
--- MC/libs/libmythtv/channel.cpp	3 Mar 2003 15:42:11 -0000	1.29
+++ MC/libs/libmythtv/channel.cpp	11 Mar 2003 05:38:20 -0000
@@ -96,21 +96,30 @@
         memset(&test, 0, sizeof(test));
         test.channel = i;
         ioctl(videofd, VIDIOCGCHAN, &test);
 
         cout << "Probed: " << device << " - " << test.name << endl;
         channelnames[i] = test.name;
+        inputChannel[i] = "";
+        input1stChannel[i] = "";
+        inputTuneTo[i] = "";
+        externalChanger[i] = "";
     }
 
     struct video_channel vc;
     memset(&vc, 0, sizeof(vc));
     ioctl(videofd, VIDIOCGCHAN, &vc);
     vc.norm = mode;
     ioctl(videofd, VIDIOCSCHAN, &vc);
 
     videomode = mode;
+
+    pParent->RetrieveInputChannels( inputChannel,
+                                    inputTuneTo,
+                                    input1stChannel,
+                                    externalChanger);
 }
 
 void Channel::SetFreqTable(const QString &name)
 {
     int i = 0;
     char *listname = (char *)chanlists[i].name;
@@ -141,43 +150,41 @@
     if (!isopen)
         return false;
 
     if (curchannelname == chan)
         return true;
 
-    int finetune = 0;
-
-    if (pParent->CheckChannel(this, chan, finetune))
-    {
-        if (GetCurrentInput() == "Television")
+    if (externalChanger[currentcapchannel].isEmpty())
         {
             int i = GetCurrentChannelNum(chan);
-            if (i == -1)
+        if (i == -1 || !TuneTo(chan))
+            return false;
+    }
+    else if (!ChangeExternalChannel(chan))
                 return false;
-
-            int frequency = curList[i].freq * 16 / 1000 + finetune;
-            if (ioctl(videofd, VIDIOCSFREQ, &frequency) == -1)
-                perror("channel set:");
 
             curchannelname = chan;
-
             pParent->SetVideoFiltersForChannel(this, chan);
+    inputChannel[currentcapchannel] = curchannelname;
+
 	    return true;
         }
-        else
-        {
-            if (pParent->ChangeExternalChannel(chan))
+
+bool Channel::TuneTo(const QString &chan)
             {
-                curchannelname = chan;
-                pParent->SetVideoFiltersForChannel(this, chan);
-                return true;
-            }
-        }
-    }
+    int finetune;
 
+    if (!pParent->CheckChannel(this, chan, finetune))
     return false;
+
+    int i = GetCurrentChannelNum(chan);
+    int frequency = curList[i].freq * 16 / 1000 + finetune;
+    if (ioctl(videofd, VIDIOCSFREQ, &frequency) == -1)
+        perror("channel set:");
+
+    return true;
 }
 
 int Channel::GetCurrentChannelNum(const QString &channame)
 {
     bool foundit = false;
     int i;
@@ -278,47 +285,76 @@
 {
     return channelnames[currentcapchannel];
 }
 
 void Channel::ToggleInputs(void)
 {
-    currentcapchannel++;
-    if (currentcapchannel >= capchannels)
-        currentcapchannel = 0;
+    int newcapchannel = currentcapchannel;
 
-    struct video_channel set;
-    memset(&set, 0, sizeof(set));
-    ioctl(videofd, VIDIOCGCHAN, &set);
-    set.channel = currentcapchannel;
-    set.norm = videomode;
-    ioctl(videofd, VIDIOCSCHAN, &set);
+    do {
+        newcapchannel = (newcapchannel+1) % capchannels;
+    } while (inputTuneTo[newcapchannel].isEmpty());
+
+    SwitchToInput(newcapchannel, true);
 }
 
-void Channel::SwitchToInput(const QString &input)
-{
-    int inputnum = 0;
-    for (int i = 0; i < capchannels; i++)
+int Channel::GetInputByName(const QString &input)
     {
+    for (int i = capchannels-1; i >= 0; i--)
         if (channelnames[i] == input)
-            inputnum = i;
+            return i;
+    return -1;
     }
 
-    if (inputnum == currentcapchannel)
-        return;
+void Channel::SwitchToInput(const QString &inputname)
+{
+    int input = GetInputByName(inputname);
 
-    currentcapchannel = inputnum;
+    if (input >= 0)
+        SwitchToInput(input, true);
+}
+
+void Channel::SwitchToInput(const QString &inputname, const QString &chan)
+{
+    int input = GetInputByName(inputname);
+
+    if (input >= 0)
+    {
+        SwitchToInput(input, false);
+        SetChannelByString(chan);
+    }
+}
+
+void Channel::SwitchToInput(int newcapchannel, bool setstarting)
+{
+    if (newcapchannel == currentcapchannel)
+        return;
 
     struct video_channel set;
     memset(&set, 0, sizeof(set));
     ioctl(videofd, VIDIOCGCHAN, &set);
-    set.channel = currentcapchannel;
+    set.channel = newcapchannel;
     set.norm = videomode;
     if (ioctl(videofd, VIDIOCSCHAN, &set) < 0)
     {
         perror("VIDIOCSCHAN: ");
     }
+
+    currentcapchannel = newcapchannel;
+    curchannelname = "";
+
+    if (inputTuneTo[currentcapchannel].toUInt() > 0)
+        TuneTo(inputTuneTo[currentcapchannel]);
+
+    if (setstarting)
+    {
+        if (!inputChannel[currentcapchannel].isEmpty())
+            SetChannelByString(inputChannel[currentcapchannel]);
+        else if (!input1stChannel[currentcapchannel].isEmpty())
+            SetChannelByString(input1stChannel[currentcapchannel]);
+    }
 }
 
 int Channel::ChangeColour(bool up)
 {
     struct video_picture vid_pic;
     memset(&vid_pic, 0, sizeof(vid_pic));
@@ -421,7 +457,21 @@
     {
         perror("VIDIOCSPICT: ");
         return -1;
     }
 
     return vid_pic.contrast;
+}
+
+bool Channel::ChangeExternalChannel(const QString &channum)
+{
+    if (externalChanger[currentcapchannel].isEmpty())
+        return false;
+
+    QString command = QString("%1 %2")
+        .arg(externalChanger[currentcapchannel])
+        .arg(channum);
+    cout << "External channel change: " << command << endl;
+    system(command.ascii());
+
+    return true;
 }
Index: MC/libs/libmythtv/channel.h
===================================================================
RCS file: /var/lib/cvs/MC/libs/libmythtv/channel.h,v
retrieving revision 1.15
diff -d -w -U6 -r1.15 channel.h
--- MC/libs/libmythtv/channel.h	3 Mar 2003 04:54:53 -0000	1.15
+++ MC/libs/libmythtv/channel.h	11 Mar 2003 05:38:20 -0000
@@ -31,15 +31,20 @@
     int ChangeColour(bool up);
     int ChangeBrightness(bool up);
     int ChangeContrast(bool up);
  
     void ToggleInputs(void); 
     void SwitchToInput(const QString &input);
+    void SwitchToInput(const QString &input, const QString &chan);
+    void SwitchToInput(int newcapchannel, bool setstarting);
+    bool TuneTo(const QString &chan);
+    bool ChangeExternalChannel(const QString &newchan);
  
     QString GetCurrentName(void);
     QString GetCurrentInput(void);
+    int GetInputByName(const QString &input);
 
     void SetFd(int fd) { videofd = fd; } 
     QString GetDevice() { return device; }
 
     QString GetOrdering() { return channelorder; }
 
@@ -58,11 +63,15 @@
 
     int videomode;
 
     int capchannels;
     int currentcapchannel;
     map<int, QString> channelnames;
+    map<int, QString> inputTuneTo;
+    map<int, QString> input1stChannel;
+    map<int, QString> externalChanger;
+    map<int, QString> inputChannel;
 
     QString channelorder;
 };
 
 #endif
Index: MC/libs/libmythtv/tv_rec.cpp
===================================================================
RCS file: /var/lib/cvs/MC/libs/libmythtv/tv_rec.cpp,v
retrieving revision 1.48
diff -d -w -U6 -r1.48 tv_rec.cpp
--- MC/libs/libmythtv/tv_rec.cpp	11 Mar 2003 04:07:19 -0000	1.48
+++ MC/libs/libmythtv/tv_rec.cpp	11 Mar 2003 05:38:21 -0000
@@ -56,15 +56,15 @@
                inputname);
 
     channel = new Channel(this, videodev);
     channel->Open();
     channel->SetFormat(gContext->GetSetting("TVFormat"));
     channel->SetFreqTable(gContext->GetSetting("FreqTable"));
-    if (inputname != "")
-        channel->SwitchToInput(inputname);
-    channel->SetChannelByString(startchannel);
+    if (inputname.isEmpty())
+        inputname = channel->GetCurrentInput();
+    SwitchToInput(inputname, startchannel);
     channel->SetChannelOrdering(chanorder);
     channel->Close();
 }
 
 void TVRec::Init(void)
 {
@@ -577,14 +577,13 @@
     } else {
         MythContext::DBError("SetChannel", query);
     }
 
     pthread_mutex_unlock(&db_lock);
 
-    channel->SwitchToInput(inputname);
-    channel->SetChannelByString(chanstr);
+    SwitchToInput(inputname);
 
     if (needopen)
         channel->Close();
 }
 
 void *TVRec::EventThread(void *param)
@@ -1168,50 +1168,12 @@
 
     pthread_mutex_unlock(&db_lock);
 
     return ret;
 }
 
-bool TVRec::ChangeExternalChannel(const QString& channum)
-{
-    QString query = QString("SELECT cardinput.externalcommand "
-                            "FROM cardinput,channel,capturecard "
-                            "WHERE channel.channum = %1 "
-                            "AND channel.sourceid = cardinput.sourceid "
-                            "AND cardinput.inputname = '%2' "
-                            "AND cardinput.cardid = capturecard.cardid "
-                            "AND capturecard.videodevice = '%3' "
-                            "AND capturecard.hostname = \"%4\";")
-                           .arg(channum).arg(channel->GetCurrentInput())
-                           .arg(channel->GetDevice())
-                           .arg(gContext->GetHostName());
-
-    QString command(QString::null);
-
-    pthread_mutex_lock(&db_lock);
-
-    QSqlQuery result = db_conn->exec(query);
-    if (!result.isActive())
-        MythContext::DBError("changeexternalchannel", result);
-    else if (result.numRowsAffected()) {
-        result.next();
-        command = QString("%1 %2")
-            .arg(result.value(0).toString())
-            .arg(channum);
-
-    }
-    pthread_mutex_unlock(&db_lock);
-
-    if (command != QString::null) {
-        cout << "External channel change: " << command << endl;
-        system(command.ascii());
-    }
-
-    return true;
-}
-
 bool TVRec::IsReallyRecording(void)
 {
     if (nvr && nvr->IsRecording())
         return true;
 
     return false;
@@ -1316,37 +1278,61 @@
 
     PauseClearRingBuffer();
 } 
 
 void TVRec::ToggleInputs(void)
 {
-    rbuffer->Reset();
-
+    PreInputSwitch();
     channel->ToggleInputs();
+    PostInputSwitch();
+}
+
+void TVRec::SwitchToInput(QString inputname)
+{
+    PreInputSwitch();
+    channel->SwitchToInput(inputname);
+    PostInputSwitch();
+}
+
+void TVRec::SwitchToInput(QString inputname, QString start)
+{
+    PreInputSwitch();
+    channel->SwitchToInput(inputname, start);
+    PostInputSwitch();
+}
+
+void TVRec::PreInputSwitch(void)
+{
+    if (rbuffer)
+        rbuffer->Reset();
+}
 
+void TVRec::PostInputSwitch(void)
+{
+    if (nvr)
+    {
     nvr->Reset();
     nvr->Unpause();
+    }
 
+    if (rbuffer)
     UnpauseRingBuffer();
 }
 
 void TVRec::ChangeChannel(int channeldirection)
 {
-    rbuffer->Reset();
+    PreInputSwitch();
     
     if (channeldirection == CHANNEL_DIRECTION_FAVORITE)
         channel->NextFavorite();
     else if (channeldirection == CHANNEL_DIRECTION_UP)
         channel->ChannelUp();
     else
         channel->ChannelDown();
 
-    nvr->Reset();
-    nvr->Unpause();
-
-    UnpauseRingBuffer();
+    PostInputSwitch();
 }
 
 void TVRec::ToggleChannelFavorite(void)
 {
     // Get current channel id...
     QString channum = channel->GetCurrentName();
@@ -1435,24 +1421,24 @@
 {
     channel->ChangeColour(direction);
 }
 
 void TVRec::SetChannel(QString name)
 {
-    rbuffer->Reset();
+    PreInputSwitch();
 
+    if (!name.isEmpty())
+    {
     QString chan = name.stripWhiteSpace();
     QString prevchan = channel->GetCurrentName();
 
     if (!channel->SetChannelByString(chan))
         channel->SetChannelByString(prevchan);
+    }
 
-    nvr->Reset();
-    nvr->Unpause();
-
-    UnpauseRingBuffer();
+    PostInputSwitch();
 }
 
 bool TVRec::CheckChannel(QString name)
 {
     int finetune = 0;
     return CheckChannel(channel, name, finetune);
@@ -1614,7 +1600,51 @@
     if (skipMethod == COMMERCIAL_SKIP_BLANKS)
     {
         BuildCommListFromBlanks(blank_frame_map, nvr->GetFrameRate(),
             comm_breaks);
         curRecording->SetCommBreakList(comm_breaks, db_conn);
     }
+}
+
+void TVRec::RetrieveInputChannels(map<int, QString> &inputChannel,
+                                  map<int, QString> &inputTuneTo,
+                                  map<int, QString> &input1stChannel,
+                                  map<int, QString> &externalChanger)
+{
+    pthread_mutex_lock(&db_lock);
+    MythContext::KickDatabase(db_conn);
+
+    QString query = QString("SELECT "
+                        "inputname, "
+                        "trim(externalcommand), "
+                        "if(tunechan, tunechan, 0), "
+                        "ifnull(startchan, '') "
+                    "FROM capturecard, cardinput "
+                    "WHERE capturecard.cardid = %1 "
+                        "AND capturecard.cardid = cardinput.cardid;")
+                    .arg(m_capturecardnum);
+
+    QSqlQuery result = db_conn->exec(query);
+
+    if (!result.isActive())
+        MythContext::DBError("RetrieveInputChannels", result);
+    else if (!result.numRowsAffected())
+    {
+        cerr << "Error getting inputs for the capturecard.  Perhaps you have\n"
+                "forgotten to bind video sources to your card's inputs?" << endl;
+    }
+    else
+    {
+        int cap;
+
+        while (result.next())
+        {
+            cap = channel->GetInputByName(result.value(0).toString());
+            externalChanger[cap] = result.value(1).toString();
+            inputTuneTo[cap] = result.value(2).toString();
+            input1stChannel[cap] = result.value(3).toString();
+            inputChannel[cap] = "";
+        }
+    }
+
+    pthread_mutex_unlock(&db_lock);
 }
Index: MC/libs/libmythtv/tv_rec.h
===================================================================
RCS file: /var/lib/cvs/MC/libs/libmythtv/tv_rec.h,v
retrieving revision 1.22
diff -d -w -U6 -r1.22 tv_rec.h
--- MC/libs/libmythtv/tv_rec.h	10 Mar 2003 23:09:20 -0000	1.22
+++ MC/libs/libmythtv/tv_rec.h	11 Mar 2003 05:38:22 -0000
@@ -38,13 +38,12 @@
     bool IsPlaying(void) { return StateIsPlaying(internalState); }
     bool IsRecording(void) { return StateIsRecording(internalState); }
 
     bool CheckChannel(Channel *chan, const QString &channum, int &finetuning); 
     void SetChannelValue(QString &field_name,int value, Channel *chan, const QString &channum);
     int GetChannelValue(const QString &channel_field,Channel *chan, const QString &channum);
-    bool ChangeExternalChannel(const QString &channum);
     bool SetVideoFiltersForChannel(Channel *chan, const QString &channum);
     QString GetNextChannel(Channel *chan, int channeldirection);
 
     bool IsReallyRecording(void);
     float GetFramerate(void);
     long long GetFramesWritten(void);
@@ -55,12 +54,20 @@
     void StopPlaying(void);
     void SetupRingBuffer(QString &path, long long &filesize, 
                          long long &fillamount, bool pip = false);
     void SpawnLiveTV(void);
     void StopLiveTV(void);
     void PauseRecorder(void);
+    void RetrieveInputChannels(map<int, QString> &inputChannel,
+                               map<int, QString> &inputTuneTo,
+                               map<int, QString> &input1stChannel,
+                               map<int, QString> &externalChanger);
+    void PreInputSwitch(void);
+    void PostInputSwitch(void);
+    void SwitchToInput(QString inputname);
+    void SwitchToInput(QString inputname, QString channel);
     void ToggleInputs(void);
     void ToggleChannelFavorite(void);
     void ChangeChannel(int channeldirection);
     void SetChannel(QString name);
     void ChangeColour(bool direction);
     void ChangeContrast(bool direction);
-------------- next part --------------
alter table cardinput add tunechan tinyint not null, add startchan char(5) not null;


More information about the mythtv-dev mailing list