[mythtv] [PATCH] Plextor PX-TV402 / go7007 keyframe seek fix
Jack Porter
jack at porter.net.au
Mon May 23 01:26:36 UTC 2005
This patch fixes the problem of up to a second of mpeg blockiess
whenever you seek in a video captured with one of these devices.
The first frame the Plextor gives us isn't necessarily an I-frame, so
the seek table isn't synced with what's in the mpeg stream. Thanks to
Mark Spieth for tracking down the root cause of this. Simply throwing
away everything before the first I-frame lets everything start off in sync.
But unfortunately things sometimes get out of sync again for the rest of
the recording for some reason - perhaps if a frame is dropped.
My solution was to write a 'sync' frame to the nuv only when the frame
data written is an MPEG4 I-frame. Why are the sync frames placed so
rigidly placed exactly 30 frames apart in the nuv?
Mark suggested it might be nicer to do something like what the firewire
code does using SetPositionMapDelta.
I'm posting this because (1) it works for me (tm), (2) it doesn't change
behavior for anyone not using a go7007, and (3) I won't have a chance to
look at this again til next weekend at the earliest.
- Jack
-------------- next part --------------
Index: NuppelVideoRecorder.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/NuppelVideoRecorder.cpp,v
retrieving revision 1.198
diff -u -r1.198 NuppelVideoRecorder.cpp
--- NuppelVideoRecorder.cpp 3 May 2005 18:58:58 -0000 1.198
+++ NuppelVideoRecorder.cpp 22 May 2005 13:44:00 -0000
@@ -160,6 +160,7 @@
volume = 100;
go7007 = false;
+ go7007keyframenumber = 0;
}
NuppelVideoRecorder::~NuppelVideoRecorder(void)
@@ -1347,6 +1348,8 @@
encoding = true;
recording = true;
+ int hadgo7007iframe = false;
+
while (encoding) {
again:
if (paused)
@@ -1443,6 +1446,17 @@
BufferIt(conversion_buffer, video_buffer_size);
}
+ else if (go7007)
+ {
+ // On go7007, don't write anything but S-frames until we
+ // get the first I-frame, to correctly synchronize
+ unsigned char frametype = buffers[frame][4]>>6;
+ if (!hadgo7007iframe && frametype==0)
+ hadgo7007iframe = true;
+
+ if (hadgo7007iframe || frametype==3)
+ BufferIt(buffers[frame], vbuf.bytesused);
+ }
else
{
// buffer the frame directly
@@ -3369,13 +3383,25 @@
frameheader.keyframe = frameofgop; // no keyframe defaulted
bool wantkeyframe = forcekey;
+ bool writesyncheader;
- if (((fnum-startnum)>>1) % keyframedist == 0 && !skipsync) {
+ if (go7007)
+ writesyncheader = (frame->buf[4]>>6)==0;
+ else
+ writesyncheader = ((fnum-startnum)>>1) % keyframedist == 0;
+
+ if (writesyncheader && !skipsync) {
+ int keyframenumber;
+ if (go7007)
+ keyframenumber = go7007keyframenumber++;
+ else
+ keyframenumber = ((fnum - startnum) >> 1) / keyframedist;
+
frameheader.keyframe=0;
frameofgop=0;
ringBuffer->Write("RTjjjjjjjjjjjjjjjjjjjjjjjj", FRAMEHEADERSIZE);
- UpdateSeekTable(((fnum - startnum) >> 1) / keyframedist, true);
+ UpdateSeekTable(keyframenumber, true);
frameheader.frametype = 'S'; // sync frame
frameheader.comptype = 'V'; // video sync information
Index: NuppelVideoRecorder.h
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/NuppelVideoRecorder.h,v
retrieving revision 1.79
diff -u -r1.79 NuppelVideoRecorder.h
--- NuppelVideoRecorder.h 19 Mar 2005 06:51:41 -0000 1.79
+++ NuppelVideoRecorder.h 22 May 2005 13:44:00 -0000
@@ -278,6 +278,7 @@
int volume;
bool go7007;
+ int go7007keyframenumber;
};
#endif
More information about the mythtv-dev
mailing list