diff options
author | Sven Gothel <[email protected]> | 2014-02-16 06:12:45 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2014-02-16 06:12:45 +0100 |
commit | e685f79ec7071e266a1bd3d3ce3e742397b5372e (patch) | |
tree | 7328960c34c3083e91ec47793993c686359e0015 /src/jogl/native/libav | |
parent | a6acce1be19060a6a4801582f0534e0d6887467a (diff) |
Bug 927: Fix minor MT issues w/ libav/ffmpeg
Issue:
[NULL @ 0x35bde60] insufficient thread locking around avcodec_open/close()
Decorating said libav functions w/ mutex lock/release.
Abstract impl. to either use pthread or JNI Monitor,
but using the latter to reduce dependencies (ming64 windows).
FFMPEGNatives is now an abstract class containing the
'static final Object mutex_avcodec_openclose'
Diffstat (limited to 'src/jogl/native/libav')
-rw-r--r-- | src/jogl/native/libav/ffmpeg_impl_template.c | 79 | ||||
-rw-r--r-- | src/jogl/native/libav/ffmpeg_tool.h | 15 |
2 files changed, 74 insertions, 20 deletions
diff --git a/src/jogl/native/libav/ffmpeg_impl_template.c b/src/jogl/native/libav/ffmpeg_impl_template.c index e86b2a542..274eb37a5 100644 --- a/src/jogl/native/libav/ffmpeg_impl_template.c +++ b/src/jogl/native/libav/ffmpeg_impl_template.c @@ -344,6 +344,14 @@ static void _setIsGLOriented(JNIEnv *env, FFMPEGToolBasicAV_t* pAV) { } } +#ifdef USE_PTHREAD_LOCKING + #define MY_MUTEX_LOCK(e,s) pthread_mutex_lock(&(s)) + #define MY_MUTEX_UNLOCK(e,s) pthread_mutex_unlock(&(s)) +#else + #define MY_MUTEX_LOCK(e,s) (*e)->MonitorEnter(e, s) + #define MY_MUTEX_UNLOCK(e,s) (*e)->MonitorExit(e, s) +#endif + static void freeInstance(JNIEnv *env, FFMPEGToolBasicAV_t* pAV) { int i; if(NULL != pAV) { @@ -361,19 +369,23 @@ static void freeInstance(JNIEnv *env, FFMPEGToolBasicAV_t* pAV) { pAV->aResampleBuffer = NULL; } - // Close the V codec - if(NULL != pAV->pVCodecCtx) { - sp_avcodec_close(pAV->pVCodecCtx); - pAV->pVCodecCtx = NULL; - } - pAV->pVCodec=NULL; + MY_MUTEX_LOCK(env, pAV->mutex_avcodec_openclose); + { + // Close the V codec + if(NULL != pAV->pVCodecCtx) { + sp_avcodec_close(pAV->pVCodecCtx); + pAV->pVCodecCtx = NULL; + } + pAV->pVCodec=NULL; - // Close the A codec - if(NULL != pAV->pACodecCtx) { - sp_avcodec_close(pAV->pACodecCtx); - pAV->pACodecCtx = NULL; + // Close the A codec + if(NULL != pAV->pACodecCtx) { + sp_avcodec_close(pAV->pACodecCtx); + pAV->pACodecCtx = NULL; + } + pAV->pACodec=NULL; } - pAV->pACodec=NULL; + MY_MUTEX_UNLOCK(env, pAV->mutex_avcodec_openclose); // Close the frames if(NULL != pAV->pVFrame) { @@ -421,6 +433,14 @@ static void freeInstance(JNIEnv *env, FFMPEGToolBasicAV_t* pAV) { (*env)->DeleteGlobalRef(env, pAV->ffmpegMediaPlayer); pAV->ffmpegMediaPlayer = NULL; } + + #ifdef USE_PTHREAD_LOCKING + pthread_mutex_unlock(&pAV->mutex_avcodec_openclose); + pthread_mutex_destroy(&pAV->mutex_avcodec_openclose); + #else + (*env)->DeleteGlobalRef(env, pAV->mutex_avcodec_openclose); + #endif + free(pAV); } } @@ -488,8 +508,11 @@ JNIEXPORT jint JNICALL FF_FUNC(getSwResampleMajorVersionCC0) } JNIEXPORT jlong JNICALL FF_FUNC(createInstance0) - (JNIEnv *env, jobject instance, jobject ffmpegMediaPlayer, jboolean verbose) + (JNIEnv *env, jobject instance, jobject mutex_avcodec_openclose, jobject ffmpegMediaPlayer, jboolean verbose) { + #ifdef USE_PTHREAD_LOCKING + pthread_mutexattr_t renderLockAttr; + #endif FFMPEGToolBasicAV_t * pAV = calloc(1, sizeof(FFMPEGToolBasicAV_t)); if(NULL==pAV) { JoglCommon_throwNewRuntimeException(env, "Couldn't alloc instance"); @@ -524,6 +547,14 @@ JNIEXPORT jlong JNICALL FF_FUNC(createInstance0) pAV->vid=AV_STREAM_ID_AUTO; pAV->aid=AV_STREAM_ID_AUTO; + #ifdef USE_PTHREAD_LOCKING + pthread_mutexattr_init(&renderLockAttr); + pthread_mutexattr_settype(&renderLockAttr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&pAV->mutex_avcodec_openclose, &renderLockAttr); // recursive + #else + pAV->mutex_avcodec_openclose = (*env)->NewGlobalRef(env, mutex_avcodec_openclose); + #endif + if(pAV->verbose) { fprintf(stderr, "Info: Use avresample %d, swresample %d, device %d, refCount %d\n", AV_HAS_API_AVRESAMPLE(pAV), AV_HAS_API_SWRESAMPLE(pAV), HAS_FUNC(sp_avdevice_register_all), pAV->useRefCountedFrames); @@ -824,10 +855,14 @@ JNIEXPORT void JNICALL FF_FUNC(setStream0) } // Open codec - #if LIBAVCODEC_VERSION_MAJOR >= 55 - pAV->pACodecCtx->refcounted_frames = pAV->useRefCountedFrames; - #endif - res = sp_avcodec_open2(pAV->pACodecCtx, pAV->pACodec, NULL); + MY_MUTEX_LOCK(env, pAV->mutex_avcodec_openclose); + { + #if LIBAVCODEC_VERSION_MAJOR >= 55 + pAV->pACodecCtx->refcounted_frames = pAV->useRefCountedFrames; + #endif + res = sp_avcodec_open2(pAV->pACodecCtx, pAV->pACodec, NULL); + } + MY_MUTEX_UNLOCK(env, pAV->mutex_avcodec_openclose); if(res<0) { JoglCommon_throwNewRuntimeException(env, "Couldn't open audio codec %d, %s", pAV->pACodecCtx->codec_id, pAV->acodec); return; @@ -982,10 +1017,14 @@ JNIEXPORT void JNICALL FF_FUNC(setStream0) } // Open codec - #if LIBAVCODEC_VERSION_MAJOR >= 55 - pAV->pVCodecCtx->refcounted_frames = pAV->useRefCountedFrames; - #endif - res = sp_avcodec_open2(pAV->pVCodecCtx, pAV->pVCodec, NULL); + MY_MUTEX_LOCK(env, pAV->mutex_avcodec_openclose); + { + #if LIBAVCODEC_VERSION_MAJOR >= 55 + pAV->pVCodecCtx->refcounted_frames = pAV->useRefCountedFrames; + #endif + res = sp_avcodec_open2(pAV->pVCodecCtx, pAV->pVCodec, NULL); + } + MY_MUTEX_UNLOCK(env, pAV->mutex_avcodec_openclose); if(res<0) { JoglCommon_throwNewRuntimeException(env, "Couldn't open video codec %d, %s", pAV->pVCodecCtx->codec_id, pAV->vcodec); return; diff --git a/src/jogl/native/libav/ffmpeg_tool.h b/src/jogl/native/libav/ffmpeg_tool.h index 97e60afce..66c3519e6 100644 --- a/src/jogl/native/libav/ffmpeg_tool.h +++ b/src/jogl/native/libav/ffmpeg_tool.h @@ -64,6 +64,15 @@ typedef struct SwrContext SwrContext; #include <stdio.h> #include <stdlib.h> +// We use JNI Monitor Locking, since this removes the need +// to statically link-in pthreads on window .. +// #define USE_PTHREAD_LOCKING 1 +// +#ifdef USE_PTHREAD_LOCKING + #include <pthread.h> + #error PTHREAD path not tested yet +#endif + #include <GL/gl.h> typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); @@ -148,6 +157,12 @@ typedef struct { PFNGLFLUSH procAddrGLFlush; PFNGLFINISH procAddrGLFinish; + #ifdef USE_PTHREAD_LOCKING + pthread_mutex_t mutex_avcodec_openclose; + #else + jobject mutex_avcodec_openclose; + #endif + AVFormatContext* pFormatCtx; int32_t vid; AVStream* pVStream; |