[mythtv] [PATCH] -UPDATED- MythTV Previous Channel functionality

Dan M dan at milkcarton.com
Thu Apr 17 16:32:40 EDT 2003


Attached is a patch for MythTV to provide channel history.  To use it 
press the "H" key.  That will go to the previous channel.  If you press 
"H" twice, it will go to the channel you were on two channel changes 
ago.  etc etc.   Pressing "H" once will make it perform just like the 
'Previous Channel' functionality we're all used to on a standard TV.

The one thing I'm not happy about is it not wrapping if you hit "H" more 
times then there are channels in the buffer (Per Andy Davidoff's 
suggestion).  I couldn't get it to work properly without seg faulting so 
I took it out.

Patch is made against CVS as of around 2030 AKDT (-0900) 16-Apr-2003

If any changes need to be made to get this committed, please let me know.

-dan

Additional Credits:  Chris Palmer, Andy Davidoff, John Danner, and Isaac 
for help in the debugging process
-------------- next part --------------
Index: libs/libmythtv/tv_play.cpp
===================================================================
RCS file: /var/lib/cvs/MC/libs/libmythtv/tv_play.cpp,v
retrieving revision 1.43
diff -u -d -r1.43 tv_play.cpp
--- libs/libmythtv/tv_play.cpp	12 Apr 2003 16:12:30 -0000	1.43
+++ libs/libmythtv/tv_play.cpp	17 Apr 2003 21:54:37 -0000
@@ -7,6 +7,7 @@
 #include <qapplication.h>
 #include <qregexp.h>
 #include <qfile.h>
+#include <qtimer.h>

 #include <iostream>
 using namespace std;
@@ -122,6 +123,13 @@

     deinterlace_mode = DEINTERLACE_NONE;
     gContext->addListener(this);
+
+    //The channel name vector will hold 30 items
+    PrevChannelVector channame_vector( 30 );
+
+    //Create and connect our timer
+    prevChannelTimer = new QTimer(this);
+    connect( prevChannelTimer, SIGNAL(timeout()), SLOT(SetPreviousChannel()) );
 }

 void TV::Init(void)
@@ -998,6 +1006,8 @@

             case 'x': ChangeDeinterlacer(); break;

+            case 'H': case 'h': PreviousChannel(); break;
+
             default: break;
         }
     }
@@ -1380,10 +1390,17 @@
     while (!activenvp->GetPause())
         usleep(5);

+    //Save the current channel if this is the first time
+    if ( channame_vector.size() == 0 )
+        AddPreviousChannel();
+
     activerecorder->Pause();
     activerbuffer->Reset();
     activerecorder->ChangeChannel(direction);

+    //Save the new channel
+    AddPreviousChannel();
+
     activenvp->ResetPlaying();
     while (!activenvp->ResetYet())
         usleep(5);
@@ -1467,10 +1484,17 @@
     while (!activenvp->GetPause())
         usleep(5);

+    //Save the current channel if this is the first time
+    if ( channame_vector.size() == 0 )
+        AddPreviousChannel();
+
     activerecorder->Pause();
     activerbuffer->Reset();
     activerecorder->SetChannel(name);

+    //Save the new channel
+    AddPreviousChannel();
+
     activenvp->ResetPlaying();
     while (!activenvp->ResetYet())
         usleep(5);
@@ -1483,6 +1507,89 @@
     activenvp->Unpause();
 }

+void TV::AddPreviousChannel(void)
+{
+    //Don't store more than thirty channels.  Remove the first item
+    if ( channame_vector.size() > 29 )
+    {
+        PrevChannelVector::iterator it;
+        it = channame_vector.begin();
+        channame_vector.erase( it );
+    }
+
+    //Get the current channel and add it to the vector
+    QString dummy     = "";
+    QString chan_name = "";
+    activerecorder->GetChannelInfo( dummy, dummy, dummy, dummy,     dummy,
+                                    dummy, dummy, dummy, chan_name, dummy);
+
+    //This method builds the stack of previous channels
+    channame_vector.push_back(chan_name);
+}
+
+void TV::PreviousChannel(void)
+{
+    //Save the channel if this is the first time, and return so we don't
+    // change chan to the current chan
+    if ( channame_vector.size() == 0 )
+    {
+        AddPreviousChannel();
+        return;
+    }
+
+    //Increment the times_pressed counter so we know how far to jump
+    times_pressed++;
+
+    //If the user hits the prev chan button and there is no history there can be a problem
+    int vector = (channame_vector.size()) - times_pressed - 1;
+    if ( vector < 0 )
+        vector = 0;
+
+    //Display channel name in the OSD for up to 1 second.
+    if (activenvp == nvp && osd)
+    {
+        osd->HideSet("program_info");
+        osd->SetChannumText(channame_vector[vector], 1);
+    }
+
+    //Reset the timer
+    prevChannelTimer->stop();
+    prevChannelTimer->start(500);
+}
+
+void TV::SetPreviousChannel()
+{
+    //Stop the timer
+    prevChannelTimer->stop();
+
+    int vector = (channame_vector.size()) - times_pressed - 1;
+    if ( vector < 0 )
+        vector = 0;
+
+    //Reset the times_pressed counter
+    times_pressed = 0;
+
+    //Only change channel if channame_vector[vector] != current channel
+    QString dummy     = "";
+    QString chan_name = "";
+    activerecorder->GetChannelInfo( dummy, dummy, dummy, dummy,     dummy,
+                                    dummy, dummy, dummy, chan_name, dummy);
+    if ( chan_name != channame_vector[vector].latin1() )
+    {
+        //Populate the array with the channel
+        for(uint i = 0; i < channame_vector[vector].length(); i++)
+        {
+            channelKeys[i] = (int ) *channame_vector[vector].mid(i, 1).latin1();
+        }
+
+        channelqueued = true;
+    }
+
+    //Turn off the OSD Channel Num so the channel changes right away
+    if (activenvp == nvp && osd)
+        osd->HideSet("channel_number");
+}
+
 void TV::UpdateOSD(void)
 {
     QString title, subtitle, desc, category, starttime, endtime;
@@ -1553,7 +1660,7 @@
     {
         chanstr = chanstr.left(4);
         sprintf(channelKeys, "%s", chanstr.ascii());
-        channelqueued = true; 
+        channelqueued = true;
     }
 
     StopEmbeddingOutput();
Index: libs/libmythtv/tv_play.h
===================================================================
RCS file: /var/lib/cvs/MC/libs/libmythtv/tv_play.h,v
retrieving revision 1.25
diff -u -d -r1.25 tv_play.h
--- libs/libmythtv/tv_play.h	8 Apr 2003 00:59:13 -0000	1.25
+++ libs/libmythtv/tv_play.h	17 Apr 2003 21:54:37 -0000
@@ -3,7 +3,9 @@
 
 #include <qstring.h>
 #include <pthread.h>
+#include <qvaluevector.h>
 
+#include "tv.h"
 #include <qobject.h>
 
 class QSqlDatabase;
@@ -17,7 +19,8 @@
 
 class TV : public QObject
 {
- public:
+Q_OBJECT
+public:
     TV(QSqlDatabase *db);
    ~TV(void);
 
@@ -56,6 +59,9 @@
     void ProcessKeypress(int keypressed);
     void customEvent(QCustomEvent *e);
 
+    void AddPreviousChannel(void);
+    void PreviousChannel(void);
+
  protected:
     void doLoadMenu(void);
     static void *MenuHandler(void *param);
@@ -175,6 +181,14 @@
 
     unsigned int embedid;
     int embx, emby, embw, embh;
+
+    typedef QValueVector<QString> PrevChannelVector;
+    PrevChannelVector channame_vector;
+    unsigned int times_pressed;
+    QTimer *prevChannelTimer;
+
+protected slots:
+    void SetPreviousChannel();
 };
 
 #endif


More information about the mythtv-dev mailing list