[mythtv] Tracing Channel Change

Edward Wildgoose edward.wildgoose at frmhedge.com
Sun Nov 23 14:42:49 EST 2003


I have been tracing the channel change code to track down a pause during channel change, and I have got stuck.  Can anyone help with some ideas on where to look please.

Basically the motivation is to see if I can't speedup channel change time.  What I'm finding is that when tracing through tv_play.cpp in ChangeChannel the lines:

    activenvp->Pause(false);
    activerbuffer->WaitForPause();

Are taking up to 600ms+ to complete.  This is using a DVB card as the input source.  

At first I thought I had it sussed with the following:

--- NuppelVideoPlayer.cpp       23 Nov 2003 05:44:16 -0000      1.297
+++ NuppelVideoPlayer.cpp       23 Nov 2003 18:42:59 -0000
@@ -1518,7 +1528,7 @@
             else
             {
                 //printf("startplaying waiting for unpause\n");
-                usleep(500);
+                usleep(100);
                 continue;
             }
         }

However, this merely pushes the wait time into the ringbuffer->WaitForPause();  So first of all, why usleep(500) anyway? And also, does anyone have any ideas on how to trace where this second call is spending all it's time?

Here's what I checked: The play loop in dvbrecorder appears to be very responsive, it only seems to be reading a single ts frame at a time.  In the "if (paused)" section of the play loop there is no significant time delay pausing the recorder thread.  Also I can't spot any significant delays pausing the decoder thread, it seems to be decoding a single frame each time round the play loop, so it should be pretty responsive?  So what the heck is it doing for 600ms?

I think this would be a useful speedup if this pausing delay could be worked out.  If anyone wants to time this for themselves try the following:

--- tv_play.cpp 23 Nov 2003 01:15:30 -0000      1.122
+++ tv_play.cpp 23 Nov 2003 18:43:04 -0000
@@ -1669,6 +1669,8 @@

 void TV::ChangeChannel(int direction)
 {
+    QTime qtm;qtm.start();
+    cout << "Starting Channel Change\r\n";
     bool muted = false;

     if (volumeControl && !volumeControl->GetMute() && activenvp == nvp)
@@ -1684,20 +1686,28 @@
         paused = false;
     }

+    cout << "Before Pause:" << qtm.elapsed() << "\r\n";
     activenvp->Pause(false);
+    cout << "Pause Issued:" << qtm.elapsed() << "\r\n";
     // all we care about is the ringbuffer being paused, here..
     activerbuffer->WaitForPause();
+    cout << "Paused:" << qtm.elapsed() << "\r\n";

     // Save the current channel if this is the first time
     if (channame_vector.size() == 0 && activenvp == nvp)
         AddPreviousChannel();

     activerecorder->Pause();
+    cout << "Active Recorder Paused:" << qtm.elapsed() << "\r\n";
     activerbuffer->Reset();
+    cout << "Buffer reset:"  << qtm.elapsed() << "\r\n";
     activerecorder->ChangeChannel(direction);
+    cout << "Active Recorder Channel Changed:" << qtm.elapsed() << "\r\n";

     activenvp->ResetPlaying();
+    cout << "Reset Playing:" << qtm.elapsed() << "\r\n";
     activenvp->Unpause(false);
+    cout << "Un Paused:" << qtm.elapsed() << "\r\n";

     if (activenvp == nvp)
     {


However, whilst I was fiddling it occurs to me that the current mpegrecorder.cpp uses this in the StartRecording loop:

        ret = read(readfd, buffer, 256000);

Someone with a PVR card might want to try dropping the read size to say 64000.  Just eyeballing the code, but this would appear to make the record loop more responsive and speedup the pausing code?  I don't have one, so feedback appreciated..

The other thing I don't quite understand is how much pre-buffering is required for various input sources.  It seems at least for DVB input sources that the following change works very well:

--- videoout_xv.cpp     10 Nov 2003 21:45:01 -0000      1.87
+++ videoout_xv.cpp     23 Nov 2003 18:43:04 -0000
@@ -46,7 +46,8 @@

 const int kNumBuffers = 31;
 const int kNeedFreeFrames = 1;
-const int kPrebufferFrames = 12;
+//const int kPrebufferFrames = 12;
+const int kPrebufferFrames = 2;
 const int kKeepPrebuffer = 2;

 struct XvData


What are the issues with reducing this?  Also, what is the difference between kKeppPrebuffer and kPrebufferFrames?

In any case, with these changes, at least for the times when the pause runs quickly, the channel change time is pretty good really.  Any chance someone could pitch in with some feedback and lets see if we can't tune this a little

Ed
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mythtv.org/pipermail/mythtv-dev/attachments/20031123/3d738115/attachment.htm


More information about the mythtv-dev mailing list