diff options
author | Sven Göthel <[email protected]> | 2024-01-28 22:05:18 +0100 |
---|---|---|
committer | Sven Göthel <[email protected]> | 2024-01-28 22:05:18 +0100 |
commit | a19f810c9618e2fa6829f1c157d2e1a88ca178de (patch) | |
tree | 50730d855a37f287330b8aecbdeefbde849cf128 /src/jogl/native | |
parent | 3e95c1994d363bc137ffcf548fd3751ac500ac7b (diff) |
FFMPEGPlayer: Prep for bitmap'ed subtitles: Use glEnable()/glBindTexture() func-ptr in native; readNextPacket0() passes video+subtitle texTarget and texID
For bitmap subtitles we need to push the bitmap into its own texture.
Hence readNextPacket0() must switch to used texture using glEnable() on !core and glBindTexture().
Diffstat (limited to 'src/jogl/native')
-rw-r--r-- | src/jogl/native/libav/ffmpeg_impl_template.c | 149 | ||||
-rw-r--r-- | src/jogl/native/libav/ffmpeg_static.c | 3 | ||||
-rw-r--r-- | src/jogl/native/libav/ffmpeg_static.h | 1 | ||||
-rw-r--r-- | src/jogl/native/libav/ffmpeg_tool.h | 5 |
4 files changed, 106 insertions, 52 deletions
diff --git a/src/jogl/native/libav/ffmpeg_impl_template.c b/src/jogl/native/libav/ffmpeg_impl_template.c index 5261c8443..61aa798a0 100644 --- a/src/jogl/native/libav/ffmpeg_impl_template.c +++ b/src/jogl/native/libav/ffmpeg_impl_template.c @@ -1390,13 +1390,16 @@ JNIEXPORT void JNICALL FF_FUNC(setStream0) } JNIEXPORT void JNICALL FF_FUNC(setGLFuncs0) - (JNIEnv *env, jobject instance, jlong ptr, jlong jProcAddrGLTexSubImage2D, jlong jProcAddrGLGetError, jlong jProcAddrGLFlush, jlong jProcAddrGLFinish) + (JNIEnv *env, jobject instance, jlong ptr, jlong jProcAddrGLTexSubImage2D, jlong jProcAddrGLGetError, jlong jProcAddrGLFlush, jlong jProcAddrGLFinish, + jlong jProcAddrGLEnable, jlong jProcAddrGLBindTexture) { FFMPEGToolBasicAV_t *pAV = (FFMPEGToolBasicAV_t *)((void *)((intptr_t)ptr)); pAV->procAddrGLTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC) (intptr_t)jProcAddrGLTexSubImage2D; pAV->procAddrGLGetError = (PFNGLGETERRORPROC) (intptr_t)jProcAddrGLGetError; pAV->procAddrGLFlush = (PFNGLFLUSH) (intptr_t)jProcAddrGLFlush; pAV->procAddrGLFinish = (PFNGLFINISH) (intptr_t)jProcAddrGLFinish; + pAV->procAddrGLEnable = (PFNGLENABLE) (intptr_t)jProcAddrGLEnable; + pAV->procAddrGLBindTexture = (PFNGLBINDTEXTURE) (intptr_t)jProcAddrGLBindTexture; } #if 0 @@ -1408,7 +1411,8 @@ JNIEXPORT void JNICALL FF_FUNC(setGLFuncs0) #endif JNIEXPORT jint JNICALL FF_FUNC(readNextPacket0) - (JNIEnv *env, jobject instance, jlong ptr, jint texTarget, jint texFmt, jint texType) + (JNIEnv *env, jobject instance, jlong ptr, jint vTexTarget, jint vTexID, jint vTexFmt, jint vTexType, + jint sTexTarget, jint sTexID) { FFMPEGToolBasicAV_t *pAV = (FFMPEGToolBasicAV_t *)((void *)((intptr_t)ptr)); if( 0 == pAV->ready ) { @@ -1723,58 +1727,65 @@ JNIEXPORT jint JNICALL FF_FUNC(readNextPacket0) _setIsGLOriented(env, pAV); } - // 1st plane or complete packed frame - // FIXME: Libav Binary compatibility! JAU01 - DBG_TEXSUBIMG2D_a('Y',pAV,1,1,1,0); - pAV->procAddrGLTexSubImage2D(texTarget, 0, - 0, 0, - pAV->vTexWidth[0], pAV->pVCodecCtx->height, - texFmt, texType, pAV->pVFrame->data[0] + p_offset[0]); - DBG_TEXSUBIMG2D_b(pAV); - - if( pAV->vPixFmt == AV_PIX_FMT_YUV420P || pAV->vPixFmt == AV_PIX_FMT_YUVJ420P ) { - // U plane - // FIXME: Libav Binary compatibility! JAU01 - DBG_TEXSUBIMG2D_a('U',pAV,1,1,2,1); - pAV->procAddrGLTexSubImage2D(texTarget, 0, - pAV->pVCodecCtx->width, 0, - pAV->vTexWidth[1], pAV->pVCodecCtx->height/2, - texFmt, texType, pAV->pVFrame->data[1] + p_offset[1]); - DBG_TEXSUBIMG2D_b(pAV); - // V plane - // FIXME: Libav Binary compatibility! JAU01 - DBG_TEXSUBIMG2D_a('V',pAV,1,1,2,2); - pAV->procAddrGLTexSubImage2D(texTarget, 0, - pAV->pVCodecCtx->width, pAV->pVCodecCtx->height/2, - pAV->vTexWidth[2], pAV->pVCodecCtx->height/2, - texFmt, texType, pAV->pVFrame->data[2] + p_offset[2]); - DBG_TEXSUBIMG2D_b(pAV); - } else if( pAV->vPixFmt == AV_PIX_FMT_YUV422P || pAV->vPixFmt == AV_PIX_FMT_YUVJ422P ) { - // U plane - // FIXME: Libav Binary compatibility! JAU01 - DBG_TEXSUBIMG2D_a('U',pAV,1,1,1,1); - pAV->procAddrGLTexSubImage2D(texTarget, 0, - pAV->pVCodecCtx->width, 0, - pAV->vTexWidth[1], pAV->pVCodecCtx->height, - texFmt, texType, pAV->pVFrame->data[1] + p_offset[1]); - DBG_TEXSUBIMG2D_b(pAV); - // V plane + if( 0 != vTexID ) { + if( NULL != pAV->procAddrGLEnable ) { + pAV->procAddrGLEnable(vTexTarget); + } + pAV->procAddrGLBindTexture(vTexTarget, vTexID); + + // 1st plane or complete packed frame // FIXME: Libav Binary compatibility! JAU01 - DBG_TEXSUBIMG2D_a('V',pAV,3,2,1,1); - pAV->procAddrGLTexSubImage2D(texTarget, 0, - pAV->pVCodecCtx->width+pAV->pVCodecCtx->width/2, 0, - pAV->vTexWidth[2], pAV->pVCodecCtx->height, - texFmt, texType, pAV->pVFrame->data[2] + p_offset[2]); + DBG_TEXSUBIMG2D_a('Y',pAV,1,1,1,0); + pAV->procAddrGLTexSubImage2D(vTexTarget, 0, + 0, 0, + pAV->vTexWidth[0], pAV->pVCodecCtx->height, + vTexFmt, vTexType, pAV->pVFrame->data[0] + p_offset[0]); DBG_TEXSUBIMG2D_b(pAV); - } // FIXME: Add more planar formats ! - // We might want a sync here, ensuring the texture data is uploaded? - // - // No, glTexSubImage2D() shall block until new pixel data are taken, - // i.e. shall be a a synchronous client command - // - // pAV->procAddrGLFinish(); // No sync required and too expensive for multiple player - pAV->procAddrGLFlush(); // No sync required, but be nice + if( pAV->vPixFmt == AV_PIX_FMT_YUV420P || pAV->vPixFmt == AV_PIX_FMT_YUVJ420P ) { + // U plane + // FIXME: Libav Binary compatibility! JAU01 + DBG_TEXSUBIMG2D_a('U',pAV,1,1,2,1); + pAV->procAddrGLTexSubImage2D(vTexTarget, 0, + pAV->pVCodecCtx->width, 0, + pAV->vTexWidth[1], pAV->pVCodecCtx->height/2, + vTexFmt, vTexType, pAV->pVFrame->data[1] + p_offset[1]); + DBG_TEXSUBIMG2D_b(pAV); + // V plane + // FIXME: Libav Binary compatibility! JAU01 + DBG_TEXSUBIMG2D_a('V',pAV,1,1,2,2); + pAV->procAddrGLTexSubImage2D(vTexTarget, 0, + pAV->pVCodecCtx->width, pAV->pVCodecCtx->height/2, + pAV->vTexWidth[2], pAV->pVCodecCtx->height/2, + vTexFmt, vTexType, pAV->pVFrame->data[2] + p_offset[2]); + DBG_TEXSUBIMG2D_b(pAV); + } else if( pAV->vPixFmt == AV_PIX_FMT_YUV422P || pAV->vPixFmt == AV_PIX_FMT_YUVJ422P ) { + // U plane + // FIXME: Libav Binary compatibility! JAU01 + DBG_TEXSUBIMG2D_a('U',pAV,1,1,1,1); + pAV->procAddrGLTexSubImage2D(vTexTarget, 0, + pAV->pVCodecCtx->width, 0, + pAV->vTexWidth[1], pAV->pVCodecCtx->height, + vTexFmt, vTexType, pAV->pVFrame->data[1] + p_offset[1]); + DBG_TEXSUBIMG2D_b(pAV); + // V plane + // FIXME: Libav Binary compatibility! JAU01 + DBG_TEXSUBIMG2D_a('V',pAV,3,2,1,1); + pAV->procAddrGLTexSubImage2D(vTexTarget, 0, + pAV->pVCodecCtx->width+pAV->pVCodecCtx->width/2, 0, + pAV->vTexWidth[2], pAV->pVCodecCtx->height, + vTexFmt, vTexType, pAV->pVFrame->data[2] + p_offset[2]); + DBG_TEXSUBIMG2D_b(pAV); + } // FIXME: Add more planar formats ! + + // We might want a sync here, ensuring the texture data is uploaded? + // + // No, glTexSubImage2D() shall block until new pixel data are taken, + // i.e. shall be a a synchronous client command + // + // pAV->procAddrGLFinish(); // No sync required and too expensive for multiple player + pAV->procAddrGLFlush(); // No sync required, but be nice + } sp_av_frame_unref(pAV->pVFrame); } // draining frames loop @@ -1822,9 +1833,43 @@ JNIEXPORT jint JNICALL FF_FUNC(readNextPacket0) (*env)->CallVoidMethod(env, pAV->ffmpegMediaPlayer, ffmpeg_jni_mid_pushSubtitleASS, (*env)->NewStringUTF(env, r->ass), sPTS, sStart, sEnd); JoglCommon_ExceptionCheck1_throwNewRuntimeException(env, "FFmpeg: Exception occured at pushSubtitleASS(..)"); } else { + /** + * + * - AV_PIX_FMT_PAL8 8 bits with AV_PIX_FMT_RGB32 palette + * + * - SUBTITLE_BITMAP images are special in the sense that they + * are like PAL8 images. first pointer to data, second to + * palette. This makes the size calculation match this. + * size_t buf_size = src_rect->type == SUBTITLE_BITMAP && j == 1 ? AVPALETTE_SIZE : src_rect->h * src_rect->linesize[j]; + * - linesize[0] > 0 + * - linesize[1] == 0 -> AVPALETTE_SIZE + */ if( pAV->verbose ) { - fprintf(stderr, "S[f %d, i %d]: null\n", (int)r->type, i); + int hasText = NULL != r->text; + int hasASS = NULL != r->ass; + fprintf(stderr, "S[f %d, i %d, pts[%d [%d..%d]]: text %d, ass %d, %d/%d %dx%d c %d, lsz[%d, %d, %d, %d], data[%d, %d, %d, %d]\n", + (int)r->type, i, sPTS, sStart, sEnd, hasText, hasASS, + r->x, r->y, r->w, r->h, r->nb_colors, + r->linesize[0], r->linesize[1], r->linesize[2], r->linesize[3], + NULL != r->data[0], NULL != r->data[1], NULL != r->data[2], NULL != r->data[3]); + } + if( 0 != sTexID ) { + if( NULL != pAV->procAddrGLEnable ) { + pAV->procAddrGLEnable(sTexTarget); + } + pAV->procAddrGLBindTexture(sTexTarget, sTexID); + + const GLenum texIFmt = GL_RGBA; + const GLenum texType = GL_UNSIGNED_BYTE; + + // pAV->procAddrGLTexSubImage2D(sTexTarget, 0, + // 0, 0, + // pAV->vTexWidth[0], pAV->pVCodecCtx->height, + // texIFmt, texType, pAV->pVFrame->data[0] + p_offset[0]); } + (*env)->CallVoidMethod(env, pAV->ffmpegMediaPlayer, ffmpeg_jni_mid_pushSubtitleTex, + sTexID, r->x, r->y, r->w, r->h, sPTS, sStart, sEnd); + JoglCommon_ExceptionCheck1_throwNewRuntimeException(env, "FFmpeg: Exception occured at pushSubtitleTex(..)"); } } pAV->sPTS = sPTS; diff --git a/src/jogl/native/libav/ffmpeg_static.c b/src/jogl/native/libav/ffmpeg_static.c index 184972306..a0145cee8 100644 --- a/src/jogl/native/libav/ffmpeg_static.c +++ b/src/jogl/native/libav/ffmpeg_static.c @@ -38,6 +38,7 @@ static jclass ffmpegMediaPlayerClazz = NULL; jmethodID ffmpeg_jni_mid_pushSound = NULL; jmethodID ffmpeg_jni_mid_pushSubtitleText = NULL; jmethodID ffmpeg_jni_mid_pushSubtitleASS = NULL; +jmethodID ffmpeg_jni_mid_pushSubtitleTex = NULL; jmethodID ffmpeg_jni_mid_updateAttributes = NULL; jmethodID ffmpeg_jni_mid_setIsGLOriented = NULL; jmethodID ffmpeg_jni_mid_setupFFAttributes = NULL; @@ -69,6 +70,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_opengl_util_av_impl_FFMPEGStaticNatives_i ffmpeg_jni_mid_pushSound = (*env)->GetMethodID(env, ffmpegMediaPlayerClazz, "pushSound", "(Ljava/nio/ByteBuffer;II)V"); ffmpeg_jni_mid_pushSubtitleText = (*env)->GetMethodID(env, ffmpegMediaPlayerClazz, "pushSubtitleText", "(Ljava/lang/String;III)V"); ffmpeg_jni_mid_pushSubtitleASS = (*env)->GetMethodID(env, ffmpegMediaPlayerClazz, "pushSubtitleASS", "(Ljava/lang/String;III)V"); + ffmpeg_jni_mid_pushSubtitleTex = (*env)->GetMethodID(env, ffmpegMediaPlayerClazz, "pushSubtitleTex", "(IIIIIIII)V"); ffmpeg_jni_mid_updateAttributes = (*env)->GetMethodID(env, ffmpegMediaPlayerClazz, "updateAttributes", "(Ljava/lang/String;[I[Ljava/lang/String;I[I[Ljava/lang/String;I[I[Ljava/lang/String;IIIIIIFIIILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"); ffmpeg_jni_mid_setIsGLOriented = (*env)->GetMethodID(env, ffmpegMediaPlayerClazz, "setIsGLOriented", "(Z)V"); @@ -78,6 +80,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_opengl_util_av_impl_FFMPEGStaticNatives_i if(ffmpeg_jni_mid_pushSound == NULL || ffmpeg_jni_mid_pushSubtitleText == NULL || ffmpeg_jni_mid_pushSubtitleASS == NULL || + ffmpeg_jni_mid_pushSubtitleTex == NULL || ffmpeg_jni_mid_updateAttributes == NULL || ffmpeg_jni_mid_setIsGLOriented == NULL || ffmpeg_jni_mid_setupFFAttributes == NULL || diff --git a/src/jogl/native/libav/ffmpeg_static.h b/src/jogl/native/libav/ffmpeg_static.h index c77783424..4bdb1ff55 100644 --- a/src/jogl/native/libav/ffmpeg_static.h +++ b/src/jogl/native/libav/ffmpeg_static.h @@ -43,6 +43,7 @@ extern jmethodID ffmpeg_jni_mid_pushSound; extern jmethodID ffmpeg_jni_mid_pushSubtitleText; extern jmethodID ffmpeg_jni_mid_pushSubtitleASS; +extern jmethodID ffmpeg_jni_mid_pushSubtitleTex; extern jmethodID ffmpeg_jni_mid_updateAttributes; extern jmethodID ffmpeg_jni_mid_setIsGLOriented; extern jmethodID ffmpeg_jni_mid_setupFFAttributes; diff --git a/src/jogl/native/libav/ffmpeg_tool.h b/src/jogl/native/libav/ffmpeg_tool.h index 852ff8d1e..be186d818 100644 --- a/src/jogl/native/libav/ffmpeg_tool.h +++ b/src/jogl/native/libav/ffmpeg_tool.h @@ -65,6 +65,9 @@ typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLi typedef GLenum (APIENTRYP PFNGLGETERRORPROC) (void); typedef void (APIENTRYP PFNGLFLUSH) (void); typedef void (APIENTRYP PFNGLFINISH) (void); +typedef void (APIENTRYP PFNGLENABLE) (GLenum cap); +typedef void (APIENTRYP PFNGLBINDTEXTURE) (GLenum target, GLuint texture); +typedef void (APIENTRYP PFNGLACTIVETEXTURE) (GLenum texture); /** * AV_TIME_BASE 1000000 @@ -150,6 +153,8 @@ typedef struct { PFNGLGETERRORPROC procAddrGLGetError; PFNGLFLUSH procAddrGLFlush; PFNGLFINISH procAddrGLFinish; + PFNGLENABLE procAddrGLEnable; + PFNGLBINDTEXTURE procAddrGLBindTexture; AVPacket* packet; AVFormatContext* pFormatCtx; |