From ffb291cf48063d94049d83af8a92659f01e3213f Mon Sep 17 00:00:00 2001 From: Stephan Raue Date: Sun, 13 Apr 2014 21:33:32 +0200 Subject: [PATCH] projects/Cuboxi/patches/xbmc: update imx patch Signed-off-by: Stephan Raue --- .../patches/xbmc/xbmc-001-imx6_support.patch | 1375 +++++++++++++---- 1 file changed, 1062 insertions(+), 313 deletions(-) diff --git a/projects/Cuboxi/patches/xbmc/xbmc-001-imx6_support.patch b/projects/Cuboxi/patches/xbmc/xbmc-001-imx6_support.patch index c2c986823a..2bd44b602a 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-gotham-latest.test/configure.in xbmc-imx6-koying.test/configure.in ---- xbmc-gotham-latest.test/configure.in 2014-02-21 23:10:49.246106103 +0100 -+++ xbmc-imx6-koying.test/configure.in 2014-02-21 23:11:24.639122704 +0100 +diff -Naur xbmc-13b3/configure.in xbmc-13b3-imx6/configure.in +--- xbmc-13b3/configure.in 2014-04-13 21:22:52.829923018 +0200 ++++ xbmc-13b3-imx6/configure.in 2014-04-13 21:18:33.889476601 +0200 @@ -558,7 +558,7 @@ AC_ARG_ENABLE([codec], @@ -10,7 +10,23 @@ diff -Naur xbmc-gotham-latest.test/configure.in xbmc-imx6-koying.test/configure. [add_codecs=$enableval], [add_codecs=no]) -@@ -1993,6 +1993,17 @@ +@@ -1034,6 +1034,15 @@ + AC_MSG_RESULT($wayland_disabled) + fi + ++# i.MX6 ++AC_MSG_CHECKING([for i.MX framebuffer support]) ++AC_CHECK_HEADER([linux/mxcfb.h], have_imxfb=yes,have_imxfb=no) ++AC_MSG_RESULT($have_imxfb) ++if test "x$have_imxfb" = "xyes"; then ++ AC_DEFINE([HAS_IMXFB], [1], [Whether i.MX framebuffer support is enabled.]) ++ AC_SUBST([USE_IMXFB], 1) ++fi ++ + # Checks for platforms libraries. + if test "$use_gles" = "yes"; then + use_gl="no" +@@ -1991,6 +2000,17 @@ *libstagefright*) XB_ADD_CODEC([LIBSTAGEFRIGHT], [libstagefright], [$codecs]) ;; @@ -28,9 +44,9 @@ diff -Naur xbmc-gotham-latest.test/configure.in xbmc-imx6-koying.test/configure. *) esac done -diff -Naur xbmc-gotham-latest.test/lib/ffmpeg/libavcodec/arm/dca.h xbmc-imx6-koying.test/lib/ffmpeg/libavcodec/arm/dca.h ---- xbmc-gotham-latest.test/lib/ffmpeg/libavcodec/arm/dca.h 2014-02-21 23:10:38.903101147 +0100 -+++ xbmc-imx6-koying.test/lib/ffmpeg/libavcodec/arm/dca.h 2014-02-21 23:11:24.183122503 +0100 +diff -Naur xbmc-13b3/lib/ffmpeg/libavcodec/arm/dca.h xbmc-13b3-imx6/lib/ffmpeg/libavcodec/arm/dca.h +--- xbmc-13b3/lib/ffmpeg/libavcodec/arm/dca.h 2014-04-13 21:22:45.975925014 +0200 ++++ xbmc-13b3-imx6/lib/ffmpeg/libavcodec/arm/dca.h 2014-04-13 21:18:34.191477295 +0200 @@ -30,9 +30,9 @@ #define decode_blockcodes decode_blockcodes @@ -48,10 +64,10 @@ diff -Naur xbmc-gotham-latest.test/lib/ffmpeg/libavcodec/arm/dca.h xbmc-imx6-koy #endif /* AVCODEC_ARM_DCA_H */ + -diff -Naur xbmc-gotham-latest.test/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp xbmc-imx6-koying.test/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp ---- xbmc-gotham-latest.test/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp 2014-02-21 23:10:30.558097110 +0100 -+++ xbmc-imx6-koying.test/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp 2014-02-21 23:11:23.795122326 +0100 -@@ -714,7 +714,10 @@ +diff -Naur xbmc-13b3/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp xbmc-13b3-imx6/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp +--- xbmc-13b3/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp 2014-04-13 21:22:38.977937037 +0200 ++++ xbmc-13b3-imx6/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp 2014-04-13 21:18:35.298479839 +0200 +@@ -720,7 +720,10 @@ * will automatically add "@" instead to enable surroundXX mangling. * We don't want to do that if "default" can handle multichannel * itself (e.g. in case of a pulseaudio server). */ @@ -63,7 +79,7 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp x void **hints; -@@ -765,8 +768,8 @@ +@@ -771,8 +774,8 @@ * found by the enumeration process. Skip them as well ("hw", "dmix", * "plughw", "dsnoop"). */ @@ -73,7 +89,7 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp x && baseName != "surround40" && baseName != "surround41" && baseName != "surround50" -@@ -875,6 +878,22 @@ +@@ -881,6 +884,22 @@ AEDeviceType CAESinkALSA::AEDeviceTypeFromName(const std::string &name) { @@ -96,9 +112,9 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp x 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-gotham-latest.test/xbmc/cores/AudioEngine/Utils/AEConvert.cpp xbmc-imx6-koying.test/xbmc/cores/AudioEngine/Utils/AEConvert.cpp ---- xbmc-gotham-latest.test/xbmc/cores/AudioEngine/Utils/AEConvert.cpp 2014-02-21 23:10:30.595097127 +0100 -+++ xbmc-imx6-koying.test/xbmc/cores/AudioEngine/Utils/AEConvert.cpp 2014-02-21 23:11:23.796122326 +0100 +diff -Naur xbmc-13b3/xbmc/cores/AudioEngine/Utils/AEConvert.cpp xbmc-13b3-imx6/xbmc/cores/AudioEngine/Utils/AEConvert.cpp +--- xbmc-13b3/xbmc/cores/AudioEngine/Utils/AEConvert.cpp 2014-04-13 21:22:39.007936966 +0200 ++++ xbmc-13b3-imx6/xbmc/cores/AudioEngine/Utils/AEConvert.cpp 2014-04-13 21:18:35.320479890 +0200 @@ -841,7 +841,7 @@ _mm_empty(); #else /* no SSE2 */ @@ -108,9 +124,9 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/AudioEngine/Utils/AEConvert.cpp xb #endif return samples << 2; -diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp xbmc-imx6-koying.test/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp ---- xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp 2014-02-21 23:10:30.378097022 +0100 -+++ xbmc-imx6-koying.test/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp 2014-02-21 23:11:23.790122324 +0100 +diff -Naur xbmc-13b3/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp xbmc-13b3-imx6/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp +--- xbmc-13b3/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp 2014-04-13 21:22:38.682937885 +0200 ++++ xbmc-13b3-imx6/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp 2014-04-13 21:18:35.416480110 +0200 @@ -35,6 +35,9 @@ #include "Video/DVDVideoCodecFFmpeg.h" #include "Video/DVDVideoCodecOpenMax.h" @@ -150,9 +166,9 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCode #if defined(TARGET_DARWIN_OSX) if (!hint.software && CSettings::Get().GetBool("videoplayer.usevda")) { -diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h xbmc-imx6-koying.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h ---- xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h 2014-02-21 23:10:30.397097031 +0100 -+++ xbmc-imx6-koying.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h 2014-02-21 23:11:23.790122324 +0100 +diff -Naur xbmc-13b3/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h xbmc-13b3-imx6/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h +--- xbmc-13b3/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h 2014-04-13 21:22:38.733937740 +0200 ++++ xbmc-13b3-imx6/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h 2014-04-13 21:18:35.424480129 +0200 @@ -27,6 +27,7 @@ #include #include @@ -173,11 +189,11 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideo }; unsigned int iFlags; -diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp xbmc-imx6-koying.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-imx6-koying.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp 2014-02-21 23:11:23.790122324 +0100 -@@ -0,0 +1,950 @@ -+/* +diff -Naur xbmc-13b3/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp xbmc-13b3-imx6/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp +--- xbmc-13b3/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ xbmc-13b3-imx6/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp 2014-04-13 21:18:35.425480131 +0200 +@@ -0,0 +1,1501 @@ ++/* + * Copyright (C) 2010-2013 Team XBMC + * http://www.xbmc.org + * @@ -197,15 +213,16 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideo + * + */ + -+#include +#include "DVDVideoCodecIMX.h" + -+#include +#include ++#include +#include +#include +#include +#include ++#include ++#include +#include "threads/SingleLock.h" +#include "utils/log.h" +#include "DVDClock.h" @@ -217,17 +234,22 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideo +#define MEDIAINFO 1 +#define _4CC(c1,c2,c3,c4) (((uint32_t)(c4)<<24)|((uint32_t)(c3)<<16)|((uint32_t)(c2)<<8)|(uint32_t)(c1)) +#define Align(ptr,align) (((unsigned int)ptr + (align) - 1)/(align)*(align)) -+#define min(a, b) (adata[1] ++#define GET_VIRT_ADDR(buf) (buf)->data[0] ++#define GET_DEINTERLACER(buf) (buf)->data[2] ++#define GET_FIELDTYPE(buf) (buf)->data[3] ++ +// Experiments show that we need at least one more (+1) V4L buffer than the min value returned by the VPU -+const int CDVDVideoCodecIMX::m_extraVpuBuffers = IMX_MAX_QUEUE_SIZE + 6; ++const int CDVDVideoCodecIMX::m_extraVpuBuffers = 6; ++const int CDVDVideoCodecIMX::m_maxVpuDecodeLoops = 5; +CCriticalSection CDVDVideoCodecIMX::m_codecBufferLock; + +bool CDVDVideoCodecIMX::VpuAllocBuffers(VpuMemInfo *pMemBlock) +{ + int i, size; -+ unsigned char * ptr; ++ void* ptr; + VpuMemDesc vpuMem; + VpuDecRetCode ret; + @@ -236,7 +258,7 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideo + size = pMemBlock->MemSubBlock[i].nAlignment + pMemBlock->MemSubBlock[i].nSize; + if (pMemBlock->MemSubBlock[i].MemType == VPU_MEM_VIRT) + { // Allocate standard virtual memory -+ ptr = (unsigned char *)malloc(size); ++ ptr = malloc(size); + if(ptr == NULL) + { + CLog::Log(LOGERROR, "%s - Unable to malloc %d bytes.\n", __FUNCTION__, size); @@ -244,8 +266,9 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideo + } + pMemBlock->MemSubBlock[i].pVirtAddr = (unsigned char*)Align(ptr, pMemBlock->MemSubBlock[i].nAlignment); + -+ m_decMemInfo.virtMem[m_decMemInfo.nVirtNum] = (unsigned int)ptr; + m_decMemInfo.nVirtNum++; ++ m_decMemInfo.virtMem = (void**)realloc(m_decMemInfo.virtMem, m_decMemInfo.nVirtNum*sizeof(void*)); ++ m_decMemInfo.virtMem[m_decMemInfo.nVirtNum-1] = ptr; + } + else + { // Allocate contigous mem for DMA @@ -259,11 +282,12 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideo + 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); + -+ m_decMemInfo.phyMem_phyAddr[m_decMemInfo.nPhyNum] = (unsigned int)vpuMem.nPhyAddr; -+ 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.phyMem = (VpuMemDesc*)realloc(m_decMemInfo.phyMem, m_decMemInfo.nPhyNum*sizeof(VpuMemDesc)); ++ m_decMemInfo.phyMem[m_decMemInfo.nPhyNum-1].nPhyAddr = vpuMem.nPhyAddr; ++ m_decMemInfo.phyMem[m_decMemInfo.nPhyNum-1].nVirtAddr = vpuMem.nVirtAddr; ++ m_decMemInfo.phyMem[m_decMemInfo.nPhyNum-1].nCpuAddr = vpuMem.nCpuAddr; ++ m_decMemInfo.phyMem[m_decMemInfo.nPhyNum-1].nSize = size; + } + } + @@ -290,29 +314,39 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideo + VpuDecRetCode vpuRet; + bool ret = true; + -+ //free virtual mem -+ for(int i=0; iConvert(demuxer_content, demuxer_bytes)) @@ -762,14 +834,6 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideo + CLog::Log(LOGERROR,"%s - bitstream_convert error", __FUNCTION__); + } + -+ if (m_usePTS) -+ { -+ if (pts != DVD_NOPTS_VALUE) -+ m_pts.push(-pts); -+ else if (dts != DVD_NOPTS_VALUE) -+ m_pts.push(-dts); -+ } -+ + inData.nSize = demuxer_bytes; + inData.pPhyAddr = NULL; + inData.pVirAddr = demuxer_content; @@ -787,12 +851,13 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideo + inData.sCodecData.nSize = 0; + } + -+ do // Decode as long as the VPU consumes data ++ while (true) // Decode as long as the VPU consumes data + { -+ retry = false; +#ifdef IMX_PROFILE + before_dec = XbmcThreads::SystemClockMillis(); +#endif ++ if (m_frameReported) ++ m_bytesToBeConsumed += inData.nSize; + 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, XbmcThreads::SystemClockMillis() - before_dec); @@ -840,11 +905,31 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideo + { + ret = VPU_DecGetConsumedFrameInfo(m_vpuHandle, &frameLengthInfo); + if (ret != VPU_DEC_RET_SUCCESS) ++ { + CLog::Log(LOGERROR, "%s - VPU error retireving info about consummed frame (%d).\n", __FUNCTION__, ret); ++ } ++ m_bytesToBeConsumed -= (frameLengthInfo.nFrameLength + frameLengthInfo.nStuffLength); ++ if (frameLengthInfo.pFrame) ++ { ++ idx = VpuFindBuffer(frameLengthInfo.pFrame->pbufY); ++ if (m_bytesToBeConsumed < 50) ++ m_bytesToBeConsumed = 0; ++ if (idx != -1) ++ { ++ if (m_previousPts != DVD_NOPTS_VALUE) ++ { ++ m_outputBuffers[idx]->SetPts(m_previousPts); ++ m_previousPts = DVD_NOPTS_VALUE; ++ } ++ else ++ m_outputBuffers[idx]->SetPts(pts); ++ } ++ else ++ CLog::Log(LOGERROR, "%s - could not find frame buffer\n", __FUNCTION__); ++ } + } //VPU_DEC_ONE_FRM_CONSUMED + -+ if ((decRet & VPU_DEC_OUTPUT_DIS) || -+ (decRet & VPU_DEC_OUTPUT_MOSAIC_DIS)) ++ if (decRet & VPU_DEC_OUTPUT_DIS) + // Frame ready to be displayed + { + if (retStatus & VC_PICTURE) @@ -856,9 +941,35 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideo + CLog::Log(LOGERROR, "%s - VPU Cannot get output frame(%d).\n", __FUNCTION__, ret); + goto out_error; + } ++ ++ // Some codecs (VC1?) lie about their frame size (mod 16). Adjust... ++ m_frameInfo.pExtInfo->nFrmWidth = (((m_frameInfo.pExtInfo->nFrmWidth) + 15) & ~15); ++ m_frameInfo.pExtInfo->nFrmHeight = (((m_frameInfo.pExtInfo->nFrmHeight) + 15) & ~15); ++ + retStatus |= VC_PICTURE; + } //VPU_DEC_OUTPUT_DIS + ++ // According to libfslvpuwrap: If this flag is set then the frame should ++ // be dropped. It is just returned to gather decoder information but not ++ // for display. ++ if (decRet & VPU_DEC_OUTPUT_MOSAIC_DIS) ++ { ++ ret = VPU_DecGetOutputFrame(m_vpuHandle, &m_frameInfo); ++ if(ret != VPU_DEC_RET_SUCCESS) ++ { ++ CLog::Log(LOGERROR, "%s - VPU Cannot get output frame(%d).\n", __FUNCTION__, ret); ++ goto out_error; ++ } ++ ++ // Display frame ++ ret = VPU_DecOutFrameDisplayed(m_vpuHandle, m_frameInfo.pDisplayFrameBuf); ++ if(ret != VPU_DEC_RET_SUCCESS) ++ { ++ CLog::Log(LOGERROR, "%s: VPU Clear frame display failure(%d)\n",__FUNCTION__,ret); ++ goto out_error; ++ } ++ } //VPU_DEC_OUTPUT_MOSAIC_DIS ++ + if (decRet & VPU_DEC_OUTPUT_REPEAT) + { + CLog::Log(LOGDEBUG, "%s - Frame repeat.\n", __FUNCTION__); @@ -878,39 +989,37 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideo + if (decRet & VPU_DEC_FLUSH) + { + CLog::Log(LOGNOTICE, "%s - VPU requires a flush.\n", __FUNCTION__); -+ ret = VPU_DecFlushAll(m_vpuHandle); -+ if (ret != VPU_DEC_RET_SUCCESS) -+ { -+ CLog::Log(LOGERROR, "%s - VPU flush failed(%d).\n", __FUNCTION__, ret); -+ } ++ Reset(); + retStatus = VC_FLUSHED; + } + if (decRet & VPU_DEC_OUTPUT_EOS) + { + CLog::Log(LOGNOTICE, "%s - EOS encountered.\n", __FUNCTION__); + } -+ if (decRet & VPU_DEC_NO_ENOUGH_INBUF) ++ if ((decRet & VPU_DEC_NO_ENOUGH_INBUF) || ++ (decRet & VPU_DEC_OUTPUT_DIS)) + { + // We are done with VPU decoder that time + break; + } ++ ++ retries++; ++ if (retries >= m_maxVpuDecodeLoops) ++ { ++ CLog::Log(LOGERROR, "%s - Leaving VPU decoding loop after %d iterations\n", __FUNCTION__, m_maxVpuDecodeLoops); ++ break; ++ } ++ + if (!(decRet & VPU_DEC_INPUT_USED)) + { + CLog::Log(LOGERROR, "%s - input not used : addr %p size :%d!\n", __FUNCTION__, inData.pVirAddr, inData.nSize); + } + -+ if (!(decRet & VPU_DEC_OUTPUT_DIS) && -+ (inData.nSize != 0)) -+ { -+ // Let's process again as VPU_DEC_NO_ENOUGH_INBUF was not set -+ // and we don't have an image ready if we reach that point -+ -+ inData.pVirAddr = NULL; -+ inData.nSize = 0; -+ retry = true; -+ } -+ -+ } while (retry == true); ++ // Let's process again as VPU_DEC_NO_ENOUGH_INBUF was not set ++ // and we don't have an image ready if we reach that point ++ inData.pVirAddr = NULL; ++ inData.nSize = 0; ++ } // Decode loop + } //(pData && iSize) + + if (retStatus == 0) @@ -918,6 +1027,17 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideo + retStatus |= VC_BUFFER; + } + ++ if (m_bytesToBeConsumed > 0) ++ { ++ // Remember the current pts because the data which has just ++ // been sent to the VPU has not yet been consumed. ++ // This pts is related to the frame that will be consumed ++ // at next call... ++ m_previousPts = pts; ++ } ++ // Store current dts (will be used only if VC_PICTURE is set) ++ m_dts = dts; ++ +#ifdef IMX_PROFILE + CLog::Log(LOGDEBUG, "%s - returns %x - duration %lld\n", __FUNCTION__, retStatus, XbmcThreads::SystemClockMillis() - previous); +#endif @@ -933,14 +1053,19 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideo + + CLog::Log(LOGDEBUG, "%s - called\n", __FUNCTION__); + -+ // Clear pts queue -+ while(!m_pts.empty()) -+ m_pts.pop(); ++ // Release last buffer ++ if(m_lastBuffer) ++ SAFE_RELEASE(m_lastBuffer); + + // Invalidate all buffers + for(int i=0; i < m_vpuFrameBufferNum; i++) + m_outputBuffers[i]->ReleaseFramebuffer(&m_vpuHandle); + ++ m_frameCounter = 0; ++ m_deinterlacer.Reset(); ++ m_bytesToBeConsumed = 0; ++ m_previousPts = DVD_NOPTS_VALUE; ++ + // Flush VPU + ret = VPU_DecFlushAll(m_vpuHandle); + if (ret != VPU_DEC_RET_SUCCESS) @@ -967,6 +1092,17 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideo + +bool CDVDVideoCodecIMX::GetPicture(DVDVideoPicture* pDvdVideoPicture) +{ ++#ifdef IMX_PROFILE ++ static unsigned int previous = 0; ++ unsigned int current; ++ ++ current = XbmcThreads::SystemClockMillis(); ++ CLog::Log(LOGDEBUG, "%s tm:%03d\n", __FUNCTION__, current - previous); ++ previous = current; ++#endif ++ ++ m_frameCounter++; ++ + pDvdVideoPicture->iFlags = DVP_FLAG_ALLOCATED; + if (m_dropState) + pDvdVideoPicture->iFlags |= DVP_FLAG_DROPPED; @@ -974,7 +1110,6 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideo + pDvdVideoPicture->iFlags &= ~DVP_FLAG_DROPPED; + + pDvdVideoPicture->format = RENDER_FMT_IMXMAP; -+ pDvdVideoPicture->pts = DVD_NOPTS_VALUE; + pDvdVideoPicture->dts = DVD_NOPTS_VALUE; + pDvdVideoPicture->iWidth = m_frameInfo.pExtInfo->FrmCropRect.nRight - m_frameInfo.pExtInfo->FrmCropRect.nLeft; + pDvdVideoPicture->iHeight = m_frameInfo.pExtInfo->FrmCropRect.nBottom - m_frameInfo.pExtInfo->FrmCropRect.nTop; @@ -986,30 +1121,39 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideo + if (idx != -1) + { + CDVDVideoCodecIMXBuffer *buffer = m_outputBuffers[idx]; -+ if (m_usePTS) ++ ++ pDvdVideoPicture->pts = buffer->GetPts(); ++ pDvdVideoPicture->dts = m_dts; ++ if (!m_usePTS) + { -+ if (m_pts.size()) -+ { -+ pDvdVideoPicture->pts = -m_pts.top(); -+ m_pts.pop(); -+ } -+ else -+ CLog::Log(LOGERROR, "%s - logic error: no PTS available", __FUNCTION__); ++ pDvdVideoPicture->pts = DVD_NOPTS_VALUE; ++ pDvdVideoPicture->dts = DVD_NOPTS_VALUE; + } + -+ buffer->Queue(m_frameInfo.pDisplayFrameBuf); -+ pDvdVideoPicture->codecinfo = buffer; ++ buffer->Queue(&m_frameInfo, m_lastBuffer); + +#ifdef TRACE_FRAMES -+ CLog::Log(LOGDEBUG, "+ %02d\n", idx); -+ CLog::Log(LOGDEBUG, "pts %f\n",pDvdVideoPicture->pts); ++ CLog::Log(LOGDEBUG, "+ %02d dts %f pts %f (VPU)\n", idx, pDvdVideoPicture->dts, pDvdVideoPicture->pts); +#endif + ++ /* ++ // This does not work reliably since some streams do not report ++ // correctly if a frame is interlaced. ++ if (m_frameInfo.eFieldType != VPU_FIELD_NONE) ++ GET_DEINTERLACER(buffer) = (uint8_t*)&m_deinterlacer; ++ else ++ GET_DEINTERLACER(buffer) = NULL; ++ */ ++ ++ pDvdVideoPicture->codecinfo = buffer; + pDvdVideoPicture->codecinfo->Lock(); -+ pDvdVideoPicture->codecinfo->iWidth = m_frameInfo.pExtInfo->nFrmWidth; -+ pDvdVideoPicture->codecinfo->iHeight = m_frameInfo.pExtInfo->nFrmHeight; -+ pDvdVideoPicture->codecinfo->data[0] = m_frameInfo.pDisplayFrameBuf->pbufVirtY; -+ pDvdVideoPicture->codecinfo->data[1] = m_frameInfo.pDisplayFrameBuf->pbufY; ++ ++ // Save last buffer ++ if (m_lastBuffer) ++ SAFE_RELEASE(m_lastBuffer); ++ ++ m_lastBuffer = buffer; ++ m_lastBuffer->Lock(); + } + else + { @@ -1029,10 +1173,22 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideo + if (m_dropState != bDrop) + { + m_dropState = bDrop; -+ CLog::Log(LOGNOTICE, "%s : %d\n", __FUNCTION__, bDrop); ++#ifdef TRACE_FRAMES ++ CLog::Log(LOGDEBUG, "%s : %d\n", __FUNCTION__, bDrop); ++#endif + } +} + ++void CDVDVideoCodecIMX::Enter() ++{ ++ m_codecBufferLock.lock(); ++} ++ ++void CDVDVideoCodecIMX::Leave() ++{ ++ m_codecBufferLock.unlock(); ++} ++ +/*******************************************/ + +#ifdef TRACE_FRAMES @@ -1045,14 +1201,17 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideo +#endif + , m_frameBuffer(NULL) + , m_rendered(false) ++ , m_pts(DVD_NOPTS_VALUE) ++ , m_previousBuffer(NULL) +{ ++ GET_DEINTERLACER(this) = NULL; +} + +void CDVDVideoCodecIMXBuffer::Lock() +{ +#ifdef TRACE_FRAMES + long count = AtomicIncrement(&m_refs); -+ CLog::Log(LOGDEBUG, "R+ %02d - ref : %d\n", m_idx, count); ++ CLog::Log(LOGDEBUG, "R+ %02d - ref : %d (VPU)\n", m_idx, count); +#else + AtomicIncrement(&m_refs); +#endif @@ -1062,24 +1221,28 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideo +{ + long count = AtomicDecrement(&m_refs); +#ifdef TRACE_FRAMES -+ CLog::Log(LOGDEBUG, "R- %02d - ref : %d\n", m_idx, count); ++ CLog::Log(LOGDEBUG, "R- %02d - ref : %d (VPU)\n", m_idx, count); +#endif ++ if (count == 2) ++ { ++ // Only referenced by the coded and its next frame, release the previous ++ SAFE_RELEASE(m_previousBuffer); ++ } + if (count == 1) + { + // If count drops to 1 then the only reference is being held by the codec + // that it can be released in the next Decode call. + if(m_frameBuffer != NULL) ++ { + m_rendered = true; ++ SAFE_RELEASE(m_previousBuffer); +#ifdef TRACE_FRAMES -+ CLog::Log(LOGDEBUG, "R %02d\n", m_idx); ++ CLog::Log(LOGDEBUG, "R %02d (VPU)\n", m_idx); +#endif ++ } + } + else if (count == 0) + { -+#ifdef TRACE_FRAMES -+ CLog::Log(LOGDEBUG, "~ %02d\n", m_idx); -+#endif -+ + delete this; + } + @@ -1088,25 +1251,36 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideo + +bool CDVDVideoCodecIMXBuffer::IsValid() +{ -+ CSingleLock lock(CDVDVideoCodecIMX::m_codecBufferLock); + return m_frameBuffer != NULL; +} + -+bool CDVDVideoCodecIMXBuffer::Rendered() ++bool CDVDVideoCodecIMXBuffer::Rendered() const +{ + return m_rendered; +} + -+void CDVDVideoCodecIMXBuffer::Queue(VpuFrameBuffer *buffer) ++void CDVDVideoCodecIMXBuffer::Queue(VpuDecOutFrameInfo *frameInfo, ++ CDVDVideoCodecIMXBuffer *previous) +{ -+ CSingleLock lock(CDVDVideoCodecIMX::m_codecBufferLock); -+ m_frameBuffer = buffer; ++ // No lock necessary because at this time there is definitely no ++ // thread still holding a reference ++ m_frameBuffer = frameInfo->pDisplayFrameBuf; + m_rendered = false; ++ m_previousBuffer = previous; ++ if (m_previousBuffer) ++ m_previousBuffer->Lock(); ++ ++ iWidth = frameInfo->pExtInfo->nFrmWidth; ++ iHeight = frameInfo->pExtInfo->nFrmHeight; ++ GET_VIRT_ADDR(this) = m_frameBuffer->pbufVirtY; ++ GET_PHYS_ADDR(this) = m_frameBuffer->pbufY; ++ GET_FIELDTYPE(this) = (uint8_t*)frameInfo->eFieldType; +} + +VpuDecRetCode CDVDVideoCodecIMXBuffer::ReleaseFramebuffer(VpuDecHandle *handle) +{ -+ CSingleLock lock(CDVDVideoCodecIMX::m_codecBufferLock); ++ // Again no lock required because this is only issued after the last ++ // external reference was released + VpuDecRetCode ret = VPU_DEC_RET_FAILURE; + + if((m_frameBuffer != NULL) && *handle) @@ -1116,21 +1290,414 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideo + CLog::Log(LOGERROR, "%s: vpu clear frame display failure: ret=%d \r\n",__FUNCTION__,ret); + } +#ifdef TRACE_FRAMES -+ CLog::Log(LOGDEBUG, "- %02d\n", m_idx); ++ CLog::Log(LOGDEBUG, "- %02d (VPU)\n", m_idx); +#endif + m_rendered = false; + m_frameBuffer = NULL; ++ m_pts = DVD_NOPTS_VALUE; ++ SAFE_RELEASE(m_previousBuffer); ++ + return ret; +} + ++void CDVDVideoCodecIMXBuffer::SetPts(double pts) ++{ ++ m_pts = pts; ++} ++ ++double CDVDVideoCodecIMXBuffer::GetPts(void) const ++{ ++ return m_pts; ++} ++ ++CDVDVideoCodecIMXBuffer *CDVDVideoCodecIMXBuffer::GetPreviousBuffer() const ++{ ++ return m_previousBuffer; ++} ++ +CDVDVideoCodecIMXBuffer::~CDVDVideoCodecIMXBuffer() +{ + assert(m_refs == 0); ++#ifdef TRACE_FRAMES ++ CLog::Log(LOGDEBUG, "~ %02d (VPU)\n", m_idx); ++#endif +} -diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h xbmc-imx6-koying.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-imx6-koying.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h 2014-02-21 23:11:23.791122324 +0100 -@@ -0,0 +1,129 @@ ++ ++#ifdef TRACE_FRAMES ++CDVDVideoCodecIPUBuffer::CDVDVideoCodecIPUBuffer(int idx) ++ : m_refs(1) ++ , m_idx(idx) ++#else ++CDVDVideoCodecIPUBuffer::CDVDVideoCodecIPUBuffer() ++ : m_refs(1) ++#endif ++ , m_source(NULL) ++ , m_pPhyAddr(NULL) ++ , m_pVirtAddr(NULL) ++ , m_nSize(0) ++{ ++} ++ ++CDVDVideoCodecIPUBuffer::~CDVDVideoCodecIPUBuffer() ++{ ++ assert(m_refs == 0); ++#ifdef TRACE_FRAMES ++ CLog::Log(LOGDEBUG, "~ %02d (IPU)\n", m_idx); ++#endif ++} ++ ++void CDVDVideoCodecIPUBuffer::Lock() ++{ ++#ifdef TRACE_FRAMES ++ long count = AtomicIncrement(&m_refs); ++ CLog::Log(LOGDEBUG, "R+ %02d - ref : %d (IPU)\n", m_idx, count); ++#else ++ AtomicIncrement(&m_refs); ++#endif ++ ++} ++ ++long CDVDVideoCodecIPUBuffer::Release() ++{ ++ long count = AtomicDecrement(&m_refs); ++#ifdef TRACE_FRAMES ++ CLog::Log(LOGDEBUG, "R- %02d - ref : %d (IPU)\n", m_idx, count); ++#endif ++ if (count == 1) ++ { ++ ReleaseFrameBuffer(); ++ } ++ else if (count == 0) ++ { ++ delete this; ++ } ++ ++ return count; ++} ++ ++bool CDVDVideoCodecIPUBuffer::IsValid() ++{ ++ return m_source && m_source->IsValid() && m_pPhyAddr; ++} ++ ++bool CDVDVideoCodecIPUBuffer::Process(int fd, CDVDVideoCodecIMXBuffer *buffer, ++ VpuFieldType fieldType, int fieldFmt, ++ bool lowMotion) ++{ ++ CDVDVideoCodecIMXBuffer *previousBuffer; ++ struct ipu_task task; ++ memset(&task, 0, sizeof(task)); ++ task.priority = IPU_TASK_PRIORITY_HIGH; ++ ++ if (lowMotion) ++ previousBuffer = buffer->GetPreviousBuffer(); ++ else ++ previousBuffer = NULL; ++ ++ SAFE_RELEASE(m_source); ++ ++ iWidth = buffer->iWidth; ++ iHeight = buffer->iHeight; ++ ++ // Input is the VPU decoded frame ++ task.input.width = iWidth; ++ task.input.height = iHeight; ++ task.input.format = IPU_PIX_FMT_NV12; ++ ++ // Output is our IPU buffer ++ task.output.width = iWidth; ++ task.output.height = iHeight; ++ task.output.format = IPU_PIX_FMT_NV12; ++ task.output.paddr = (int)GET_PHYS_ADDR(this); ++ ++ // Fill current and next buffer address ++ if (lowMotion && previousBuffer && previousBuffer->IsValid()) ++ { ++ task.input.paddr = (int)GET_PHYS_ADDR(previousBuffer); ++ task.input.paddr_n = (int)GET_PHYS_ADDR(buffer); ++ task.input.deinterlace.motion = LOW_MOTION; ++ } ++ else ++ { ++ task.input.paddr = (int)GET_PHYS_ADDR(buffer); ++ task.input.deinterlace.motion = HIGH_MOTION; ++ } ++ ++ task.input.deinterlace.enable = 1; ++ task.input.deinterlace.field_fmt = fieldFmt; ++ ++ switch (fieldType) ++ { ++ case VPU_FIELD_TOP: ++ case VPU_FIELD_TB: ++ task.input.deinterlace.field_fmt |= IPU_DEINTERLACE_FIELD_TOP; ++ break; ++ case VPU_FIELD_BOTTOM: ++ case VPU_FIELD_BT: ++ task.input.deinterlace.field_fmt |= IPU_DEINTERLACE_FIELD_BOTTOM; ++ break; ++ default: ++ break; ++ } ++ ++#ifdef IMX_PROFILE ++ unsigned int time = XbmcThreads::SystemClockMillis(); ++#endif ++ int ret = ioctl(fd, IPU_QUEUE_TASK, &task); ++#ifdef IMX_PROFILE ++ CLog::Log(LOGDEBUG, "DEINT: tm:%d\n", XbmcThreads::SystemClockMillis() - time); ++#endif ++ if (ret < 0) ++ { ++ CLog::Log(LOGERROR, "IPU task failed: %s\n", strerror(errno)); ++ return false; ++ } ++ ++ buffer->Lock(); ++ ++ // Remember the source buffer. This is actually not necessary since the output ++ // buffer is the one that is used by the renderer. But keep it bound for now ++ // since this state is used in IsValid which then needs to become a flag in ++ // this class. ++ m_source = buffer; ++ m_source->Lock(); ++ ++ buffer->Release(); ++ ++ return true; ++} ++ ++void CDVDVideoCodecIPUBuffer::ReleaseFrameBuffer() ++{ ++#ifdef TRACE_FRAMES ++ CLog::Log(LOGDEBUG, "- %02d (IPU)\n", m_idx); ++#endif ++ CSingleLock lock(CDVDVideoCodecIMX::m_codecBufferLock); ++ SAFE_RELEASE(m_source); ++} ++ ++bool CDVDVideoCodecIPUBuffer::Allocate(int fd, int width, int height, int nAlign) ++{ ++ m_iWidth = Align(width,FRAME_ALIGN); ++ m_iHeight = Align(height,(2*FRAME_ALIGN)); ++ // NV12 == 12 bpp ++ m_nSize = m_iWidth*m_iHeight*12/8; ++ m_pPhyAddr = m_nSize; ++ ++ GET_PHYS_ADDR(this) = GET_VIRT_ADDR(this) = NULL; ++ ++ int r = ioctl(fd, IPU_ALLOC, &m_pPhyAddr); ++ if (r < 0) ++ { ++ m_pPhyAddr = 0; ++ CLog::Log(LOGERROR, "ioctl IPU_ALLOC fail: disable deinterlacing: %s\n", strerror(errno)); ++ return false; ++ } ++ ++ CLog::Log(LOGNOTICE, "IPU: alloc %d bytes for frame of %dx%d at 0x%x\n", ++ m_nSize, m_iWidth, m_iHeight, m_pPhyAddr); ++ ++ m_pVirtAddr = (uint8_t*)mmap(0, m_nSize, PROT_READ | PROT_WRITE, MAP_SHARED, ++ fd, m_pPhyAddr); ++ if (!m_pVirtAddr) ++ { ++ CLog::Log(LOGERROR, "IPU mmap failed: disable deinterlacing: %s\n", strerror(errno)); ++ return false; ++ } ++ ++ if (nAlign>1) ++ { ++ GET_PHYS_ADDR(this) = (uint8_t*)Align(m_pPhyAddr, nAlign); ++ GET_VIRT_ADDR(this) = (uint8_t*)Align(m_pVirtAddr, nAlign); ++ } ++ else ++ { ++ GET_PHYS_ADDR(this) = (uint8_t*)m_pPhyAddr; ++ GET_VIRT_ADDR(this) = (uint8_t*)m_pVirtAddr; ++ } ++ ++ GET_DEINTERLACER(this) = NULL; ++ ++ return true; ++} ++ ++bool CDVDVideoCodecIPUBuffer::Free(int fd) ++{ ++ CSingleLock lock(CDVDVideoCodecIMX::m_codecBufferLock); ++ bool ret = true; ++ ++ // Unmap virtual memory ++ if (m_pVirtAddr != NULL) ++ { ++ if(munmap(m_pVirtAddr, m_nSize)) ++ { ++ CLog::Log(LOGERROR, "IPU unmap failed: %s\n", strerror(errno)); ++ ret = false; ++ } ++ ++ m_pVirtAddr = NULL; ++ } ++ ++ // Free IPU memory ++ if (m_pPhyAddr) ++ { ++ if (ioctl(fd, IPU_FREE, &m_pPhyAddr)) ++ { ++ CLog::Log(LOGERROR, "IPU free buffer 0x%x failed: %s\n", ++ m_pPhyAddr, strerror(errno)); ++ ret = false; ++ } ++ ++ m_pPhyAddr = 0; ++ } ++ ++ GET_PHYS_ADDR(this) = GET_VIRT_ADDR(this) = NULL; ++ SAFE_RELEASE(m_source); ++ ++ return ret; ++} ++ ++CDVDVideoCodecIPUBuffers::CDVDVideoCodecIPUBuffers() ++ : m_ipuHandle(0) ++ , m_bufferNum(0) ++ , m_buffers(NULL) ++ , m_currentFieldFmt(0) ++{ ++} ++ ++CDVDVideoCodecIPUBuffers::~CDVDVideoCodecIPUBuffers() ++{ ++ Close(); ++} ++ ++bool CDVDVideoCodecIPUBuffers::Init(int width, int height, int numBuffers, int nAlign) ++{ ++ if (numBuffers<=0) ++ { ++ CLog::Log(LOGERROR, "IPU Init: invalid number of buffers: %d\n", numBuffers); ++ return false; ++ } ++ ++ m_ipuHandle = open("/dev/mxc_ipu", O_RDWR, 0); ++ if (m_ipuHandle<=0) ++ { ++ CLog::Log(LOGWARNING, "Failed to initialize IPU: deinterlacing disabled: %s\n", ++ strerror(errno)); ++ m_ipuHandle = 0; ++ return false; ++ } ++ ++ m_bufferNum = numBuffers; ++ m_buffers = new CDVDVideoCodecIPUBuffer*[m_bufferNum]; ++ m_currentFieldFmt = 0; ++ ++ for (int i=0; i < m_bufferNum; i++) ++ { ++#ifdef TRACE_FRAMES ++ m_buffers[i] = new CDVDVideoCodecIPUBuffer(i); ++#else ++ m_buffers[i] = new CDVDVideoCodecIPUBuffer; ++#endif ++ if (!m_buffers[i]->Allocate(m_ipuHandle, width, height, nAlign)) ++ { ++ Close(); ++ return false; ++ } ++ } ++ ++ return true; ++} ++ ++bool CDVDVideoCodecIPUBuffers::Reset() ++{ ++ for (int i=0; i < m_bufferNum; i++) ++ m_buffers[i]->ReleaseFrameBuffer(); ++ m_currentFieldFmt = 0; ++} ++ ++bool CDVDVideoCodecIPUBuffers::Close() ++{ ++ bool ret = true; ++ ++ if (m_ipuHandle) ++ { ++ for (int i=0; i < m_bufferNum; i++) ++ { ++ if (m_buffers[i] == NULL ) continue; ++ if (!m_buffers[i]->Free(m_ipuHandle)) ++ ret = false; ++ } ++ ++ // Close IPU device ++ if (close(m_ipuHandle)) ++ { ++ CLog::Log(LOGERROR, "IPU failed to close interface: %s\n", strerror(errno)); ++ ret = false; ++ } ++ ++ m_ipuHandle = 0; ++ } ++ ++ if (m_buffers) ++ { ++ for (int i=0; i < m_bufferNum; i++) ++ SAFE_RELEASE(m_buffers[i]); ++ ++ delete m_buffers; ++ m_buffers = NULL; ++ } ++ ++ m_bufferNum = 0; ++ return true; ++} ++ ++CDVDVideoCodecIPUBuffer * ++CDVDVideoCodecIPUBuffers::Process(CDVDVideoCodecBuffer *sourceBuffer, ++ VpuFieldType fieldType, bool lowMotion) ++{ ++ CDVDVideoCodecIPUBuffer *target = NULL; ++ bool ret = true; ++ ++ // TODO: Needs further checks on real streams ++ if (!m_bufferNum /*|| (fieldType == VPU_FIELD_NONE)*/) ++ return NULL; ++ ++ for (int i=0; i < m_bufferNum; i++ ) ++ { ++ if (!m_buffers[i]->Rendered()) continue; ++ ++ // IPU process: ++ // SRC: Current VPU physical buffer address + last VPU buffer address ++ // DST: IPU buffer[i] ++ ret = m_buffers[i]->Process(m_ipuHandle, (CDVDVideoCodecIMXBuffer*)sourceBuffer, ++ fieldType, m_currentFieldFmt/* | IPU_DEINTERLACE_RATE_EN*/, ++ lowMotion); ++ if (ret) ++ { ++#ifdef TRACE_FRAMES ++ CLog::Log(LOGDEBUG, "+ %02d (IPU)\n", i); ++#endif ++ target = m_buffers[i]; ++ } ++ break; ++ } ++ ++ // Buffers are there but there is no free one, this is an error! ++ // Rendering will continue with unprocessed frames ... ++ if (ret && target==NULL) ++ { ++ CLog::Log(LOGERROR, "Deinterlacing: did not find free buffer, forward unprocessed frame\n"); ++ } ++ ++ // Toggle frame index bit ++ //m_currentFieldFmt ^= IPU_DEINTERLACE_RATE_FRAME1; ++ ++ return target; ++} +diff -Naur xbmc-13b3/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h xbmc-13b3-imx6/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h +--- xbmc-13b3/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h 1970-01-01 01:00:00.000000000 +0100 ++++ xbmc-13b3-imx6/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h 2014-04-13 21:18:35.425480131 +0200 +@@ -0,0 +1,215 @@ +#pragma once +/* + * Copyright (C) 2010-2013 Team XBMC @@ -1152,7 +1719,6 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideo + * + */ +#include -+#include +#include +#include "DVDVideoCodec.h" +#include "DVDStreamInfo.h" @@ -1160,26 +1726,30 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideo +#include "threads/CriticalSection.h" +#include "utils/BitstreamConverter.h" + -+#include + +//#define IMX_PROFILE +//#define TRACE_FRAMES + -+// FIXME TODO Develop real proper CVPUBuffer class -+#define VPU_DEC_MAX_NUM_MEM_NUM 20 -+typedef struct ++class CDecMemInfo +{ ++public: ++ CDecMemInfo() ++ : nVirtNum(0) ++ , virtMem(NULL) ++ , nPhyNum(0) ++ , phyMem(NULL) ++ {} ++ + //virtual mem info + int nVirtNum; -+ unsigned int virtMem[VPU_DEC_MAX_NUM_MEM_NUM]; ++ void** virtMem; + + //phy mem info + int nPhyNum; -+ 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]; -+} DecMemInfo; ++ VpuMemDesc* phyMem; ++}; ++ ++class CDVDVideoCodecIPUBuffer; + +class CDVDVideoCodecIMXBuffer : public CDVDVideoCodecBuffer +{ @@ -1191,29 +1761,104 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideo +#endif + + // reference counting -+ virtual void Lock(); -+ virtual long Release(); -+ virtual bool IsValid(); ++ virtual void Lock(); ++ virtual long Release(); ++ virtual bool IsValid(); + -+ bool Rendered(); -+ void Queue(VpuFrameBuffer *buffer); -+ VpuDecRetCode ReleaseFramebuffer(VpuDecHandle *handle); ++ bool Rendered() const; ++ void Queue(VpuDecOutFrameInfo *frameInfo, ++ CDVDVideoCodecIMXBuffer *previous); ++ VpuDecRetCode ReleaseFramebuffer(VpuDecHandle *handle); ++ void SetPts(double pts); ++ double GetPts(void) const; ++ CDVDVideoCodecIMXBuffer *GetPreviousBuffer() const; + -+protected: ++private: + // private because we are reference counted -+ virtual ~CDVDVideoCodecIMXBuffer(); ++ virtual ~CDVDVideoCodecIMXBuffer(); + ++private: +#ifdef TRACE_FRAMES -+ int m_idx; ++ int m_idx; +#endif -+ long m_refs; -+ VpuFrameBuffer *m_frameBuffer; -+ bool m_rendered; ++ long m_refs; ++ VpuFrameBuffer *m_frameBuffer; ++ bool m_rendered; ++ double m_pts; ++ CDVDVideoCodecIMXBuffer *m_previousBuffer; // Holds a the reference counted ++ // previous buffer +}; + ++// Shared buffer that holds an IPU allocated memory block and serves as target ++// for IPU operations such as deinterlacing, rotation or color conversion. ++class CDVDVideoCodecIPUBuffer : public CDVDVideoCodecBuffer ++{ ++public: ++#ifdef TRACE_FRAMES ++ CDVDVideoCodecIPUBuffer(int idx); ++#else ++ CDVDVideoCodecIPUBuffer(); ++#endif ++ ++ // reference counting ++ virtual void Lock(); ++ virtual long Release(); ++ virtual bool IsValid(); ++ ++ // Returns whether the buffer is ready to be used ++ bool Rendered() const { return m_source == NULL; } ++ bool Process(int fd, CDVDVideoCodecIMXBuffer *buffer, ++ VpuFieldType fieldType, int fieldFmt, ++ bool lowMotion); ++ void ReleaseFrameBuffer(); ++ ++ bool Allocate(int fd, int width, int height, int nAlign); ++ bool Free(int fd); ++ ++private: ++ virtual ~CDVDVideoCodecIPUBuffer(); ++ ++private: ++#ifdef TRACE_FRAMES ++ int m_idx; ++#endif ++ long m_refs; ++ CDVDVideoCodecBuffer *m_source; ++ int m_pPhyAddr; ++ uint8_t *m_pVirtAddr; ++ int m_iWidth; ++ int m_iHeight; ++ int m_nSize; ++}; ++ ++// Collection class that manages a pool of IPU buffers that are used for ++// deinterlacing. In future they can also serve rotation or color conversion ++// buffers. ++class CDVDVideoCodecIPUBuffers ++{ ++ public: ++ CDVDVideoCodecIPUBuffers(); ++ ~CDVDVideoCodecIPUBuffers(); ++ ++ bool Init(int width, int height, int numBuffers, int nAlign); ++ bool Reset(); ++ bool Close(); ++ ++ CDVDVideoCodecIPUBuffer *Process(CDVDVideoCodecBuffer *sourceBuffer, ++ VpuFieldType fieldType, bool lowMotion); ++ ++ private: ++ int m_ipuHandle; ++ int m_bufferNum; ++ CDVDVideoCodecIPUBuffer **m_buffers; ++ int m_currentFieldFmt; ++}; ++ ++ +class CDVDVideoCodecIMX : public CDVDVideoCodec +{ + friend class CDVDVideoCodecIMXBuffer; ++ friend class CDVDVideoCodecIPUBuffer; + +public: + CDVDVideoCodecIMX(); @@ -1230,39 +1875,47 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideo + virtual const char* GetName(void) { return (const char*)m_pFormatName; } + virtual unsigned GetAllowedReferences(); + ++ static void Enter(); ++ static void Leave(); ++ +protected: + -+ bool VpuOpen(void); ++ bool VpuOpen(); + bool VpuAllocBuffers(VpuMemInfo *); -+ bool VpuFreeBuffers(void); -+ bool VpuAllocFrameBuffers(void); ++ bool VpuFreeBuffers(); ++ bool VpuAllocFrameBuffers(); + int VpuFindBuffer(void *frameAddr); + -+ static const int m_extraVpuBuffers; // Number of additional buffers for VPU -+ static CCriticalSection m_codecBufferLock; ++ static const int m_extraVpuBuffers; // Number of additional buffers for VPU ++ static const int m_maxVpuDecodeLoops; // Maximum iterations in VPU decoding loop ++ static CCriticalSection m_codecBufferLock; + -+ 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 -+ DecMemInfo m_decMemInfo; // VPU dedicated memory description -+ VpuDecHandle m_vpuHandle; // Handle for VPU library calls -+ VpuDecInitInfo m_initInfo; // Initial info returned from VPU at decoding start -+ bool m_dropState; // Current drop state -+ int m_vpuFrameBufferNum; // Total number of allocated frame buffers -+ VpuFrameBuffer *m_vpuFrameBuffers; // Table of VPU frame buffers description ++ 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 ++ CDecMemInfo m_decMemInfo; // VPU dedicated memory description ++ VpuDecHandle m_vpuHandle; // Handle for VPU library calls ++ VpuDecInitInfo m_initInfo; // Initial info returned from VPU at decoding start ++ bool m_dropState; // Current drop state ++ int m_vpuFrameBufferNum; // Total number of allocated frame buffers ++ VpuFrameBuffer *m_vpuFrameBuffers; // Table of VPU frame buffers description ++ CDVDVideoCodecIPUBuffers m_deinterlacer; + CDVDVideoCodecIMXBuffer **m_outputBuffers; -+ VpuMemDesc *m_extraMem; // Table of allocated extra Memory -+// VpuMemDesc *m_outputBuffers; // Table of buffers out of VPU (used to call properly VPU_DecOutFrameDisplayed) -+ int m_frameCounter; // Decoded frames counter -+ bool m_usePTS; // State whether pts out of decoding process should be used -+ std::priority_queue m_pts; -+ VpuDecOutFrameInfo m_frameInfo; -+ CBitstreamConverter *m_converter; -+ bool m_convert_bitstream; ++ CDVDVideoCodecIMXBuffer *m_lastBuffer; ++ VpuMemDesc *m_extraMem; // Table of allocated extra Memory ++ int m_frameCounter; // Decoded frames counter ++ bool m_usePTS; // State whether pts out of decoding process should be used ++ VpuDecOutFrameInfo m_frameInfo; ++ CBitstreamConverter *m_converter; ++ bool m_convert_bitstream; ++ int m_bytesToBeConsumed; // Remaining bytes in VPU ++ double m_previousPts; // Enable to keep pts when needed ++ bool m_frameReported; // State whether the frame consumed event will be reported by libfslvpu ++ double m_dts; // Current dts +}; -diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecInfo.h xbmc-imx6-koying.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecInfo.h ---- xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecInfo.h 1970-01-01 01:00:00.000000000 +0100 -+++ xbmc-imx6-koying.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecInfo.h 2014-02-21 23:11:23.791122324 +0100 +diff -Naur xbmc-13b3/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecInfo.h xbmc-13b3-imx6/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecInfo.h +--- xbmc-13b3/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecInfo.h 1970-01-01 01:00:00.000000000 +0100 ++++ xbmc-13b3-imx6/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecInfo.h 2014-04-13 21:18:35.425480131 +0200 @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2010-2013 Team XBMC @@ -1302,9 +1955,9 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideo +}; + +#endif // DVDVIDEOCODECINFO_H -diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in xbmc-imx6-koying.test/xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in ---- xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in 2014-02-21 23:10:30.382097024 +0100 -+++ xbmc-imx6-koying.test/xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in 2014-02-21 23:11:23.790122324 +0100 +diff -Naur xbmc-13b3/xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in xbmc-13b3-imx6/xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in +--- xbmc-13b3/xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in 2014-04-13 21:22:38.706937819 +0200 ++++ xbmc-13b3-imx6/xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in 2014-04-13 21:18:35.427480135 +0200 @@ -24,6 +24,9 @@ SRCS += OpenMaxVideo.cpp SRCS += DVDVideoCodecOpenMax.cpp @@ -1315,9 +1968,9 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile ifeq (@USE_LIBAMCODEC@,1) SRCS += AMLCodec.cpp SRCS += DVDVideoCodecAmlogic.cpp -diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp xbmc-imx6-koying.test/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp ---- xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp 2014-02-21 23:10:30.530097095 +0100 -+++ xbmc-imx6-koying.test/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp 2014-02-21 23:11:23.794122325 +0100 +diff -Naur xbmc-13b3/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp xbmc-13b3-imx6/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +--- xbmc-13b3/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp 2014-04-13 21:22:38.877937332 +0200 ++++ xbmc-13b3-imx6/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp 2014-04-13 21:18:35.456480202 +0200 @@ -995,6 +995,8 @@ case RENDER_FMT_EGLIMG: return "EGLIMG"; case RENDER_FMT_BYPASS: return "BYPASS"; @@ -1327,15 +1980,17 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp xbmc- case RENDER_FMT_NONE: return "NONE"; } return "UNKNOWN"; -diff -Naur xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp xbmc-imx6-koying.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp ---- xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp 2014-02-21 23:10:30.329096998 +0100 -+++ xbmc-imx6-koying.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp 2014-02-21 23:11:23.788122322 +0100 -@@ -76,6 +76,15 @@ +diff -Naur xbmc-13b3/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp xbmc-13b3-imx6/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp +--- xbmc-13b3/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp 2014-04-13 21:22:38.630938033 +0200 ++++ xbmc-13b3-imx6/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp 2014-04-13 21:18:35.391480053 +0200 +@@ -76,6 +76,17 @@ static PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES; #endif +#ifdef HAS_IMXVPU +#include "windowing/egl/EGLWrapper.h" ++#include "DVDCodecs/Video/DVDVideoCodecIMX.h" ++ +#define GL_VIV_NV12 0x8FC1 +typedef void (GL_APIENTRYP PFNGLTEXDIRECTVIVMAPPROC) (GLenum Target, GLsizei Width, GLsizei Height, GLenum Format, GLvoid ** Logical, const GLuint * Physical); +typedef void (GL_APIENTRYP PFNGLTEXDIRECTINVALIDATEVIVPROC) (GLenum Target); @@ -1346,7 +2001,7 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.c #if defined(TARGET_ANDROID) #include "DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.h" #endif -@@ -100,6 +109,7 @@ +@@ -100,6 +111,7 @@ #if defined(TARGET_ANDROID) mediacodec = NULL; #endif @@ -1354,7 +2009,7 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.c } CLinuxRendererGLES::YUVBUFFER::~YUVBUFFER() -@@ -151,6 +161,12 @@ +@@ -151,6 +163,12 @@ if (!glEGLImageTargetTexture2DOES) glEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) CEGLWrapper::GetProcAddress("glEGLImageTargetTexture2DOES"); #endif @@ -1367,7 +2022,7 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.c } CLinuxRendererGLES::~CLinuxRendererGLES() -@@ -279,6 +295,10 @@ +@@ -279,6 +297,10 @@ { return source; } @@ -1378,7 +2033,7 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.c #ifdef HAVE_VIDEOTOOLBOXDECODER if (m_renderMethod & RENDER_CVREF ) -@@ -604,6 +624,10 @@ +@@ -604,6 +626,10 @@ #if defined(TARGET_ANDROID) m_formats.push_back(RENDER_FMT_MEDIACODEC); #endif @@ -1389,7 +2044,7 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.c // setup the background colour m_clearColour = (float)(g_advancedSettings.m_videoBlackBarColour & 0xff) / 0xff; -@@ -715,6 +739,16 @@ +@@ -715,6 +741,16 @@ m_renderMethod = RENDER_MEDIACODEC; break; } @@ -1406,7 +2061,7 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.c else if (m_format == RENDER_FMT_BYPASS) { CLog::Log(LOGNOTICE, "GL: Using BYPASS render method"); -@@ -807,6 +841,18 @@ +@@ -807,6 +843,18 @@ m_textureCreate = &CLinuxRendererGLES::CreateNV12Texture; m_textureDelete = &CLinuxRendererGLES::DeleteNV12Texture; } @@ -1425,7 +2080,7 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.c else { // default to YV12 texture handlers -@@ -952,6 +998,10 @@ +@@ -952,6 +1000,10 @@ { RenderSurfaceTexture(index, m_currentField); } @@ -1436,7 +2091,7 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.c else { RenderSoftware(index, m_currentField); -@@ -1156,7 +1206,7 @@ +@@ -1156,7 +1208,7 @@ // imgwidth *= planes[0].pixpertex_x; // imgheight *= planes[0].pixpertex_y; // } @@ -1445,7 +2100,7 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.c // glBegin(GL_QUADS); // // glMultiTexCoord2fARB(GL_TEXTURE0, planes[0].rect.x1, planes[0].rect.y1); -@@ -1578,6 +1628,75 @@ +@@ -1578,6 +1630,85 @@ #endif } @@ -1459,7 +2114,15 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.c + YUVPLANE &plane = m_buffers[index].fields[field][0]; + CDVDVideoCodecBuffer* codecinfo = m_buffers[index].codecinfo; + -+ if((codecinfo == NULL) || !codecinfo->IsValid()) return; ++ if(codecinfo == NULL) return; ++ ++ CDVDVideoCodecIMX::Enter(); ++ ++ if(!codecinfo->IsValid()) ++ { ++ CDVDVideoCodecIMX::Leave(); ++ return; ++ } + + glDisable(GL_DEPTH_TEST); + @@ -1512,6 +2175,8 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.c + glBindTexture(m_textureTarget, 0); + VerifyGLState(); + ++ CDVDVideoCodecIMX::Leave(); ++ +#ifdef DEBUG_VERBOSE + CLog::Log(LOGDEBUG, "RenderIMXMAPTexture %d: tm:%d\n", index, XbmcThreads::SystemClockMillis() - time); +#endif @@ -1521,7 +2186,7 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.c bool CLinuxRendererGLES::RenderCapture(CRenderCapture* capture) { if (!m_bValidated) -@@ -2299,7 +2418,7 @@ +@@ -2299,7 +2430,7 @@ glTexParameteri(m_textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(m_textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -1530,7 +2195,7 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.c glTexParameteri(m_textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(m_textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glPixelStorei(GL_UNPACK_ALIGNMENT, 4); -@@ -2405,7 +2524,7 @@ +@@ -2405,7 +2536,7 @@ glTexParameteri(m_textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(m_textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -1539,7 +2204,7 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.c glTexParameteri(m_textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(m_textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); -@@ -2479,6 +2598,84 @@ +@@ -2479,6 +2610,84 @@ return true; } @@ -1624,7 +2289,7 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.c void CLinuxRendererGLES::SetTextureFilter(GLenum method) { for (int i = 0 ; iIsValid()) ++ if(codecinfo) + { ++ CDVDVideoCodecIMX::Enter(); ++ ++ if(!codecinfo->IsValid()) ++ { ++ CDVDVideoCodecIMX::Leave(); ++ return; ++ } ++ + YUVPLANE &plane = m_buffers[index].fields[0][0]; ++ CDVDVideoCodecIPUBuffers *deinterlacer = (CDVDVideoCodecIPUBuffers*)codecinfo->data[2]; ++ ++ if (deinterlacer) ++ { ++ EDEINTERLACEMODE deinterlacemode = CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode; ++ ++ if (deinterlacemode != VS_DEINTERLACEMODE_OFF) ++ { ++ CDVDVideoCodecBuffer *deint; ++ EINTERLACEMETHOD interlacemethod = CMediaSettings::Get().GetCurrentVideoSettings().m_InterlaceMethod; ++ deint = deinterlacer->Process(codecinfo, (VpuFieldType)(int)codecinfo->data[3], ++ interlacemethod == VS_INTERLACEMETHOD_DEINTERLACE); ++ if (deint) ++ { ++ SAFE_RELEASE(buf.codecinfo); ++ buf.codecinfo = deint; ++ buf.codecinfo->Lock(); ++ codecinfo = buf.codecinfo; ++ } ++ } ++ } + + glActiveTexture(GL_TEXTURE0); + glBindTexture(m_textureTarget, plane.id); + + GLuint physical = ~0U; ++ GLvoid *virt = (GLvoid*)codecinfo->data[0]; + glTexDirectVIVMap(m_textureTarget, codecinfo->iWidth, codecinfo->iHeight, GL_VIV_NV12, -+ (GLvoid **)(&codecinfo->data[0]), &physical); ++ (GLvoid **)&virt, &physical); + glTexDirectInvalidateVIV(m_textureTarget); + + glBindTexture(m_textureTarget, 0); @@ -1656,6 +2351,8 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.c + plane.texheight = codecinfo->iHeight; + + CalculateTextureSourceRects(index, 1); ++ ++ CDVDVideoCodecIMX::Leave(); + } + +#endif @@ -1707,7 +2404,48 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.c bool CLinuxRendererGLES::Supports(ERENDERFEATURE feature) { // Player controls render, let it dictate available render features -@@ -2737,5 +3010,16 @@ +@@ -2574,9 +2891,14 @@ + if(m_renderMethod & RENDER_CVREF) + return false; + ++#ifdef HAS_IMXVPU ++ if(mode == VS_DEINTERLACEMODE_AUTO) ++ return true; ++#else + if(mode == VS_DEINTERLACEMODE_AUTO + || mode == VS_DEINTERLACEMODE_FORCE) + return true; ++#endif + + return false; + } +@@ -2605,6 +2927,15 @@ + if(method == VS_INTERLACEMETHOD_AUTO) + return true; + ++ if(m_renderMethod & RENDER_IMXMAP) ++ { ++ if(method == VS_INTERLACEMETHOD_DEINTERLACE ++ || method == VS_INTERLACEMETHOD_DEINTERLACE_HALF) ++ return true; ++ else ++ return false; ++ } ++ + #if defined(__i386__) || defined(__x86_64__) + if(method == VS_INTERLACEMETHOD_DEINTERLACE + || method == VS_INTERLACEMETHOD_DEINTERLACE_HALF +@@ -2653,6 +2984,9 @@ + if(m_renderMethod & RENDER_CVREF) + return VS_INTERLACEMETHOD_NONE; + ++ if(m_renderMethod & RENDER_IMXMAP) ++ return VS_INTERLACEMETHOD_DEINTERLACE_HALF; ++ + #if defined(__i386__) || defined(__x86_64__) + return VS_INTERLACEMETHOD_DEINTERLACE_HALF; + #else +@@ -2737,5 +3071,16 @@ } #endif @@ -1724,9 +2462,9 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.c + #endif -diff -Naur xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.h xbmc-imx6-koying.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.h ---- xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.h 2014-02-21 23:10:30.317096992 +0100 -+++ xbmc-imx6-koying.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.h 2014-02-21 23:11:23.788122322 +0100 +diff -Naur xbmc-13b3/xbmc/cores/VideoRenderers/LinuxRendererGLES.h xbmc-13b3-imx6/xbmc/cores/VideoRenderers/LinuxRendererGLES.h +--- xbmc-13b3/xbmc/cores/VideoRenderers/LinuxRendererGLES.h 2014-04-13 21:22:38.615938076 +0200 ++++ xbmc-13b3-imx6/xbmc/cores/VideoRenderers/LinuxRendererGLES.h 2014-04-13 21:18:35.391480053 +0200 @@ -33,6 +33,7 @@ #include "guilib/GraphicContext.h" #include "BaseRenderer.h" @@ -1782,9 +2520,9 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/LinuxRendererGLES.h }; typedef YUVBUFFER YUVBUFFERS[NUM_BUFFERS]; -diff -Naur xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/RenderFormats.h xbmc-imx6-koying.test/xbmc/cores/VideoRenderers/RenderFormats.h ---- xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/RenderFormats.h 2014-02-21 23:10:30.318096992 +0100 -+++ xbmc-imx6-koying.test/xbmc/cores/VideoRenderers/RenderFormats.h 2014-02-21 23:11:23.788122322 +0100 +diff -Naur xbmc-13b3/xbmc/cores/VideoRenderers/RenderFormats.h xbmc-13b3-imx6/xbmc/cores/VideoRenderers/RenderFormats.h +--- xbmc-13b3/xbmc/cores/VideoRenderers/RenderFormats.h 2014-04-13 21:22:38.629938036 +0200 ++++ xbmc-13b3-imx6/xbmc/cores/VideoRenderers/RenderFormats.h 2014-04-13 21:18:35.394480060 +0200 @@ -37,6 +37,8 @@ RENDER_FMT_BYPASS, RENDER_FMT_EGLIMG, @@ -1794,21 +2532,23 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/RenderFormats.h xbm }; #endif -diff -Naur xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/RenderManager.cpp xbmc-imx6-koying.test/xbmc/cores/VideoRenderers/RenderManager.cpp ---- xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/RenderManager.cpp 2014-02-21 23:10:30.318096992 +0100 -+++ xbmc-imx6-koying.test/xbmc/cores/VideoRenderers/RenderManager.cpp 2014-02-21 23:11:23.788122322 +0100 -@@ -928,6 +928,8 @@ +diff -Naur xbmc-13b3/xbmc/cores/VideoRenderers/RenderManager.cpp xbmc-13b3-imx6/xbmc/cores/VideoRenderers/RenderManager.cpp +--- xbmc-13b3/xbmc/cores/VideoRenderers/RenderManager.cpp 2014-04-13 21:22:38.619938064 +0200 ++++ xbmc-13b3-imx6/xbmc/cores/VideoRenderers/RenderManager.cpp 2014-04-13 21:18:35.394480060 +0200 +@@ -928,6 +928,10 @@ else if(pic.format == RENDER_FMT_MEDIACODEC) m_pRenderer->AddProcessor(pic.mediacodec, index); #endif ++#ifdef HAS_IMXVPU + else if(pic.format == RENDER_FMT_YV12_BUFFER || pic.format == RENDER_FMT_IMXMAP) + m_pRenderer->AddProcessor(pic.codecinfo, index); ++#endif m_pRenderer->ReleaseImage(index, false); -diff -Naur xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/VideoShaders/YUV2RGBShader.cpp xbmc-imx6-koying.test/xbmc/cores/VideoRenderers/VideoShaders/YUV2RGBShader.cpp ---- xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/VideoShaders/YUV2RGBShader.cpp 2014-02-21 23:10:30.315096991 +0100 -+++ xbmc-imx6-koying.test/xbmc/cores/VideoRenderers/VideoShaders/YUV2RGBShader.cpp 2014-02-21 23:11:23.788122322 +0100 +diff -Naur xbmc-13b3/xbmc/cores/VideoRenderers/VideoShaders/YUV2RGBShader.cpp xbmc-13b3-imx6/xbmc/cores/VideoRenderers/VideoShaders/YUV2RGBShader.cpp +--- xbmc-13b3/xbmc/cores/VideoRenderers/VideoShaders/YUV2RGBShader.cpp 2014-04-13 21:22:38.593938138 +0200 ++++ xbmc-13b3-imx6/xbmc/cores/VideoRenderers/VideoShaders/YUV2RGBShader.cpp 2014-04-13 21:18:35.395480062 +0200 @@ -39,12 +39,12 @@ // // Transformation matrixes for different colorspaces. @@ -1865,24 +2605,12 @@ diff -Naur xbmc-gotham-latest.test/xbmc/cores/VideoRenderers/VideoShaders/YUV2RG m_defines += "#define XBMC_YV12\n"; else if (m_format == RENDER_FMT_NV12) m_defines += "#define XBMC_NV12\n"; -diff -Naur xbmc-gotham-latest.test/xbmc/input/linux/LinuxInputDevices.cpp xbmc-imx6-koying.test/xbmc/input/linux/LinuxInputDevices.cpp ---- xbmc-gotham-latest.test/xbmc/input/linux/LinuxInputDevices.cpp 2014-02-21 23:10:27.131095441 +0100 -+++ xbmc-imx6-koying.test/xbmc/input/linux/LinuxInputDevices.cpp 2014-02-21 23:11:23.525122201 +0100 -@@ -1222,7 +1222,8 @@ - - if ((now - m_lastHotplugCheck) >= 10) - { -- CheckHotplugged(); -+ // Comment for now as it has visible issue on video decoding when USB devices are available -+ //CheckHotplugged(); - m_lastHotplugCheck = now; - } - } -diff -Naur xbmc-gotham-latest.test/xbmc/powermanagement/PowerManager.cpp xbmc-imx6-koying.test/xbmc/powermanagement/PowerManager.cpp -diff -Naur xbmc-gotham-latest.test/xbmc/windowing/egl/EGLNativeTypeIMX.cpp xbmc-imx6-koying.test/xbmc/windowing/egl/EGLNativeTypeIMX.cpp ---- xbmc-gotham-latest.test/xbmc/windowing/egl/EGLNativeTypeIMX.cpp 1970-01-01 01:00:00.000000000 +0100 -+++ xbmc-imx6-koying.test/xbmc/windowing/egl/EGLNativeTypeIMX.cpp 2014-02-21 23:11:23.780122319 +0100 -@@ -0,0 +1,300 @@ +diff -Naur xbmc-13b3/xbmc/input/linux/LinuxInputDevices.cpp xbmc-13b3-imx6/xbmc/input/linux/LinuxInputDevices.cpp +diff -Naur xbmc-13b3/xbmc/powermanagement/PowerManager.cpp xbmc-13b3-imx6/xbmc/powermanagement/PowerManager.cpp +diff -Naur xbmc-13b3/xbmc/windowing/egl/EGLNativeTypeIMX.cpp xbmc-13b3-imx6/xbmc/windowing/egl/EGLNativeTypeIMX.cpp +--- xbmc-13b3/xbmc/windowing/egl/EGLNativeTypeIMX.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ xbmc-13b3-imx6/xbmc/windowing/egl/EGLNativeTypeIMX.cpp 2014-04-13 21:18:35.990481429 +0200 +@@ -0,0 +1,321 @@ +/* + * Copyright (C) 2011-2013 Team XBMC + * http://www.xbmc.org @@ -1917,8 +2645,12 @@ diff -Naur xbmc-gotham-latest.test/xbmc/windowing/egl/EGLNativeTypeIMX.cpp xbmc- +#include "utils/Environment.h" +#include "guilib/gui3d.h" +#include "windowing/WindowingFactory.h" ++#include "cores/AudioEngine/AEFactory.h" ++#include + +CEGLNativeTypeIMX::CEGLNativeTypeIMX() ++ : m_display(NULL) ++ , m_window(NULL) +{ +} + @@ -1928,13 +2660,8 @@ diff -Naur xbmc-gotham-latest.test/xbmc/windowing/egl/EGLNativeTypeIMX.cpp xbmc- + +bool CEGLNativeTypeIMX::CheckCompatibility() +{ -+ char name[256] = {0}; -+ get_sysfs_str("/sys/class/graphics/fb0/device/modalias", name, 255); -+ CStdString strName = name; -+ StringUtils::Trim(strName); -+ if (strName == "platform:mxc_sdc_fb") -+ return true; -+ return false; ++ std::ifstream file("/sys/class/graphics/fb0/fsl_disp_dev_property"); ++ return file; +} + +void CEGLNativeTypeIMX::Initialize() @@ -1948,7 +2675,7 @@ diff -Naur xbmc-gotham-latest.test/xbmc/windowing/egl/EGLNativeTypeIMX.cpp xbmc- + return; + } + -+ // Unblank the fbs ++ // Unblank the fb + if (ioctl(fd, FBIOBLANK, 0) < 0) + { + CLog::Log(LOGERROR, "%s - Error while unblanking fb0.\n", __FUNCTION__); @@ -1956,6 +2683,7 @@ diff -Naur xbmc-gotham-latest.test/xbmc/windowing/egl/EGLNativeTypeIMX.cpp xbmc- + + close(fd); + ++ // Check if we can change the framebuffer resolution + fd = open("/sys/class/graphics/fb0/mode", O_RDWR); + if (fd >= 0) + { @@ -2005,6 +2733,9 @@ diff -Naur xbmc-gotham-latest.test/xbmc/windowing/egl/EGLNativeTypeIMX.cpp xbmc- + +bool CEGLNativeTypeIMX::CreateNativeDisplay() +{ ++ // Force double-buffering ++ CEnvironment::setenv("FB_MULTI_BUFFER", "2", 0); ++ + // EGL will be rendered on fb0 + m_display = fbGetDisplayByIndex(0); + m_nativeDisplay = &m_display; @@ -2022,6 +2753,8 @@ diff -Naur xbmc-gotham-latest.test/xbmc/windowing/egl/EGLNativeTypeIMX.cpp xbmc- +{ + if (!nativeDisplay) + return false; ++ if (!m_nativeDisplay) ++ return false; + *nativeDisplay = (XBNativeDisplayType*)m_nativeDisplay; + return true; +} @@ -2030,24 +2763,32 @@ diff -Naur xbmc-gotham-latest.test/xbmc/windowing/egl/EGLNativeTypeIMX.cpp xbmc- +{ + if (!nativeWindow) + return false; ++ if (!m_nativeWindow || !m_window) ++ return false; + *nativeWindow = (XBNativeWindowType*)m_nativeWindow; + return true; +} + +bool CEGLNativeTypeIMX::DestroyNativeDisplay() +{ ++ if (m_display) ++ fbDestroyDisplay(m_display); ++ m_display = NULL; + return true; +} + +bool CEGLNativeTypeIMX::DestroyNativeWindow() +{ ++ if (m_window) ++ fbDestroyWindow(m_window); ++ m_window = NULL; + return true; +} + +bool CEGLNativeTypeIMX::GetNativeResolution(RESOLUTION_INFO *res) const +{ -+ char mode[256] = {0}; -+ get_sysfs_str("/sys/class/graphics/fb0/mode", mode, 255); ++ std::string mode; ++ get_sysfs_str("/sys/class/graphics/fb0/mode", mode); + return ModeToResolution(mode, res); +} + @@ -2056,9 +2797,22 @@ diff -Naur xbmc-gotham-latest.test/xbmc/windowing/egl/EGLNativeTypeIMX.cpp xbmc- + if (m_readonly) + return false; + -+ set_sysfs_str("/sys/class/graphics/fb0/blank", "1"); -+ set_sysfs_str("/sys/class/graphics/fb0/mode", res.strId.c_str()); -+ set_sysfs_str("/sys/class/graphics/fb0/blank", "0"); ++ std::string mode; ++ get_sysfs_str("/sys/class/graphics/fb0/mode", mode); ++ if (res.strId == mode) ++ return false; ++ ++ DestroyNativeWindow(); ++ DestroyNativeDisplay(); ++ ++ set_sysfs_str("/sys/class/graphics/fb0/mode", res.strId); ++ ++ CreateNativeDisplay(); ++ ++ CLog::Log(LOGDEBUG, "%s: %s",__FUNCTION__, res.strId.c_str()); ++ ++ // Reset AE ++ CAEFactory::DeviceChange(); + + return true; +} @@ -2068,8 +2822,8 @@ diff -Naur xbmc-gotham-latest.test/xbmc/windowing/egl/EGLNativeTypeIMX.cpp xbmc- + if (m_readonly) + return false; + -+ char valstr[256] = {0}; -+ get_sysfs_str("/sys/class/graphics/fb0/modes", valstr, 255); ++ std::string valstr; ++ get_sysfs_str("/sys/class/graphics/fb0/modes", valstr); + std::vector probe_str; + StringUtils::SplitString(valstr, "\n", probe_str); + @@ -2077,9 +2831,9 @@ diff -Naur xbmc-gotham-latest.test/xbmc/windowing/egl/EGLNativeTypeIMX.cpp xbmc- + RESOLUTION_INFO res; + for (size_t i = 0; i < probe_str.size(); i++) + { -+ if(!StringUtils::StartsWith(probe_str[i], "U:")) // && !StringUtils::StartsWith(mode, "S:")) ++ if(!StringUtils::StartsWith(probe_str[i], "S:")) + continue; -+ if(ModeToResolution(probe_str[i].c_str(), &res)) ++ if(ModeToResolution(probe_str[i], &res)) + resolutions.push_back(res); + } + return resolutions.size() > 0; @@ -2092,56 +2846,51 @@ diff -Naur xbmc-gotham-latest.test/xbmc/windowing/egl/EGLNativeTypeIMX.cpp xbmc- + +bool CEGLNativeTypeIMX::ShowWindow(bool show) +{ -+ // Force vsync depending on FB_MULTI_BUFFER -+ EGLBoolean status; -+ EGLint result; -+ -+ std::string fb_buffers = CEnvironment::getenv("FB_MULTI_BUFFER"); -+ if (fb_buffers.empty()) -+ status = eglSwapInterval(g_Windowing.GetEGLDisplay(), 0); -+ else -+ { -+ CLog::Log(LOGNOTICE, "%s - FB_MULTI_BUFFER is set",__FUNCTION__); -+ status = eglSwapInterval(g_Windowing.GetEGLDisplay(), 1); -+ } -+ result = eglGetError(); ++ // Force vsync by default ++ eglSwapInterval(g_Windowing.GetEGLDisplay(), 1); ++ EGLint result = eglGetError(); + if(result != EGL_SUCCESS) + CLog::Log(LOGERROR, "EGL error in %s: %x",__FUNCTION__, result); + + return false; +} + -+int CEGLNativeTypeIMX::get_sysfs_str(const char *path, char *valstr, const int size) const ++int CEGLNativeTypeIMX::get_sysfs_str(std::string path, std::string& valstr) const +{ -+ int fd = open(path, O_RDONLY); ++ int len; ++ char buf[256] = {0}; ++ ++ int fd = open(path.c_str(), O_RDONLY); + if (fd >= 0) + { -+ int len = read(fd, valstr, size - 1); -+ if (len != -1 ) -+ valstr[len] = '\0'; ++ while ((len = read(fd, buf, 255)) > 0) ++ valstr.append(buf, len); + close(fd); + } + else + { -+ sprintf(valstr, "%s", "fail"); ++ CLog::Log(LOGERROR, "%s: error reading %s",__FUNCTION__, path.c_str()); ++ valstr = "fail"; + return -1; + } + return 0; +} + -+int CEGLNativeTypeIMX::set_sysfs_str(const char *path, const char *val) ++int CEGLNativeTypeIMX::set_sysfs_str(std::string path, std::string val) const +{ -+ int fd = open(path, O_RDWR); ++ int fd = open(path.c_str(), O_WRONLY); + if (fd >= 0) + { -+ write(fd, val, strlen(val)); ++ val += '\n'; ++ write(fd, val.c_str(), val.size()); + close(fd); + return 0; + } ++ CLog::Log(LOGERROR, "%s: error writing %s",__FUNCTION__, path.c_str()); + return -1; +} + -+bool CEGLNativeTypeIMX::ModeToResolution(const char *mode, RESOLUTION_INFO *res) const ++bool CEGLNativeTypeIMX::ModeToResolution(std::string mode, RESOLUTION_INFO *res) const +{ + if (!res) + return false; @@ -2149,7 +2898,7 @@ diff -Naur xbmc-gotham-latest.test/xbmc/windowing/egl/EGLNativeTypeIMX.cpp xbmc- + res->iWidth = 0; + res->iHeight= 0; + -+ if(!mode) ++ if(mode.empty()) + return false; + + std::string fromMode = StringUtils::Mid(mode, 2); @@ -2183,9 +2932,9 @@ diff -Naur xbmc-gotham-latest.test/xbmc/windowing/egl/EGLNativeTypeIMX.cpp xbmc- + return res->iWidth > 0 && res->iHeight> 0; +} + -diff -Naur xbmc-gotham-latest.test/xbmc/windowing/egl/EGLNativeTypeIMX.h xbmc-imx6-koying.test/xbmc/windowing/egl/EGLNativeTypeIMX.h ---- xbmc-gotham-latest.test/xbmc/windowing/egl/EGLNativeTypeIMX.h 1970-01-01 01:00:00.000000000 +0100 -+++ xbmc-imx6-koying.test/xbmc/windowing/egl/EGLNativeTypeIMX.h 2014-02-21 23:11:23.780122319 +0100 +diff -Naur xbmc-13b3/xbmc/windowing/egl/EGLNativeTypeIMX.h xbmc-13b3-imx6/xbmc/windowing/egl/EGLNativeTypeIMX.h +--- xbmc-13b3/xbmc/windowing/egl/EGLNativeTypeIMX.h 1970-01-01 01:00:00.000000000 +0100 ++++ xbmc-13b3-imx6/xbmc/windowing/egl/EGLNativeTypeIMX.h 2014-04-13 21:18:35.990481429 +0200 @@ -0,0 +1,60 @@ +#pragma once + @@ -2237,19 +2986,19 @@ diff -Naur xbmc-gotham-latest.test/xbmc/windowing/egl/EGLNativeTypeIMX.h xbmc-im + virtual bool GetPreferredResolution(RESOLUTION_INFO *res) const; + + virtual bool ShowWindow(bool show); -+ ++ +protected: + bool m_readonly; -+ int get_sysfs_str(const char *path, char *valstr, const int size) const; -+ int set_sysfs_str(const char *path, const char *val); -+ bool ModeToResolution(const char *mode, RESOLUTION_INFO *res) const; -+ ++ int get_sysfs_str(std::string path, std::string& valstr) const; ++ int set_sysfs_str(std::string path, std::string val) const; ++ bool ModeToResolution(std::string mode, RESOLUTION_INFO *res) const; ++ + EGLNativeDisplayType m_display; + EGLNativeWindowType m_window; +}; -diff -Naur xbmc-gotham-latest.test/xbmc/windowing/egl/EGLWrapper.cpp xbmc-imx6-koying.test/xbmc/windowing/egl/EGLWrapper.cpp ---- xbmc-gotham-latest.test/xbmc/windowing/egl/EGLWrapper.cpp 2014-02-21 23:10:29.976096826 +0100 -+++ xbmc-imx6-koying.test/xbmc/windowing/egl/EGLWrapper.cpp 2014-02-21 23:11:23.780122319 +0100 +diff -Naur xbmc-13b3/xbmc/windowing/egl/EGLWrapper.cpp xbmc-13b3-imx6/xbmc/windowing/egl/EGLWrapper.cpp +--- xbmc-13b3/xbmc/windowing/egl/EGLWrapper.cpp 2014-04-13 21:22:38.089939567 +0200 ++++ xbmc-13b3-imx6/xbmc/windowing/egl/EGLWrapper.cpp 2014-04-13 21:18:35.990481429 +0200 @@ -17,16 +17,17 @@ * . * @@ -2276,21 +3025,21 @@ diff -Naur xbmc-gotham-latest.test/xbmc/windowing/egl/EGLWrapper.cpp xbmc-imx6-k (nativeGuess = CreateEGLNativeType(implementation)) || - (nativeGuess = CreateEGLNativeType(implementation))) + (nativeGuess = CreateEGLNativeType(implementation)) -+#ifdef HAS_IMXVPU ++#ifdef HAS_IMXFB + || (nativeGuess = CreateEGLNativeType(implementation)) +#endif + ) { m_nativeTypes = nativeGuess; -diff -Naur xbmc-gotham-latest.test/xbmc/windowing/egl/Makefile.in xbmc-imx6-koying.test/xbmc/windowing/egl/Makefile.in ---- xbmc-gotham-latest.test/xbmc/windowing/egl/Makefile.in 2014-02-21 23:10:29.933096805 +0100 -+++ xbmc-imx6-koying.test/xbmc/windowing/egl/Makefile.in 2014-02-21 23:11:23.779122318 +0100 +diff -Naur xbmc-13b3/xbmc/windowing/egl/Makefile.in xbmc-13b3-imx6/xbmc/windowing/egl/Makefile.in +--- xbmc-13b3/xbmc/windowing/egl/Makefile.in 2014-04-13 21:22:38.063939640 +0200 ++++ xbmc-13b3-imx6/xbmc/windowing/egl/Makefile.in 2014-04-13 21:18:35.990481429 +0200 @@ -24,6 +24,10 @@ wayland/XBMCSurface.cpp endif -+ifeq (@USE_IMXVPU@,1) ++ifeq (@USE_IMXFB@,1) +SRCS+= EGLNativeTypeIMX.cpp +endif +