aboutsummaryrefslogtreecommitdiffstats
path: root/src/demos/com/jogamp/opengl
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2023-10-15 07:06:53 +0200
committerSven Gothel <[email protected]>2023-10-15 07:06:53 +0200
commitb1956113f5601b0cc6ac525d3918a0dfa8d240af (patch)
treeb7365f799d5bdad00f8b0f60632884175cff4ef1 /src/demos/com/jogamp/opengl
parent86210fde931400ff6f1b0a2da48ca031a957df8d (diff)
Bug 1472: Enhance GLMediaPlayer AV Sync: Utilize SCR aware audio PTS used as master-clock, enabling proper AV sync w/ untouched audio
We can finally utilize the added pass through audio PTS, see commits - GlueGen 52725b4c6525487f93407f529dc0a758b387a4fc - JOAL 12029f1ec1d8afa576e1ac61655f318cc37c1d16 This enables us to use the audio PTS as the master-clock and adjust video to the untouched audio. In case no audio is selected/playing or audio is muted, we sync merely on the system-clock (SCR) w/o audio. AV granularity is 22ms, however, since the ALAudioSink PTS may be a little late, it renders even a slightly better sync in case of too early audio (d_apts < 0). Since video frames are sync'ed to audio, the resync procedure may result in a hysteresis swinging into sync. This might be notable at start and when resumed audio or after seek. We leave the audio frames untouched to reduce processing burden and allow non-disrupted listening. Passed AV sync tests - Five-minute-sync-test.mp4 - Audio-Video-Sync-Test-Calibration-23.98fps-24fps.mp4 - Audio-Video-Sync-Test-2.mkv
Diffstat (limited to 'src/demos/com/jogamp/opengl')
-rw-r--r--src/demos/com/jogamp/opengl/demos/av/MovieSimple.java8
1 files changed, 6 insertions, 2 deletions
diff --git a/src/demos/com/jogamp/opengl/demos/av/MovieSimple.java b/src/demos/com/jogamp/opengl/demos/av/MovieSimple.java
index 504d97990..9bf984d40 100644
--- a/src/demos/com/jogamp/opengl/demos/av/MovieSimple.java
+++ b/src/demos/com/jogamp/opengl/demos/av/MovieSimple.java
@@ -34,6 +34,7 @@ import java.net.URI;
import java.net.URISyntaxException;
import com.jogamp.common.net.Uri;
+import com.jogamp.common.os.Clock;
import com.jogamp.common.util.InterruptSource;
import com.jogamp.graph.curve.Region;
import com.jogamp.graph.curve.opengl.GLRegion;
@@ -155,6 +156,7 @@ public class MovieSimple implements GLEventListener {
final float tfps = null != anim ? anim.getTotalFPS() : 0f;
final boolean hasVideo = GLMediaPlayer.STREAM_ID_NONE != mPlayer.getVID();
final float pts = ( hasVideo ? mPlayer.getVideoPTS() : mPlayer.getAudioPTS() ) / 1000f;
+ final float scr = ( Clock.currentMillis() - play_t0 ) / 1000f;
// Note: MODELVIEW is from [ 0 .. height ]
@@ -163,8 +165,8 @@ public class MovieSimple implements GLEventListener {
final float aspect = (float)mPlayer.getWidth() / (float)mPlayer.getHeight();
final String ptsPrec = null != regionFPS ? "3.1" : "3.0";
- final String text1 = String.format("%0"+ptsPrec+"f/%0"+ptsPrec+"f s, %s (%01.2fx, vol %01.2f), a %01.2f, fps %02.1f -> %02.1f / %02.1f, swap %d",
- pts, mPlayer.getDuration() / 1000f,
+ final String text1 = String.format("%0"+ptsPrec+"f/%0"+ptsPrec+"f/%0"+ptsPrec+"f s, %s (%01.2fx, vol %01.2f), a %01.2f, fps %02.1f -> %02.1f / %02.1f, swap %d",
+ scr, pts, mPlayer.getDuration() / 1000f,
mPlayer.getState().toString().toLowerCase(), mPlayer.getPlaySpeed(), mPlayer.getAudioVolume(),
aspect, mPlayer.getFramerate(), lfps, tfps, drawable.getGL().getSwapInterval());
final String text2 = String.format("audio: id %d, kbps %d, codec %s",
@@ -627,6 +629,7 @@ public class MovieSimple implements GLEventListener {
}
if( eventMask.isSet(GLMediaPlayer.EventMask.Bit.Play) ) {
window.getAnimator().resetFPSCounter();
+ ms.play_t0 = Clock.currentMillis();
}
boolean destroy = false;
@@ -668,6 +671,7 @@ public class MovieSimple implements GLEventListener {
}
};
public final static MyGLMediaEventListener myGLMediaEventListener = new MyGLMediaEventListener();
+ long play_t0 = 0;
static boolean loopEOS = false;
static boolean origSize;