From c200045aa661cf82474c2b3c1db0ac69db40452a Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Fri, 16 Aug 2013 20:18:36 +0200 Subject: GLMediaPlayer Multithreaded Decoding: GLMediaPlayer* (Part-4) - WIP - Use Platform.currentTimeMillis() for accurate timing! - GLMediaPlayer / GLMediaPlayerImpl - Add DEBUG_NATIVE property jogl.debug.GLMediaPlayer.Native for verbose impl. messages, i.e. ffmpeg/libav - Add 'synchronization' section in GLMediaPlayer API doc (WIP) - Use passive non-blocking video synchronization, i.e. repeat frames instead of 'sleep'. Thx to Xerxes's suggestion. - Add flushing of cached decoded frames, allowing to remove complicated 'videoSCR_reset_latch' - FramePusher (threaded decoding): - Always create a shared context! - Release context while pausing - Pre/post 'getNextTextureImpl()' actions only at makeCurrent/release. - newFrameAvailable(..) signal after decoded frame is enqueued - FFMPEGDynamicLibraryBundleInfo - Bind add. functions of libavcodec: + "av_init_packet", + "av_new_packet", + "av_destruct_packet", - Bind add. functions of libavformat: + "avformat_seek_file", + "av_read_play", + "av_read_pause", - DEBUG property := FFMPEGMediaPlayer.DEBUG || DynamicLibraryBundleInfo.DEBUG; - FFMPEGMediaPlayer - Use libavformat's 'av_read_play()' and 'av_read_pause()', which may get utilized for network streams, e.g. RTSP - getNextTextureImpl(..): - Fix retry loop - Use postNextTextureImpl/preNextTextureImpl if desired (PSM) - Native: - Use fixed my_av_q2i32(..) macro (again) - Use INVALID_PTS marker (synced w/ Java code) - DEBUG: Dump more detailed frame information - TODO: Consider passing frame_delay, especially for repeated frames! - Tests (MovieSimple, MovieCube): - Refine KeyEvents control for seek and speed. - TODO: - Proper audio clock calculation - difficult w/ OpenAL ! - Video / Audio sync: - seek ! - streams w/ very async A/V frames - Test Streams: - Five-minute-sync-test.mp4 - Audio-Video-Sync-Test-Calibration-23.98fps-24fps.mp4 - sound_in_sync_test.mp4 - big_buck_bunny_1080p_surround.avi --- .../classes/jogamp/opengl/openal/av/ALAudioSink.java | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'src/jogl/classes/jogamp/opengl/openal') diff --git a/src/jogl/classes/jogamp/opengl/openal/av/ALAudioSink.java b/src/jogl/classes/jogamp/opengl/openal/av/ALAudioSink.java index 5783c32f1..217ab2954 100644 --- a/src/jogl/classes/jogamp/opengl/openal/av/ALAudioSink.java +++ b/src/jogl/classes/jogamp/opengl/openal/av/ALAudioSink.java @@ -80,7 +80,7 @@ public class ALAudioSink implements AudioSink { private SyncedRingbuffer alBufferAvail = null; private SyncedRingbuffer alBufferPlaying = null; private volatile int alBufferBytesQueued = 0; - private volatile int ptsPlaying = 0; + private volatile int playingPTS = AudioFrame.INVALID_PTS; private volatile int enqueuedFrameCount; private int[] alSource = null; @@ -207,11 +207,11 @@ public class ALAudioSink implements AudioSink { return "ALAudioSink[init "+initialized+", playRequested "+playRequested+", device "+deviceSpecifier+", ctx "+toHexString(ctxHash)+", alSource "+alSrcName+ ", chosen "+chosenFormat+", alFormat "+toHexString(alFormat)+ ", playSpeed "+playSpeed+", buffers[total "+alBuffersLen+", avail "+alBufferAvail.size()+", "+ - "queued["+alBufferPlaying.size()+", apts "+ptsPlaying+", "+getQueuedTime() + " ms, " + alBufferBytesQueued+" bytes]"; + "queued["+alBufferPlaying.size()+", apts "+getPTS()+", "+getQueuedTime() + " ms, " + alBufferBytesQueued+" bytes]"; } public final String getPerfString() { final int alBuffersLen = null != alBuffers ? alBuffers.length : 0; - return "Play [buffer "+alBufferPlaying.size()+"/"+alBuffersLen+", apts "+ptsPlaying+", "+getQueuedTime() + " ms, " + alBufferBytesQueued+" bytes]"; + return "Play [buffer "+alBufferPlaying.size()+"/"+alBuffersLen+", apts "+getPTS()+", "+getQueuedTime() + " ms, " + alBufferBytesQueued+" bytes]"; } @Override @@ -289,9 +289,9 @@ public class ALAudioSink implements AudioSink { t.printStackTrace(); } } - alBufferAvail.clear(true); + alBufferAvail.clear(); alBufferAvail = null; - alBufferPlaying.clear(true); + alBufferPlaying.clear(); alBufferPlaying = null; alBufferBytesQueued = 0; alBuffers = null; @@ -434,7 +434,11 @@ public class ALAudioSink implements AudioSink { } final int dequeuedBufferCount = dequeueBuffer( false /* all */, wait ); final ActiveBuffer currentBuffer = alBufferPlaying.peek(); - ptsPlaying = null != currentBuffer ? currentBuffer.pts : audioFrame.pts; + if( null != currentBuffer ) { + playingPTS = currentBuffer.pts; + } else { + playingPTS = audioFrame.pts; + } if( DEBUG ) { System.err.println(getThreadName()+": ALAudioSink: Write "+audioFrame.pts+", "+getQueuedTimeImpl(audioFrame.dataSize)+" ms, dequeued "+dequeuedBufferCount+", wait "+wait+", "+getPerfString()); } @@ -652,5 +656,5 @@ public class ALAudioSink implements AudioSink { } @Override - public final int getPTS() { return ptsPlaying; } + public final int getPTS() { return playingPTS; } } -- cgit v1.2.3