Well, its of course always better to just complain and hope that someone else should fix it, but after my post above I decided to give it a try myself...
So after having fetched the sources from CVS and dived into the libdvb C-code, I realized that at least the simple solution was closer than expected: the repeat count of slow motion and the skip count of fast winding can be specified orthogonally to each other! Furthermore, this can be done directly from python with no need to modify the C-code.
This means that it is already possible from python to achieve e.g. 2x backwards speed by skipping 16 frames back and repeating this frame 8 times. As noted in my post above, this will not be a smooth rewind, but in discrete jumps, but at least it will give time to react.
Here is a patch to "Screens/InfoBarGenerics.py" (in the standard distribution, but it will hopefully work with some fuzz in the variants) which implements this. It adds -2x, -4x, and -8x speed, and also the "missing" x16 forward. It also adds a repeat count for x16 and higher, both forwards and backwards. At those speeds each frame may sometimes be from a new scene, and repeating each frame a few times makes winding at those speeds a less subliminal experience...
--- InfoBarGenerics.py.orig 2007-09-03 16:25:55.000000000 +0200
+++ InfoBarGenerics.py 2007-09-07 22:32:55.000000000 +0200
@@ -613,14 +613,16 @@
SEEK_STATE_FF_2X = (0, 2, 0, ">> 2x")
SEEK_STATE_FF_4X = (0, 4, 0, ">> 4x")
SEEK_STATE_FF_8X = (0, 8, 0, ">> 8x")
- SEEK_STATE_FF_32X = (0, 32, 0, ">> 32x")
- SEEK_STATE_FF_64X = (0, 64, 0, ">> 64x")
- SEEK_STATE_FF_128X = (0, 128, 0, ">> 128x")
-
- SEEK_STATE_BACK_16X = (0, -16, 0, "<< 16x")
- SEEK_STATE_BACK_32X = (0, -32, 0, "<< 32x")
- SEEK_STATE_BACK_64X = (0, -64, 0, "<< 64x")
- SEEK_STATE_BACK_128X = (0, -128, 0, "<< 128x")
+ SEEK_STATE_FF_16X = (0, 48, 3, ">> 16x")
+ SEEK_STATE_FF_32X = (0, 96, 3, ">> 32x")
+ SEEK_STATE_FF_64X = (0, 192, 3, ">> 64x")
+
+ SEEK_STATE_BACK_2X = (0, -16, 8, "<< 2x")
+ SEEK_STATE_BACK_4X = (0, -16, 4, "<< 4x")
+ SEEK_STATE_BACK_8X = (0, -24, 3, "<< 8x")
+ SEEK_STATE_BACK_16X = (0, -48, 3, "<< 16x")
+ SEEK_STATE_BACK_32X = (0, -96, 3, "<< 32x")
+ SEEK_STATE_BACK_64X = (0, -192, 3, "<< 64x")
SEEK_STATE_SM_HALF = (0, 0, 2, "/2")
SEEK_STATE_SM_QUARTER = (0, 0, 4, "/4")
@@ -795,39 +797,44 @@
self.SEEK_STATE_PAUSE: self.SEEK_STATE_SM_EIGHTH,
self.SEEK_STATE_FF_2X: self.SEEK_STATE_FF_4X,
self.SEEK_STATE_FF_4X: self.SEEK_STATE_FF_8X,
- self.SEEK_STATE_FF_8X: self.SEEK_STATE_FF_32X,
+ self.SEEK_STATE_FF_8X: self.SEEK_STATE_FF_16X,
+ self.SEEK_STATE_FF_16X: self.SEEK_STATE_FF_32X,
self.SEEK_STATE_FF_32X: self.SEEK_STATE_FF_64X,
- self.SEEK_STATE_FF_64X: self.SEEK_STATE_FF_128X,
- self.SEEK_STATE_FF_128X: self.SEEK_STATE_FF_128X,
- self.SEEK_STATE_BACK_16X: self.SEEK_STATE_PLAY,
+ self.SEEK_STATE_FF_64X: self.SEEK_STATE_FF_64X,
+ self.SEEK_STATE_BACK_2X: self.SEEK_STATE_PLAY,
+ self.SEEK_STATE_BACK_4X: self.SEEK_STATE_BACK_2X,
+ self.SEEK_STATE_BACK_8X: self.SEEK_STATE_BACK_4X,
+ self.SEEK_STATE_BACK_16X: self.SEEK_STATE_BACK_8X,
self.SEEK_STATE_BACK_32X: self.SEEK_STATE_BACK_16X,
self.SEEK_STATE_BACK_64X: self.SEEK_STATE_BACK_32X,
self.SEEK_STATE_BACK_128X: self.SEEK_STATE_BACK_64X,
self.SEEK_STATE_SM_HALF: self.SEEK_STATE_SM_HALF,
self.SEEK_STATE_SM_QUARTER: self.SEEK_STATE_SM_HALF,
self.SEEK_STATE_SM_EIGHTH: self.SEEK_STATE_SM_QUARTER,
- self.SEEK_STATE_EOF: self.SEEK_STATE_EOF,
+ self.SEEK_STATE_EOF: self.SEEK_STATE_EOF
}
self.setSeekState(lookup[self.seekstate])
def seekBack(self):
lookup = {
- self.SEEK_STATE_PLAY: self.SEEK_STATE_BACK_16X,
+ self.SEEK_STATE_PLAY: self.SEEK_STATE_BACK_2X,
self.SEEK_STATE_PAUSE: self.SEEK_STATE_PAUSE,
self.SEEK_STATE_FF_2X: self.SEEK_STATE_PLAY,
self.SEEK_STATE_FF_4X: self.SEEK_STATE_FF_2X,
self.SEEK_STATE_FF_8X: self.SEEK_STATE_FF_4X,
- self.SEEK_STATE_FF_32X: self.SEEK_STATE_FF_8X,
+ self.SEEK_STATE_FF_16X: self.SEEK_STATE_FF_8X,
+ self.SEEK_STATE_FF_32X: self.SEEK_STATE_FF_16X,
self.SEEK_STATE_FF_64X: self.SEEK_STATE_FF_32X,
- self.SEEK_STATE_FF_128X: self.SEEK_STATE_FF_64X,
+ self.SEEK_STATE_BACK_2X: self.SEEK_STATE_BACK_4X,
+ self.SEEK_STATE_BACK_4X: self.SEEK_STATE_BACK_8X,
+ self.SEEK_STATE_BACK_8X: self.SEEK_STATE_BACK_16X,
self.SEEK_STATE_BACK_16X: self.SEEK_STATE_BACK_32X,
self.SEEK_STATE_BACK_32X: self.SEEK_STATE_BACK_64X,
- self.SEEK_STATE_BACK_64X: self.SEEK_STATE_BACK_128X,
- self.SEEK_STATE_BACK_128X: self.SEEK_STATE_BACK_128X,
+ self.SEEK_STATE_BACK_64X: self.SEEK_STATE_BACK_64X,
self.SEEK_STATE_SM_HALF: self.SEEK_STATE_SM_QUARTER,
self.SEEK_STATE_SM_QUARTER: self.SEEK_STATE_SM_EIGHTH,
self.SEEK_STATE_SM_EIGHTH: self.SEEK_STATE_PAUSE,
- self.SEEK_STATE_EOF: self.SEEK_STATE_BACK_16X,
+ self.SEEK_STATE_EOF: self.SEEK_STATE_BACK_2X
}
self.setSeekState(lookup[self.seekstate])
Alles anzeigen
You also need a small fix to "Screens/MediaPlayer.py" to stop it from refering to individual speed states, since these will change when you start experimenting with this.
--- MediaPlayer.py.orig 2007-07-22 20:27:34.000000000 +0200
+++ MediaPlayer.py 2007-09-07 22:30:37.000000000 +0200
@@ -643,17 +643,9 @@
self.playlist.pauseFile()
elif self.seekstate == self.SEEK_STATE_PLAY:
self.playlist.playFile()
- elif self.seekstate in ( self.SEEK_STATE_FF_2X,
- self.SEEK_STATE_FF_4X,
- self.SEEK_STATE_FF_8X,
- self.SEEK_STATE_FF_32X,
- self.SEEK_STATE_FF_64X,
- self.SEEK_STATE_FF_128X):
+ elif self.seekstate[1] > 0:
self.playlist.forwardFile()
- elif self.seekstate in ( self.SEEK_STATE_BACK_16X,
- self.SEEK_STATE_BACK_32X,
- self.SEEK_STATE_BACK_64X,
- self.SEEK_STATE_BACK_128X,):
+ elif self.seekstate[1] < 0:
self.playlist.rewindFile()
def pauseEntry(self):
Alles anzeigen
This is just an example patch - you can play around with it in many ways. For example, as suggested earlier in the thread, the first press on back/forward could start at a higher speed than 2x (and further presses will climb up or down in speed). Just modify the end of the two lines starting with "self.SEEK_STATE_PLAY:" by inserting the state with the preferred initial speed.
Some notes:
As mentioned in my previous post, the backwards speed is not always accurate. "-16x" is actually closer to -30x for many services. In the same way, after the above modification "-2x" may still be closer to -4x in reality.
I also tried, as MacDisein above, using "smooth" backward rewind in lower speeds than 16x. What happens can be described as "sawtooth" playback, i.e. it jumps one GOP backwards and plays it up forward in the specified speed, then jumps another GOP backwards and plays it up, and so on. This is most pronounced at lower speeds, which gives a really shaky impression. At -8x it is not so pronounced, but it still exist. This may explain the confusion in the thread above of wheither -8x or -16x is the lowest acceptable "smooth" speed. However, then I noticed a slight "sawtooth" behavior also at -16x (even when the typical GOP size is less than 16). This of course gets easier to see when the speed is slowed down by repeating frames. Although annoying for a perfectionist, it is however fortunately not very disturbing, and you probably woudn't notice if you didn't know it was there (OK, sorry for mentioning it...).
Best Regards
Anders Holst