Click here to Skip to main content
15,867,141 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
Hi

I have an AVPlayer written in Delphi using the FFMPEG libraries. This basically implements a video player as per FFPLAY but under Delphi.

I want to add variable speed video playback to this player, which is easy on the video side as you simply change the period to delay between each frame and the video plays at the desired rate.

However, the audio then gets out of sync. Even though I am using the video clock, the standard audio sync to the video doesn't correctly match the video.

From looking at the code, the Delphi implementation seems to basically parallel the ffplay operation, using the ffmpeg library and SDL for the player. This has synchronisation between audio and video if you set the video clock as master, but it doesn't keep them in sync.

They sync again after a seek, but I would like to be able to change speed on the fly, so really want them to stay in sync.

I got a bit of an understanding of the operation by referring to this tutorial
ffmpeg tutorial[^]

But it doesn't provide any suggestions on variable speed playback.
As I already have the delphi source, I would ideally like to just add to the existing code rather than trying a whole new component.

What I have tried:

As I don't need audio when playing video at a different rate, I am thinking I just need to get the delphi code to simply discard audio when not playing at normal speed and keep the audio seek position at the video position for when the video resumes at normal speed.  However, I am not sure where to start looking to do this. I tried increasing the SAMPLE_CORRECTION_PERCENT_MAX from 10 to 50 and this did improve things a bit at double speed playback, but didn't work at all for 25% playback speed
Posted
Updated 1-Sep-21 19:50pm
Comments
[no name] 2-Sep-21 12:07pm    
The ratio of audio to video "file position" is how one would sync them.

1 solution

I managed to get this working for me by making a change in the stream reader thread for Audio when video is playing at anything other than normal speed.

I am not sure this is the correct place, but it seems to work well at both high and low speed playback.

Pascal
if (pkt^.stream_index = FPlayer.GetAudioStream) and pkt_in_play_range and (not FPlayer.DisableAudio)then
begin
    // BAZ
    if (FPlayer.FPlaybackRate > 0.0) and (FPlayer.FPlaybackRate <> 1.0) then
    begin
      if (FPlayer.FAudioStreamIndex >= 0) then
      begin
        FPlayer.FAudioQ.Flush;
        FPlayer.FAudioQ.Put(@FPlayer.FFlushPkt);
      end;
      av_packet_unref(pkt);
    end
    else
    begin
      FPlayer.FAudioQ.Put(pkt);
      FLastPktType:=1;
    end;
end
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900