Skip to content
Browse files

changeset: 15524:829272517ff9

tag: tip
user: Rabeeh Khoury <rabeeh@solid-run.com>
date: Thu Nov 15 16:08:19 2012 +0200
summary: Reworked iLineSize detection for vmeta
  • Loading branch information...
1 parent a8d2f66 commit 37042f0c5a7c26839fc272909160b3d1e0d83cc3 @tomlohave tomlohave committed
View
314 config/platforms/arm/armada5xx/packages/xbmc/patches/0040-Reworked-iLineSize-detection.patch
@@ -0,0 +1,314 @@
+From 50b1137e9e917c6e06f5fca7093f86621374fad4 Mon Sep 17 00:00:00 2001
+From: Rabeeh Khoury <rabeeh@solid-run.com>
+Date: Thu, 15 Nov 2012 15:49:10 +0200
+Subject: [PATCH] Reworked iLineSize detection
+
+1. Use y-pitch provided by vmeta to decide line size (typically 32 bytes aligned)
+2. Fixes to better support frames coming from vmeta and ffmpeg
+
+Signed-off-by: Rabeeh Khoury <rabeeh@solid-run.com>
+---
+ xbmc/cores/VideoRenderers/DoveOverlayRenderer.cpp | 146 +++++++++-----------
+ xbmc/cores/VideoRenderers/DoveOverlayRenderer.h | 5 +-
+ .../DVDCodecs/Video/DVDVideoCodecVMETA.cpp | 11 +-
+ 3 files changed, 78 insertions(+), 84 deletions(-)
+
+diff --git a/xbmc/cores/VideoRenderers/DoveOverlayRenderer.cpp b/xbmc/cores/VideoRenderers/DoveOverlayRenderer.cpp
+index e7c14ff..2913420 100644
+--- a/xbmc/cores/VideoRenderers/DoveOverlayRenderer.cpp
++++ b/xbmc/cores/VideoRenderers/DoveOverlayRenderer.cpp
+@@ -86,10 +86,11 @@ CDoveOverlayRenderer::~CDoveOverlayRenderer()
+ }
+
+
+-void CDoveOverlayRenderer::ManageDisplay()
++void CDoveOverlayRenderer::ManageDisplay(bool first)
+ {
+ CRect view;
+-
++ struct _sOvlySurface tmp_overlaySurface;
++ memcpy (&tmp_overlaySurface, &m_overlaySurface, sizeof(struct _sOvlySurface));
+ view.x1 = (float)g_settings.m_ResInfo[m_resolution].Overscan.left;
+ view.y1 = (float)g_settings.m_ResInfo[m_resolution].Overscan.top;
+ view.x2 = (float)g_settings.m_ResInfo[m_resolution].Overscan.right;
+@@ -106,19 +107,24 @@ void CDoveOverlayRenderer::ManageDisplay()
+ {
+ int delta;
+ m_overlaySurface.videoMode = DOVEFB_VMODE_YUV422PACKED_SWAPYUorV;
+- m_overlaySurface.viewPortInfo.ycPitch = (m_sourceRect.x2 - m_sourceRect.x1) * 2;
+- /* Align ycPitch to 16 pixels (32 bytes) since vmeta outputs in 16byte alignment per stride */
+- /* TODO check of decoded via vmeta or ffmpeg and change accordingly */
+- delta = m_overlaySurface.viewPortInfo.ycPitch % 32;
+- if (delta)
+- m_overlaySurface.viewPortInfo.ycPitch = m_overlaySurface.viewPortInfo.ycPitch - delta + 32;
++ if (m_SoftPicture[m_currentBuffer].iLineSize[0])
++ m_overlaySurface.viewPortInfo.ycPitch = m_SoftPicture[m_currentBuffer].iLineSize[0] * 2;
++ else
++ m_overlaySurface.viewPortInfo.ycPitch = (m_sourceRect.x2 - m_sourceRect.x1) * 2;
+ m_overlaySurface.viewPortInfo.uvPitch = 0;
+ }
+ else if (m_format == RENDER_FMT_YUV420P)
+ {
+ m_overlaySurface.videoMode = DOVEFB_VMODE_YUV420PLANAR;
+- m_overlaySurface.viewPortInfo.ycPitch = m_sourceRect.x2 - m_sourceRect.x1;
+- m_overlaySurface.viewPortInfo.uvPitch = (m_sourceRect.x2 - m_sourceRect.x1) / 2;
++ if (m_SoftPicture[m_currentBuffer].iLineSize[0])
++ {
++ m_overlaySurface.viewPortInfo.ycPitch = m_SoftPicture[m_currentBuffer].iLineSize[0];
++ m_overlaySurface.viewPortInfo.uvPitch = m_SoftPicture[m_currentBuffer].iLineSize[1];
++ } else
++ {
++ m_overlaySurface.viewPortInfo.ycPitch = m_sourceRect.x2 - m_sourceRect.x1;
++ m_overlaySurface.viewPortInfo.uvPitch = (m_sourceRect.x2 - m_sourceRect.x1) / 2;
++ }
+ }
+
+ m_overlaySurface.viewPortInfo.srcWidth = m_sourceRect.x2 - m_sourceRect.x1;
+@@ -128,7 +134,27 @@ void CDoveOverlayRenderer::ManageDisplay()
+
+ m_overlaySurface.viewPortOffset.xOffset = m_destRect.x1;
+ m_overlaySurface.viewPortOffset.yOffset = m_destRect.y1;
+-
++ if (first || (tmp_overlaySurface.videoMode != m_overlaySurface.videoMode))
++ {
++ if (ioctl(m_overlayfd, DOVEFB_IOCTL_SET_VIDEO_MODE, &m_overlaySurface.videoMode) == -1)
++ {
++ CLog::Log(LOGERROR, "%s::%s - Failed to setup video mode\n", CLASSNAME, __func__);
++ }
++ }
++ if (first || memcmp (&tmp_overlaySurface.viewPortInfo, &m_overlaySurface.viewPortInfo, sizeof (struct _sViewPortInfo)))
++ {
++ if (ioctl(m_overlayfd, DOVEFB_IOCTL_SET_VIEWPORT_INFO, &m_overlaySurface.viewPortInfo) != 0)
++ {
++ CLog::Log(LOGERROR, "%s::%s - Failed to setup video port\n", CLASSNAME, __func__);
++ }
++ }
++ if (first || memcmp (&tmp_overlaySurface.viewPortOffset, &m_overlaySurface.viewPortOffset, sizeof (struct _sVideoBufferAddr)))
++ {
++ if (ioctl(m_overlayfd, DOVEFB_IOCTL_SET_VID_OFFSET, &m_overlaySurface.viewPortOffset) != 0)
++ {
++ CLog::Log(LOGERROR, "%s::%s - Failed to setup video port offset\n", CLASSNAME, __func__);
++ }
++ }
+ }
+
+ bool CDoveOverlayRenderer::Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned int flags, ERenderFormat format, unsigned extended_format, unsigned int orientation)
+@@ -155,12 +181,20 @@ bool CDoveOverlayRenderer::Configure(unsigned int width, unsigned int height, un
+ m_sourceHeight = height;
+ m_iFlags = flags;
+ m_format = format;
+-
+ // Calculate the input frame aspect ratio.
+ CalculateFrameAspectRatio(d_width, d_height);
+ ChooseBestResolution(fps);
+ SetViewMode(g_settings.m_currentVideoSettings.m_ViewMode);
+- ManageDisplay();
++
++ /* Open the video overlay */
++ m_overlayfd = open("/dev/fb1", O_RDWR);
++ if (m_overlayfd == -1)
++ {
++ CLog::Log(LOGERROR, "%s::%s - Failed to open framebuffer", CLASSNAME, __func__);
++ return false;
++ }
++
++ ManageDisplay(true);
+
+ CLog::Log(LOGDEBUG, "%s::%s - Setting ycPitch to %d, uvPitch to %d\n", CLASSNAME, __func__,
+ m_overlaySurface.viewPortInfo.ycPitch ,m_overlaySurface.viewPortInfo.uvPitch);
+@@ -172,14 +206,6 @@ bool CDoveOverlayRenderer::Configure(unsigned int width, unsigned int height, un
+
+ m_enabled = 0;
+
+- // Open the framebuffer
+- m_overlayfd = open("/dev/fb1", O_RDWR);
+- if (m_overlayfd == -1)
+- {
+- CLog::Log(LOGERROR, "%s::%s - Failed to open framebuffer", CLASSNAME, __func__);
+- return false;
+- }
+-
+ int srcMode = SHM_NORMAL;
+
+ if (ioctl(m_overlayfd, DOVEFB_IOCTL_SET_SRC_MODE, &srcMode) == -1)
+@@ -187,25 +213,6 @@ bool CDoveOverlayRenderer::Configure(unsigned int width, unsigned int height, un
+ CLog::Log(LOGERROR, "%s::%s - Failed to enable video overlay\n", CLASSNAME, __func__);
+ return false;
+ }
+-
+- if (ioctl(m_overlayfd, DOVEFB_IOCTL_SET_VIDEO_MODE, &m_overlaySurface.videoMode) == -1)
+- {
+- CLog::Log(LOGERROR, "%s::%s - Failed to setup video mode\n", CLASSNAME, __func__);
+- return false;
+- }
+-
+- if (ioctl(m_overlayfd, DOVEFB_IOCTL_SET_VIEWPORT_INFO, &m_overlaySurface.viewPortInfo) != 0)
+- {
+- CLog::Log(LOGERROR, "%s::%s - Failed to setup video port\n", CLASSNAME, __func__);
+- return false;
+- }
+-
+- if (ioctl(m_overlayfd, DOVEFB_IOCTL_SET_VID_OFFSET, &m_overlaySurface.viewPortOffset) != 0)
+- {
+- CLog::Log(LOGERROR, "%s::%s - Failed to setup video port offset\n", CLASSNAME, __func__);
+- return false;
+- }
+-
+ int interpolation = 3; // bi-linear interpolation
+
+ if (ioctl(m_overlayfd, DOVEFB_IOCTL_SET_INTERPOLATION_MODE, &interpolation) != 0)
+@@ -305,7 +312,7 @@ void CDoveOverlayRenderer::FlipPage(int source)
+ if (!m_bConfigured)
+ return;
+
+- ManageDisplay();
++ ManageDisplay(false);
+
+ IppVmetaPicture *pPicture = m_SoftPicture[m_currentBuffer].pPicture;
+
+@@ -329,12 +336,21 @@ void CDoveOverlayRenderer::FlipPage(int source)
+ //ioctl by Solid-Run not in marvel kernel
+ if (m_format == RENDER_FMT_UYVY422) /* Typically frames from vMeta */
+ {
+- phy_addr[0] = (unsigned int) pPicture->nPhyAddr;
+- phy_addr[1] = (unsigned int) pPicture->nPhyAddr + (unsigned int) pPicture->nBufSize/2;
+- phy_addr[2] = (unsigned int )pPicture->nPhyAddr + (unsigned int) pPicture->nBufSize/2 + (unsigned int) pPicture->nBufSize/4;
++ phy_addr[0] = (unsigned int) m_SoftPicture[m_currentBuffer].buf[0];
++ phy_addr[1] = (unsigned int) m_SoftPicture[m_currentBuffer].buf[0];
++ phy_addr[2] = (unsigned int) m_SoftPicture[m_currentBuffer].buf[0];
++ m_next_frame_present = true;
++ if(ioctl(m_overlayfd, DOVEFB_IOCTL_NEXT_FRAME_PRESENT, &phy_addr) != 0)
++ CLog::Log(LOGERROR, "%s::%s - Error flipping\n", CLASSNAME, __func__);
++ } else if (m_format == RENDER_FMT_YUV420P)
++ {
++ phy_addr[0] = (unsigned int) m_SoftPicture[m_currentBuffer].buf[0];
++ phy_addr[1] = (unsigned int) m_SoftPicture[m_currentBuffer].buf[1];
++ phy_addr[2] = (unsigned int) m_SoftPicture[m_currentBuffer].buf[2];
+ m_next_frame_present = true;
+ if(ioctl(m_overlayfd, DOVEFB_IOCTL_NEXT_FRAME_PRESENT, &phy_addr) != 0)
+ CLog::Log(LOGERROR, "%s::%s - Error flipping\n", CLASSNAME, __func__);
++
+ } else if(ioctl(m_overlayfd, DOVEFB_IOCTL_FLIP_VID_BUFFER, &m_overlaySurface) != 0)
+ CLog::Log(LOGERROR, "%s::%s - Error flipping\n", CLASSNAME, __func__);
+
+@@ -415,6 +431,12 @@ unsigned int CDoveOverlayRenderer::DrawSlice(DVDVideoPicture *pDvdVideoPicture)
+ if(!pPicture)
+ return false;
+
++ /* Save the original data buffers and pitch */
++ for (int i = 0 ; i < 4 ; i ++)
++ {
++ m_SoftPicture[m_currentBuffer].iLineSize[i] = pDvdVideoPicture->iLineSize[i];
++ m_SoftPicture[m_currentBuffer].data[i] = pDvdVideoPicture->data[i];
++ }
+ if(nPhyAddr)
+ {
+ // Decoder allocated buffer
+@@ -437,16 +459,15 @@ unsigned int CDoveOverlayRenderer::DrawSlice(DVDVideoPicture *pDvdVideoPicture)
+ unsigned int memSize = (pDvdVideoPicture->iLineSize[0] * pDvdVideoPicture->iHeight) +
+ (pDvdVideoPicture->iLineSize[1] * pDvdVideoPicture->iHeight / 2) +
+ (pDvdVideoPicture->iLineSize[2] * pDvdVideoPicture->iHeight / 2);
+-
++ /* Potentiall issue since pre-allocated buffer might be too small */
+ if(!pPicture->pBuf)
+- pPicture->pBuf = (Ipp8u*)m_DllVMETA->vdec_os_api_dma_alloc(memSize, VMETA_DIS_BUF_ALIGN, &(pPicture->nPhyAddr));
++ pPicture->pBuf = (Ipp8u*)m_DllVMETA->vdec_os_api_dma_alloc_cached(memSize, VMETA_DIS_BUF_ALIGN, &(pPicture->nPhyAddr));
+
+ if(!pPicture->pBuf)
+ {
+ CLog::Log(LOGERROR, "%s::%s - Failed to alloc memory\n", CLASSNAME, __func__);
+ return false;
+ }
+-
+ m_SoftPicture[m_currentBuffer].bFree = true;
+ m_SoftPicture[m_currentBuffer].buf[0] = (unsigned char *)pPicture->nPhyAddr;
+ m_SoftPicture[m_currentBuffer].buf[1] = (unsigned char *)pPicture->nPhyAddr +
+@@ -454,39 +475,8 @@ unsigned int CDoveOverlayRenderer::DrawSlice(DVDVideoPicture *pDvdVideoPicture)
+ m_SoftPicture[m_currentBuffer].buf[2] = (unsigned char *)pPicture->nPhyAddr +
+ (pDvdVideoPicture->iLineSize[0] * pDvdVideoPicture->iHeight) +
+ (pDvdVideoPicture->iLineSize[1] * pDvdVideoPicture->iHeight / 2);
+-
+ unsigned char *dst = (unsigned char *)pPicture->pBuf;
+
+- memset(dst, 0, memSize);
+-
+- /*
+- int i;
+-
+- unsigned char *src = pDvdVideoPicture->data[0];
+- for(i = 0; i < pDvdVideoPicture->iHeight; i++)
+- {
+- fast_memcpy(dst, src, pDvdVideoPicture->iLineSize[0]);
+- src += pDvdVideoPicture->iLineSize[0];
+- dst += pDvdVideoPicture->iLineSize[0];
+- }
+-
+- src = pDvdVideoPicture->data[1];
+- for(i = 0; i < pDvdVideoPicture->iHeight / 2; i++)
+- {
+- fast_memcpy(dst, src, pDvdVideoPicture->iLineSize[1]);
+- src += pDvdVideoPicture->iLineSize[1];
+- dst += pDvdVideoPicture->iLineSize[1];
+- }
+-
+- src = pDvdVideoPicture->data[2];
+- for(i = 0; i < pDvdVideoPicture->iHeight / 2; i++)
+- {
+- fast_memcpy(dst, src, pDvdVideoPicture->iLineSize[2]);
+- src += pDvdVideoPicture->iLineSize[2];
+- dst += pDvdVideoPicture->iLineSize[2];
+- }
+- */
+-
+ fast_memcpy( dst, (unsigned char *)pDvdVideoPicture->data[0], pDvdVideoPicture->iLineSize[0] * pDvdVideoPicture->iHeight );
+ dst += pDvdVideoPicture->iLineSize[0] * pDvdVideoPicture->iHeight;
+ fast_memcpy( dst, (unsigned char *)pDvdVideoPicture->data[1], pDvdVideoPicture->iLineSize[1] * pDvdVideoPicture->iHeight / 2 );
+diff --git a/xbmc/cores/VideoRenderers/DoveOverlayRenderer.h b/xbmc/cores/VideoRenderers/DoveOverlayRenderer.h
+index 0e1b591..117e251 100644
+--- a/xbmc/cores/VideoRenderers/DoveOverlayRenderer.h
++++ b/xbmc/cores/VideoRenderers/DoveOverlayRenderer.h
+@@ -126,6 +126,9 @@ typedef struct _OutputBuffer
+ IppVmetaPicture *pPicture;
+ bool bFree;
+ unsigned char *buf[3];
++ /* Original data from pPicture */
++ BYTE* data[4]; // [4] = alpha channel, currently not used
++ int iLineSize[4]; // [4] = alpha channel, currently not used
+ } OutputBuffer;
+
+ class CDoveOverlayRenderer : public CBaseRenderer
+@@ -142,7 +145,7 @@ class CDoveOverlayRenderer : public CBaseRenderer
+ void CreateThumbnail(CBaseTexture *texture, unsigned int width, unsigned int height);
+
+ // Player functions
+- virtual void ManageDisplay();
++ virtual void ManageDisplay(bool first);
+ virtual bool Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height,
+ float fps, unsigned int flags, ERenderFormat format, unsigned extended_format, unsigned int orientation);
+ virtual bool IsConfigured() { return m_bConfigured; }
+diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVMETA.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVMETA.cpp
+index 391a356..b7b3281 100644
+--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVMETA.cpp
++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVMETA.cpp
+@@ -583,12 +583,13 @@ bool CDVDVideoCodecVMETA::GetPicture(DVDVideoPicture *pDvdVideoPicture)
+
+ unsigned char *pDisplayStart = ((Ipp8u*)pPicture->pic.ppPicPlane[0]) + (pPicture->pic.picROI.y)*(pPicture->pic.picPlaneStep[0]) + ((pPicture->pic.picROI.x)<<1);
+
++ /* data[1] and data[2] are not needed in UYVY */
+ pDvdVideoPicture->data[0] = pDisplayStart;
+- pDvdVideoPicture->iLineSize[0] = ALIGN (m_picture_width, 4);
+- pDvdVideoPicture->data[1] = pDvdVideoPicture->data[0] + pDvdVideoPicture->iLineSize[0] * ALIGN (m_picture_width, 2);
+- pDvdVideoPicture->iLineSize[1] = ALIGN (m_picture_height, 8) / 2;
+- pDvdVideoPicture->data[2] = (BYTE *)pDisplayStart;
+- pDvdVideoPicture->iLineSize[2] = pDvdVideoPicture->iLineSize[1];
++ pDvdVideoPicture->iLineSize[0] = ALIGN (pPicture->pic.picWidth, 4);
++ pDvdVideoPicture->data[1] = 0;
++ pDvdVideoPicture->iLineSize[1] = 0;
++ pDvdVideoPicture->data[2] = 0;
++ pDvdVideoPicture->iLineSize[2] = 0;
+ if (!m_pts_queue.empty())
+ {
+ //pDvdVideoPicture->pts = m_pts_queue.front();
+--
+1.7.9.5
+

0 comments on commit 37042f0

Please sign in to comment.
Something went wrong with that request. Please try again.