[mythtv] Frame numbers in DVB (and perhaps HDTV)
Mike Wilcox
mike at trouble.org.uk
Sun Apr 11 06:33:07 EDT 2004
Hi,
I'm using DVB-T as my picture source, and have a couple of enduring
problems, which I have a hunch may be a little connected. I'm gradually
trying to debug things, and perhaps someone can help shed a bit more
light...
1st is that, after editting a recorded program, the frame-numbers in the
cutlist don't match up with where external programs see things. Myth's
count seems to be too high - perhaps 3-4 minutes worth in a 30 minute
program (but *not* regular).
The first hint is that the position map in the DB shows a fair number of
keyframe intervals of 13. My experience here in the UK is that the
interval is usually 12, but occassionally has I frames closer.
What appears to be happening is that the streaming/state parser in
dvbrecorder.cpp recognises some extra "picture start" markers, so
increments the framesWritten counter. I have altered the code, so that
the framesWritten counter only increments if the "picture start" marker
exists *and* the picture type (2 bytes later) indicates an I-frame,
P-frame or B-frame, and creates a warning otherwise.
Now, this works, in that the position map in the DB now seems to get the
right values.
I don't know *why* the parser is recognising frames incorrectly. Perhaps
my code will help someone with MPEG2 experience provide a better answer!
Debug code attached - *not* a patch proposal.
With this patch in place, I still find that the frame numbers in the
cutlist don't match the external program, but the file offsets (found by
looking up the frame number in the position map) *do* match. Still
working this out...
The 2nd problem is only with live TV, not recordings. I find that I
regularly get the video playing in a jerky manner. Audio sounds fine,
but the video plays in half-second long jerks, and usually with warnings
about prebuffering.
A workaround to this problem is to pause the live TV for a second or
two, then let it run again. Video will then run smoothly for quite a
while, but will eventually go jerky again. Pausing briefly gets it
working for a while...
Now, I note that as I pause live TV, the overlaid indication about how
far behind I am is gradually getting further back in time - and much
more than the amount I pause the live programme for. As this time
indication comes from a calculation of frame counters, I'm wondering if
this is related to the above - Perhaps one side is getting it's frame
counting wrong, and not providing enough (real) frames to the other for
decoding. No solution, but it's another area to investigate for the
known "stuttering" problem.
Cheers,
Mike
-------------- next part --------------
Index: libs/libmythtv/dvbrecorder.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/dvbrecorder.cpp,v
retrieving revision 1.30
diff -w -c -r1.30 dvbrecorder.cpp
*** libs/libmythtv/dvbrecorder.cpp 30 Mar 2004 06:06:53 -0000 1.30
--- libs/libmythtv/dvbrecorder.cpp 4 Apr 2004 15:43:53 -0000
***************
*** 642,647 ****
--- 642,652 ----
unsigned int state = 0xFFFFFFFF, v = 0;
int prvcount = -1;
+ // MPW
+ int findFrameTypeCount = 0;
+ int lastIframe = 0;
+ int diff;
+
while (bufptr < &buffer[pos] + datalen)
{
if (++prvcount < 3)
***************
*** 649,654 ****
--- 654,691 ----
else
v = *bufptr++;
+ // MPW
+ if (findFrameTypeCount > 0) {
+ if (findFrameTypeCount == 1) {
+ int type = ((v>>3)&0x07);
+ switch (type) {
+ case 1:
+ //WARNING(" I-Frame");
+ framesWritten++;
+
+ diff = framesWritten - lastIframe;
+ if (diff != 12) {
+ WARNING("Frame " << framesWritten << ": IFrame gap of " << diff);
+ }
+ lastIframe = framesWritten;
+
+ break;
+ case 2:
+ //WARNING(" P-Frame");
+ framesWritten++;
+ break;
+ case 3:
+ //WARNING(" B-Frame");
+ framesWritten++;
+ break;
+ default:
+ //WARNING(" v = " << v << ", frame type = " << type);
+ break;
+ }
+ }
+ findFrameTypeCount--;
+ }
+
if (state == 0x000001)
{
state = ((state << 8) | v) & 0xFFFFFF;
***************
*** 658,663 ****
--- 695,703 ----
if (state == SEQ_START)
wait_for_seqstart = false;
+ // MPW
+ // WARNING("state = " << state);
+
switch (state)
{
case GOP_START:
***************
*** 682,688 ****
break;
case PICTURE_START:
! framesWritten++;
break;
}
continue;
--- 722,730 ----
break;
case PICTURE_START:
! // MPW
! //framesWritten++;
! findFrameTypeCount = 2;
break;
}
continue;
***************
*** 690,695 ****
--- 732,743 ----
state = ((state << 8) | v) & 0xFFFFFF;
}
+ // MPW
+ if (findFrameTypeCount > 0) {
+ WARNING(" Finishing buffer with findFrameTypeCount > 0");
+ framesWritten++;
+ }
+
memcpy(prvpkt, &buffer[len-3], 3);
}
More information about the mythtv-dev
mailing list