diff options
author | Sven Gothel <[email protected]> | 2013-08-30 09:38:01 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2013-08-30 09:38:01 +0200 |
commit | e1883b6402231044cc6bdf67a45c1b3610e34535 (patch) | |
tree | 3d47d0d99ef32a2bad94bd40ca5c37d8ab70632b /src/jogl/native/libav | |
parent | eca6a5cb1e2beda84dfbafc31ed225e272f4f3fb (diff) |
FFMPEGMediaPlayer: Handle v-flipped 'bottom-up' pictures ; Refine API doc 'camera ID'
If linesize is < 0, it is not invalid as assumed in commit eca6a5cb1e2beda84dfbafc31ed225e272f4f3fb,
but vertically flipped (bottom-up).
We have to adjust the data pointers, which are moved to the upper end of memory as well
and can proceed as usual.
TODO:
- Update texture 'mustFlipVertically' to 'false' in this case.
- Later:
- Allow updating texture size ..
- Whole pixel-fmt/texture-lookup-shader association must scale better,
i.e. extract the 'knowledge' into one class, use a static shader code
using uniforms instead of hard-coded values .. etc.
Diffstat (limited to 'src/jogl/native/libav')
-rw-r--r-- | src/jogl/native/libav/ffmpeg_dshow.c | 4 | ||||
-rw-r--r-- | src/jogl/native/libav/ffmpeg_impl_template.c | 79 | ||||
-rw-r--r-- | src/jogl/native/libav/ffmpeg_tool.h | 2 |
3 files changed, 52 insertions, 33 deletions
diff --git a/src/jogl/native/libav/ffmpeg_dshow.c b/src/jogl/native/libav/ffmpeg_dshow.c index 4f8fedb9f..8c9903d6b 100644 --- a/src/jogl/native/libav/ffmpeg_dshow.c +++ b/src/jogl/native/libav/ffmpeg_dshow.c @@ -123,11 +123,11 @@ static int GetDeviceInformation(IEnumMoniker *pEnum, int verbose, int devIdx, getBSTRChars(var.bstrVal, pName, nameSize); } if( verbose ) { - fprintf(stderr, "DShowParser: Dev[%d]: FName %S\n", i, var.bstrVal); + fprintf(stderr, "DShowParser: Dev[%d]: Name %S\n", i, var.bstrVal); } VariantClear(&var); } else if( verbose ) { - fprintf(stderr, "DShowParser: Dev[%d]: cannot read FName..\n", i); + fprintf(stderr, "DShowParser: Dev[%d]: cannot read Name..\n", i); } hr = pPropBag->lpVtbl->Write(pPropBag, L"FriendlyName", &var); diff --git a/src/jogl/native/libav/ffmpeg_impl_template.c b/src/jogl/native/libav/ffmpeg_impl_template.c index 9f371a720..6d28e77b6 100644 --- a/src/jogl/native/libav/ffmpeg_impl_template.c +++ b/src/jogl/native/libav/ffmpeg_impl_template.c @@ -1092,6 +1092,19 @@ JNIEXPORT void JNICALL FF_FUNC(setStream0) JoglCommon_throwNewRuntimeException(env, "Couldn't alloc video frame"); return; } + // Min. requirement for 'get_buffer2' ! + pAV->pVFrame->width = pAV->pVCodecCtx->width; + pAV->pVFrame->height = pAV->pVCodecCtx->height; + pAV->pVFrame->format = pAV->pVCodecCtx->pix_fmt; + #if LIBAVCODEC_VERSION_MAJOR >= 55 + res = sp_avcodec_default_get_buffer2(pAV->pVCodecCtx, pAV->pVFrame, 0); + #else + res = sp_avcodec_default_get_buffer(pAV->pVCodecCtx, pAV->pVFrame); + #endif + if(0!=res) { + JoglCommon_throwNewRuntimeException(env, "Couldn't peek video buffer dimension"); + return; + } { const int32_t bytesPerPixel = ( pAV->vBitsPerPixel + 7 ) / 8 ; if(1 == pAV->vBufferPlanes) { @@ -1108,32 +1121,14 @@ JNIEXPORT void JNICALL FF_FUNC(setStream0) pAV->vTexWidth[i] = vLinesize[i] / pAV->vBytesPerPixelPerPlane ; } #else - // Min. requirement for 'get_buffer2' ! - pAV->pVFrame->width = pAV->pVCodecCtx->width; - pAV->pVFrame->height = pAV->pVCodecCtx->height; - pAV->pVFrame->format = pAV->pVCodecCtx->pix_fmt; - #if LIBAVCODEC_VERSION_MAJOR >= 55 - res = sp_avcodec_default_get_buffer2(pAV->pVCodecCtx, pAV->pVFrame, 0); - #else - res = sp_avcodec_default_get_buffer(pAV->pVCodecCtx, pAV->pVFrame); - #endif - if(0!=res) { - JoglCommon_throwNewRuntimeException(env, "Couldn't peek video buffer dimension"); - return; - } for(i=0; i<pAV->vBufferPlanes; i++) { // FIXME: Libav Binary compatibility! JAU01 vLinesize[i] = pAV->pVFrame->linesize[i]; pAV->vTexWidth[i] = vLinesize[i] / pAV->vBytesPerPixelPerPlane ; } - #if LIBAVCODEC_VERSION_MAJOR >= 55 - sp_av_frame_unref(pAV->pVFrame); - #else - sp_avcodec_default_release_buffer(pAV->pVCodecCtx, pAV->pVFrame); - #endif #endif } else { - vLinesize[0] = pAV->pVCodecCtx->width * pAV->vBytesPerPixelPerPlane; + vLinesize[0] = pAV->pVFrame->linesize[0]; if( pAV->vPixFmt == PIX_FMT_YUYV422 ) { // Stuff 2x 16bpp (YUYV) into one RGBA pixel! pAV->vTexWidth[0] = pAV->pVCodecCtx->width / 2; @@ -1143,10 +1138,15 @@ JNIEXPORT void JNICALL FF_FUNC(setStream0) } if( pAV->verbose ) { for(i=0; i<pAV->vBufferPlanes; i++) { - fprintf(stderr, "P[%d]: %d texw * %d bytesPP -> %d line\n", i, pAV->vTexWidth[i], pAV->vBytesPerPixelPerPlane, vLinesize[i]); + fprintf(stderr, "Video: P[%d]: %d texw * %d bytesPP -> %d line\n", i, pAV->vTexWidth[i], pAV->vBytesPerPixelPerPlane, vLinesize[i]); } } } + #if LIBAVCODEC_VERSION_MAJOR >= 55 + sp_av_frame_unref(pAV->pVFrame); + #else + sp_avcodec_default_release_buffer(pAV->pVCodecCtx, pAV->pVFrame); + #endif } pAV->vPTS=0; pAV->aPTS=0; @@ -1380,27 +1380,45 @@ JNIEXPORT jint JNICALL FF_FUNC(readNextPacket0) const int32_t frame_repeat_i = pAV->pVFrame->repeat_pict * (frame_delay_i / 2); const char * warn = frame_repeat_i > 0 ? "REPEAT" : "NORMAL" ; - const char * oopsLsz = pAV->pVFrame->linesize[0] <= 0 ? "Ooops LSZ" : "OK" ; - fprintf(stderr, "V fix_pts %d, pts %d [pkt_pts %ld], dts %d [pkt_dts %ld], time d(%lf s + r %lf = %lf s), i(%d ms + r %d = %d ms) - %s - f# %d, data %p, lsz %d (%s)\n", + fprintf(stderr, "V fix_pts %d, pts %d [pkt_pts %ld], dts %d [pkt_dts %ld], time d(%lf s + r %lf = %lf s), i(%d ms + r %d = %d ms) - %s - f# %d, dec %d, data %p, lsz %d\n", pAV->vPTS, vPTS, pkt_pts, vDTS, pkt_dts, frame_delay_d, frame_repeat_d, (frame_delay_d + frame_repeat_d), frame_delay_i, frame_repeat_i, (frame_delay_i + frame_repeat_i), warn, frameCount, - pAV->pVFrame->data[0], pAV->pVFrame->linesize[0], oopsLsz); + len1, pAV->pVFrame->data[0], pAV->pVFrame->linesize[0]); + // fflush(NULL); } - if( pAV->pVFrame->linesize[0] <= 0 ) { - // Ooops ! + if( 0 == pAV->pVFrame->linesize[0] ) { + if( pAV->useRefCountedFrames ) { + sp_av_frame_unref(pAV->pVFrame); + } continue; } resPTS = pAV->vPTS; // Video Frame! + int p_offset[] = { 0, 0, 0, 0 }; + if( pAV->pVFrame->linesize[0] < 0 ) { + // image bottom-up + int h_1 = pAV->pVCodecCtx->height - 1; + p_offset[0] = pAV->pVFrame->linesize[0] * h_1; + if( pAV->vBufferPlanes > 1 ) { + p_offset[1] = pAV->pVFrame->linesize[1] * h_1; + } + if( pAV->vBufferPlanes > 2 ) { + p_offset[2] = pAV->pVFrame->linesize[2] * h_1; + } + /** + if( pAV->vBufferPlanes > 3 ) { + p_offset[3] = pAV->pVFrame->linesize[3] * h_1; + } */ + } // 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]); + texFmt, texType, pAV->pVFrame->data[0] + p_offset[0]); DBG_TEXSUBIMG2D_b(pAV); if( pAV->vPixFmt == PIX_FMT_YUV420P || pAV->vPixFmt == PIX_FMT_YUVJ420P ) { @@ -1410,7 +1428,7 @@ JNIEXPORT jint JNICALL FF_FUNC(readNextPacket0) pAV->procAddrGLTexSubImage2D(texTarget, 0, pAV->pVCodecCtx->width, 0, pAV->vTexWidth[1], pAV->pVCodecCtx->height/2, - texFmt, texType, pAV->pVFrame->data[1]); + texFmt, texType, pAV->pVFrame->data[1] + p_offset[1]); DBG_TEXSUBIMG2D_b(pAV); // V plane // FIXME: Libav Binary compatibility! JAU01 @@ -1418,7 +1436,7 @@ JNIEXPORT jint JNICALL FF_FUNC(readNextPacket0) pAV->procAddrGLTexSubImage2D(texTarget, 0, pAV->pVCodecCtx->width, pAV->pVCodecCtx->height/2, pAV->vTexWidth[2], pAV->pVCodecCtx->height/2, - texFmt, texType, pAV->pVFrame->data[2]); + texFmt, texType, pAV->pVFrame->data[2] + p_offset[2]); DBG_TEXSUBIMG2D_b(pAV); } else if( pAV->vPixFmt == PIX_FMT_YUV422P || pAV->vPixFmt == PIX_FMT_YUVJ422P ) { // U plane @@ -1427,7 +1445,7 @@ JNIEXPORT jint JNICALL FF_FUNC(readNextPacket0) pAV->procAddrGLTexSubImage2D(texTarget, 0, pAV->pVCodecCtx->width, 0, pAV->vTexWidth[1], pAV->pVCodecCtx->height, - texFmt, texType, pAV->pVFrame->data[1]); + texFmt, texType, pAV->pVFrame->data[1] + p_offset[1]); DBG_TEXSUBIMG2D_b(pAV); // V plane // FIXME: Libav Binary compatibility! JAU01 @@ -1435,9 +1453,10 @@ JNIEXPORT jint JNICALL FF_FUNC(readNextPacket0) pAV->procAddrGLTexSubImage2D(texTarget, 0, pAV->pVCodecCtx->width+pAV->pVCodecCtx->width/2, 0, pAV->vTexWidth[2], pAV->pVCodecCtx->height, - texFmt, texType, pAV->pVFrame->data[2]); + texFmt, texType, pAV->pVFrame->data[2] + p_offset[2]); DBG_TEXSUBIMG2D_b(pAV); } // FIXME: Add more planar formats ! + pAV->procAddrGLFinish(); //pAV->procAddrGLFlush(); if( pAV->useRefCountedFrames ) { diff --git a/src/jogl/native/libav/ffmpeg_tool.h b/src/jogl/native/libav/ffmpeg_tool.h index e4b10f95f..72345fbb7 100644 --- a/src/jogl/native/libav/ffmpeg_tool.h +++ b/src/jogl/native/libav/ffmpeg_tool.h @@ -160,7 +160,7 @@ typedef struct { enum PixelFormat vPixFmt; // native decoder fmt int32_t vPTS; // msec - overall last video PTS PTSStats vPTSStats; - int32_t vTexWidth[AV_NUM_DATA_POINTERS]; // decoded video tex width in bytes for each plane + int32_t vTexWidth[4]; // decoded video tex width in bytes for each plane (max 4) int32_t vWidth; int32_t vHeight; |