<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 14 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Tahoma;
        panose-1:2 11 6 4 3 5 4 4 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri","sans-serif";
        mso-fareast-language:EN-US;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
p.MsoAcetate, li.MsoAcetate, div.MsoAcetate
        {mso-style-priority:99;
        mso-style-link:"Balloon Text Char";
        margin:0cm;
        margin-bottom:.0001pt;
        font-size:8.0pt;
        font-family:"Tahoma","sans-serif";
        mso-fareast-language:EN-US;}
span.BalloonTextChar
        {mso-style-name:"Balloon Text Char";
        mso-style-priority:99;
        mso-style-link:"Balloon Text";
        font-family:"Tahoma","sans-serif";}
span.EmailStyle19
        {mso-style-type:personal-compose;
        font-family:"Calibri","sans-serif";
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;
        font-family:"Calibri","sans-serif";
        mso-fareast-language:EN-US;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-GB" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal">Good afternoon all,<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">As this is my first post, and I'm trying my hardest to keep it simple and keep
<o:p></o:p></p>
<p class="MsoNormal">to your standards - let me know if I get anything wrong, especially
<o:p></o:p></p>
<p class="MsoNormal">terminology!<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I've been troubleshooting a problem with our video playout application that
<o:p></o:p></p>
<p class="MsoNormal">uses avformat-52.dll from a scarily old drop of code taken out of svn a year
<o:p></o:p></p>
<p class="MsoNormal">ago. The problem is reproducible with avformat-53.dll from FFmpeg 0.8.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I'm posting here, rather than raising a bug report since we've done the donkey
<o:p></o:p></p>
<p class="MsoNormal">work; have got to the bottom of the problem and have a dirty fix. If a ticket
<o:p></o:p></p>
<p class="MsoNormal">needs raising in trac, I'll put one in once I've got some feedback from you
<o:p></o:p></p>
<p class="MsoNormal">all. Should this fix go into the mainstream ffmpeg distribution? If so then
<o:p></o:p></p>
<p class="MsoNormal">I can supply the patch and I should be able to make some test media available.<o:p></o:p></p>
<p class="MsoNormal">I'm sure there are "better" fixes for the issue.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I've an mxf file with I-frame only MPEG2 content, generated by another
<o:p></o:p></p>
<p class="MsoNormal">company's editing software. The same problem happens in a noticeable number of
<o:p></o:p></p>
<p class="MsoNormal">files, so it's not a one-off issue. There are legacy files building up with
<o:p></o:p></p>
<p class="MsoNormal">the same problem over time, so ideally, I want to allow our playout
<o:p></o:p></p>
<p class="MsoNormal">application to deal with these files. Playout of these files stalls at a
<o:p></o:p></p>
<p class="MsoNormal">specific point in the file. It's always an edit point that causes this, but
<o:p></o:p></p>
<p class="MsoNormal">not all edit points cause the issue.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">What happens at the edit point, is that we get an "invalid" bit of data. The
<o:p></o:p></p>
<p class="MsoNormal">frame in question has a sequence extension where "low delay" is not set (byte
<o:p></o:p></p>
<p class="MsoNormal">9, bit 7 according to http://dvd.sourceforge.net/dvdinfo/mpeghdrs.html#ext).
<o:p></o:p></p>
<p class="MsoNormal">According to arcane lore, the sequence extension should not vary like this.
<o:p></o:p></p>
<p class="MsoNormal">Cerify reports "In repeated sequence extensions, all data elements must have
<o:p></o:p></p>
<p class="MsoNormal">the same values as in the first sequence_extension()". But in these files, it
<o:p></o:p></p>
<p class="MsoNormal">does. And although we will obviously make the editing software manufacturer
<o:p></o:p></p>
<p class="MsoNormal">aware, there is still media out there in the wild that we need to play.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">The reason that the playout stalls is that our call to av_read_frame doesn't
<o:p></o:p></p>
<p class="MsoNormal">return promptly. Our app gets reset by some of our other software by
<o:p></o:p></p>
<p class="MsoNormal">virtue of the playout stopping unexpectedly before it ever returns. In fact,
<o:p></o:p></p>
<p class="MsoNormal">having got to the bottom of the problem, I think it would eventually return
<o:p></o:p></p>
<p class="MsoNormal">having parsed the entire video file, but I haven't had reason to test that.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">We have hit an "unexpected combination" of AVFMT_FLAG_GENPTS and the logic in
<o:p></o:p></p>
<p class="MsoNormal">mpegvideo_extract_headers, compute_pkt_fields and av_read_frame. We use<o:p></o:p></p>
<p class="MsoNormal">AVFMT_FLAG_GENPTS since we need it for other scenarios. av_read_frame is
<o:p></o:p></p>
<p class="MsoNormal">therefore trying to ensure it generates pts and dts for each packet. Until
<o:p></o:p></p>
<p class="MsoNormal">this point, compute_pkt_fields has been setting dts and pts for each frame to
<o:p></o:p></p>
<p class="MsoNormal">be the stream's current dts. Bog standard "low delay" I-frame playout.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">When the frame marked "not low delay" appears, the codec context field<o:p></o:p></p>
<p class="MsoNormal">"avctx->has_b_frames" is set to 1 in mpegvideo_extract_headers. In turn, this
<o:p></o:p></p>
<p class="MsoNormal">causes compute_pkt_fields to set the "presentation_delayed" flag, implying
<o:p></o:p></p>
<p class="MsoNormal">long GOP logic is being used. compute_pkt_fields only sets pkt->dts. pkt->pts
<o:p></o:p></p>
<p class="MsoNormal">will be set later, in av_read_frame when the next I- or P- frame is found.
<o:p></o:p></p>
<p class="MsoNormal">When av_read_frame is processing the frame, it invokes its own long GOP logic.
<o:p></o:p></p>
<p class="MsoNormal">It needs to find the next I- or P- frame, so it calls for the next packets to
<o:p></o:p></p>
<p class="MsoNormal">be decoded until it finds them. Unfortunately it never does. For all of the
<o:p></o:p></p>
<p class="MsoNormal">rest of the packets in the stream, "low delay" is set correctly, so
<o:p></o:p></p>
<p class="MsoNormal">compute_pkt_fields sets every subsequent I-frame to have dts and pts set to be
<o:p></o:p></p>
<p class="MsoNormal">the stream's current dts. The long GOP logic in av_read_frame (we are still
<o:p></o:p></p>
<p class="MsoNormal">processing the bad frame, remember) sees these as b-frames and will not use<o:p></o:p></p>
<p class="MsoNormal">them to provide the correct pts.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">We found it difficult to figure out a robust patch for this. Obviously, the
<o:p></o:p></p>
<p class="MsoNormal">file is at fault. However I want the code to keep running despite that. The
<o:p></o:p></p>
<p class="MsoNormal">cause of the problem in code seemed to me to be a couple of assumptions. I'm
<o:p></o:p></p>
<p class="MsoNormal">not sure that "not low delay" is exactly the same as "has b-frames", which is
<o:p></o:p></p>
<p class="MsoNormal">driving the logic in compute_pkt_fields. I really don't know the code, or the<o:p></o:p></p>
<p class="MsoNormal">MPEG standard well enough to know if there is a better test available to say<o:p></o:p></p>
<p class="MsoNormal">"use long GOP logic". Secondly, av_read_frame implies that "if a packet has
<o:p></o:p></p>
<p class="MsoNormal">pts == dts it is a b-frame". Of course, that's always true for long GOP. My
<o:p></o:p></p>
<p class="MsoNormal">preference is to make the test against a flag in the packet that says "this
<o:p></o:p></p>
<p class="MsoNormal">is a b-frame". Of course there is no such flag in the packet. The parser
<o:p></o:p></p>
<p class="MsoNormal">context has a flag for that transiently, which only applies to the last decoded
<o:p></o:p></p>
<p class="MsoNormal">packet. There may be many reasons why the packet is the wrong level to store
<o:p></o:p></p>
<p class="MsoNormal">that information anyway.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Eventually we came up with a patch that works within the constraints of the
<o:p></o:p></p>
<p class="MsoNormal">current code, as well as our limited understanding of it. Let me know if
<o:p></o:p></p>
<p class="MsoNormal">you're interested in fixing this in the main stream and I'll get back to you.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Best Regards,<o:p></o:p></p>
<p class="MsoNormal">Pete Gosden<o:p></o:p></p>
</div>
</body>
</html>