diff --git a/projects/Cuboxi/patches/xbmc/xbmc-001-imx6_support.patch b/projects/Cuboxi/patches/xbmc/xbmc-001-imx6_support.patch index 4aa7e4ecc0..c75cfbf370 100644 --- a/projects/Cuboxi/patches/xbmc/xbmc-001-imx6_support.patch +++ b/projects/Cuboxi/patches/xbmc/xbmc-001-imx6_support.patch @@ -1,6 +1,6 @@ -diff -Naur xbmc-master.test/configure.in xbmc-wolfgar-imx-wip.test/configure.in ---- xbmc-master.test/configure.in 2014-01-10 19:50:18.000000000 +0100 -+++ xbmc-wolfgar-imx-wip.test/configure.in 2014-01-12 04:55:00.000000000 +0100 +diff -Naur xbmc-gotham-latest.test/configure.in xbmc-wolfgar-imx-wip.test/configure.in +--- xbmc-gotham-latest.test/configure.in 2014-01-23 22:58:46.720345686 +0100 ++++ xbmc-wolfgar-imx-wip.test/configure.in 2014-01-23 23:04:12.846234320 +0100 @@ -558,7 +558,7 @@ AC_ARG_ENABLE([codec], @@ -10,7 +10,7 @@ diff -Naur xbmc-master.test/configure.in xbmc-wolfgar-imx-wip.test/configure.in [add_codecs=$enableval], [add_codecs=no]) -@@ -1973,6 +1973,17 @@ +@@ -1978,6 +1978,17 @@ *libstagefright*) XB_ADD_CODEC([LIBSTAGEFRIGHT], [libstagefright], [$codecs]) ;; @@ -28,7 +28,7 @@ diff -Naur xbmc-master.test/configure.in xbmc-wolfgar-imx-wip.test/configure.in *) esac done -@@ -2648,6 +2659,7 @@ +@@ -2653,6 +2664,7 @@ AC_SUBST(USE_DOXYGEN) AC_SUBST(USE_PVR_ADDONS) @@ -36,9 +36,9 @@ diff -Naur xbmc-master.test/configure.in xbmc-wolfgar-imx-wip.test/configure.in # pushd and popd are not available in other shells besides bash, so implement # our own pushd/popd functions XB_DIRSTACK="$PWD" -diff -Naur xbmc-master.test/lib/ffmpeg/libavcodec/arm/dca.h xbmc-wolfgar-imx-wip.test/lib/ffmpeg/libavcodec/arm/dca.h ---- xbmc-master.test/lib/ffmpeg/libavcodec/arm/dca.h 2013-09-03 05:03:25.000000000 +0200 -+++ xbmc-wolfgar-imx-wip.test/lib/ffmpeg/libavcodec/arm/dca.h 2014-01-12 04:37:24.000000000 +0100 +diff -Naur xbmc-gotham-latest.test/lib/ffmpeg/libavcodec/arm/dca.h xbmc-wolfgar-imx-wip.test/lib/ffmpeg/libavcodec/arm/dca.h +--- xbmc-gotham-latest.test/lib/ffmpeg/libavcodec/arm/dca.h 2014-01-23 22:58:34.315337604 +0100 ++++ xbmc-wolfgar-imx-wip.test/lib/ffmpeg/libavcodec/arm/dca.h 2014-01-23 23:04:12.622234510 +0100 @@ -30,9 +30,9 @@ #define decode_blockcodes decode_blockcodes @@ -56,9 +56,9 @@ diff -Naur xbmc-master.test/lib/ffmpeg/libavcodec/arm/dca.h xbmc-wolfgar-imx-wip #endif /* AVCODEC_ARM_DCA_H */ + -diff -Naur xbmc-master.test/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp xbmc-wolfgar-imx-wip.test/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp ---- xbmc-master.test/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp 2014-01-10 19:50:19.000000000 +0100 -+++ xbmc-wolfgar-imx-wip.test/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp 2014-01-12 04:55:00.000000000 +0100 +diff -Naur xbmc-gotham-latest.test/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp xbmc-wolfgar-imx-wip.test/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp +--- xbmc-gotham-latest.test/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp 2014-01-23 22:58:27.848333534 +0100 ++++ xbmc-wolfgar-imx-wip.test/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp 2014-01-23 23:04:12.268234811 +0100 @@ -714,7 +714,10 @@ * will automatically add "@" instead to enable surroundXX mangling. * We don't want to do that if "default" can handle multichannel @@ -104,9 +104,9 @@ diff -Naur xbmc-master.test/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp xbmc-wol if (name.substr(0, 4) == "hdmi") return AE_DEVTYPE_HDMI; else if (name.substr(0, 6) == "iec958" || name.substr(0, 5) == "spdif") -diff -Naur xbmc-master.test/xbmc/cores/AudioEngine/Utils/AEConvert.cpp xbmc-wolfgar-imx-wip.test/xbmc/cores/AudioEngine/Utils/AEConvert.cpp ---- xbmc-master.test/xbmc/cores/AudioEngine/Utils/AEConvert.cpp 2013-09-03 05:03:26.000000000 +0200 -+++ xbmc-wolfgar-imx-wip.test/xbmc/cores/AudioEngine/Utils/AEConvert.cpp 2014-01-12 04:37:25.000000000 +0100 +diff -Naur xbmc-gotham-latest.test/xbmc/cores/AudioEngine/Utils/AEConvert.cpp xbmc-wolfgar-imx-wip.test/xbmc/cores/AudioEngine/Utils/AEConvert.cpp +--- xbmc-gotham-latest.test/xbmc/cores/AudioEngine/Utils/AEConvert.cpp 2014-01-23 22:58:27.866333545 +0100 ++++ xbmc-wolfgar-imx-wip.test/xbmc/cores/AudioEngine/Utils/AEConvert.cpp 2014-01-23 23:04:12.269234810 +0100 @@ -841,7 +841,7 @@ _mm_empty(); #else /* no SSE2 */ @@ -116,9 +116,9 @@ diff -Naur xbmc-master.test/xbmc/cores/AudioEngine/Utils/AEConvert.cpp xbmc-wolf #endif return samples << 2; -diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp xbmc-wolfgar-imx-wip.test/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp ---- xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp 2014-01-10 19:50:19.000000000 +0100 -+++ xbmc-wolfgar-imx-wip.test/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp 2014-01-12 04:37:25.000000000 +0100 +diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp xbmc-wolfgar-imx-wip.test/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp +--- xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp 2014-01-23 22:58:27.759333479 +0100 ++++ xbmc-wolfgar-imx-wip.test/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp 2014-01-23 23:04:12.261234816 +0100 @@ -35,6 +35,9 @@ #include "Video/DVDVideoCodecFFmpeg.h" #include "Video/DVDVideoCodecOpenMax.h" @@ -158,9 +158,9 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp x #if defined(TARGET_DARWIN_OSX) if (!hint.software && CSettings::Get().GetBool("videoplayer.usevda")) { -diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h xbmc-wolfgar-imx-wip.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h ---- xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h 2014-01-10 19:50:19.000000000 +0100 -+++ xbmc-wolfgar-imx-wip.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h 2014-01-12 04:37:25.000000000 +0100 +diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h xbmc-wolfgar-imx-wip.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h +--- xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h 2014-01-23 22:58:27.772333487 +0100 ++++ xbmc-wolfgar-imx-wip.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h 2014-01-23 23:04:12.261234816 +0100 @@ -38,7 +38,9 @@ class COpenMax; class COpenMaxVideo; @@ -193,10 +193,10 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h CDVDVideoCodecStageFright* stf; EGLImageKHR eglimg; }; -diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp xbmc-wolfgar-imx-wip.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp ---- xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp 1970-01-01 01:00:00.000000000 +0100 -+++ xbmc-wolfgar-imx-wip.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp 2014-01-12 04:37:25.000000000 +0100 -@@ -0,0 +1,1686 @@ +diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp xbmc-wolfgar-imx-wip.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp +--- xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ xbmc-wolfgar-imx-wip.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp 2014-01-23 23:04:12.262234815 +0100 +@@ -0,0 +1,1733 @@ +/* + * Copyright (C) 2013 Stephan Rafin + * @@ -232,6 +232,7 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM +#include "threads/Atomics.h" + +//#define NO_V4L_RENDERING ++//#define V4L_OUTPUT_PROFILE + +#ifdef IMX_PROFILE +static unsigned long long render_ts[30]; @@ -248,6 +249,12 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM +} +#endif + ++void CIMXOutputFrame::Render(struct v4l2_crop &crop) ++{ ++ CIMXRenderingFrames& renderingFrames = CIMXRenderingFrames::GetInstance(); ++ renderingFrames.Queue(this, crop); ++} ++ +/* video device on which the video will be rendered (/dev/video17 => /dev/fb1) */ +const char *CIMXRenderingFrames::m_v4lDeviceName = "/dev/video17"; +static long sg_singleton_lock_variable = 0; @@ -272,6 +279,7 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + m_v4lBuffers = NULL; + memset(&m_crop, 0, sizeof(m_crop)); + m_crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; ++ m_motionCtrl = -1; +} + +bool CIMXRenderingFrames::AllocateBuffers(const struct v4l2_format *format, int nbBuffers) @@ -280,6 +288,7 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + struct v4l2_requestbuffers bufReq; + struct v4l2_format fmt; + struct v4l2_buffer v4lBuf; ++ struct v4l2_control ctrl; + + CSingleLock lock(m_renderingFramesLock); + if (m_ready) @@ -304,6 +313,37 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + return false; + } + ++ if (format->fmt.pix.field != V4L2_FIELD_NONE) ++ { ++ char * motion_entry; ++ motion_entry = getenv("IMX_DEINT_MOTION"); ++ if (motion_entry != NULL) ++ { ++ errno = 0; ++ m_motionCtrl = strtol(motion_entry, NULL, 10); ++ if (errno != 0) ++ m_motionCtrl = -1; ++ } ++ if (m_motionCtrl == -1) ++ m_motionCtrl = 2; /* Default value : 2 stands for high motion */ ++ ++ if ((m_motionCtrl >= 0) && (m_motionCtrl <=2)) ++ { ++ ctrl.id = V4L2_CID_MXC_MOTION; ++ ctrl.value = m_motionCtrl; ++ ret = ioctl (m_v4lfd, VIDIOC_S_CTRL, &ctrl); ++ if (ret < 0) ++ { ++ CLog::Log(LOGERROR, "%s - Error while setting V4L motion (ret %d : %s).\n", __FUNCTION__, ret, strerror(errno)); ++ } ++ } ++ else ++ { ++ CLog::Log(LOGNOTICE, "%s - IMX_DEINT_MOTION set to %d. Disabling deinterlacing.\n", __FUNCTION__, m_motionCtrl); ++ m_motionCtrl = -2; ++ } ++ } ++ + fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + ret = ioctl(m_v4lfd, VIDIOC_G_FMT, &fmt); + if (ret < 0) @@ -362,7 +402,6 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + m_crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + m_pushedFrames = 0; + m_streamOn = false; -+ m_currentField = VPU_FIELD_UNKNOWN; + m_ready = true; + return true; +} @@ -434,7 +473,7 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + CSingleLock lock(m_renderingFramesLock); + if (!m_ready) + { -+ CLog::Log(LOGNOTICE, "%s - Cannot dequeue frame as buffers were released !\n", ++ CLog::Log(LOGNOTICE, "%s - Cannot dequeue frame as buffers were released !\n", + __FUNCTION__); + return -1; + } @@ -443,7 +482,8 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + return -1; + } + -+ if (wait) { ++ if (wait) ++ { + status = fcntl(m_v4lfd, F_GETFL); + fcntl(m_v4lfd, F_SETFL, status & (~O_NONBLOCK)); + } @@ -451,7 +491,9 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + buf.memory = V4L2_MEMORY_MMAP; + ret = ioctl(m_v4lfd, VIDIOC_DQBUF, &buf); + if (wait) ++ { + fcntl(m_v4lfd, F_SETFL, status | O_NONBLOCK); ++ } + if (ret != 0) + { + if (errno != EAGAIN) @@ -464,6 +506,8 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + CLog::Log(LOGDEBUG, "%s - Time render to dequeue (%d) %llu\n", + __FUNCTION__, buf.index, get_time() - render_ts[buf.index]); +#endif ++// CLog::Log(LOGERROR, "%s dequeued retuns (%d)\n", __FUNCTION__, buf.index); ++ + return buf.index; +} + @@ -475,10 +519,7 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + + int ret, type; + struct timeval queue_ts; -+ struct v4l2_format fmt; + int stream_trigger; -+ struct v4l2_control ctrl; -+ struct v4l2_rect rect; + bool crop_update = false; + + CSingleLock lock(m_renderingFramesLock); @@ -494,25 +535,28 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + + if ((picture->v4l2BufferIdx < 0) || (picture->v4l2BufferIdx >= m_bufferNum)) + { -+ CLog::Log(LOGERROR, "%s - Invalid buffer index : %d - picture adress : %p\n", ++ CLog::Log(LOGERROR, "%s - Invalid buffer index : %d - picture address : %p\n", + __FUNCTION__, picture->v4l2BufferIdx, picture); ++ return; + } -+ else ++ ++ /* Set field type for each buffer otherwise the mxc_vout driver reverts to progressive */ ++ switch (picture->field) + { -+ /* Set field type for each buffer otherwise the mxc_vout driver reverts to progressive */ -+ switch (picture->field) -+ { -+ case VPU_FIELD_TB: -+ m_v4lBuffers[picture->v4l2BufferIdx].field = V4L2_FIELD_INTERLACED_TB; -+ break; -+ case VPU_FIELD_BT: -+ m_v4lBuffers[picture->v4l2BufferIdx].field= V4L2_FIELD_INTERLACED_BT; -+ break; -+ case VPU_FIELD_NONE: -+ default: -+ m_v4lBuffers[picture->v4l2BufferIdx].field = V4L2_FIELD_NONE; -+ break; -+ } ++ case VPU_FIELD_TB: ++ m_v4lBuffers[picture->v4l2BufferIdx].field = V4L2_FIELD_INTERLACED_TB; ++ break; ++ case VPU_FIELD_BT: ++ m_v4lBuffers[picture->v4l2BufferIdx].field= V4L2_FIELD_INTERLACED_BT; ++ break; ++ case VPU_FIELD_NONE: ++ default: ++ m_v4lBuffers[picture->v4l2BufferIdx].field = V4L2_FIELD_NONE; ++ break; ++ } ++ /* In case deinterlacing is forced to disabled */ ++ if (m_motionCtrl == -2) ++ m_v4lBuffers[picture->v4l2BufferIdx].field = V4L2_FIELD_NONE; + + /* mxc_vout driver does not display immediatly + * if timestamp is set to 0 @@ -521,6 +565,7 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + */ + gettimeofday (&queue_ts, NULL); + m_v4lBuffers[picture->v4l2BufferIdx].timestamp = queue_ts; ++ +#ifndef NO_V4L_RENDERING + ret = ioctl(m_v4lfd, VIDIOC_QBUF, &m_v4lBuffers[picture->v4l2BufferIdx]); + if (ret < 0) @@ -529,8 +574,11 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + __FUNCTION__, ret, strerror(errno)); + /* If it fails odds are very high picture is invalid so just exit now */ + return; -+ } else ++ } ++ else ++ { + m_pushedFrames++; ++ } + + /* Force cropping dimensions to be aligned */ + destRect.c.top &= 0xFFFFFFF8; @@ -542,7 +590,7 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + (m_crop.c.width != destRect.c.width) || + (m_crop.c.height != destRect.c.height)) + { -+ CLog::Log(LOGNOTICE, "%s - Newcrop : %d % d %d %d\n", ++ CLog::Log(LOGNOTICE, "%s - Newcrop : %d % d %d %d\n", + __FUNCTION__, destRect.c.top, destRect.c.left, destRect.c.width, destRect.c.height); + m_crop.c = destRect.c; + crop_update = true; @@ -550,74 +598,19 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + + if (!m_streamOn) + { -+ if (picture->field != m_currentField) -+ { -+ CLog::Log(LOGNOTICE, "%s - New field is %d\n", -+ __FUNCTION__, picture->field); -+ -+ /* Handle interlace field */ -+ fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; -+ ret = ioctl (m_v4lfd, VIDIOC_G_FMT, &fmt); -+ if (ret < 0) { -+ CLog::Log(LOGERROR, "%s - V4L VIDIOC_G_FMT failed (ret %d : %s)\n", -+ __FUNCTION__, ret, strerror(errno)); -+ } else { -+ switch (picture->field) -+ { -+ case VPU_FIELD_TOP: -+ case VPU_FIELD_BOTTOM: -+ CLog::Log(LOGERROR, "%s - mxc_out driver does not handle this field type :%d\n", -+ __FUNCTION__, picture->field); -+ fmt.fmt.pix.field = V4L2_FIELD_NONE; -+ break; -+ case VPU_FIELD_TB: -+ fmt.fmt.pix.field = V4L2_FIELD_INTERLACED_TB; -+ break; -+ case VPU_FIELD_BT: -+ fmt.fmt.pix.field = V4L2_FIELD_INTERLACED_BT; -+ break; -+ case VPU_FIELD_NONE: -+ default: -+ fmt.fmt.pix.field = V4L2_FIELD_NONE; -+ break; -+ } -+ -+ /* Take into account cropping from decoded video (for input picture) */ -+ rect.left = picture->picCrop.nLeft; -+ rect.top = picture->picCrop.nTop; -+ rect.width = picture->picCrop.nRight - picture->picCrop.nLeft; -+ rect.height = picture->picCrop.nBottom - picture->picCrop.nTop; -+ fmt.fmt.pix.priv = (unsigned int)▭ -+ -+ fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; -+ ret = ioctl (m_v4lfd, VIDIOC_S_FMT, &fmt); -+ if (ret < 0) -+ { -+ CLog::Log(LOGERROR, "%s - V4L VIDIOC_S_FMT failed (ret %d : %s)\n", -+ __FUNCTION__, ret, strerror(errno)); -+ } -+ else -+ m_currentField = picture->field; -+ } -+ } -+ if (m_currentField == VPU_FIELD_NONE) ++ if (picture->field == VPU_FIELD_NONE) + stream_trigger = 1; + else { -+ stream_trigger = 2; /* should be 3 if V4L2_CID_MXC_MOTION < 2 */ -+ -+ /* FIXME : How to select the most appropriate motion type ? */ -+ ctrl.id = V4L2_CID_MXC_MOTION; -+ ctrl.value = 2; /* 2 stands for high motion */ -+ ret = ioctl (m_v4lfd, VIDIOC_S_CTRL, &ctrl); -+ if (ret < 0) -+ { -+ CLog::Log(LOGERROR, "%s - Error while setting V4L motion (ret %d : %s).\n", __FUNCTION__, ret, strerror(errno)); -+ } ++ if (m_motionCtrl < 2) ++ stream_trigger = 3; ++ else ++ stream_trigger = 2; + } -+ CLog::Log(LOGDEBUG, "%s - Number of required frames before streaming : %d\n", -+ __FUNCTION__, stream_trigger); + + if (m_pushedFrames >= stream_trigger) { ++ CLog::Log(LOGDEBUG, "%s - Motion control is : %d - Number of required frames before streaming : %d\n", ++ __FUNCTION__, m_motionCtrl, stream_trigger); ++ + type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + ret = ioctl(m_v4lfd, VIDIOC_STREAMON, &type); + if (ret < 0) @@ -632,7 +625,7 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + m_streamOn = true; + } + /* We have to repeat crop command after streamon for some vids -+ * FIXME check why in drivers... ++ * FIXME : Check why in drivers... + */ + ret = ioctl(m_v4lfd, VIDIOC_S_CROP, &m_crop); + if (ret < 0) @@ -661,9 +654,6 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + CLog::Log(LOGDEBUG, "%s - Time push to render (%d) %llu\n", + __FUNCTION__, picture->v4l2BufferIdx, render_ts[picture->v4l2BufferIdx] - picture->pushTS); +#endif -+ -+ delete picture; -+ } +} + +void CIMXRenderingFrames::ReleaseBuffers() @@ -714,7 +704,9 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + m_v4lBuffers = NULL; + } + m_bufferNum = 0; ++ m_pushedFrames = 0; + m_ready = false; ++ m_motionCtrl = -1; +} + +/* FIXME get rid of these defines properly */ @@ -724,18 +716,28 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM +#define Align(ptr,align) (((unsigned int)ptr + (align) - 1)/(align)*(align)) +#define min(a, b) (aGetClock() / DVD_TIME_BASE; ++ ++ return clock_pts; ++} ++ ++void CDVDVideoCodecIMX::FlushDecodedFrames(void) ++{ ++ DVDVideoPicture DVDFrame; ++ while (m_decodedFrames.size() > 0) + { -+ VPU_DecOutFrameDisplayed(m_vpuHandle, m_outputBuffers[m_outputFrame.imxOutputFrame->v4l2BufferIdx]); -+ m_outputBuffers[m_outputFrame.imxOutputFrame->v4l2BufferIdx] = NULL; -+ delete m_outputFrame.imxOutputFrame; -+ m_outputFrameReady = false; ++ DVDFrame = m_decodedFrames.front(); ++ VpuReleaseBufferV4L(DVDFrame.imxOutputFrame->v4l2BufferIdx); ++ m_decodedFrames.pop(); + } +} + @@ -745,9 +747,9 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + unsigned char * ptr; + VpuMemDesc vpuMem; + VpuDecRetCode ret; -+ ++ + for(i=0; inSubBlockNum; i++) -+ { ++ { + size = pMemBlock->MemSubBlock[i].nAlignment + pMemBlock->MemSubBlock[i].nSize; + if (pMemBlock->MemSubBlock[i].MemType == VPU_MEM_VIRT) + { // Allocate standard virtual memory @@ -756,13 +758,13 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + { + CLog::Log(LOGERROR, "%s - Unable to malloc %d bytes.\n", __FUNCTION__, size); + goto AllocFailure; -+ } ++ } + pMemBlock->MemSubBlock[i].pVirtAddr = (unsigned char*)Align(ptr, pMemBlock->MemSubBlock[i].nAlignment); + + m_decMemInfo.virtMem[m_decMemInfo.nVirtNum] = (unsigned int)ptr; + m_decMemInfo.nVirtNum++; + } -+ else ++ else + { // Allocate contigous mem for DMA + vpuMem.nSize = size; + ret = VPU_DecGetMem(&vpuMem); @@ -770,7 +772,7 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + { + CLog::Log(LOGERROR, "%s - Unable alloc %d bytes of physical memory (%d).\n", __FUNCTION__, size, ret); + goto AllocFailure; -+ } ++ } + pMemBlock->MemSubBlock[i].pVirtAddr = (unsigned char*)Align(vpuMem.nVirtAddr, pMemBlock->MemSubBlock[i].nAlignment); + pMemBlock->MemSubBlock[i].pPhyAddr = (unsigned char*)Align(vpuMem.nPhyAddr, pMemBlock->MemSubBlock[i].nAlignment); + @@ -778,15 +780,15 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + m_decMemInfo.phyMem_virtAddr[m_decMemInfo.nPhyNum] = (unsigned int)vpuMem.nVirtAddr; + m_decMemInfo.phyMem_cpuAddr[m_decMemInfo.nPhyNum] = (unsigned int)vpuMem.nCpuAddr; + m_decMemInfo.phyMem_size[m_decMemInfo.nPhyNum] = size; -+ m_decMemInfo.nPhyNum++; ++ m_decMemInfo.nPhyNum++; + } + } + + return true; -+ ++ +AllocFailure: + VpuFreeBuffers(); -+ return false; ++ return false; +} + +bool CDVDVideoCodecIMX::VpuFreeBuffers(void) @@ -799,7 +801,7 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + //free virtual mem + for(i=0; ipDisplayFrameBuf; -+ CIMXOutputFrame *outputFrame = new CIMXOutputFrame(); ++ CIMXOutputFrame *outputFrame; + CIMXRenderingFrames &renderingFrames = CIMXRenderingFrames::GetInstance(); + int i; -+ //outputFrameType outputFrame; + double pts; ++ DVDVideoPicture DVDFrame; + + pts = (double)TSManagerSend2(m_tsm, frameBuffer) / (double)1000.0; -+ if (m_dropState) -+ { -+ /* If we are dropping frame then release current frame immediatly */ -+ VPU_DecOutFrameDisplayed(m_vpuHandle, frameBuffer); -+ return false; -+ } -+ + /* Find Frame given physical address */ + i = renderingFrames.FindBuffer(frameBuffer->pbufY); + if (i == -1) @@ -1046,48 +1025,42 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + CLog::Log(LOGERROR, "%s - V4L buffer not found\n", __FUNCTION__); + return false; + } -+ if (m_outputBuffers[i] != NULL) ++ if (m_outputBuffers[i].used()) + { + CLog::Log(LOGERROR, "%s - Try to reuse buffer which was not dequeued !\n", __FUNCTION__); + return false; + } -+ if (m_outputFrameReady) -+ { -+ CLog::Log(LOGERROR, "%s - Called while GetPicture has not consumed previous frame\n", __FUNCTION__); -+ } + + /* Store the pointer to be able to invoke VPU_DecOutFrameDisplayed when the buffer will be dequeued */ -+ m_outputBuffers[i] = frameBuffer; -+ //CLog::Log(LOGDEBUG, "%s - set ouputBuffer idx %d : %x\n", __FUNCTION__, i, frameBuffer); ++ m_outputBuffers[i].store(frameBuffer, m_frameCounter++); + -+ outputFrame = new CIMXOutputFrame(); ++ outputFrame = &m_outputBuffers[i].outputFrame; + outputFrame->v4l2BufferIdx = i; + outputFrame->field = frameInfo->eFieldType; + outputFrame->picCrop = frameInfo->pExtInfo->FrmCropRect; + outputFrame->nQ16ShiftWidthDivHeightRatio = frameInfo->pExtInfo->nQ16ShiftWidthDivHeightRatio; -+ m_outputFrame.imxOutputFrame = outputFrame; ++ DVDFrame.imxOutputFrame = outputFrame; + -+ m_outputFrame.pts = pts; -+ m_outputFrame.dts = DVD_NOPTS_VALUE; ++ DVDFrame.pts = pts; ++ DVDFrame.dts = DVD_NOPTS_VALUE; + /* + m_outputFrame.iWidth = frameInfo->pExtInfo->nFrmWidth; + m_outputFrame.iHeight = frameInfo->pExtInfo->nFrmHeight; + */ -+ m_outputFrame.iWidth = frameInfo->pExtInfo->FrmCropRect.nRight - frameInfo->pExtInfo->FrmCropRect.nLeft; -+ m_outputFrame.iHeight = frameInfo->pExtInfo->FrmCropRect.nBottom - frameInfo->pExtInfo->FrmCropRect.nTop; -+ /* FIXME plug aspect ratio correction here frameInfo->nQ16ShiftWidthDivHeightRatio */ -+ m_outputFrame.format = RENDER_FMT_IMX; -+ m_outputFrameReady = true; ++ DVDFrame.iWidth = frameInfo->pExtInfo->FrmCropRect.nRight - frameInfo->pExtInfo->FrmCropRect.nLeft; ++ DVDFrame.iHeight = frameInfo->pExtInfo->FrmCropRect.nBottom - frameInfo->pExtInfo->FrmCropRect.nTop; ++ DVDFrame.format = RENDER_FMT_IMX; ++ ++ m_decodedFrames.push(DVDFrame); + +#ifdef IMX_PROFILE -+ m_outputFrame.imxOutputFrame->pushTS = get_time(); -+ CLog::Log(LOGDEBUG, "%s - Time between push %llu\n", -+ __FUNCTION__, m_outputFrame.imxOutputFrame->pushTS - previous_ts); -+ previous_ts =m_outputFrame.imxOutputFrame->pushTS; ++ DVDFrame.imxOutputFrame->pushTS = get_time(); ++ CLog::Log(LOGDEBUG, "%s - push (%i) Time between push %llu\n", ++ __FUNCTION__, i, DVDFrame.imxOutputFrame->pushTS - previous_ts); ++ previous_ts =DVDFrame.imxOutputFrame->pushTS; +#endif + + return true; -+ +} + +int CDVDVideoCodecIMX::GetAvailableBufferNb(void) @@ -1097,42 +1070,79 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + nb = 0; + for (i = 0; i < m_vpuFrameBufferNum; i++) + { -+ if (m_outputBuffers[i] == NULL) ++ if (!m_outputBuffers[i].used()) + nb++; + } + return nb; +} + ++bool CDVDVideoCodecIMX::VpuReleaseBufferV4L(int idx) ++{ ++ if (idx < 0 || idx >= m_vpuFrameBufferNum) ++ { ++ CLog::Log(LOGERROR, "%s - Invalid index - idx : %d\n", __FUNCTION__, idx); ++ return false; ++ } ++ ++ /*CLog::Log(LOGDEBUG, "%s - idx : %d - frame : %d\n", __FUNCTION__, ++ idx, m_outputBuffers[idx].frameNo);*/ ++ ++ VPU_DecOutFrameDisplayed(m_vpuHandle, m_outputBuffers[idx].buffer); ++ m_outputBuffers[idx].clear(); ++ return true; ++} ++ ++/* Dequeue queued frames and free the corresponding VPU buffers */ +bool CDVDVideoCodecIMX::VpuDeQueueFrame(bool wait) +{ -+ int idx; -+ CIMXRenderingFrames &renderingFrames = CIMXRenderingFrames::GetInstance(); ++ int idx, i, frameNo; + -+ idx = renderingFrames.DeQueue(wait); ++ idx = m_renderingFrames.DeQueue(wait); + if (idx != -1) + { -+ VPU_DecOutFrameDisplayed(m_vpuHandle, m_outputBuffers[idx]); -+ m_outputBuffers[idx] = NULL; -+ return true; ++ if (!m_outputBuffers[idx].used()) ++ { ++ CLog::Log(LOGERROR, "%s - WTF : associated buffer does not exist anymore\n", ++ __FUNCTION__); ++ return true; ++ } ++ else ++ { ++ frameNo = m_outputBuffers[idx].frameNo(); ++ VpuReleaseBufferV4L(idx); ++ if (frameNo > 0) ++ { ++ /* Release buffers which are not used anymore and were ++ * queued before the idx buffer that has just been dequeued*/ ++ for (i = 0; i < m_vpuFrameBufferNum; ++i) ++ { ++ if (m_outputBuffers[i].expired(frameNo)) ++ { ++ CLog::Log(LOGNOTICE, "%s - Release expired buffer - idx : %d\n", __FUNCTION__, i); ++ VpuReleaseBufferV4L(i); ++ } ++ } ++ } ++ return true; ++ } + } + else + { +#ifdef NO_V4L_RENDERING -+ int i; -+ for (i = 0; i < m_vpuFrameBufferNum; i++) ++ int i; ++ for (i = 0; i < m_vpuFrameBufferNum; i++) ++ { ++ if (m_outputBuffers[i].used()) + { -+ if (m_outputBuffers[i] != NULL) -+ { -+ VPU_DecOutFrameDisplayed(m_vpuHandle, m_outputBuffers[i]); -+ m_outputBuffers[i] = NULL; -+ } ++ VpuReleaseBufferV4L(idx); + } ++ } +#endif + return false; + } +} + -+CDVDVideoCodecIMX::CDVDVideoCodecIMX() ++CDVDVideoCodecIMX::CDVDVideoCodecIMX() : m_renderingFrames(CIMXRenderingFrames::GetInstance()) +{ + m_pFormatName = "iMX-xxx"; + memset(&m_decMemInfo, 0, sizeof(DecMemInfo)); @@ -1145,6 +1155,7 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + m_dropState = false; + m_tsm = NULL; + m_convert_bitstream = false; ++ m_frameCounter = 0; +} + +CDVDVideoCodecIMX::~CDVDVideoCodecIMX() @@ -1160,10 +1171,9 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + return false; + } + -+ m_outputFrameReady = false; + m_hints = hints; -+ CLog::Log(LOGDEBUG, "Let's decode with iMX VPU\n"); -+ ++ CLog::Log(LOGDEBUG, "Let's decode with iMX VPU\n"); ++ +#ifdef MEDIAINFO + CLog::Log(LOGDEBUG, "Decode: MEDIAINFO: fpsrate %d / fpsscale %d\n", m_hints.fpsrate, m_hints.fpsscale); + CLog::Log(LOGDEBUG, "Decode: MEDIAINFO: CodecID %d \n", m_hints.codec); @@ -1199,13 +1209,13 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + m_pFormatName = "iMX-mpeg2"; + break; + case CODEC_ID_H263: -+ m_decOpenParam.CodecFormat = VPU_V_H263; ++ m_decOpenParam.CodecFormat = VPU_V_H263; + m_pFormatName = "iMX-h263"; + break; + case CODEC_ID_H264: + m_decOpenParam.CodecFormat = VPU_V_AVC; + m_pFormatName = "iMX-h264"; -+ if (hints.extrasize >= 7) ++ if (hints.extradata) + { + if ( *(char*)hints.extradata == 1 ) + m_convert_bitstream = bitstream_convert_init(hints.extradata,hints.extrasize); @@ -1216,7 +1226,7 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + m_pFormatName = "iMX-vc1"; + break; +/* FIXME TODO -+ * => for this type we have to set height, width, nChromaInterleave and nMapType ++ * => for this type we have to set height, width, nChromaInterleave and nMapType + case CODEC_ID_MJPEG: + m_decOpenParam.CodecFormat = VPU_V_MJPG; + m_pFormatName = "iMX-mjpg"; @@ -1236,7 +1246,7 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + case CODEC_ID_KMVC: + m_decOpenParam.CodecFormat = VPU_V_AVC_MVC; + m_pFormatName = "iMX-MVC"; -+ break; ++ break; + case CODEC_ID_VP8: + m_decOpenParam.CodecFormat = VPU_V_VP8; + m_pFormatName = "iMX-vp8"; @@ -1284,21 +1294,20 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + VpuDecRetCode ret; + int i; + bool VPU_loaded = m_vpuHandle; -+ CIMXRenderingFrames &renderingFrames = CIMXRenderingFrames::GetInstance(); -+ -+ FlushOutputFrame(); ++ ++ FlushDecodedFrames(); + if (m_vpuHandle) -+ { ++ { + ret = VPU_DecFlushAll(m_vpuHandle); + if (ret != VPU_DEC_RET_SUCCESS) + { + CLog::Log(LOGERROR, "%s - VPU flush failed with error code %d.\n", __FUNCTION__, ret); -+ } ++ } + ret = VPU_DecClose(m_vpuHandle); + if (ret != VPU_DEC_RET_SUCCESS) + { + CLog::Log(LOGERROR, "%s - VPU close failed with error code %d.\n", __FUNCTION__, ret); -+ } ++ } + m_vpuHandle = 0; + } + @@ -1307,7 +1316,7 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + if (m_outputBuffers != NULL) + { + while (VpuDeQueueFrame(false)); -+ renderingFrames.ReleaseBuffers(); ++ m_renderingFrames.ReleaseBuffers(); + RestoreFB(); + delete m_outputBuffers; + m_outputBuffers = NULL; @@ -1366,7 +1375,7 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM +} + +int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts) -+{ ++{ + VpuDecFrameLengthInfo frameLengthInfo; + VpuBufferNode inData; + VpuDecRetCode ret; @@ -1377,9 +1386,11 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + uint8_t *demuxer_content = pData; + bool bitstream_convered = false; + bool retry = false; ++ bool bufAvail; + +#ifdef IMX_PROFILE + static unsigned long long previous, current; ++ unsigned long long before_dec; +#endif + + if (!m_vpuHandle) @@ -1394,6 +1405,7 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + CLog::Log(LOGDEBUG, "%s - delta time decode : %llu - demux size : %d dts : %f - pts : %f\n", __FUNCTION__, current - previous, iSize, dts, pts); + previous = current; +#endif ++ +/* FIXME tests + CLog::Log(LOGDEBUG, "%s - demux size : %d dts : %f - pts : %f - %x %x %x %x\n", __FUNCTION__, iSize, dts, pts, ((unsigned int *)pData)[0], ((unsigned int *)pData)[1], ((unsigned int *)pData)[2], ((unsigned int *)pData)[3]); + ((unsigned int *)pData)[0] = htonl(iSize-4); @@ -1420,7 +1432,7 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + bitstream_convered = true; + demuxer_bytes = bytestream_size; + demuxer_content = bytestream_buff; -+ } ++ } + } + + if (pts != DVD_NOPTS_VALUE) @@ -1468,7 +1480,14 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + do // Decode as long as the VPU consumes data + { + retry = false; ++#ifdef IMX_PROFILE ++ before_dec = get_time(); ++#endif + ret = VPU_DecDecodeBuf(m_vpuHandle, &inData, &decRet); ++#ifdef IMX_PROFILE ++ CLog::Log(LOGDEBUG, "%s - VPU dec 0x%x decode takes : %lld\n\n", __FUNCTION__, decRet, get_time() - before_dec); ++#endif ++ + if (ret != VPU_DEC_RET_SUCCESS) + { + CLog::Log(LOGERROR, "%s - VPU decode failed with error code %d.\n", __FUNCTION__, ret); @@ -1478,11 +1497,11 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + if (decRet & VPU_DEC_INIT_OK) + /* VPU decoding init OK : We can retrieve stream info */ + { -+ ret = VPU_DecGetInitialInfo(m_vpuHandle, &m_initInfo); ++ ret = VPU_DecGetInitialInfo(m_vpuHandle, &m_initInfo); + if (ret == VPU_DEC_RET_SUCCESS) + { + CLog::Log(LOGDEBUG, "%s - VPU Init Stream Info : %dx%d (interlaced : %d - Minframe : %d)"\ -+ " - Align : %d bytes - crop : %d %d %d %d - Q16Ratio : %x\n", __FUNCTION__, ++ " - Align : %d bytes - crop : %d %d %d %d - Q16Ratio : %x\n", __FUNCTION__, + m_initInfo.nPicWidth, m_initInfo.nPicHeight, m_initInfo.nInterlace, m_initInfo.nMinFrameBufferCount, + m_initInfo.nAddressAlignment, m_initInfo.PicCropRect.nLeft, m_initInfo.PicCropRect.nTop, + m_initInfo.PicCropRect.nRight, m_initInfo.PicCropRect.nBottom, m_initInfo.nQ16ShiftWidthDivHeightRatio); @@ -1534,9 +1553,9 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + if (VpuPushFrame(&frameInfo)) + { + retSatus |= VC_PICTURE; -+ } ++ } + } //VPU_DEC_OUTPUT_DIS -+ ++ + if (decRet & VPU_DEC_OUTPUT_REPEAT) + { + TSManagerSend(m_tsm); @@ -1581,7 +1600,7 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + TSManagerSend(m_tsm); + } + -+ ++ + if (!(decRet & VPU_DEC_OUTPUT_DIS) && + (inData.nSize != 0)) + { @@ -1596,31 +1615,45 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + } while (retry == true); + } //(pData && iSize) + ++#ifdef V4L_OUTPUT_PROFILE ++ CLog::Log(LOGDEBUG, "%s - QF : %d - HW : %d/%d/%d\n", __FUNCTION__, ++ (int)m_decodedFrames.size(), GetAvailableBufferNb(), ++ m_extraVpuBuffers, m_vpuFrameBufferNum); ++#endif + -+ if (GetAvailableBufferNb() > (m_vpuFrameBufferNum - m_extraVpuBuffers)) ++ bufAvail = GetAvailableBufferNb() > (m_vpuFrameBufferNum - m_extraVpuBuffers); ++ retSatus &= (~VC_PICTURE); ++ ++ // If there are still buffers left, fill them ++ if (bufAvail) ++ { + retSatus |= VC_BUFFER; ++ CLog::Log(LOGDEBUG, "%s - want more data\n", __FUNCTION__); ++ } + else -+ if (retSatus == 0) { -+ /* No Picture ready and Not enough VPU buffers. -+ * Lets wait for the IPU to free a buffer -+ * Anyway we have several decoded frames ready... */ -+ usleep(5000); ++ { ++ if (!m_decodedFrames.empty()) ++ retSatus |= VC_PICTURE; ++ else if (retSatus == 0) { ++ /* No Picture ready and Not enough VPU buffers. It should NOT happen so log dedicated error */ ++ CLog::Log(LOGERROR, "%s - Not hw buffer available. Waiting for 5ms\n", __FUNCTION__); ++ /* Lets wait for the IPU to free a buffer. Anyway we have several decoded frames ready */ ++ usleep(2000); + } ++ } + ++ if (bitstream_convered) ++ free(demuxer_content); + +#ifdef IMX_PROFILE + CLog::Log(LOGDEBUG, "%s - returns %x - duration %lld\n", __FUNCTION__, retSatus, get_time() - previous); +#endif -+ -+ if (bitstream_convered) -+ free(demuxer_content); -+ + return retSatus; + +out_error: -+ if (bitstream_convered) -+ free(demuxer_content); -+ return VC_ERROR; ++ if (bitstream_convered) ++ free(demuxer_content); ++ return VC_ERROR; +} + +void CDVDVideoCodecIMX::Reset() @@ -1632,8 +1665,8 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + /* We have to resync timestamp manager */ + m_tsSyncRequired = true; + -+ /* Flush the output frame */ -+ FlushOutputFrame(); ++ /* Flush decoded frames */ ++ FlushDecodedFrames(); + + /* Flush VPU */ + ret = VPU_DecFlushAll(m_vpuHandle); @@ -1649,38 +1682,36 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + // Note : It is useless if CLinuxRendererGLES::GetProcessorSize returns 0 for RENDER_FMT_IMX + return min(3, m_extraVpuBuffers / 2); +} -+ -+static double GetPlayerPtsSeconds() -+{ -+ double clock_pts = 0.0; -+ CDVDClock *playerclock = CDVDClock::GetMasterClock(); -+ if (playerclock) -+ clock_pts = playerclock->GetClock() / DVD_TIME_BASE; + -+ return clock_pts; -+} + +bool CDVDVideoCodecIMX::GetPicture(DVDVideoPicture* pDvdVideoPicture) -+{ ++{ + double currentPlayerPts; + double ts = DVD_NOPTS_VALUE; ++ DVDVideoPicture DVDFrame; + -+ if (!m_outputFrameReady) ++ if (m_decodedFrames.size() == 0) + { + CLog::Log(LOGERROR, "%s called while no picture ready\n", __FUNCTION__); + return false; + } + ++ /* Retrieve oldest decoded frame */ ++ DVDFrame = m_decodedFrames.front(); ++ m_decodedFrames.pop(); ++ //CLog::Log(LOGNOTICE, "%s - buffer(%d)\n", __FUNCTION__, DVDFrame.imxOutputFrame->v4l2BufferIdx); ++ + pDvdVideoPicture->iFlags &= DVP_FLAG_DROPPED; + if ((pDvdVideoPicture->iFlags != 0) || (m_dropState)) + { -+ CLog::Log(LOGERROR, "%s - Flushing video picture\n", __FUNCTION__); ++ CLog::Log(LOGNOTICE, "%s - Flushing video picture\n", __FUNCTION__); + pDvdVideoPicture->iFlags = DVP_FLAG_DROPPED; -+ FlushOutputFrame(); ++ VpuReleaseBufferV4L(DVDFrame.imxOutputFrame->v4l2BufferIdx); ++ DVDFrame.imxOutputFrame = NULL; + } + else + { -+ ts = m_outputFrame.pts; ++ ts = DVDFrame.pts; + currentPlayerPts = GetPlayerPtsSeconds() * (double)DVD_TIME_BASE; + if (currentPlayerPts > ts) + { @@ -1690,32 +1721,48 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + } + +#ifdef NO_V4L_RENDERING -+ VPU_DecOutFrameDisplayed(m_vpuHandle, m_outputBuffers[m_outputFrame.imxOutputFrame->v4l2BufferIdx]); -+ m_outputBuffers[m_outputFrame.imxOutputFrame->v4l2BufferIdx] = NULL; ++ if (!m_dropState) ++ { ++ VpuReleaseBufferV4L(DVDFrame.imxOutputFrame->v4l2BufferIdx); ++ } +#endif + -+ pDvdVideoPicture->pts = m_outputFrame.pts; -+ pDvdVideoPicture->dts = m_outputFrame.dts; -+ pDvdVideoPicture->iWidth = m_outputFrame.iWidth; -+ pDvdVideoPicture->iHeight = m_outputFrame.iHeight; -+ pDvdVideoPicture->iDisplayWidth = ((pDvdVideoPicture->iWidth * m_outputFrame.imxOutputFrame->nQ16ShiftWidthDivHeightRatio) + 32767) >> 16; -+ pDvdVideoPicture->iDisplayHeight = pDvdVideoPicture->iHeight; -+ pDvdVideoPicture->format = m_outputFrame.format; -+ pDvdVideoPicture->imxOutputFrame = m_outputFrame.imxOutputFrame; -+ m_outputFrameReady = false; ++ pDvdVideoPicture->pts = DVDFrame.pts; ++ pDvdVideoPicture->dts = DVDFrame.dts; ++ pDvdVideoPicture->iWidth = DVDFrame.iWidth; ++ pDvdVideoPicture->iHeight = DVDFrame.iHeight; ++ if (m_dropState) ++ { ++ pDvdVideoPicture->iDisplayWidth = DVDFrame.iWidth; ++ pDvdVideoPicture->iDisplayHeight = DVDFrame.iHeight; ++ } ++ else ++ { ++ pDvdVideoPicture->iDisplayWidth = ((pDvdVideoPicture->iWidth * DVDFrame.imxOutputFrame->nQ16ShiftWidthDivHeightRatio) + 32767) >> 16; ++ pDvdVideoPicture->iDisplayHeight = pDvdVideoPicture->iHeight; ++ } ++ pDvdVideoPicture->format = DVDFrame.format; ++ pDvdVideoPicture->imxOutputFrame = DVDFrame.imxOutputFrame; ++ ++#ifdef V4L_OUTPUT_PROFILE ++ CLog::Log(LOGDEBUG, "%s - QF : %d - HW : %d/%d/%d\n", __FUNCTION__, ++ (int)m_decodedFrames.size(), GetAvailableBufferNb(), ++ m_extraVpuBuffers, m_vpuFrameBufferNum); ++#endif + return true; +} + +void CDVDVideoCodecIMX::SetDropState(bool bDrop) +{ ++ + /* We are fast enough to continue to really decode every frames + * and avoid artefacts... + * (Of course these frames won't be rendered but only decoded !) -+ */ ++ */ + if (m_dropState != bDrop) + { -+ CLog::Log(LOGNOTICE, "%s : %d.\n", __FUNCTION__, bDrop); -+ m_dropState = bDrop; ++ m_dropState = bDrop; ++ CLog::Log(LOGNOTICE, "%s : %d\n", __FUNCTION__, bDrop); + } +} + @@ -1730,7 +1777,7 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + + m_sps_pps_size = 0; + m_sps_pps_context.sps_pps_data = NULL; -+ ++ + // nothing to filter + if (!in_extradata || in_extrasize < 6) + return false; @@ -1883,10 +1930,10 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + (*poutbuf + offset + sps_pps_size)[2] = 1; + } +} -diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h xbmc-wolfgar-imx-wip.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h ---- xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h 1970-01-01 01:00:00.000000000 +0100 -+++ xbmc-wolfgar-imx-wip.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h 2014-01-12 04:37:25.000000000 +0100 -@@ -0,0 +1,162 @@ +diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h xbmc-wolfgar-imx-wip.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h +--- xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h 1970-01-01 01:00:00.000000000 +0100 ++++ xbmc-wolfgar-imx-wip.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h 2014-01-23 23:04:12.262234815 +0100 +@@ -0,0 +1,190 @@ +#pragma once +/* + * Copyright (C) 2010-2013 Team XBMC @@ -1930,15 +1977,21 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + unsigned int phyMem_virtAddr[VPU_DEC_MAX_NUM_MEM_NUM]; + unsigned int phyMem_phyAddr[VPU_DEC_MAX_NUM_MEM_NUM]; + unsigned int phyMem_cpuAddr[VPU_DEC_MAX_NUM_MEM_NUM]; -+ unsigned int phyMem_size[VPU_DEC_MAX_NUM_MEM_NUM]; ++ unsigned int phyMem_size[VPU_DEC_MAX_NUM_MEM_NUM]; +} DecMemInfo; + +/* Output frame properties */ +struct CIMXOutputFrame { ++ // Render a picture. Calls RenderingFrames.Queue ++ void Render(struct v4l2_crop &); ++ // Clear a picture by settings the frameNo to "expired" ++ void Release() { frameNo = 0; } ++ + int v4l2BufferIdx; + VpuFieldType field; + VpuRect picCrop; + unsigned int nQ16ShiftWidthDivHeightRatio; ++ int frameNo; +#ifdef IMX_PROFILE + unsigned long long pushTS; +#endif @@ -1952,8 +2005,8 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + void *GetVirtAddr(int idx); + void *GetPhyAddr(int idx); + void ReleaseBuffers(); -+ int FindBuffer(void *); -+ int DeQueue(bool wait); ++ int FindBuffer(void *); ++ int DeQueue(bool wait); + void Queue(CIMXOutputFrame *, struct v4l2_crop &); + +private: @@ -1962,7 +2015,7 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + + static const char *m_v4lDeviceName; // V4L2 device Name + static CIMXRenderingFrames* m_instance; // Unique instance of the class -+ ++ + CCriticalSection m_renderingFramesLock; // Lock to ensure multithreading safety for class fields + bool m_ready; // Buffers are allocated and frames can be Queued/Dequeue + int m_v4lfd; // fd on V4L2 device @@ -1970,9 +2023,9 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + int m_bufferNum; // Number of allocated V4L2 buffers + struct v4l2_crop m_crop; // Current cropping properties + bool m_streamOn; // Flag that indicates whether streaming in on (from V4L point of view) -+ VpuFieldType m_currentField; // Current field type + int m_pushedFrames; // Number of frames queued in V4L2 + void **m_virtAddr; // Table holding virtual adresses of mmaped V4L2 buffers ++ int m_motionCtrl; // Current motion control algo +}; + +class CDVDVideoCodecIMX : public CDVDVideoCodec @@ -2002,10 +2055,33 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + int GetAvailableBufferNb(void); + void InitFB(void); + void RestoreFB(void); -+ void FlushOutputFrame(void); ++ void FlushDecodedFrames(void); ++ bool VpuReleaseBufferV4L(int); ++ ++ /* Helper structure which holds a queued output frame ++ * and its associated decoder frame buffer.*/ ++ struct VpuV4LFrameBuffer ++ { ++ // Returns whether the buffer is currently used (associated) ++ bool used() const { return buffer != NULL; } ++ int frameNo() const { return outputFrame.frameNo; } ++ bool expired(int frameNo) const ++ { return (buffer != NULL) && (outputFrame.frameNo < frameNo); } ++ // Associate a VPU frame buffer ++ void store(VpuFrameBuffer *b, int frameNo) { ++ buffer = b; ++ outputFrame.frameNo = frameNo; ++ } ++ // Reset the state ++ void clear() { store(NULL, 0); } ++ ++ VpuFrameBuffer *buffer; ++ CIMXOutputFrame outputFrame; ++ }; + + static const int m_extraVpuBuffers; // Number of additional buffers for VPU + ++ CIMXRenderingFrames&m_renderingFrames; // The global RenderingFrames instance + CDVDStreamInfo m_hints; // Hints from demuxer at stream opening + const char *m_pFormatName; // Current decoder format name + VpuDecOpenParam m_decOpenParam; // Parameters required to call VPU_DecOpen @@ -2018,10 +2094,9 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + int m_vpuFrameBufferNum; // Total number of allocated frame buffers + VpuFrameBuffer *m_vpuFrameBuffers; // Table of VPU frame buffers description + VpuMemDesc *m_extraMem; // Table of allocated extra Memory -+ VpuFrameBuffer **m_outputBuffers; // Table of buffer pointers from VPU (index is V4L buf index) (used to call properly VPU_DecOutFrameDisplayed) -+ DVDVideoPicture m_outputFrame; // Decoded frame ready to be retrieved by GetPicture -+ bool m_outputFrameReady; // State whether m_outputFrame is available or not -+ ++ VpuV4LFrameBuffer *m_outputBuffers; // Table of V4L buffers out of VPU (index is V4L buf index) (used to call properly VPU_DecOutFrameDisplayed) ++ std::queue m_decodedFrames; // Decoded Frames ready to be retrieved by GetPicture ++ int m_frameCounter; // Decoded frames counter + + /* FIXME : Rework is still required for fields below this line */ + @@ -2030,7 +2105,7 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + bool bitstream_convert_init(void *in_extradata, int in_extrasize); + bool bitstream_convert(BYTE* pData, int iSize, uint8_t **poutbuf, int *poutbuf_size); + static void bitstream_alloc_and_copy( uint8_t **poutbuf, int *poutbuf_size, -+ const uint8_t *sps_pps, uint32_t sps_pps_size, const uint8_t *in, uint32_t in_size); ++ const uint8_t *sps_pps, uint32_t sps_pps_size, const uint8_t *in, uint32_t in_size); + typedef struct omx_bitstream_ctx { + uint8_t length_size; + uint8_t first_idr; @@ -2045,13 +2120,13 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIM + } + } omx_bitstream_ctx; + uint32_t m_sps_pps_size; -+ omx_bitstream_ctx m_sps_pps_context; ++ omx_bitstream_ctx m_sps_pps_context; + bool m_convert_bitstream; + +}; -diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in xbmc-wolfgar-imx-wip.test/xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in ---- xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in 2014-01-10 19:50:19.000000000 +0100 -+++ xbmc-wolfgar-imx-wip.test/xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in 2014-01-12 04:37:25.000000000 +0100 +diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in xbmc-wolfgar-imx-wip.test/xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in +--- xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in 2014-01-23 22:58:27.759333479 +0100 ++++ xbmc-wolfgar-imx-wip.test/xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in 2014-01-23 23:04:12.261234816 +0100 @@ -23,6 +23,22 @@ SRCS += OpenMaxVideo.cpp SRCS += DVDVideoCodecOpenMax.cpp @@ -2075,9 +2150,9 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in xbm ifeq (@USE_LIBAMCODEC@,1) SRCS += AMLCodec.cpp SRCS += DVDVideoCodecAmlogic.cpp -diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/mfw_gst_ts.c xbmc-wolfgar-imx-wip.test/xbmc/cores/dvdplayer/DVDCodecs/Video/mfw_gst_ts.c ---- xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/mfw_gst_ts.c 1970-01-01 01:00:00.000000000 +0100 -+++ xbmc-wolfgar-imx-wip.test/xbmc/cores/dvdplayer/DVDCodecs/Video/mfw_gst_ts.c 2014-01-12 04:37:25.000000000 +0100 +diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/mfw_gst_ts.c xbmc-wolfgar-imx-wip.test/xbmc/cores/dvdplayer/DVDCodecs/Video/mfw_gst_ts.c +--- xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/mfw_gst_ts.c 1970-01-01 01:00:00.000000000 +0100 ++++ xbmc-wolfgar-imx-wip.test/xbmc/cores/dvdplayer/DVDCodecs/Video/mfw_gst_ts.c 2014-01-23 23:04:12.262234815 +0100 @@ -0,0 +1,752 @@ +/* + * Copyright (c) 2010-2012, Freescale Semiconductor, Inc. All rights reserved. @@ -2831,9 +2906,9 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/mfw_gst_ts.c xb + } + return i; +} -diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/mfw_gst_ts.h xbmc-wolfgar-imx-wip.test/xbmc/cores/dvdplayer/DVDCodecs/Video/mfw_gst_ts.h ---- xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/mfw_gst_ts.h 1970-01-01 01:00:00.000000000 +0100 -+++ xbmc-wolfgar-imx-wip.test/xbmc/cores/dvdplayer/DVDCodecs/Video/mfw_gst_ts.h 2014-01-12 04:37:25.000000000 +0100 +diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/mfw_gst_ts.h xbmc-wolfgar-imx-wip.test/xbmc/cores/dvdplayer/DVDCodecs/Video/mfw_gst_ts.h +--- xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/mfw_gst_ts.h 1970-01-01 01:00:00.000000000 +0100 ++++ xbmc-wolfgar-imx-wip.test/xbmc/cores/dvdplayer/DVDCodecs/Video/mfw_gst_ts.h 2014-01-23 23:04:12.261234816 +0100 @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2010-2012, Freescale Semiconductor, Inc. All rights reserved. @@ -3005,9 +3080,9 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDCodecs/Video/mfw_gst_ts.h xb +#endif + +#endif /*_TIMESTAMP_H_ */ -diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp xbmc-wolfgar-imx-wip.test/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp ---- xbmc-master.test/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp 2014-01-10 19:50:19.000000000 +0100 -+++ xbmc-wolfgar-imx-wip.test/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp 2014-01-12 04:55:00.000000000 +0100 +diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp xbmc-wolfgar-imx-wip.test/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +--- xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp 2014-01-23 22:58:27.826333521 +0100 ++++ xbmc-wolfgar-imx-wip.test/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp 2014-01-23 23:04:12.267234811 +0100 @@ -994,6 +994,7 @@ case RENDER_FMT_CVBREF: return "BGRA"; case RENDER_FMT_EGLIMG: return "EGLIMG"; @@ -3016,9 +3091,9 @@ diff -Naur xbmc-master.test/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp xbmc-wolfgar case RENDER_FMT_MEDIACODEC:return "MEDIACODEC"; case RENDER_FMT_NONE: return "NONE"; } -diff -Naur xbmc-master.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp xbmc-wolfgar-imx-wip.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp ---- xbmc-master.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp 2014-01-10 19:50:19.000000000 +0100 -+++ xbmc-wolfgar-imx-wip.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp 2014-01-12 04:37:25.000000000 +0100 +diff -Naur xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp xbmc-wolfgar-imx-wip.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp +--- xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp 2014-01-23 22:58:27.715333452 +0100 ++++ xbmc-wolfgar-imx-wip.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp 2014-01-23 23:04:12.259234818 +0100 @@ -20,6 +20,10 @@ //#define DEBUG_VERBOSE 1 @@ -3086,7 +3161,7 @@ diff -Naur xbmc-master.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp xbmc ManageDisplay(); // if running bypass, then the player might need the src/dst rects // for sizing video playback on a layer other than the gles layer. -@@ -498,17 +530,51 @@ +@@ -498,18 +530,53 @@ (*m_RenderUpdateCallBackFn)(m_RenderUpdateCallBackCtx, m_sourceRect, m_destRect); CRect old = g_graphicsContext.GetScissors(); @@ -3121,10 +3196,10 @@ diff -Naur xbmc-master.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp xbmc g_graphicsContext.SetScissors(old); g_graphicsContext.EndPaint(); + ++#ifdef HAS_IMXVPU + // FIXME : move in its own render mode instead of mixup with BYPASS + if (m_format == RENDER_FMT_IMX) + { -+ CIMXRenderingFrames &renderingFrames = CIMXRenderingFrames::GetInstance(); + int index = m_iYV12RenderBuffer; + struct v4l2_crop crop; + crop.c.top = (int)m_destRect.y1; @@ -3134,14 +3209,16 @@ diff -Naur xbmc-master.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp xbmc + CIMXOutputFrame *imxPicture = m_buffers[index].imxOutputFrame; + if (imxPicture != NULL) + { -+ renderingFrames.Queue(imxPicture, crop); ++ imxPicture->Render(crop); + m_buffers[index].imxOutputFrame = NULL; + } + } return; ++#endif } -@@ -597,6 +663,9 @@ + // this needs to be checked after texture validation +@@ -597,6 +664,9 @@ #ifdef HAVE_VIDEOTOOLBOXDECODER m_formats.push_back(RENDER_FMT_CVBREF); #endif @@ -3151,7 +3228,7 @@ diff -Naur xbmc-master.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp xbmc #ifdef HAS_LIBSTAGEFRIGHT m_formats.push_back(RENDER_FMT_EGLIMG); #endif -@@ -726,6 +795,13 @@ +@@ -726,6 +796,13 @@ m_renderMethod = RENDER_CVREF; break; } @@ -3165,7 +3242,26 @@ diff -Naur xbmc-master.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp xbmc #if defined(TARGET_DARWIN_IOS) else if (ios_version < 5.0 && m_format == RENDER_FMT_YUV420P) { -@@ -2667,6 +2743,15 @@ +@@ -890,6 +967,18 @@ + SAFE_RELEASE(buf.mediacodec); + } + #endif ++#ifdef HAS_IMXVPU ++ if (buf.imxOutputFrame != NULL) ++ { ++ // If we take that branch the buffer was not queued to V4L2 ++ // So release the picture now so that VPU will be given ++ // the buffer back as soon as next ::Decode() call ++ buf.imxOutputFrame->Release(); ++ buf.imxOutputFrame = NULL; ++ } ++ return; ++#endif ++ + } + + void CLinuxRendererGLES::Render(DWORD flags, int index) +@@ -2667,6 +2756,15 @@ CVBufferRetain(buf.cvBufferRef); } #endif @@ -3181,7 +3277,7 @@ diff -Naur xbmc-master.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp xbmc #ifdef HAS_LIBSTAGEFRIGHT void CLinuxRendererGLES::AddProcessor(CDVDVideoCodecStageFright* stf, EGLImageKHR eglimg, int index) { -@@ -2688,6 +2773,7 @@ +@@ -2688,6 +2786,7 @@ } #endif @@ -3189,9 +3285,9 @@ diff -Naur xbmc-master.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp xbmc #if defined(TARGET_ANDROID) void CLinuxRendererGLES::AddProcessor(CDVDMediaCodecInfo *mediacodec, int index) { -diff -Naur xbmc-master.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.h xbmc-wolfgar-imx-wip.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.h ---- xbmc-master.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.h 2014-01-10 19:50:19.000000000 +0100 -+++ xbmc-wolfgar-imx-wip.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.h 2014-01-12 04:55:00.000000000 +0100 +diff -Naur xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.h xbmc-wolfgar-imx-wip.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.h +--- xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.h 2014-01-23 22:58:27.711333449 +0100 ++++ xbmc-wolfgar-imx-wip.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.h 2014-01-23 23:04:12.259234818 +0100 @@ -42,6 +42,7 @@ class COpenMaxVideo; class CDVDVideoCodecStageFright; @@ -3220,9 +3316,9 @@ diff -Naur xbmc-master.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.h xbmc-w #ifdef HAS_LIBSTAGEFRIGHT CDVDVideoCodecStageFright* stf; EGLImageKHR eglimg; -diff -Naur xbmc-master.test/xbmc/cores/VideoRenderers/RenderFormats.h xbmc-wolfgar-imx-wip.test/xbmc/cores/VideoRenderers/RenderFormats.h ---- xbmc-master.test/xbmc/cores/VideoRenderers/RenderFormats.h 2013-10-03 04:06:35.000000000 +0200 -+++ xbmc-wolfgar-imx-wip.test/xbmc/cores/VideoRenderers/RenderFormats.h 2014-01-12 04:37:25.000000000 +0100 +diff -Naur xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/RenderFormats.h xbmc-wolfgar-imx-wip.test/xbmc/cores/VideoRenderers/RenderFormats.h +--- xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/RenderFormats.h 2014-01-23 22:58:27.714333451 +0100 ++++ xbmc-wolfgar-imx-wip.test/xbmc/cores/VideoRenderers/RenderFormats.h 2014-01-23 23:04:12.259234818 +0100 @@ -35,6 +35,7 @@ RENDER_FMT_OMXEGL, RENDER_FMT_CVBREF, @@ -3231,9 +3327,9 @@ diff -Naur xbmc-master.test/xbmc/cores/VideoRenderers/RenderFormats.h xbmc-wolfg RENDER_FMT_EGLIMG, RENDER_FMT_MEDIACODEC, }; -diff -Naur xbmc-master.test/xbmc/cores/VideoRenderers/RenderManager.cpp xbmc-wolfgar-imx-wip.test/xbmc/cores/VideoRenderers/RenderManager.cpp ---- xbmc-master.test/xbmc/cores/VideoRenderers/RenderManager.cpp 2014-01-10 19:50:19.000000000 +0100 -+++ xbmc-wolfgar-imx-wip.test/xbmc/cores/VideoRenderers/RenderManager.cpp 2014-01-12 04:37:25.000000000 +0100 +diff -Naur xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/RenderManager.cpp xbmc-wolfgar-imx-wip.test/xbmc/cores/VideoRenderers/RenderManager.cpp +--- xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/RenderManager.cpp 2014-01-23 22:58:27.712333450 +0100 ++++ xbmc-wolfgar-imx-wip.test/xbmc/cores/VideoRenderers/RenderManager.cpp 2014-01-23 23:04:12.259234818 +0100 @@ -920,6 +920,10 @@ else if(pic.format == RENDER_FMT_VAAPI) m_pRenderer->AddProcessor(*pic.vaapi, index); @@ -3245,9 +3341,9 @@ diff -Naur xbmc-master.test/xbmc/cores/VideoRenderers/RenderManager.cpp xbmc-wol #ifdef HAS_LIBSTAGEFRIGHT else if(pic.format == RENDER_FMT_EGLIMG) m_pRenderer->AddProcessor(pic.stf, pic.eglimg, index); -diff -Naur xbmc-master.test/xbmc/input/linux/LinuxInputDevices.cpp xbmc-wolfgar-imx-wip.test/xbmc/input/linux/LinuxInputDevices.cpp ---- xbmc-master.test/xbmc/input/linux/LinuxInputDevices.cpp 2014-01-10 19:50:19.000000000 +0100 -+++ xbmc-wolfgar-imx-wip.test/xbmc/input/linux/LinuxInputDevices.cpp 2014-01-12 04:37:25.000000000 +0100 +diff -Naur xbmc-gotham-latest.test/xbmc/input/linux/LinuxInputDevices.cpp xbmc-wolfgar-imx-wip.test/xbmc/input/linux/LinuxInputDevices.cpp +--- xbmc-gotham-latest.test/xbmc/input/linux/LinuxInputDevices.cpp 2014-01-23 22:58:25.249331931 +0100 ++++ xbmc-wolfgar-imx-wip.test/xbmc/input/linux/LinuxInputDevices.cpp 2014-01-23 23:04:10.023236994 +0100 @@ -1222,7 +1222,8 @@ if ((now - m_lastHotplugCheck) >= 10) @@ -3258,30 +3354,12 @@ diff -Naur xbmc-master.test/xbmc/input/linux/LinuxInputDevices.cpp xbmc-wolfgar- m_lastHotplugCheck = now; } } -diff -Naur xbmc-master.test/xbmc/powermanagement/PowerManager.cpp xbmc-wolfgar-imx-wip.test/xbmc/powermanagement/PowerManager.cpp -diff -Naur xbmc-master.test/xbmc/video/dialogs/GUIDialogVideoOSD.cpp xbmc-wolfgar-imx-wip.test/xbmc/video/dialogs/GUIDialogVideoOSD.cpp -diff -Naur xbmc-master.test/xbmc/windowing/egl/EGLNativeTypeAmlogic.cpp xbmc-wolfgar-imx-wip.test/xbmc/windowing/egl/EGLNativeTypeAmlogic.cpp ---- xbmc-master.test/xbmc/windowing/egl/EGLNativeTypeAmlogic.cpp 2014-01-10 19:50:20.000000000 +0100 -+++ xbmc-wolfgar-imx-wip.test/xbmc/windowing/egl/EGLNativeTypeAmlogic.cpp 2014-01-12 04:37:25.000000000 +0100 -@@ -17,6 +17,7 @@ - * . - * - */ -+#include - - #include "EGLNativeTypeAmlogic.h" - #include "guilib/gui3d.h" -@@ -24,7 +25,6 @@ - #include "utils/StringUtils.h" - - #include --#include - #include - #include - -diff -Naur xbmc-master.test/xbmc/windowing/egl/EGLNativeTypeIMX.cpp xbmc-wolfgar-imx-wip.test/xbmc/windowing/egl/EGLNativeTypeIMX.cpp ---- xbmc-master.test/xbmc/windowing/egl/EGLNativeTypeIMX.cpp 1970-01-01 01:00:00.000000000 +0100 -+++ xbmc-wolfgar-imx-wip.test/xbmc/windowing/egl/EGLNativeTypeIMX.cpp 2014-01-12 04:37:25.000000000 +0100 +diff -Naur xbmc-gotham-latest.test/xbmc/powermanagement/PowerManager.cpp xbmc-wolfgar-imx-wip.test/xbmc/powermanagement/PowerManager.cpp +diff -Naur xbmc-gotham-latest.test/xbmc/video/dialogs/GUIDialogVideoOSD.cpp xbmc-wolfgar-imx-wip.test/xbmc/video/dialogs/GUIDialogVideoOSD.cpp +diff -Naur xbmc-gotham-latest.test/xbmc/windowing/egl/EGLNativeTypeAmlogic.cpp xbmc-wolfgar-imx-wip.test/xbmc/windowing/egl/EGLNativeTypeAmlogic.cpp +diff -Naur xbmc-gotham-latest.test/xbmc/windowing/egl/EGLNativeTypeIMX.cpp xbmc-wolfgar-imx-wip.test/xbmc/windowing/egl/EGLNativeTypeIMX.cpp +--- xbmc-gotham-latest.test/xbmc/windowing/egl/EGLNativeTypeIMX.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ xbmc-wolfgar-imx-wip.test/xbmc/windowing/egl/EGLNativeTypeIMX.cpp 2014-01-23 23:04:12.249234827 +0100 @@ -0,0 +1,272 @@ +/* + * Copyright (C) 2011-2013 Team XBMC @@ -3555,9 +3633,9 @@ diff -Naur xbmc-master.test/xbmc/windowing/egl/EGLNativeTypeIMX.cpp xbmc-wolfgar + } + return 0; +} -diff -Naur xbmc-master.test/xbmc/windowing/egl/EGLNativeTypeIMX.h xbmc-wolfgar-imx-wip.test/xbmc/windowing/egl/EGLNativeTypeIMX.h ---- xbmc-master.test/xbmc/windowing/egl/EGLNativeTypeIMX.h 1970-01-01 01:00:00.000000000 +0100 -+++ xbmc-wolfgar-imx-wip.test/xbmc/windowing/egl/EGLNativeTypeIMX.h 2014-01-12 04:37:25.000000000 +0100 +diff -Naur xbmc-gotham-latest.test/xbmc/windowing/egl/EGLNativeTypeIMX.h xbmc-wolfgar-imx-wip.test/xbmc/windowing/egl/EGLNativeTypeIMX.h +--- xbmc-gotham-latest.test/xbmc/windowing/egl/EGLNativeTypeIMX.h 1970-01-01 01:00:00.000000000 +0100 ++++ xbmc-wolfgar-imx-wip.test/xbmc/windowing/egl/EGLNativeTypeIMX.h 2014-01-23 23:04:12.249234827 +0100 @@ -0,0 +1,62 @@ +#pragma once + @@ -3621,9 +3699,9 @@ diff -Naur xbmc-master.test/xbmc/windowing/egl/EGLNativeTypeIMX.h xbmc-wolfgar-i + struct fb_var_screeninfo m_screeninfo; + +}; -diff -Naur xbmc-master.test/xbmc/windowing/egl/EGLWrapper.cpp xbmc-wolfgar-imx-wip.test/xbmc/windowing/egl/EGLWrapper.cpp ---- xbmc-master.test/xbmc/windowing/egl/EGLWrapper.cpp 2014-01-10 19:50:20.000000000 +0100 -+++ xbmc-wolfgar-imx-wip.test/xbmc/windowing/egl/EGLWrapper.cpp 2014-01-12 04:37:25.000000000 +0100 +diff -Naur xbmc-gotham-latest.test/xbmc/windowing/egl/EGLWrapper.cpp xbmc-wolfgar-imx-wip.test/xbmc/windowing/egl/EGLWrapper.cpp +--- xbmc-gotham-latest.test/xbmc/windowing/egl/EGLWrapper.cpp 2014-01-23 22:58:27.493333312 +0100 ++++ xbmc-wolfgar-imx-wip.test/xbmc/windowing/egl/EGLWrapper.cpp 2014-01-23 23:04:12.249234827 +0100 @@ -17,11 +17,10 @@ * . * @@ -3647,9 +3725,9 @@ diff -Naur xbmc-master.test/xbmc/windowing/egl/EGLWrapper.cpp xbmc-wolfgar-imx-w { m_nativeTypes = nativeGuess; -diff -Naur xbmc-master.test/xbmc/windowing/egl/Makefile.in xbmc-wolfgar-imx-wip.test/xbmc/windowing/egl/Makefile.in ---- xbmc-master.test/xbmc/windowing/egl/Makefile.in 2014-01-10 19:50:20.000000000 +0100 -+++ xbmc-wolfgar-imx-wip.test/xbmc/windowing/egl/Makefile.in 2014-01-12 04:37:25.000000000 +0100 +diff -Naur xbmc-gotham-latest.test/xbmc/windowing/egl/Makefile.in xbmc-wolfgar-imx-wip.test/xbmc/windowing/egl/Makefile.in +--- xbmc-gotham-latest.test/xbmc/windowing/egl/Makefile.in 2014-01-23 22:58:27.445333284 +0100 ++++ xbmc-wolfgar-imx-wip.test/xbmc/windowing/egl/Makefile.in 2014-01-23 23:04:12.248234828 +0100 @@ -5,6 +5,7 @@ SRCS+= EGLNativeTypeAndroid.cpp SRCS+= EGLNativeTypeRaspberryPI.cpp