diff options
author | Sven Gothel <[email protected]> | 2013-08-24 23:38:42 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2013-08-24 23:38:42 +0200 |
commit | 517371b2c200783890e2f6a173748cf65d3c8c91 (patch) | |
tree | ca4c43e48762c7f67c13e5fb5175476f4c5de57c /src | |
parent | d0e01cb5c0ec3e48b8a9b9b79a7795b214c6e3ea (diff) |
AudioSink.init(..) abstract 'frame count' -> duration [ms] allowing non-frame based AudioSink's to deal w/ desired queue sizes.
- Rename AudioSink.initSink(..) -> AudioSink.init(..)
- Move: "int initialFrameCount, int frameGrowAmount, int frameLimit" to
"int initialQueueSize, int queueGrowAmount, int queueLimit"
based on milliseconds instead of frame count.
- Passing hint 'float frameDuration' to calculate frame count for fame based audio sink, i.e. ALAudioSink.
- Adding sensible static final default values
- AudioDataFormat: Add convenient conversion routines (samples/bytes/frame-count)
- FFMPEGMediaPlayer: Retrieve audio frame size in samples per channel, pass it to AudioSink.init(..)
to properly calculate frame count/limits based on duration.
Diffstat (limited to 'src')
7 files changed, 131 insertions, 56 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/util/av/AudioSink.java b/src/jogl/classes/com/jogamp/opengl/util/av/AudioSink.java index cacf8c5a4..2b8da8af9 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/av/AudioSink.java +++ b/src/jogl/classes/com/jogamp/opengl/util/av/AudioSink.java @@ -36,6 +36,18 @@ import jogamp.opengl.Debug; public interface AudioSink { public static final boolean DEBUG = Debug.debug("AudioSink"); + /** Default frame duration in millisecond, i.e. 1 frame per {@value} ms. */ + public static final int DefaultFrameDuration = 32; + + /** Initial audio queue size in milliseconds. {@value} ms, i.e. 16 frames per 32 ms. See {@link #init(AudioDataFormat, float, int, int, int)}.*/ + public static final int DefaultInitialQueueSize = 16 * 32; // 512 ms + /** Audio queue grow size in milliseconds. {@value} ms, i.e. 16 frames per 32 ms. See {@link #init(AudioDataFormat, float, int, int, int)}.*/ + public static final int DefaultQueueGrowAmount = 16 * 32; // 512 ms + /** Audio queue limit w/ video in milliseconds. {@value} ms, i.e. 96 frames per 32 ms. See {@link #init(AudioDataFormat, float, int, int, int)}.*/ + public static final int DefaultQueueLimitWithVideo = 96 * 32; // 3072 ms + /** Audio queue limit w/o video in milliseconds. {@value} ms, i.e. 32 frames per 32 ms. See {@link #init(AudioDataFormat, float, int, int, int)}.*/ + public static final int DefaultQueueLimitAudioOnly = 32 * 32; // 1024 ms + /** Specifies the audio data type. Currently only PCM is supported. */ public static enum AudioDataType { PCM }; @@ -66,21 +78,65 @@ public interface AudioSink { public final boolean littleEndian; /** - * Returns the duration in milliseconds of the given byte count according - * to {@link #sampleSize}, {@link #channelCount} and {@link #sampleRate}. + * Returns the byte size of the given milliseconds + * according to {@link #sampleSize}, {@link #channelCount} and {@link #sampleRate}. */ - public final int getDuration(int byteCount) { + public final int getByteSize(int millisecs) { final int bytesPerSample = sampleSize >>> 3; // /8 - return byteCount / ( channelCount * bytesPerSample * ( sampleRate / 1000 ) ); + return millisecs * ( channelCount * bytesPerSample * ( sampleRate / 1000 ) ); } /** - * Returns the byte count of the given milliseconds according - * to {@link #sampleSize}, {@link #channelCount} and {@link #sampleRate}. + * Returns the duration in milliseconds of the given byte count + * according to {@link #sampleSize}, {@link #channelCount} and {@link #sampleRate}. */ - public final int getByteCount(int millisecs) { + public final int getBytesDuration(int byteCount) { final int bytesPerSample = sampleSize >>> 3; // /8 - return millisecs * ( channelCount * bytesPerSample * ( sampleRate / 1000 ) ); + return byteCount / ( channelCount * bytesPerSample * ( sampleRate / 1000 ) ); + } + + /** + * Returns the duration in milliseconds of the given and sample count per frame and channel + * according to the {@link #sampleRate}, i.e. + * <pre> + * ( 1000f * sampleCount ) / sampleRate + * </pre> + * @param sampleCount sample count per frame and channel + */ + public final float getSamplesDuration(int sampleCount) { + return ( 1000f * (float) sampleCount ) / (float)sampleRate; + } + + /** + * Returns the rounded frame count of the given milliseconds and frame duration. + * <pre> + * Math.max( 1, millisecs / frameDuration + 0.5f ) + * </pre> + * <p> + * Note: <code>frameDuration</code> can be derived by <i>sample count per frame and channel</i> + * via {@link #getSamplesDuration(int)}. + * </p> + * @param millisecs time in milliseconds + * @param frameDuration duration per frame in milliseconds. + */ + public final int getFrameCount(int millisecs, float frameDuration) { + return Math.max(1, (int) ( (float)millisecs / frameDuration + 0.5f )); + } + + /** + * Returns the byte size of given sample count + * according to the {@link #sampleSize}, i.e.: + * <pre> + * sampleCount * ( sampleSize / 8 ) + * </pre> + * <p> + * Note: To retrieve the byte size for all channels, you need to pre-multiply <code>sampleCount</code> + * with {@link #channelCount}. + * </p> + * @param sampleCount sample count + */ + public final int getSamplesByteSize(int sampleCount) { + return sampleCount * ( sampleSize >>> 3 ); } public String toString() { @@ -175,12 +231,16 @@ public interface AudioSink { * The {@link #DefaultFormat} <i>should be</i> supported by all implementations. * </p> * @param requestedFormat the requested {@link AudioDataFormat}. - * @param initialFrameCount initial number of frames to queue in this sink - * @param frameGrowAmount number of frames to grow queue if full - * @param frameLimit maximum number of frames - * @return if successful the chosen AudioDataFormat based on the <code>requestedFormat</code> and this sinks capabilities, otherwise <code>null</code>. + * @param frameDuration average or fixed frame duration in milliseconds + * helping a caching {@link AudioFrame} based implementation to determine the frame count in the queue. + * See {@link #DefaultFrameDuration}. + * @param initialQueueSize initial time in milliseconds to queue in this sink, see {@link #DefaultInitialQueueSize}. + * @param queueGrowAmount time in milliseconds to grow queue if full, see {@link #DefaultQueueGrowAmount}. + * @param queueLimit maximum time in milliseconds the queue can hold (and grow), see {@link #DefaultQueueLimitWithVideo} and {@link #DefaultQueueLimitAudioOnly}. + * @return if successful the chosen AudioDataFormat based on the <code>requestedFormat</code> and this sinks capabilities, otherwise <code>null</code>. */ - public AudioDataFormat initSink(AudioDataFormat requestedFormat, int initialFrameCount, int frameGrowAmount, int frameLimit); + public AudioDataFormat init(AudioDataFormat requestedFormat, float frameDuration, + int initialQueueSize, int queueGrowAmount, int queueLimit); /** * Returns true, if {@link #play()} has been requested <i>and</i> the sink is still playing, @@ -207,7 +267,7 @@ public interface AudioSink { /** * Flush all queued buffers, implies {@link #pause()}. * <p> - * {@link #initSink(AudioDataFormat, int, int, int)} must be called first. + * {@link #init(AudioDataFormat, float, int, int, int)} must be called first. * </p> * @see #play() * @see #pause() @@ -220,17 +280,17 @@ public interface AudioSink { /** * Returns the number of allocated buffers as requested by - * {@link #initSink(AudioDataFormat, int, int, int)}. + * {@link #init(AudioDataFormat, float, int, int, int)}. */ public int getFrameCount(); - /** @return the current enqueued frames count since {@link #initSink(AudioDataFormat, int, int, int)}. */ + /** @return the current enqueued frames count since {@link #init(AudioDataFormat, float, int, int, int)}. */ public int getEnqueuedFrameCount(); /** * Returns the current number of frames queued for playing. * <p> - * {@link #initSink(AudioDataFormat, int, int, int)} must be called first. + * {@link #init(AudioDataFormat, float, int, int, int)} must be called first. * </p> */ public int getQueuedFrameCount(); @@ -238,7 +298,7 @@ public interface AudioSink { /** * Returns the current number of bytes queued for playing. * <p> - * {@link #initSink(AudioDataFormat, int, int, int)} must be called first. + * {@link #init(AudioDataFormat, float, int, int, int)} must be called first. * </p> */ public int getQueuedByteCount(); @@ -246,7 +306,7 @@ public interface AudioSink { /** * Returns the current queued frame time in milliseconds for playing. * <p> - * {@link #initSink(AudioDataFormat, int, int, int)} must be called first. + * {@link #init(AudioDataFormat, float, int, int, int)} must be called first. * </p> */ public int getQueuedTime(); @@ -259,7 +319,7 @@ public interface AudioSink { /** * Returns the current number of frames in the sink available for writing. * <p> - * {@link #initSink(AudioDataFormat, int, int, int)} must be called first. + * {@link #init(AudioDataFormat, float, int, int, int)} must be called first. * </p> */ public int getFreeFrameCount(); @@ -270,7 +330,7 @@ public interface AudioSink { * The data must comply with the chosen {@link AudioDataFormat} as returned by {@link #initSink(AudioDataFormat)}. * </p> * <p> - * {@link #initSink(AudioDataFormat, int, int, int)} must be called first. + * {@link #init(AudioDataFormat, float, int, int, int)} must be called first. * </p> * @returns the enqueued internal {@link AudioFrame}, which may differ from the input <code>audioDataFrame</code>. * @deprecated User shall use {@link #enqueueData(int, ByteBuffer, int)}, which allows implementation @@ -284,7 +344,7 @@ public interface AudioSink { * The data must comply with the chosen {@link AudioDataFormat} as returned by {@link #initSink(AudioDataFormat)}. * </p> * <p> - * {@link #initSink(AudioDataFormat, int, int, int)} must be called first. + * {@link #init(AudioDataFormat, float, int, int, int)} must be called first. * </p> * @returns the enqueued internal {@link AudioFrame}. */ diff --git a/src/jogl/classes/jogamp/opengl/openal/av/ALAudioSink.java b/src/jogl/classes/jogamp/opengl/openal/av/ALAudioSink.java index 5f98c3ad2..f9ca0c028 100644 --- a/src/jogl/classes/jogamp/opengl/openal/av/ALAudioSink.java +++ b/src/jogl/classes/jogamp/opengl/openal/av/ALAudioSink.java @@ -213,7 +213,8 @@ 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 "+alFramesAvail.size()+", "+ - "queued["+alFramesPlaying.size()+", apts "+getPTS()+", "+getQueuedTime() + " ms, " + alBufferBytesQueued+" bytes]"; + "queued["+alFramesPlaying.size()+", apts "+getPTS()+", "+getQueuedTime() + " ms, " + alBufferBytesQueued+" bytes], "+ + "queue[g "+frameGrowAmount+", l "+frameLimit+"]"; } public final String getPerfString() { final int alBuffersLen = null != alBufferNames ? alBufferNames.length : 0; @@ -226,7 +227,7 @@ public class ALAudioSink implements AudioSink { } @Override - public final AudioDataFormat initSink(AudioDataFormat requestedFormat, int initialFrameCount, int frameGrowAmount, int frameLimit) { + public final AudioDataFormat init(AudioDataFormat requestedFormat, float frameDuration, int initialQueueSize, int queueGrowAmount, int queueLimit) { if( !staticAvailable ) { return null; } @@ -260,6 +261,10 @@ public class ALAudioSink implements AudioSink { // Allocate buffers destroyBuffers(); { + final float useFrameDuration = frameDuration > 1f ? frameDuration : AudioSink.DefaultFrameDuration; + final int initialFrameCount = requestedFormat.getFrameCount( + initialQueueSize > 0 ? initialQueueSize : AudioSink.DefaultInitialQueueSize, useFrameDuration); + // frameDuration, int initialQueueSize, int queueGrowAmount, int queueLimit) { alBufferNames = new int[initialFrameCount]; al.alGenBuffers(initialFrameCount, alBufferNames, 0); final int err = al.alGetError(); @@ -274,8 +279,10 @@ public class ALAudioSink implements AudioSink { alFramesAvail = new LFRingbuffer<ALAudioFrame>(alFrames); alFramesPlaying = new LFRingbuffer<ALAudioFrame>(ALAudioFrame[].class, initialFrameCount); - this.frameGrowAmount = frameGrowAmount; - this.frameLimit = frameLimit; + this.frameGrowAmount = requestedFormat.getFrameCount( + queueGrowAmount > 0 ? queueGrowAmount : AudioSink.DefaultQueueGrowAmount, useFrameDuration); + this.frameLimit = requestedFormat.getFrameCount( + queueLimit > 0 ? queueLimit : AudioSink.DefaultQueueLimitWithVideo, useFrameDuration); } } finally { unlockContext(); @@ -423,9 +430,9 @@ public class ALAudioSink implements AudioSink { if( wait && val[0] < releaseBufferLimes ) { i++; // clip wait at [2 .. 100] ms - final int avgBufferDura = chosenFormat.getDuration( alBufferBytesQueued / alFramesPlaying.size() ); + final int avgBufferDura = chosenFormat.getBytesDuration( alBufferBytesQueued / alFramesPlaying.size() ); final int sleep = Math.max(2, Math.min(100, releaseBufferLimes * avgBufferDura)); - if( DEBUG ) { + if( DEBUG || true ) { System.err.println(getThreadName()+": ALAudioSink: Dequeue.wait["+i+"]: avgBufferDura "+avgBufferDura+", releaseBufferLimes "+releaseBufferLimes+", sleep "+sleep+" ms, playImpl "+isPlayingImpl1()+", processed "+val[0]+", "+this); } unlockContext(); @@ -512,7 +519,7 @@ public class ALAudioSink implements AudioSink { throw new RuntimeException("ALError "+toHexString(alErr)+" while makeCurrent. "+this); } - final int duration = chosenFormat.getDuration(byteCount); + final int duration = chosenFormat.getBytesDuration(byteCount); final boolean dequeueDone; if( alFramesAvail.isEmpty() ) { // try to dequeue first @@ -738,7 +745,7 @@ public class ALAudioSink implements AudioSink { if( !initialized || null == chosenFormat ) { return 0; } - return chosenFormat.getDuration(alBufferBytesQueued); + return chosenFormat.getBytesDuration(alBufferBytesQueued); } @Override diff --git a/src/jogl/classes/jogamp/opengl/util/av/JavaSoundAudioSink.java b/src/jogl/classes/jogamp/opengl/util/av/JavaSoundAudioSink.java index dcf096f05..b46b64748 100644 --- a/src/jogl/classes/jogamp/opengl/util/av/JavaSoundAudioSink.java +++ b/src/jogl/classes/jogamp/opengl/util/av/JavaSoundAudioSink.java @@ -68,7 +68,7 @@ public class JavaSoundAudioSink implements AudioSink { } @Override - public AudioDataFormat initSink(AudioDataFormat requestedFormat, int initialFrameCount, int frameGrowAmount, int frameLimit) { + public AudioDataFormat init(AudioDataFormat requestedFormat, float frameDuration, int initialQueueSize, int queueGrowAmount, int queueLimit) { if( !staticAvailable ) { return null; } @@ -178,7 +178,7 @@ public class JavaSoundAudioSink implements AudioSink { @Override public AudioFrame enqueueData(int pts, ByteBuffer bytes, int byteCount) { - return enqueueData(new AudioDataFrame(pts, chosenFormat.getDuration(byteCount), bytes, byteCount)); + return enqueueData(new AudioDataFrame(pts, chosenFormat.getBytesDuration(byteCount), bytes, byteCount)); } @Override diff --git a/src/jogl/classes/jogamp/opengl/util/av/NullAudioSink.java b/src/jogl/classes/jogamp/opengl/util/av/NullAudioSink.java index af4b83bb6..067322819 100644 --- a/src/jogl/classes/jogamp/opengl/util/av/NullAudioSink.java +++ b/src/jogl/classes/jogamp/opengl/util/av/NullAudioSink.java @@ -33,7 +33,7 @@ public class NullAudioSink implements AudioSink { } @Override - public AudioDataFormat initSink(AudioDataFormat requestedFormat, int initialFrameCount, int frameGrowAmount, int frameLimit) { + public AudioDataFormat init(AudioDataFormat requestedFormat, float frameDuration, int initialQueueSize, int queueGrowAmount, int queueLimit) { return requestedFormat; } diff --git a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java index a800f2a31..e59a8849f 100644 --- a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java +++ b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java @@ -167,14 +167,10 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl { // Audio // - /** Initial audio frame count, ALAudioSink may grow buffer! */ - private int initialAudioFrameCount = AV_DEFAULT_AFRAMES; - private final int audioFrameGrowAmount = 8; - private final int audioFrameLimitWithVideo = 64; // 128; - private final int audioFrameLimitAudioOnly = 32; // 64; private SampleFormat aSampleFmt = null; private AudioSink.AudioDataFormat avChosenAudioFormat; private AudioSink.AudioDataFormat sinkChosenAudioFormat; + private int audioSamplesPerFrameAndChannel = 0; public FFMPEGMediaPlayer() { if(!available) { @@ -237,7 +233,7 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl { if(null == audioSink) { throw new GLException("AudioSink null"); } - final int audioFrameLimit; + final int audioQueueLimit; if( null != gl ) { final GLContextImpl ctx = (GLContextImpl)gl.getContext(); AccessController.doPrivileged(new PrivilegedAction<Object>() { @@ -250,12 +246,18 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl { setGLFuncs0(moviePtr, procAddrGLTexSubImage2D, procAddrGLGetError, procAddrGLFlush, procAddrGLFinish); return null; } } ); - audioFrameLimit = audioFrameLimitWithVideo; + audioQueueLimit = AudioSink.DefaultQueueLimitWithVideo; } else { - audioFrameLimit = audioFrameLimitAudioOnly; + audioQueueLimit = AudioSink.DefaultQueueLimitAudioOnly; } - - sinkChosenAudioFormat = audioSink.initSink(avChosenAudioFormat, initialAudioFrameCount, audioFrameGrowAmount, audioFrameLimit); + final float frameDuration; + if( audioSamplesPerFrameAndChannel > 0 ) { + frameDuration= avChosenAudioFormat.getSamplesDuration(audioSamplesPerFrameAndChannel); + } else { + frameDuration = AudioSink.DefaultFrameDuration; + } + + sinkChosenAudioFormat = audioSink.init(avChosenAudioFormat, frameDuration, AudioSink.DefaultInitialQueueSize, AudioSink.DefaultQueueGrowAmount, audioQueueLimit); if(DEBUG) { System.err.println("initGL: p3 avChosen "+avChosenAudioFormat+", chosen "+sinkChosenAudioFormat); } @@ -263,7 +265,11 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl { System.err.println("AudioSink "+audioSink.getClass().getName()+" does not support "+avChosenAudioFormat+", using Null"); audioSink.destroy(); audioSink = AudioSinkFactory.createNull(); - sinkChosenAudioFormat = audioSink.initSink(avChosenAudioFormat, initialAudioFrameCount, audioFrameGrowAmount, audioFrameLimit); + sinkChosenAudioFormat = audioSink.init(avChosenAudioFormat, 0, AudioSink.DefaultInitialQueueSize, AudioSink.DefaultQueueGrowAmount, audioQueueLimit); + } + if(DEBUG) { + System.err.println("initGL: p4 chosen "+sinkChosenAudioFormat); + System.err.println("initGL: "+audioSink); } if( null != gl ) { @@ -303,14 +309,16 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl { * @param tWd1 * @param tWd2 * @param audioFrameCount snooped audio-frame-count per video-frame, maybe 0 - * @param sampleFmt - * @param sampleRate - * @param channels + * @param audioSampleFmt + * @param audioSampleRate + * @param audioChannels + * @param audioSamplesPerFrameAndChannel in audio samples per frame and channel */ private void updateAttributes2(int pixFmt, int planes, int bitsPerPixel, int bytesPerPixelPerPlane, int lSz0, int lSz1, int lSz2, int tWd0, int tWd1, int tWd2, int tH, - int audioFrameCount, int sampleFmt, int sampleRate, int channels) { + int audioFrameCount, int audioSampleFmt, int audioSampleRate, + int audioChannels, int audioSamplesPerFrameAndChannel) { vPixelFmt = PixelFormat.valueOf(pixFmt); vPlanes = planes; vBitsPerPixel = bitsPerPixel; @@ -340,8 +348,7 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl { default: // FIXME: Add more formats ! throw new RuntimeException("Unsupported pixelformat: "+vPixelFmt); } - initialAudioFrameCount = audioFrameCount > 0 ? audioFrameCount : AV_DEFAULT_AFRAMES * 2; - aSampleFmt = SampleFormat.valueOf(sampleFmt); + aSampleFmt = SampleFormat.valueOf(audioSampleFmt); final int sampleSize; final boolean signed, fixedP; switch( aSampleFmt ) { @@ -378,10 +385,11 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl { default: // FIXME: Add more formats ! throw new RuntimeException("Unsupported sampleformat: "+aSampleFmt); } - avChosenAudioFormat = new AudioDataFormat(AudioDataType.PCM, sampleRate, sampleSize, channels, signed, fixedP, true /* littleEndian */); + avChosenAudioFormat = new AudioDataFormat(AudioDataType.PCM, audioSampleRate, sampleSize, audioChannels, signed, fixedP, true /* littleEndian */); + this.audioSamplesPerFrameAndChannel = audioSamplesPerFrameAndChannel; if(DEBUG) { - System.err.println("audio: fmt "+aSampleFmt+", "+avChosenAudioFormat+", aFrameCount "+audioFrameCount+" -> "+initialAudioFrameCount); + System.err.println("audio: fmt "+aSampleFmt+", "+avChosenAudioFormat+", aFrameSize/fc "+audioSamplesPerFrameAndChannel+", aFrameCount "+audioFrameCount); System.err.println("video: fmt "+vPixelFmt+", planes "+vPlanes+", bpp "+vBitsPerPixel+"/"+vBytesPerPixelPerPlane); for(int i=0; i<3; i++) { System.err.println("video: "+i+": "+vTexWidth[i]+"/"+vLinesize[i]); diff --git a/src/jogl/native/libav/ffmpeg_tool.h b/src/jogl/native/libav/ffmpeg_tool.h index 013cc0cf2..d1320ac5d 100644 --- a/src/jogl/native/libav/ffmpeg_tool.h +++ b/src/jogl/native/libav/ffmpeg_tool.h @@ -146,7 +146,7 @@ typedef struct { int32_t aFrameCurrent; int32_t aSampleRate; int32_t aChannels; - int32_t aFrameSize; + int32_t aFrameSize; // in samples per channel! enum AVSampleFormat aSampleFmt; // native decoder fmt int32_t aPTS; // msec - overall last audio PTS PTSStats aPTSStats; diff --git a/src/jogl/native/libav/jogamp_opengl_util_av_impl_FFMPEGMediaPlayer.c b/src/jogl/native/libav/jogamp_opengl_util_av_impl_FFMPEGMediaPlayer.c index 63164e547..6bbc33863 100644 --- a/src/jogl/native/libav/jogamp_opengl_util_av_impl_FFMPEGMediaPlayer.c +++ b/src/jogl/native/libav/jogamp_opengl_util_av_impl_FFMPEGMediaPlayer.c @@ -239,7 +239,7 @@ static void _updateJavaAttributes(JNIEnv *env, jobject instance, FFMPEGToolBasic pAV->vBitsPerPixel, pAV->vBytesPerPixelPerPlane, pAV->vLinesize[0], pAV->vLinesize[1], pAV->vLinesize[2], pAV->vTexWidth[0], pAV->vTexWidth[1], pAV->vTexWidth[2], h, - pAV->aFramesPerVideoFrame, pAV->aSampleFmt, pAV->aSampleRate, pAV->aChannels); + pAV->aFramesPerVideoFrame, pAV->aSampleFmt, pAV->aSampleRate, pAV->aChannels, pAV->aFrameSize); (*env)->CallVoidMethod(env, instance, jni_mid_updateAttributes1, pAV->vid, pAV->aid, w, h, @@ -392,7 +392,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_opengl_util_av_impl_FFMPEGMediaPlayer_ini jni_mid_pushSound = (*env)->GetMethodID(env, ffmpegMediaPlayerClazz, "pushSound", "(Ljava/nio/ByteBuffer;II)V"); jni_mid_updateAttributes1 = (*env)->GetMethodID(env, ffmpegMediaPlayerClazz, "updateAttributes", "(IIIIIIIFIIILjava/lang/String;Ljava/lang/String;)V"); - jni_mid_updateAttributes2 = (*env)->GetMethodID(env, ffmpegMediaPlayerClazz, "updateAttributes2", "(IIIIIIIIIIIIIII)V"); + jni_mid_updateAttributes2 = (*env)->GetMethodID(env, ffmpegMediaPlayerClazz, "updateAttributes2", "(IIIIIIIIIIIIIIII)V"); if(jni_mid_pushSound == NULL || jni_mid_updateAttributes1 == NULL || @@ -613,7 +613,7 @@ JNIEXPORT void JNICALL Java_jogamp_opengl_util_av_impl_FFMPEGMediaPlayer_setStre pAV->aSampleRate = pAV->pACodecCtx->sample_rate; pAV->aChannels = pAV->pACodecCtx->channels; - pAV->aFrameSize = pAV->pACodecCtx->frame_size; // in samples! + pAV->aFrameSize = pAV->pACodecCtx->frame_size; // in samples per channel! pAV->aSampleFmt = pAV->pACodecCtx->sample_fmt; pAV->frames_audio = pAV->pAStream->nb_frames; if( pAV->verbose ) { |