aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/native/libav
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2013-08-30 09:38:01 +0200
committerSven Gothel <[email protected]>2013-08-30 09:38:01 +0200
commite1883b6402231044cc6bdf67a45c1b3610e34535 (patch)
tree3d47d0d99ef32a2bad94bd40ca5c37d8ab70632b /src/jogl/native/libav
parenteca6a5cb1e2beda84dfbafc31ed225e272f4f3fb (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.c4
-rw-r--r--src/jogl/native/libav/ffmpeg_impl_template.c79
-rw-r--r--src/jogl/native/libav/ffmpeg_tool.h2
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;