<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=iso-8859-1">
<META content="MSHTML 6.00.2900.2769" name=GENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=#ffffff>
<DIV><FONT face=Arial size=2>Hi Ross, hi all,</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>for a MPEG-4 video stream, generated with ffmpeg,
we found out that the timestamps were not generated always correcctly. The
timestamps are not increasing monoton. The video also showed flickering and
short breaks.</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>Without having fully understood the parsing of the
MPEG-4 stream, I found out that the problem disappeares when the variable
fPrevNewTotalTicks is reseted when a new time code is parsed from the file. (see
code below)</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>Perhaps somebody better understands the code and
can verify that the change makes sense. </FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>Best regards,</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>Bernhard</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial
size=2>------------------------------------------------------</FONT></DIV>
<DIV><FONT face="Courier New" size=2>MPEG4VideoStreamFramer.cpp</FONT></DIV>
<DIV><FONT face="Courier New" size=2> </FONT></DIV>
<DIV><FONT face="Courier New" size=2>...</FONT></DIV>
<DIV><FONT face="Courier New" size=2>unsigned
MPEG4VideoStreamParser::parseGroupOfVideoObjectPlane() {<BR>#ifdef
DEBUG<BR> fprintf(stderr, "parsing
GroupOfVideoObjectPlane\n");<BR>#endif<BR> // Note that we've already read
the GROUP_VOP_START_CODE<BR>
save4Bytes(GROUP_VOP_START_CODE);</FONT></DIV>
<DIV><FONT face="Courier New" size=2></FONT> </DIV>
<DIV><FONT face="Courier New" size=2> // Next, extract the (18-bit) time
code from the next 3 bytes:<BR> u_int8_t next3Bytes[3];<BR>
getBytes(next3Bytes, 3);<BR>
saveByte(next3Bytes[0]);saveByte(next3Bytes[1]);saveByte(next3Bytes[2]);<BR>
unsigned time_code<BR> =
(next3Bytes[0]<<10)|(next3Bytes[1]<<2)|(next3Bytes[2]>>6);<BR>
unsigned time_code_hours =
(time_code&0x0003E000)>>13;<BR> unsigned time_code_minutes
= (time_code&0x00001F80)>>7;<BR>#if defined(DEBUG) ||
defined(DEBUG_TIMESTAMPS)<BR> Boolean
marker_bit =
(time_code&0x00000040) != 0;<BR>#endif<BR> unsigned
time_code_seconds = (time_code&0x0000003F);<BR>#if defined(DEBUG) ||
defined(DEBUG_TIMESTAMPS)<BR> fprintf(stderr, "time_code: 0x%05x, hours
%d, minutes %d, marker_bit %d, seconds %d\n", time_code, time_code_hours,
time_code_minutes, marker_bit, time_code_seconds);<BR>#endif</FONT></DIV>
<DIV><FONT face="Courier New" size=2></FONT> </DIV>
<DIV><FONT face="Courier New" size=2> // Now, copy all bytes that we see,
up until we reach a VOP_START_CODE:<BR> u_int32_t next4Bytes =
get4Bytes();<BR> while (next4Bytes != VOP_START_CODE)
{<BR> saveToNextCode(next4Bytes);<BR> }</FONT></DIV>
<DIV><FONT face="Courier New" size=2></FONT> </DIV>
<DIV><FONT face="Courier New" size=2> // Compute this frame's presentation
time:<BR>
usingSource()->computePresentationTime(fTotalTicksSinceLastTimeCode);</FONT></DIV>
<DIV><FONT face="Courier New" size=2></FONT> </DIV>
<DIV><FONT face="Courier New" size=2> // Record the time code:<BR>
usingSource()->setTimeCode(time_code_hours,
time_code_minutes,<BR>
time_code_seconds, 0, 0);<BR> // Note: Because the GOV header
can appear anywhere (not just at a 1s point), we<BR> // don't
pass "fTotalTicksSinceLastTimeCode" as the "picturesSinceLastGOP"
parameter.<BR> fSecondsSinceLastTimeCode = 0;</FONT></DIV><FONT
face="Courier New" size=2>
<DIV><BR> fPrevNewTotalTicks = 0;
//>>>>>>>>>>>>> bf 051031, try to
eliminate some errors with wrong time stamps<BR></DIV>
<DIV> if (fixed_vop_rate) fTotalTicksSinceLastTimeCode = 0;</FONT></DIV>
<DIV><FONT face="Courier New" size=2></FONT> </DIV>
<DIV><FONT face="Courier New" size=2>
setParseState(PARSING_VIDEO_OBJECT_PLANE);</FONT></DIV>
<DIV><FONT face="Courier New" size=2></FONT> </DIV>
<DIV><FONT face="Courier New" size=2> return
curFrameSize();<BR>}</FONT></DIV>
<DIV><FONT face="Courier New" size=2>...</FONT></DIV></BODY></HTML>