diff --git a/sdk/android/api/org/webrtc/EglRenderer.java b/sdk/android/api/org/webrtc/EglRenderer.java index bef34f5a26..319ec7d292 100644 --- a/sdk/android/api/org/webrtc/EglRenderer.java +++ b/sdk/android/api/org/webrtc/EglRenderer.java @@ -125,6 +125,7 @@ public class EglRenderer implements VideoSink { @Nullable private EglBase eglBase; private final VideoFrameDrawer frameDrawer = new VideoFrameDrawer(); @Nullable private RendererCommon.GlDrawer drawer; + private boolean usePresentationTimeStamp; private final Matrix drawMatrix = new Matrix(); // Pending frame to render. Serves as a queue with size 1. Synchronized on |frameLock|. @@ -185,16 +186,19 @@ public class EglRenderer implements VideoSink { * Initialize this class, sharing resources with |sharedContext|. The custom |drawer| will be used * for drawing frames on the EGLSurface. This class is responsible for calling release() on * |drawer|. It is allowed to call init() to reinitialize the renderer after a previous - * init()/release() cycle. + * init()/release() cycle. If usePresentationTimeStamp is true, eglPresentationTimeANDROID will be + * set with the frame timestamps, which specifies desired presentation time and might be useful + * for e.g. syncing audio and video. */ public void init(@Nullable final EglBase.Context sharedContext, final int[] configAttributes, - RendererCommon.GlDrawer drawer) { + RendererCommon.GlDrawer drawer, boolean usePresentationTimeStamp) { synchronized (handlerLock) { if (renderThreadHandler != null) { throw new IllegalStateException(name + "Already initialized"); } logD("Initializing EglRenderer"); this.drawer = drawer; + this.usePresentationTimeStamp = usePresentationTimeStamp; final HandlerThread renderThread = new HandlerThread(name + "EglRenderer"); renderThread.start(); @@ -230,6 +234,16 @@ public class EglRenderer implements VideoSink { } } + /** + * Same as above with usePresentationTimeStamp set to false. + * + * @see #init(EglBase.Context, int[], RendererCommon.GlDrawer, boolean) + */ + public void init(@Nullable final EglBase.Context sharedContext, final int[] configAttributes, + RendererCommon.GlDrawer drawer) { + init(sharedContext, configAttributes, drawer, /* usePresentationTimeStamp= */ false); + } + public void createEglSurface(Surface surface) { createEglSurfaceInternal(surface); } @@ -617,7 +631,11 @@ public class EglRenderer implements VideoSink { eglBase.surfaceWidth(), eglBase.surfaceHeight()); final long swapBuffersStartTimeNs = System.nanoTime(); - eglBase.swapBuffers(); + if (usePresentationTimeStamp) { + eglBase.swapBuffers(frame.getTimestampNs()); + } else { + eglBase.swapBuffers(); + } final long currentTimeNs = System.nanoTime(); synchronized (statisticsLock) {