During playback(Roku2XD) of a single-rate HLS stream I create with FFmpeg, sync disruptions, or hiccups, can be observed at certain segment transitions. They occur with video using main or baseline profile, at various resolutions. These hiccups do not occur if the TS file is processed with Apple's File segmenter or HTTPSegmenter. These problems are not seen when playing the stream on iOS or Android(JellyBean). The hiccups are also not seen with a video-only stream.
The hiccup starts from few frames towards the end of one segment until few frames at the beginning of the next segment, so it is not after the transition to the new segment. It first skips a few video frames (around 30+) causing video to get ahead of audio, pauses at a video frame for audio to catchup before continuing smooth playback. For example, with segments 83 & 84, it skips directly from frame 25156 to 25166, 25166 to 25170, 25170 to 25177, 25177 to 25183 and 25183 to 25187. It then plays frames 25187 to 25204, pauses at 25204 for some time while audio catches up and continues smooth playback after that. 25173 is the last frame of segment 83 and the problem started at 25156 (half a second earlier).
I am restricting my report of an issue to a single stream, to make things simpler. I've also included frame-numbers burned into the video for better troubleshooting. The playback issues I've encountered are worse when multiple rates are available, using the same encoder/segmenter path. With multiple rates, I see that at some transitions, Roku going directly to the lowest rate stream.
I recorded what I see with a video camera, as words can only describe so much.
Demo of what it looks like:
http://realonemedia.s3.amazonaws.com/40bebfd938d1499db5cb228bd6c0c7e7/ef7b38211bcd4dad91716d05b2048b...The problematic stream, using FFmpeg's -ssegment:
http://realone-int2.s3.amazonaws.com/881700293bfb42b2ad89f2417c883e7f/909eb504b6ab426d934684635bea52...The same source stream, gone through HTTPSegmenter
http://realone-int2.s3.amazonaws.com/881700293bfb42b2ad89f2417c883e7f/909eb504b6ab426d934684635bea52...The video-only version of the stream, using FFmpeg's -ssegment:
http://realone-int2.s3.amazonaws.com/881700293bfb42b2ad89f2417c883e7f/909eb504b6ab426d934684635bea52...I encode/segment to HLS with FFmpeg using the following command parameters(In my case, the output came out as 960x540pp):
ffmpeg -i $inputFileNameFullPath -sn -pix_fmt yuv420p -c:v libx264 -b:v 1436k -maxrate 2154k -bufsize 2872k -threads 4 -preset faster -profile:v main -force_key_frames "expr:gte(t,n_forced*5)" -flags +cgop -c:a libvo_aacenc -b:a 64k -ac 2 -vsync vfr -f mpegts pipe:1 | ffmpeg -f mpegts -i pipe:0 -c copy -map 0 -f ssegment -segment_time 10 -segment_list $playlistName -segment_list_flags +live -segment_format mpegts -avoid_negative_ts 1 $segmentName
Here are some things I've tried, in an attempt to workaround or troubleshoot the issue:
1. Resampling audio from 44.1 to 48kHz
2. Changing frame-rate from 29.97 to 30.0fps with 48kHz audio
3. Setting adrift_threshold to 0.01
4. Using -f hls instead of -ssegment
5. Using FDK instead of VO AAC encoder
6. Writing TS file, then segmenting, instead of piping
An FFmpeg developer I've been in contact with suggested it might be a result of PTS interleaving not being perfect.