[FFmpeg-devel] Possible fix for trac ticket #7359

Nick Ryan nick.paul.ryan at gmail.com
Wed Oct 24 15:50:14 EEST 2018


This is my 2nd attempt with an improved fix.

With reference to:

https://trac.ffmpeg.org/ticket/7359

I believe another way this issue manifests itself is using ffplay and trying to seek forward 10 seconds with the right arrow key: playback freezes. 

I have dug into this and developed a solution  which seems to resolve the issue.

I have a local m3u8 file which was showing this problem and I can now programmatically seek to the correct point. I can also seek correctly via ffplay and ffmpeg. I have also tried the URL from the trak ticket and this now works as well. All current fate samples tests pass.

I submit the patch here for anyone that knows more about the codebase. I am happy to rework etc. as required. At the very least it might help anyone experiencing this problem in the meantime if they wish to run a patched ffmpeg version.

I have also now successfully reproduced and fixed the issue mentioned here: http://www.ffmpeg-archive.org/HLS-accurate-seeking-vs-MP4-td4685570.html

There are 2 items to this fix: 1. related to seek logic in HLS and 2. related to effect of HLS seeking on fMP4 files.

1. Change to logic in hls.c for seeking

After performing a rough seek in hls.c hls_read_seek() to the nearest segment, the logic for hls_read_packet() was to discard packets until a DTS after the accurate seek point is discovered. This was done even if AVSEEK_FLAG_ANY was not specified in the initial seek request. The patch changes this so that if AVSEEK_FLAG_ANY has not been specified, it will return the first keyframe discovered after the rough seek point. 

2. Change to logic in mov.c for reading packets after an HLS seek

Within hls.c when hls_read_seek() is called it resets the stream position as follows:

/* Reset the pos, to let the mpegts demuxer know we've seeked. */
pls->pb.pos = 0;

There is support for this in the mpegts handle_packets() code to check if the position has been reset and clear out any PES packets:

if (avio_tell(s->pb) != ts->last_pos) {
       int i;
       av_log(ts->stream, AV_LOG_TRACE, "Skipping after seek\n");
       /* seek detected, flush pes buffer */

In mov.c it now detects the pos has been reset in mov_read_packet(). It clears fragments and indexes and searches for the next root i.e. the next fragment via mov_switch_root().

Regards,

Nick





More information about the ffmpeg-devel mailing list