<div dir="ltr"><div>Hello,</div><div> </div><div>few days ago I met a problem with av_seek_frame with AVSEEK_FLAG_BACKWARD. In case of transport stream and mpeg2 or avc and others it seeks exactly to a specified time stamp and not to a previous key frame, so the first decoded frame is past desired time stamp, of course if I am unlucky to seek not to a key frame which is a most frequent case. I've been googling and it seems that this is known problem for years. From the user stand point it looks that av_seek_frame ignores passed flag and uses AVSEEK_FLAG_ANY, however there's no clear feedback that it has happened. Is any progress, helper or workaroud on this issue till now (I work with ffmpeg-20130909-git-b4e1630)? </div>

<div>In meantime I have developed my own workaround which I want to share, maybe some find it usefull. Instead of typical seek and decode until required time stamp (a simplified pseudocode below):</div><div> </div><div>av_seek_frame( desired_time_stamp, AVSEEK_FLAG_BACKWARD)</div>
<div>do</div><div>{</div><div>  demux packet and decode frame</div><div>}</div>
<div>while( frame.time_stamp < desired_time_stamp)</div><div> </div><div>I use following approach:</div><div> </div><div>// Seek to desired time stamp </div><div><div>av_seek_frame( desired_time_stamp, AVSEEK_FLAG_BACKWARD)</div>
<div> </div><div>// try to decode some frame. If decoded frame time stamp is after seek point</div><div>// then rewind (seek) once again before desired time stamp.</div><div>int round = 0;</div><div>long long rewind_time = 1 second</div>
<div>while(true)</div><div>{</div><div> demux packet and decode frame</div><div> if(frame.time_stamp < desired_time_stamp)</div><div>   break</div><div><div>  ++round</div><div><div>  av_seek_frame( desired_time_stamp - rewind_time * round, AVSEEK_FLAG_BACKWARD)</div>
<div>  reset decoder</div></div></div><div>}</div><div> </div><div>// Now we have at least one frame before desired time stamp</div><div>// Decode forward up to desired time stamp.</div><div><div><div>while( frame.time_stamp < desired_time_stamp)</div>
{</div><div>  demux packet and decode frame</div><div>}</div><div> </div><div>It works pretty well and does not add overhead for non-mpeg demuxers, where av_seek_frame works as described in documentation. Of course there's a significant overhead caused by iterative backward seeking. In this pseudocode I choosed to rewind one second. The obvious rewind time is gop size, but I found gop_size as unreliable (e.g. some of my test streams have key frame distance equal to 96, however gop_size is 12). Also GOP size may vary within the same file. Now my approach is to track gop size during decoding the file since any fixed revind value is IMHO not good. Another useful trick is to set AVCodecContext::flags2 to CODEC_FLAG2_SHOW_ALL. It gives faster decoder output so the need for rewind can be detected quicker, however a special care must be taken to not to display corrupted frames.</div>
<div>Any comments/improvements are welcome.</div><div> </div><div>best regards</div><div> </div><div>Remigiusz</div><font color="#008000" face="Consolas"><div></div><font color="#008000" face="Consolas"><div></div><p> </p>
</font><p> </p></font><p> </p></div></div></div>