Skip to content

Instantly share code, notes, and snippets.

@danielvijge
Created August 3, 2012 10:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danielvijge/3246636 to your computer and use it in GitHub Desktop.
Save danielvijge/3246636 to your computer and use it in GitHub Desktop.
XBMC for CuBox (GStreamer version) - based on https://github.com/rabeeh/xbmc
diff --git a/configure.in b/configure.in
index bca9239..8a88260 100755
--- a/configure.in
+++ b/configure.in
@@ -118,6 +118,8 @@ libplist_not_found="== Could not find libplist. AirPlay support disabled. =="
libplist_disabled="== AirPlay support disabled. =="
alsa_not_found="== Could not find ALSA. ALSA support disabled. =="
dbus_not_found="== Could not find DBUS. DBUS support disabled. =="
+gstreamer_not_found="== GStreamer libraries not found. GStreamer support disabled. =="
+gstreamer_disabled="== GStreamer support manually disabled. =="
libudev_not_found="== Could not find libudev. Will use polling to check for device changes. =="
libudev_disabled="== udev support disabled. Will use polling to check for device changes. =="
@@ -223,12 +225,30 @@ AC_ARG_ENABLE([openmax],
[use_openmax=$enableval],
[use_openmax=auto])
+AC_ARG_ENABLE([gstreamer],
+ [AS_HELP_STRING([--enable-gstreamer],
+ [enable GStreamer support (default is auto)])],
+ [use_gstreamer=$enableval],
+ [use_gstreamer=auto])
+
AC_ARG_ENABLE([tegra],
[AS_HELP_STRING([--enable-tegra],
[enable Tegra2 arm (default is no)])],
[use_tegra=$enableval],
[use_tegra=no])
+AC_ARG_ENABLE([dove],
+ [AS_HELP_STRING([--enable-dove],
+ [Enable support for Marvell Armada 510 (Dove) with overlay])],
+ [use_dove=$enableval],
+ [use_dove=no])
+
+AC_ARG_ENABLE([dove-overlay],
+ [AS_HELP_STRING([--enable-dove-overlay],
+ [enable support for Marvell Armada 510 (Dove) video overlay])],
+ [AC_DEFINE([HAS_DOVE_OVERLAY], [], [Defines dove overlay support])])
+
+
AC_ARG_ENABLE([profiling],
[AS_HELP_STRING([--enable-profiling],
[enable gprof profiling (default is no)])],
@@ -588,6 +608,13 @@ elif test "$use_arch" = "arm"; then
[ CFLAGS="$SAVE_CFLAGS -Wa,-march=armv6 -mtune=cortex-a8 -mthumb-interwork"
CXXFLAGS="$CXXFLAGS -Wa,-march=armv6 -mtune=cortex-a8 -mthumb-interwork"
use_cpu=cortex-a8])
+ elif test "$use_dove" = "yes"; then
+ # Compile for ARMv7a, vfpv3-d16 with iwmmx SIMD support (no neon)
+# use_iwmmxt=yes
+ use_cpu=cortex-a9
+ CFLAGS="$CFLAGS -Wno-psabi -Wa,-march=armv7a -mtune=cortex-a9 -mfpu=vfpv3-d16 -mthumb-interwork"
+ CXXFLAGS="$CXXFLAGS -Wno-psabi -Wa,-march=armv7a -mtune=cortex-a9 -mfpu=vfpv3-d16 -mthumb-interwork"
+ FFMPEG_EXTRACFLAGS="$FFMPEG_EXTRACFLAGS -mtune=cortex-a9 -mfpu=vfpv3-d16"
else
# Compile for ARMv7a architecture, CortexA8 cpu and check for enabled NEON coprocessor
CFLAGS="$CFLAGS -Wa,-march=armv7a -mcpu=cortex-a8"
@@ -1441,6 +1468,57 @@ else
fi
fi
+# Dove Overlay
+if test "x$use_gstreamer" = "xyes"; then
+ if test "x$use_dove" = "xyes"; then
+ USE_DOVE_OVERLAY=1
+ else
+ USE_DOVE_OVERLAY=0
+ fi
+else
+ USE_DOVE_OVERLAY=0
+fi
+
+# GSTREAMER
+if test "x$use_gstreamer" != "xno"; then
+ if test "$host_vendor" = "apple" ; then
+ if test "x$use_gstreamer" = "xyes"; then
+ AC_MSG_ERROR([GStreamer not supported on this platform])
+ else
+ use_gstreamer="no"
+ AC_MSG_NOTICE($gstreamer_disabled)
+ fi
+ USE_GSTREAMER=0
+ else
+ AC_SUBST(gstreamer_req, 0.10.0)
+ AC_SUBST(gstreamer_plugins_base_req, 0.10.0)
+ PKG_CHECK_MODULES(GSTREAMER, gstreamer-0.10 >= $gstreamer_req, HAVE_GSTREAMER=1, HAVE_GSTREAMER=0)
+ PKG_CHECK_MODULES(GSTREAMER_BASE, gstreamer-base-0.10 >= $gstreamer_req, HAVE_GSTREAMER_BASE=1, HAVE_GSTREAMER_BASE=0)
+ PKG_CHECK_MODULES(GSTREAMER_PLUGINS_BASE, gstreamer-plugins-base-0.10 >= $gstreamer_plugins_base_req, HAVE_GSTREAMER_PLUGINS_BASE=1, HAVE_GSTREAMER_PLUGINS_BASE=0)
+ HAVE_GSTREAMER_APP=1
+ AC_CHECK_LIB([gstapp-0.10], main, , HAVE_GSTREAMER_APP=0)
+
+ if test $HAVE_GSTREAMER -eq 1 -a $HAVE_GSTREAMER_BASE -eq 1 -a $HAVE_GSTREAMER_PLUGINS_BASE -eq 1 -a $HAVE_GSTREAMER_APP -eq 1; then
+ INCLUDES="$INCLUDES $GSTREAMER_CFLAGS $GSTREAMER_BASE_CFLAGS $GSTREAMER_PLUGINS_BASE_CFLAGS"
+ LIBS="$LIBS $GSTREAMER_LIBS $GSTREAMER_BASE_LIBS $GSTREAMER_PLUGINS_BASE_LIBS"
+ USE_GSTREAMER=1
+ AC_DEFINE([HAVE_LIBGSTREAMER], [1], [Define to 1 if you have the 'GStreamer' library.])
+ else
+ if test "x$use_gstreamer" = "xyes"; then
+ AC_MSG_ERROR([$gstreamer_not_found])
+ else
+ use_gstreamer="no"
+ USE_GSTREAMER=0
+ AC_MSG_RESULT($gstreamer_not_found)
+ fi
+ fi
+ fi
+else
+ USE_GSTREAMER=0
+ AC_MSG_NOTICE($gstreamer_disabled)
+fi
+
+
# yajl version check (yajl_version.h was added in yajl 2.0)
AC_CHECK_HEADERS([yajl/yajl_version.h], [], [
AC_DEFINE(YAJL_MAJOR, 1, [yajl version 1])
@@ -1545,6 +1623,12 @@ else
fi
fi
+if test "$use_gstreamer" != "no"; then
+ final_message="$final_message\n GStreamer:\tYes"
+else
+ final_message="$final_message\n GStreamer:\tNo"
+fi
+
if test "$use_alsa" = "yes"; then
USE_ALSA=1
AC_DEFINE([USE_ALSA],[1],["Define to 1 if alsa is installed"])
@@ -1949,6 +2033,8 @@ AC_SUBST(USE_LIBAFPCLIENT)
AC_SUBST(USE_AIRPLAY)
AC_SUBST(USE_VDA)
AC_SUBST(USE_OPENMAX)
+AC_SUBST(USE_GSTREAMER)
+AC_SUBST(USE_DOVE_OVERLAY)
AC_SUBST(USE_PULSE)
AC_SUBST(USE_XRANDR)
AC_SUBST(USE_ALSA)
@@ -2065,6 +2151,7 @@ XB_CONFIG_MODULE([lib/ffmpeg], [
`if test "$use_arch" != "no"; then echo --arch=$use_arch; fi`\
`if test "$use_cpu" != "no"; then echo --cpu=$use_cpu; fi`\
`if test "$use_neon" = "yes"; then echo --enable-neon; else echo --disable-neon; fi`\
+ `if test "$use_iwmmxt" = "yes"; then echo --enable-iwmmxt; fi`\
--target-os=$(tolower $(uname -s)) \
--disable-muxers \
--enable-muxer=spdif \
diff --git a/xbmc/cores/VideoRenderers/DoveOverlayRenderer.cpp b/xbmc/cores/VideoRenderers/DoveOverlayRenderer.cpp
new file mode 100644
index 0000000..3b6129b
--- /dev/null
+++ b/xbmc/cores/VideoRenderers/DoveOverlayRenderer.cpp
@@ -0,0 +1,653 @@
+/*
+ * Copyright (C) 2011 Solid-Run
+ * http://www.solid-run.com
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "system.h"
+#if (defined HAVE_CONFIG_H) && (!defined WIN32)
+ #include "config.h"
+#endif
+
+#undef COLOR_KEY_BLACK
+#define COLOR_KEY_ALPHA
+#ifdef HAS_DOVE_OVERLAY
+#include "DoveOverlayRenderer.h"
+#include "dovefb.h"
+#include "bmm_drv.h"
+#include "utils/log.h"
+#include <stdlib.h>
+#include <malloc.h>
+#include "utils/fastmemcpy.h"
+#include "settings/GUISettings.h"
+#include "guilib/GraphicContext.h"
+
+
+CDoveOverlayRenderer::CDoveOverlayRenderer()
+{
+ m_yuvBuffers[0].plane[0] = NULL;
+ m_yuvBuffers[0].plane[1] = NULL;
+ m_yuvBuffers[0].plane[2] = NULL;
+
+ m_yuvBuffers[1].plane[0] = NULL;
+ m_yuvBuffers[1].plane[1] = NULL;
+ m_yuvBuffers[1].plane[2] = NULL;
+
+ m_overlayfd = -1;
+ m_bmm = -1;
+
+ m_framebuffers[0].buf = NULL;
+ m_framebuffers[1].buf = NULL;
+ UnInit();
+}
+
+CDoveOverlayRenderer::~CDoveOverlayRenderer()
+{
+ UnInit();
+}
+
+bool CDoveOverlayRenderer::Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned int flags, unsigned int format)
+{
+ int i;
+ // When no i420 flag added in fourcc, flags were 0x1011 (4113 decimal)
+ printf("Configure with [%i, %i] and [%i, %i] and fps %f and flags 0x%x format 0x%x\n", width, height, d_width, d_height, fps, flags,format);
+
+ if (CONF_FLAGS_FORMAT_MASK(flags) == CONF_FLAGS_FORMAT_NV12)
+ {
+ printf("Bad format\n");
+ return false;
+ }
+
+// if (width != m_sourceWidth || height != m_sourceHeight)
+ {
+ m_sourceWidth = width;
+ m_sourceHeight = height;
+
+ // Set output to image size but pad it to be a multiple of 16
+ m_overlayWidth = (m_sourceWidth+15)&~15;
+
+ // Open the framebuffer
+ m_overlayfd = open("/dev/fb1", O_RDWR);
+ if (m_overlayfd == -1)
+ {
+ CLog::Log(LOGERROR, "DoveOverlay: Failed to open framebuffer");
+ return false;
+ }
+ m_bmm = open("/dev/bmm", O_RDWR);
+ if (m_bmm == -1)
+ {
+ CLog::Log(LOGERROR, "DoveOverlay: Failed to open bmm");
+ return false;
+ }
+
+
+
+ /*
+ * First allocate memory for two framebuffers and map them.
+ */
+// unsigned int frameSize = m_overlayWidth * m_sourceHeight * 2;
+// unsigned int memSize = frameSize*2;
+// ioctl_arg_t bmm_cmd;
+// bmm_cmd.input = memSize;
+// bmm_cmd.arg = 0x0;
+// if ((ioctl(m_bmm, BMM_MALLOC, &bmm_cmd) != 0))
+// {
+// CLog::Log(LOGERROR, "DoveOverlay: Failed to alloc memory from bmm");
+// printf ("BMM memory allocate FAILED\n");
+// return false;
+// }
+// m_offset = bmm_cmd.output;
+// buf1_phys = (unsigned char *)m_offset;
+// buf2_phys = (unsigned char *)m_offset + frameSize;
+ for (i=0;i<3;i++)
+ gst_buf[i] = NULL;
+// printf ("Allocated BMM memory - physical address 0x%x\n",m_offset);
+// uint8_t *fbmem = (uint8_t *)mmap(NULL, memSize, PROT_READ|PROT_WRITE, MAP_SHARED, m_bmm, m_offset);
+// printf ("fbmem mapped to 0x%x (size 0x%x)\n",(unsigned int)fbmem,memSize);
+// if (fbmem == MAP_FAILED)
+// {
+// CLog::Log(LOGERROR, "DoveOverlay: Failed to map the framebuffer");
+// return false;
+// }
+
+
+ /*
+ * Second setup the screen overlays
+ */
+#if 0
+ for (unsigned int i = 0; i < memSize / 4; i++)
+ ((uint32_t*)fbmem)[i] = 0x80008000;
+#endif
+ m_framebuffers[0].x = 0;
+ m_framebuffers[0].y = 0;
+ m_framebuffers[0].buf = 0;//fbmem;
+ m_framebuffers[1].x = 0;
+ m_framebuffers[1].y = m_sourceHeight;
+ m_framebuffers[1].buf = 0;//fbmem + frameSize;
+ memset (&m_overlaySurface, 0, sizeof(m_overlaySurface));
+ if (CONF_FLAGS_FORMAT_MASK(flags) == CONF_FLAGS_FORMAT_UYVY)
+ {
+ m_overlaySurface.videoMode = DOVEFB_VMODE_YUV422PACKED_SWAPYUorV;//DOVEFB_VMODE_YUV422PACKED;
+ m_overlaySurface.viewPortInfo.ycPitch = m_sourceWidth*2;
+ m_overlaySurface.viewPortInfo.uvPitch = 0;
+ } else if (CONF_FLAGS_FORMAT_MASK(flags) == CONF_FLAGS_FORMAT_YV12)
+ {
+ m_overlaySurface.videoMode = DOVEFB_VMODE_YUV420PLANAR;
+ m_overlaySurface.viewPortInfo.ycPitch = m_sourceWidth;
+ m_overlaySurface.viewPortInfo.uvPitch = m_sourceWidth/2;
+ } else
+ {
+ printf ("Unkown format 0x%x\n",CONF_FLAGS_FORMAT_MASK(flags));
+ return false;
+ }
+ m_overlaySurface.viewPortInfo.srcWidth = m_sourceWidth;
+ m_overlaySurface.viewPortInfo.srcHeight = m_sourceHeight;
+ m_overlaySurface.viewPortInfo.zoomXSize = m_sourceWidth;
+ m_overlaySurface.viewPortInfo.zoomYSize = m_sourceHeight;
+ printf ("Setting ycPitch to %d, uvPitch to %d\n",m_overlaySurface.viewPortInfo.ycPitch ,m_overlaySurface.viewPortInfo.uvPitch);
+
+
+ m_overlaySurface.viewPortOffset.xOffset = 0;
+ m_overlaySurface.viewPortOffset.yOffset = 0;
+
+ m_overlaySurface.videoBufferAddr.startAddr = (unsigned char *)m_offset;
+ m_overlaySurface.videoBufferAddr.length = 0;//frameSize;
+ m_overlaySurface.videoBufferAddr.inputData = 0;
+ m_overlaySurface.videoBufferAddr.frameID = 0;
+
+ int srcMode = SHM_NORMAL;
+ if (ioctl(m_overlayfd, DOVEFB_IOCTL_SET_SRC_MODE, &srcMode) == -1)
+ {
+ CLog::Log(LOGERROR, "DoveOverlay: Failed to enable video overlay");
+ return false;
+ }
+ if (ioctl(m_overlayfd, DOVEFB_IOCTL_SET_VIDEO_MODE, &m_overlaySurface.videoMode) == -1)
+ {
+ CLog::Log(LOGERROR, "DoveOverlay: Failed to setup video mode");
+ return false;
+ }
+ if (ioctl(m_overlayfd, DOVEFB_IOCTL_SET_VIEWPORT_INFO, &m_overlaySurface.viewPortInfo) != 0)
+ {
+ CLog::Log(LOGERROR, "DoveOverlay: Failed to setup video port");
+ return false;
+ }
+ if (ioctl(m_overlayfd, DOVEFB_IOCTL_SET_VID_OFFSET, &m_overlaySurface.viewPortOffset) != 0)
+ {
+ CLog::Log(LOGERROR, "DoveOverlay: Failed to setup video port offset");
+ return false;
+ }
+ int interpolation = 3; // bi-linear interpolation
+ if (ioctl(m_overlayfd, DOVEFB_IOCTL_SET_INTERPOLATION_MODE, &interpolation) != 0)
+ {
+ CLog::Log(LOGERROR, "DoveOverlay: Failed to setup video interpolation mode");
+ return false;
+ }
+
+ struct _sColorKeyNAlpha alpha;
+ memset (&alpha, 0, sizeof(alpha));
+ alpha.mode = DOVEFB_ENABLE_RGB_COLORKEY_MODE;
+ alpha.alphapath = DOVEFB_GRA_PATH_ALPHA;
+ alpha.config = 0xff;//c0;
+#ifdef COLOR_KEY_ALPHA
+ alpha.Y_ColorAlpha = 0x02020200;
+ alpha.U_ColorAlpha = 0x05050500;
+ alpha.V_ColorAlpha = 0x07070700;
+#endif
+#ifdef COLOR_KEY_BLACK
+ alpha.Y_ColorAlpha = 0x0;
+ alpha.U_ColorAlpha = 0x0;
+ alpha.V_ColorAlpha = 0x0;
+#endif
+ if (ioctl(m_overlayfd, DOVEFB_IOCTL_SET_COLORKEYnALPHA, &alpha) == -1)
+ {
+ CLog::Log(LOGERROR, "DoveOverlay: Failed to configure alpha");
+ return false;
+ }
+
+ for (unsigned int i = 0; i < 2; i++)
+ {
+ FreeYV12Image(i);
+ CreateYV12Image(i, m_sourceWidth, m_sourceHeight);
+ }
+ m_currentBuffer = 0;
+ printf("Proper format, continuing\n");
+ }
+
+ m_iFlags = flags;
+ m_bConfigured = true;
+ return m_bConfigured;
+}
+
+int CDoveOverlayRenderer::GetImage(YV12Image *image, int source, bool readonly)
+{
+// printf ("GetImage called (source = %d)\n",source);
+ if (!m_bConfigured)
+ return -1;
+ /* take next available buffer */
+// printf("GetImage before if %i\n", source);
+ if( source == AUTOSOURCE || source > 1 || source < 0)
+// source = NextYV12Image();
+ source = m_currentBuffer;
+
+// printf("GetImage %i\n", source);
+
+ YV12Image &im = m_yuvBuffers[source];
+
+ for (int p=0;p<MAX_PLANES;p++)
+ {
+ image->plane[p] = im.plane[p];
+ image->stride[p] = im.stride[p];
+ }
+
+ image->width = im.width;
+ image->height = im.height;
+ image->flags = im.flags;
+ image->cshift_x = im.cshift_x;
+ image->cshift_y = im.cshift_y;
+
+ // printf("image [%i, %i]\n", image->width, image->height);
+// printf ("In DoveOverlay GetImage --> image->plane[0] = 0x%x\n",image->plane[0]);
+
+ return source;
+}
+
+void CDoveOverlayRenderer::ReleaseImage(int source, bool preserve)
+{
+ if (!m_bConfigured)
+ return;
+
+}
+
+void CDoveOverlayRenderer::FlipPage(int source)
+{
+ unsigned char fbid,now;
+ if (!m_bConfigured)
+ return;
+ if (ioctl(m_overlayfd, DOVEFB_IOCTL_GET_FBID, &fbid) != 0)
+ {
+ printf ("Error getting FBID\n");
+ }
+ now = m_overlaySurface.videoBufferAddr.frameID;
+// if (fbid == 255) fbid=0;
+// else fbid++;
+// if (fbid != now) {
+// printf ("Skipping frame presentation (fbid=%d, now = %d)\n",fbid,now);
+// return;
+// }
+// printf ("fbid = %d, frameID = %d\n",fbid, m_overlaySurface.videoBufferAddr.frameID);
+
+ if (gst_buf[0] != NULL) {
+ m_overlaySurface.videoBufferAddr.startAddr = gst_buf[0];
+ } else {
+ if (m_currentBuffer) m_overlaySurface.videoBufferAddr.startAddr = buf2_phys;
+ else m_overlaySurface.videoBufferAddr.startAddr = buf1_phys;
+ }
+// if (m_overlaySurface.videoBufferAddr.frameID == 0) {
+// printf ("Flipping FIRST frame\n");
+// }
+// printf ("Flipping page %d (frameID = %d) address 0x%x...",m_currentBuffer, m_overlaySurface.videoBufferAddr.frameID, m_overlaySurface.videoBufferAddr.startAddr);
+ { static int hack=0;
+ if (hack>=0)
+ {
+ if (ioctl(m_overlayfd, DOVEFB_IOCTL_XBMC_PRESENT, &gst_buf) != 0)
+ {
+ printf ("Error flipping\n");
+ }}
+ else
+ {
+// hack++;
+// if (ioctl(m_overlayfd, DOVEFB_IOCTL_FLIP_VID_BUFFER, &m_overlaySurface) != 0)
+ {
+ printf ("Error flipping\n");
+ }}
+ }
+ m_overlaySurface.videoBufferAddr.frameID ++;
+ m_currentBuffer = NextYV12Image();
+ if (enabled == 0) {
+ enabled = 1;
+ if (ioctl(m_overlayfd, DOVEFB_IOCTL_SWITCH_VID_OVLY, &enabled) == -1)
+ {
+ CLog::Log(LOGERROR, "DoveOverlay: Failed to enable video overlay");
+ }
+ }
+ if (ioctl(m_overlayfd, DOVEFB_IOCTL_WAIT_VSYNC, 0) != 0)
+ {
+ printf ("Error waiting for vsync\n");
+ }
+
+// printf ("Done\n");
+}
+
+void CDoveOverlayRenderer::Reset()
+{
+ printf ("Was asked to Reset\n");
+}
+
+void CDoveOverlayRenderer::Update(bool bPauseDrawing)
+{
+ printf ("Was asked to Update bPauseDrawing = %d\n",bPauseDrawing);
+}
+
+void CDoveOverlayRenderer::AddProcessor(YV12Image *image, DVDVideoPicture *pic)
+{
+#if 0
+ image->plane[0] = pic->data[0];
+ image->plane[1] = pic->data[1];
+ image->plane[2] = pic->data[2];
+ image->stride[0] = pic->iLineSize[0];
+ image->stride[1] = pic->iLineSize[1];
+ image->stride[2] = pic->iLineSize[2];
+#endif
+ DrawSlice(pic->data, pic->iLineSize, pic->iWidth, pic->iHeight, 0, 0);
+}
+
+void CDoveOverlayRenderer::RenderUpdate(bool clear, DWORD flags, DWORD alpha)
+{
+// printf ("flags is 0x%x\n",flags);
+ if (!m_bConfigured)
+ return;
+#ifdef COLOR_KEY_ALPHA
+ static int counter = 0;
+ counter++;
+// if ((counter%20)) return ; // Rabeeh hack
+ GLfloat value;
+ GLint scissorBox[8];
+ glGetIntegerv(GL_SCISSOR_BOX, scissorBox);
+ m_zoomWidth = scissorBox[2] - scissorBox[0];
+ m_zoomHeight = scissorBox[3] - scissorBox[1];
+ if ((m_overlaySurface.viewPortInfo.zoomXSize != m_zoomWidth) ||
+ (m_overlaySurface.viewPortInfo.zoomYSize != m_zoomHeight)) {
+ // Updating zooming required
+ m_overlaySurface.viewPortInfo.zoomXSize = m_zoomWidth;
+ m_overlaySurface.viewPortInfo.zoomYSize = m_zoomHeight;
+ if (ioctl(m_overlayfd, DOVEFB_IOCTL_SET_VIEWPORT_INFO, &m_overlaySurface.viewPortInfo) != 0)
+ {
+ printf ("Error changing viewport\n");
+ }
+ }
+// glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+// if (!clear)
+// glScissor(m_destRect.x1, g_graphicsContext.GetHeight() - m_destRect.y2, m_destRect.Width(), m_destRect.Height());
+ glEnable(GL_SCISSOR_TEST);
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // RGB e2 1f 70
+ glClear(GL_COLOR_BUFFER_BIT);
+// glScissor(scissorBox[0], scissorBox[1], scissorBox[2], scissorBox[3]);
+#endif
+}
+
+bool CDoveOverlayRenderer::RenderCapture(CRenderCapture* capture)
+{
+
+ printf ("Rabeeh - fixme In RenderCapture. returning true\n");
+ return true;
+}
+
+
+unsigned int CDoveOverlayRenderer::DrawSlice(unsigned char *src[], int stride[], int w, int h, int x, int y)
+{
+ static unsigned int counter1=0, counter2=0;
+ ioctl_arg_t bmm_cmd;
+ int i;
+
+ counter1++;
+// if (!(counter1%20)) printf ("Frames %d\n",counter1);
+ memset(&bmm_cmd, 0, sizeof(ioctl_arg_t));
+ bmm_cmd.input = (unsigned int)src[0];
+ bmm_cmd.arg = 0x0;
+ if ((ioctl(m_bmm, BMM_GET_PHYS_ADDR, &bmm_cmd) != 0))
+ {
+ CLog::Log(LOGERROR, "DoveOverlay: Failed to get physical address");
+ return false;
+ }
+
+ if (bmm_cmd.output) { // Has buffer that can be directly displayed
+ /* Typically UYVY, need to see if gst_buf[1/2] needs update too */
+ gst_buf[0] = (unsigned char *) bmm_cmd.output;
+ } else
+ {
+ unsigned int memSize = w*h*2;
+ ioctl_arg_t bmm_cmd;
+ bmm_cmd.input = memSize;
+ bmm_cmd.arg = 0x0;
+ if ((ioctl(m_bmm, BMM_MALLOC, &bmm_cmd) != 0))
+ {
+ CLog::Log(LOGERROR, "DoveOverlay: Failed to alloc memory from bmm");
+ printf ("BMM memory allocate FAILED\n");
+ return false;
+ }
+ m_offset = bmm_cmd.output;
+ uint8_t *virt = (uint8_t *)mmap(NULL, memSize, PROT_READ|PROT_WRITE, MAP_SHARED, m_bmm, m_offset);
+ if (virt == MAP_FAILED)
+ {
+ CLog::Log(LOGERROR, "DoveOverlay: Failed to map the framebuffer");
+ return false;
+ }
+
+ unsigned int dst = (unsigned int)virt;
+ gst_buf[0] = (unsigned char *) bmm_cmd.output;
+ gst_buf[1] = (unsigned char *) (bmm_cmd.output + h*w);
+ gst_buf[2] = (unsigned char *) (bmm_cmd.output + h*w*3/2);
+#if 1
+ /* Notice that src[0..3] are not contiguos in memory */
+#if 0
+ printf ("src[0] =0x%x, src[1] = 0x%x, src[2] = 0x%x\n",src[0],src[1],src[2]);
+ printf ("stride[0] =0x%x, stride[1] = 0x%x, stride[2] = 0x%x\n",stride[0],stride[1],stride[2]);
+#endif
+ for (i = 0 ; i < h ; i++) {
+ fast_memcpy ((void*)dst, (void*)((unsigned int)src[0]+stride[0]*i),stride[0]);
+ dst += w;
+ }
+ for (i = 0 ; i < h ; i++) {
+ fast_memcpy ((void*)dst, (void*)((unsigned int)src[1]+stride[1]*i),stride[1]);
+ dst += w/2;
+ }
+ for (i = 0 ; i < h ; i++) {
+ fast_memcpy ((void*)dst, (void*)((unsigned int)src[2]+stride[2]*i),stride[2]);
+ dst += w/2;
+ }
+
+#else
+ unsigned int dst_addr = (unsigned int) virt;
+ unsigned int size = stride[0]*h;
+ printf ("stride = %d %d %d\n",stride[0],stride[1],stride[2]);
+ printf ("Y dst addr = 0x%x\n",dst_addr);
+ memcpy ((void *) dst_addr,src[0],size);
+ dst_addr += h * stride[0];
+ printf ("U dst addr = 0x%x\n",dst_addr);
+ size = (stride[1]*h);
+ memcpy ((void *) dst_addr,src[1],size);
+ dst_addr += (h * stride[1]);///2;
+ printf ("V dst addr = 0x%x\n",dst_addr);
+ size = (stride[2]*h);
+ memcpy ((void *) dst_addr,src[1]+stride[1]*h/2,size);
+#endif
+ munmap (virt, memSize);
+ bmm_cmd.input = bmm_cmd.output;
+ bmm_cmd.arg = 0x0;
+ if ((ioctl(m_bmm, BMM_FREE, &bmm_cmd) != 0))
+ {
+ CLog::Log(LOGERROR, "DoveOverlay: Failed to alloc memory from bmm");
+ printf ("BMM memory allocate FAILED\n");
+ return false;
+ }
+
+ }
+ return 0;
+}
+
+unsigned int CDoveOverlayRenderer::PreInit()
+{
+ UnInit();
+
+ return true;
+}
+
+void CDoveOverlayRenderer::UnInit()
+{
+ CLog::Log(LOGINFO, "CDoveOverlayRenderer::UnInit");
+ printf("UnInit\n");
+ m_bConfigured = false;
+ m_iFlags = 0;
+ m_currentBuffer = 0;
+ for (unsigned int i = 0; i < 2; i++)
+ FreeYV12Image(i);
+
+ enabled = 0;
+ if (ioctl(m_overlayfd, DOVEFB_IOCTL_SWITCH_VID_OVLY, &enabled) == -1)
+ {
+ CLog::Log(LOGERROR, "DoveOverlay: Failed to disable video overlay");
+ }
+ // Rabeeh - TODO add framebuffer memory release code
+ if (m_overlayfd > 0)
+ {
+ close(m_overlayfd);
+ m_overlayfd = -1;
+ }
+ m_sourceWidth = 0;
+ m_sourceHeight = 0;
+ m_zoomWidth = 0;
+ m_zoomHeight = 0;
+ m_offsetX = 0;
+ m_offsetY = 0;
+}
+
+void CDoveOverlayRenderer::CreateThumbnail(CBaseTexture* texture, unsigned int width, unsigned int height)
+{
+ printf ("Was asked to create thumbnail (width = %d, height = %d)\n",width,height);
+}
+
+bool CDoveOverlayRenderer::Supports(EDEINTERLACEMODE mode)
+{
+#if 0
+ if (mode == VS_DEINTERLACEMODE_OFF)
+ return true;
+
+ if(m_renderMethod & RENDER_OMXEGL)
+ return false;
+
+ if(m_renderMethod & RENDER_CVREF)
+ return false;
+
+ if(mode == VS_DEINTERLACEMODE_AUTO
+ || mode == VS_DEINTERLACEMODE_FORCE)
+ return true;
+#endif
+ printf ("Called %s\n",__FUNCTION__);
+ return false;
+}
+
+bool CDoveOverlayRenderer::Supports(ERENDERFEATURE feature)
+{
+ printf ("Called %s\n",__FUNCTION__);
+ return false;
+}
+
+bool CDoveOverlayRenderer::SupportsMultiPassRendering()
+{
+ return false;
+}
+
+bool CDoveOverlayRenderer::Supports(EINTERLACEMETHOD method)
+{
+ printf ("Called %s\n",__FUNCTION__);
+ return false;
+}
+
+bool CDoveOverlayRenderer::Supports(ESCALINGMETHOD method)
+{
+ printf ("Called %s\n",__FUNCTION__);
+ if(method == VS_SCALINGMETHOD_NEAREST
+ || method == VS_SCALINGMETHOD_LINEAR)
+ return true;
+
+ return false;
+}
+
+EINTERLACEMETHOD CDoveOverlayRenderer::AutoInterlaceMethod()
+{
+#if 0
+ if(m_renderMethod & RENDER_OMXEGL)
+ return VS_INTERLACEMETHOD_NONE;
+
+ if(m_renderMethod & RENDER_CVREF)
+ return VS_INTERLACEMETHOD_NONE;
+
+#if defined(__i386__) || defined(__x86_64__)
+ return VS_INTERLACEMETHOD_DEINTERLACE_HALF;
+#else
+ return VS_INTERLACEMETHOD_SW_BLEND;
+#endif
+#endif
+// printf ("Called %s\n",__FUNCTION__);
+ return VS_INTERLACEMETHOD_NONE;
+}
+
+unsigned int CDoveOverlayRenderer::NextYV12Image()
+{
+// printf ("Called to get NextYV12Image (m_currentBuffer = %d)\n",m_currentBuffer);
+ return 1 - m_currentBuffer;
+}
+
+bool CDoveOverlayRenderer::CreateYV12Image(unsigned int index, unsigned int width, unsigned int height)
+{
+ YV12Image &im = m_yuvBuffers[index];
+
+ im.width = width;
+ im.height = height;
+ im.cshift_x = 1;
+ im.cshift_y = 1;
+
+#if 0
+ im.stride[0] = im.width;
+ im.stride[1] = im.width >> im.cshift_x;
+ im.stride[2] = im.width >> im.cshift_x;
+#else
+unsigned paddedWidth = (im.width + 15) & ~15;
+// printf("w %i | padded %i\n", width, paddedWidth);
+ im.stride[0] = paddedWidth;
+ im.stride[1] = paddedWidth >> im.cshift_x;
+ im.stride[2] = paddedWidth >> im.cshift_x;
+#endif
+ im.planesize[0] = im.stride[0] * im.height;
+ im.planesize[1] = im.stride[1] * ( im.height >> im.cshift_y );
+ im.planesize[2] = im.stride[2] * ( im.height >> im.cshift_y );
+#if 0
+ for (int i = 0; i < 3; i++) {
+// im.plane[i] = new BYTE[im.planesize[i]];
+ im.plane[i] = (BYTE *)memalign(16, im.planesize[i]);
+// printf ("CreateYV12Image shows 0x%x (index = %d, width = %d, height = %d) --> size = 0x%x\n",im.plane[i], index, width, height,im.planesize[i]);
+ }
+#endif
+ return true;
+}
+
+bool CDoveOverlayRenderer::FreeYV12Image(unsigned int index)
+{
+ YV12Image &im = m_yuvBuffers[index];
+ for (int i = 0; i < 3; i++)
+ {
+ delete[] im.plane[i];
+ im.plane[i] = NULL;
+ }
+
+ memset(&im , 0, sizeof(YV12Image));
+
+ return true;
+}
+
+#endif
diff --git a/xbmc/cores/VideoRenderers/DoveOverlayRenderer.h b/xbmc/cores/VideoRenderers/DoveOverlayRenderer.h
new file mode 100644
index 0000000..9b4949d
--- /dev/null
+++ b/xbmc/cores/VideoRenderers/DoveOverlayRenderer.h
@@ -0,0 +1,214 @@
+#ifndef DOVEOVERLAYRENDERER_RENDERER
+#define DOVEOVERLAYRENDERER_RENDERER
+
+/*
+ * Copyright (C) 2005-2010 Team XBMC
+ * http://xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#ifdef HAS_DOVE_OVERLAY
+
+#undef __u8
+#undef byte
+
+extern "C"
+{
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <gst/app/gstappsrc.h>
+#include <gst/app/gstappsink.h>
+#include <linux/fb.h>
+#include "dovefb.h"
+}
+
+#include "../../settings/VideoSettings.h"
+#include "../dvdplayer/DVDCodecs/Video/DVDVideoCodec.h"
+#include "RenderFlags.h"
+#include "BaseRenderer.h"
+
+class CRenderCapture;
+class CBaseTexture;
+
+#undef ALIGN
+#define ALIGN(value, alignment) (((value)+((alignment)-1))&~((alignment)-1))
+//#define CLAMP(a, min, max) ((a) > (max) ? (max) : ( (a) < (min) ? (min) : a ))
+
+#define AUTOSOURCE -1
+
+#define IMAGE_FLAG_WRITING 0x01 /* image is in use after a call to GetImage, caller may be reading or writing */
+#define IMAGE_FLAG_READING 0x02 /* image is in use after a call to GetImage, caller is only reading */
+#define IMAGE_FLAG_DYNAMIC 0x04 /* image was allocated due to a call to GetImage */
+#define IMAGE_FLAG_RESERVED 0x08 /* image is reserved, must be asked for specifically used to preserve images */
+#define IMAGE_FLAG_READY 0x16 /* image is ready to be uploaded to texture memory */
+#define IMAGE_FLAG_INUSE (IMAGE_FLAG_WRITING | IMAGE_FLAG_READING | IMAGE_FLAG_RESERVED)
+
+struct DRAWRECT
+{
+ float left;
+ float top;
+ float right;
+ float bottom;
+};
+
+enum EFIELDSYNC
+{
+ FS_NONE,
+ FS_TOP, // Rabeeh FS_ODD,
+ FS_BOT // Rabeeh FS_EVEN
+};
+
+struct YUVRANGE
+{
+ int y_min, y_max;
+ int u_min, u_max;
+ int v_min, v_max;
+};
+
+struct YUVCOEF
+{
+ float r_up, r_vp;
+ float g_up, g_vp;
+ float b_up, b_vp;
+};
+
+/*
+enum RenderMethod
+{
+ RENDER_GLSL=0x01,
+ RENDER_SW=0x04,
+ RENDER_POT=0x10
+};
+
+enum RenderQuality
+{
+ RQ_LOW=1,
+ RQ_SINGLEPASS,
+ RQ_MULTIPASS,
+ RQ_SOFTWARE
+};
+*/
+
+#define PLANE_Y 0
+#define PLANE_U 1
+#define PLANE_V 2
+
+#define FIELD_FULL 0
+#define FIELD_ODD 1
+#define FIELD_EVEN 2
+
+extern YUVRANGE yuv_range_lim;
+extern YUVRANGE yuv_range_full;
+extern YUVCOEF yuv_coef_bt601;
+extern YUVCOEF yuv_coef_bt709;
+extern YUVCOEF yuv_coef_ebu;
+extern YUVCOEF yuv_coef_smtp240m;
+
+class CDoveOverlayRenderer : public CBaseRenderer
+{
+public:
+ CDoveOverlayRenderer();
+ virtual ~CDoveOverlayRenderer();
+
+ virtual void Update(bool bPauseDrawing);
+ virtual void SetupScreenshot() {};
+
+ bool RenderCapture(CRenderCapture* capture); // Added by Rabeeh
+
+ void CreateThumbnail(CBaseTexture *texture, unsigned int width, unsigned int height);
+
+ // Player functions
+ virtual bool Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned int flags, unsigned int format);
+ virtual bool IsConfigured() { return m_bConfigured; }
+ virtual int GetImage(YV12Image *image, int source = AUTOSOURCE, bool readonly = false);
+ virtual void ReleaseImage(int source, bool preserve = false);
+ virtual unsigned int DrawSlice(unsigned char *src[], int stride[], int w, int h, int x, int y);
+ virtual void FlipPage(int source);
+ virtual unsigned int PreInit();
+ virtual void UnInit();
+ virtual void Reset(); /* resets renderer after seek for example */
+
+ virtual void AddProcessor(YV12Image *image, DVDVideoPicture *pic);
+
+ virtual void RenderUpdate(bool clear, DWORD flags = 0, DWORD alpha = 255);
+
+ // Feature support
+ virtual bool SupportsMultiPassRendering();
+ virtual bool Supports(ERENDERFEATURE feature);
+ virtual bool Supports(EDEINTERLACEMODE mode);
+ virtual bool Supports(EINTERLACEMETHOD method);
+ virtual bool Supports(ESCALINGMETHOD method);
+
+ virtual EINTERLACEMETHOD AutoInterlaceMethod();
+
+private:
+ unsigned int NextYV12Image();
+ bool CreateYV12Image(unsigned int index, unsigned int width, unsigned int height);
+ bool FreeYV12Image(unsigned int index);
+
+ bool m_bConfigured;
+ unsigned int m_iFlags;
+ unsigned int m_sourceWidth;
+ unsigned int m_sourceHeight;
+ unsigned int m_zoomWidth;
+ unsigned int m_zoomHeight;
+ unsigned int m_offsetX;
+ unsigned int m_offsetY;
+
+ unsigned int m_overlayWidth;
+
+ YV12Image m_yuvBuffers[2];
+ unsigned int m_currentBuffer;
+
+ // The Overlay handlers
+ int m_overlayfd, m_bmm;
+ unsigned int m_offset;
+ unsigned char *buf1_phys, *buf2_phys, *gst_buf[3];
+
+ struct fb_var_screeninfo m_overlayScreenInfo;
+ struct _sOvlySurface m_overlaySurface;
+ int enabled;
+ struct _sViewPortInfo m_overlayPlaneInfo;
+
+ struct
+ {
+ unsigned x;
+ unsigned y;
+ uint8_t *buf;
+ } m_framebuffers[2];
+};
+
+
+inline int NP2( unsigned x )
+{
+ --x;
+ x |= x >> 1;
+ x |= x >> 2;
+ x |= x >> 4;
+ x |= x >> 8;
+ x |= x >> 16;
+ return ++x;
+}
+#endif
+
+#endif
diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.h b/xbmc/cores/VideoRenderers/LinuxRendererGLES.h
index 3c7852a..7ba03a5 100644
--- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.h
+++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.h
@@ -22,7 +22,7 @@
*
*/
-#if HAS_GLES == 2
+#if HAS_GLES == 2 && !defined(HAS_DOVE_OVERLAY)
#include "xbmc/guilib/FrameBufferObject.h"
#include "xbmc/guilib/Shader.h"
diff --git a/xbmc/cores/VideoRenderers/Makefile.in b/xbmc/cores/VideoRenderers/Makefile.in
index 5bcaf6a..52ef981 100644
--- a/xbmc/cores/VideoRenderers/Makefile.in
+++ b/xbmc/cores/VideoRenderers/Makefile.in
@@ -16,9 +16,12 @@ SRCS+= LinuxRendererGL.cpp \
endif
ifeq (@USE_OPENGLES@,1)
-SRCS+= LinuxRendererGLES.cpp \
- OverlayRendererGL.cpp \
-
+SRCS+= OverlayRendererGL.cpp
+ifeq (@USE_DOVE_OVERLAY@,1)
+SRCS+= DoveOverlayRenderer.cpp
+else
+SRCS+= LinuxRendererGLES.cpp
+endif
endif
LIB=VideoRenderer.a
diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp
index 31bb49a..14c8ca6 100644
--- a/xbmc/cores/VideoRenderers/RenderManager.cpp
+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp
@@ -38,6 +38,8 @@
#if defined(HAS_GL)
#include "LinuxRendererGL.h"
+#elif defined(HAS_DOVE_OVERLAY)
+ #include "DoveOverlayRenderer.h"
#elif HAS_GLES == 2
#include "LinuxRendererGLES.h"
#elif defined(HAS_DX)
@@ -311,6 +313,8 @@ unsigned int CXBMCRenderManager::PreInit()
{
#if defined(HAS_GL)
m_pRenderer = new CLinuxRendererGL();
+#elif defined(HAS_DOVE_OVERLAY)
+ m_pRenderer = new CDoveOverlayRenderer();
#elif HAS_GLES == 2
m_pRenderer = new CLinuxRendererGLES();
#elif defined(HAS_DX)
@@ -748,7 +752,11 @@ int CXBMCRenderManager::AddVideoPicture(DVDVideoPicture& pic)
if(pic.format == DVDVideoPicture::FMT_YUV420P)
{
+#ifdef HAS_DOVE_OVERLAY
+ m_pRenderer->AddProcessor(&image, &pic);
+#else
CDVDCodecUtils::CopyPicture(&image, &pic);
+#endif
}
else if(pic.format == DVDVideoPicture::FMT_NV12)
{
@@ -757,7 +765,11 @@ int CXBMCRenderManager::AddVideoPicture(DVDVideoPicture& pic)
else if(pic.format == DVDVideoPicture::FMT_YUY2
|| pic.format == DVDVideoPicture::FMT_UYVY)
{
+#ifdef HAS_DOVE_OVERLAY
+ m_pRenderer->AddProcessor(&image, &pic);
+#else
CDVDCodecUtils::CopyYUV422PackedPicture(&image, &pic);
+#endif
}
else if(pic.format == DVDVideoPicture::FMT_DXVA)
{
diff --git a/xbmc/cores/VideoRenderers/RenderManager.h b/xbmc/cores/VideoRenderers/RenderManager.h
index b81bced..c757194 100644
--- a/xbmc/cores/VideoRenderers/RenderManager.h
+++ b/xbmc/cores/VideoRenderers/RenderManager.h
@@ -25,6 +25,8 @@
#if defined (HAS_GL)
#include "LinuxRendererGL.h"
+#elif defined(HAS_DOVE_OVERLAY)
+ #include "DoveOverlayRenderer.h"
#elif HAS_GLES == 2
#include "LinuxRendererGLES.h"
#elif defined(HAS_DX)
@@ -171,6 +173,8 @@ public:
#ifdef HAS_GL
CLinuxRendererGL *m_pRenderer;
+#elif defined(HAS_DOVE_OVERLAY)
+ CDoveOverlayRenderer *m_pRenderer;
#elif HAS_GLES == 2
CLinuxRendererGLES *m_pRenderer;
#elif defined(HAS_DX)
diff --git a/xbmc/cores/VideoRenderers/bmm_drv.h b/xbmc/cores/VideoRenderers/bmm_drv.h
new file mode 100644
index 0000000..4bd516a
--- /dev/null
+++ b/xbmc/cores/VideoRenderers/bmm_drv.h
@@ -0,0 +1,81 @@
+/*
+ * bmm_drv.h
+ *
+ * Buffer Management Module
+ *
+ * User/Driver level BMM Defines/Globals/Functions
+ *
+ * Li Li (lea.li@marvell.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+
+ *(C) Copyright 2007 Marvell International Ltd.
+ * All Rights Reserved
+ */
+
+#ifndef _BMM_DRV_H
+#define _BMM_DRV_H
+
+#ifdef KERNEL
+#include <linux/dma-mapping.h>
+#endif
+
+#define BMM_MINOR 94
+
+typedef struct {
+ unsigned long input; /* the starting address of the block of memory */
+ unsigned long output; /* the starting address of the block of memory */
+ unsigned long length; /* the length of the block of memory */
+ unsigned long arg; /* the arg of cmd */
+} ioctl_arg_t;
+
+#define BMEM_IOCTL_MAGIC 'G'
+/* ioctl commands */
+#define BMM_MALLOC _IOWR(BMEM_IOCTL_MAGIC, 0, ioctl_arg_t)
+#define BMM_FREE _IOWR(BMEM_IOCTL_MAGIC, 1, ioctl_arg_t)
+#define BMM_GET_VIRT_ADDR _IOWR(BMEM_IOCTL_MAGIC, 2, ioctl_arg_t)
+#define BMM_GET_PHYS_ADDR _IOWR(BMEM_IOCTL_MAGIC, 3, ioctl_arg_t)
+#define BMM_GET_MEM_ATTR _IOWR(BMEM_IOCTL_MAGIC, 4, ioctl_arg_t)
+#define BMM_SET_MEM_ATTR _IOWR(BMEM_IOCTL_MAGIC, 5, ioctl_arg_t)
+#define BMM_GET_MEM_SIZE _IOWR(BMEM_IOCTL_MAGIC, 6, ioctl_arg_t)
+#define BMM_GET_TOTAL_SPACE _IOWR(BMEM_IOCTL_MAGIC, 7, ioctl_arg_t)
+#define BMM_GET_FREE_SPACE _IOWR(BMEM_IOCTL_MAGIC, 8, ioctl_arg_t)
+#define BMM_FLUSH_CACHE _IOWR(BMEM_IOCTL_MAGIC, 9, ioctl_arg_t)
+#define BMM_DMA_MEMCPY _IOWR(BMEM_IOCTL_MAGIC, 10, ioctl_arg_t)
+#define BMM_DMA_SYNC _IOWR(BMEM_IOCTL_MAGIC, 11, ioctl_arg_t)
+#define BMM_CONSISTENT_SYNC _IOWR(BMEM_IOCTL_MAGIC, 12, ioctl_arg_t)
+#define BMM_DUMP _IOWR(BMEM_IOCTL_MAGIC, 13, ioctl_arg_t)
+#define BMM_GET_ALLOCATED_SPACE _IOWR(BMEM_IOCTL_MAGIC, 14, ioctl_arg_t)
+#define BMM_GET_KERN_PHYS_ADDR _IOWR(BMEM_IOCTL_MAGIC, 15, ioctl_arg_t)
+#define BMM_INC_USERS_PADDR _IOWR(BMEM_IOCTL_MAGIC, 16, ioctl_arg_t)
+#define BMM_DEC_USERS_PADDR _IOWR(BMEM_IOCTL_MAGIC, 17, ioctl_arg_t)
+
+/* ioctl arguments: memory attributes */
+#define BMM_ATTR_DEFAULT (0) /* cacheable bufferable */
+#define BMM_ATTR_WRITECOMBINE (1 << 0) /* non-cacheable & bufferable */
+#define BMM_ATTR_NONCACHED (1 << 1) /* non-cacheable & non-bufferable */
+/* Note: extra attributes below are not supported yet! */
+#define BMM_ATTR_HUGE_PAGE (1 << 2) /* 64KB page size */
+#define BMM_ATTR_WRITETHROUGH (1 << 3) /* implies L1 Cacheable */
+#define BMM_ATTR_L2_CACHEABLE (1 << 4) /* implies L1 Cacheable */
+
+/* ioctl arguments: cache flush direction */
+#define BMM_DMA_BIDIRECTIONAL DMA_BIDIRECTIONAL /* 0 */
+#define BMM_DMA_TO_DEVICE DMA_TO_DEVICE /* 1 */
+#define BMM_DMA_FROM_DEVICE DMA_FROM_DEVICE /* 2 */
+#define BMM_DMA_NONE DMA_NONE /* 3 */
+
+#ifdef CONFIG_DOVE_VPU_USE_BMM
+extern unsigned int dove_vmeta_get_memory_start(void);
+extern int dove_vmeta_get_memory_size(void);
+#endif
+
+#ifdef CONFIG_DOVE_GPU_USE_BMM
+extern unsigned int dove_gpu_get_memory_start(void);
+extern int dove_gpu_get_memory_size(void);
+#endif
+
+#endif
+
diff --git a/xbmc/cores/VideoRenderers/dovefb.h b/xbmc/cores/VideoRenderers/dovefb.h
new file mode 100644
index 0000000..6915616
--- /dev/null
+++ b/xbmc/cores/VideoRenderers/dovefb.h
@@ -0,0 +1,509 @@
+/*
+ * linux/include/video/dovefb.h -- Marvell frame buffer for DOVE
+ *
+ *
+ * Copyright (C) Marvell Semiconductor Company. All rights reserved.
+ *
+ * Written by Green Wan <gwan@marvell.com>
+ *
+ * Adapted from: linux/drivers/video/skeletonfb.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ *
+ */
+#ifndef _DOVEFB_H_
+#define _DOVEFB_H_
+
+/* ---------------------------------------------- */
+/* Header Files */
+/* ---------------------------------------------- */
+#include <linux/fb.h>
+
+/* ---------------------------------------------- */
+/* IOCTL Definition */
+/* ---------------------------------------------- */
+#define DOVEFB_IOC_MAGIC 'm'
+#define DOVEFB_IOCTL_CONFIG_CURSOR _IO(DOVEFB_IOC_MAGIC, 0)
+#define DOVEFB_IOCTL_DUMP_REGS _IO(DOVEFB_IOC_MAGIC, 1)
+#define DOVEFB_IOCTL_CLEAR_IRQ _IO(DOVEFB_IOC_MAGIC, 2)
+
+/*
+ * There are many video mode supported.
+ */
+#define DOVEFB_IOCTL_SET_VIDEO_MODE _IO(DOVEFB_IOC_MAGIC, 3)
+#define DOVEFB_IOCTL_GET_VIDEO_MODE _IO(DOVEFB_IOC_MAGIC, 4)
+/* Request a new video buffer from driver. User program needs to free
+ * this memory.
+ */
+#define DOVEFB_IOCTL_CREATE_VID_BUFFER _IO(DOVEFB_IOC_MAGIC, 5)
+
+/* Configure viewport in driver. */
+#define DOVEFB_IOCTL_SET_VIEWPORT_INFO _IO(DOVEFB_IOC_MAGIC, 6)
+#define DOVEFB_IOCTL_GET_VIEWPORT_INFO _IO(DOVEFB_IOC_MAGIC, 7)
+
+/* Flip the video buffer from user mode. Vide buffer can be separated into:
+ * a. Current-used buffer - user program put any data into it. It will be
+ * displayed immediately.
+ * b. Requested from driver but not current-used - user programe can put any
+ * data into it. It will be displayed after calling
+ * DOVEFB_IOCTL_FLIP_VID_BUFFER.
+ * User program should free this memory when they don't use it any more.
+ * c. User program alloated - user program can allocated a contiguos DMA
+ * buffer to store its video data. And flip it to driver. Notices that
+ * this momory should be free by user programs. Driver won't take care of
+ * this.
+ */
+#define DOVEFB_IOCTL_FLIP_VID_BUFFER _IO(DOVEFB_IOC_MAGIC, 8)
+
+/* Get the current buffer information. User program could use it to display
+ * anything directly. If developer wants to allocate multiple video layers,
+ * try to use DOVEFB_IOCTL_CREATE_VID_BUFFER to request a brand new video
+ * buffer.
+ */
+#define DOVEFB_IOCTL_GET_BUFF_ADDR _IO(DOVEFB_IOC_MAGIC, 9)
+
+/* Get/Set offset position of screen */
+#define DOVEFB_IOCTL_SET_VID_OFFSET _IO(DOVEFB_IOC_MAGIC, 10)
+#define DOVEFB_IOCTL_GET_VID_OFFSET _IO(DOVEFB_IOC_MAGIC, 11)
+
+/* Turn on the memory toggle function to improve the frame rate while playing
+ * movie.
+ */
+#define DOVEFB_IOCTL_SET_MEMORY_TOGGLE _IO(DOVEFB_IOC_MAGIC, 12)
+
+/* Turn on the memory toggle function to improve the frame rate while playing
+ * movie.
+ */
+#define DOVEFB_IOCTL_SET_COLORKEYnALPHA _IO(DOVEFB_IOC_MAGIC, 13)
+#define DOVEFB_IOCTL_GET_COLORKEYnALPHA _IO(DOVEFB_IOC_MAGIC, 14)
+#define DOVEFB_IOCTL_SWITCH_GRA_OVLY _IO(DOVEFB_IOC_MAGIC, 15)
+#define DOVEFB_IOCTL_SWITCH_VID_OVLY _IO(DOVEFB_IOC_MAGIC, 16)
+
+/* For Vmeta integration */
+#define DOVEFB_IOCTL_GET_FREELIST _IO(DOVEFB_IOC_MAGIC, 17)
+
+/* Wait for vsync happen. */
+#define DOVEFB_IOCTL_WAIT_VSYNC _IO(DOVEFB_IOC_MAGIC, 18)
+
+/* for xv+vmeta/sw decoder w/o memory move. */
+#define DOVEFB_IOCTL_GET_FBPA _IO(DOVEFB_IOC_MAGIC, 19)
+#define DOVEFB_IOCTL_GET_FBID _IO(DOVEFB_IOC_MAGIC, 20)
+#define DOVEFB_IOCTL_SET_SRC_MODE _IO(DOVEFB_IOC_MAGIC, 21)
+#define DOVEFB_IOCTL_GET_SRC_MODE _IO(DOVEFB_IOC_MAGIC, 22)
+
+/* Dynamic get EDID data */
+#define DOVEFB_IOCTL_GET_EDID_INFO _IO(DOVEFB_IOC_MAGIC, 23)
+#define DOVEFB_IOCTL_GET_EDID_DATA _IO(DOVEFB_IOC_MAGIC, 24)
+#define DOVEFB_IOCTL_SET_EDID_INTERVAL _IO(DOVEFB_IOC_MAGIC, 25)
+#define DOVEFB_IOCTL_XBMC_PRESENT _IO(DOVEFB_IOC_MAGIC, 26)
+#define DOVEFB_IOCTL_SET_INTERPOLATION_MODE _IO(DOVEFB_IOC_MAGIC, 27)
+/* clear framebuffer: Makes resolution or color space changes look nicer */
+#define FBIO_CLEAR_FRAMEBUFFER _IO(FB_IOC_MAGIC, 19)
+
+/* Global alpha blend controls - Maintaining compatibility with existing
+ user programs. */
+#define FBIOPUT_VIDEO_ALPHABLEND 0xeb
+#define FBIOPUT_GLOBAL_ALPHABLEND 0xe1
+#define FBIOPUT_GRAPHIC_ALPHABLEND 0xe2
+
+/* color swapping */
+#define FBIOPUT_SWAP_GRAPHIC_RED_BLUE 0xe3
+#define FBIOPUT_SWAP_GRAPHIC_U_V 0xe4
+#define FBIOPUT_SWAP_GRAPHIC_Y_UV 0xe5
+#define FBIOPUT_SWAP_VIDEO_RED_BLUE 0xe6
+#define FBIOPUT_SWAP_VIDEO_U_V 0xe7
+#define FBIOPUT_SWAP_VIDEO_Y_UV 0xe8
+
+/* colorkey compatibility */
+#define FBIOGET_CHROMAKEYS 0xe9
+#define FBIOPUT_CHROMAKEYS 0xea
+
+#define DOVEFB_VMODE_RGB565 0x100
+#define DOVEFB_VMODE_BGR565 0x101
+#define DOVEFB_VMODE_RGB1555 0x102
+#define DOVEFB_VMODE_BGR1555 0x103
+#define DOVEFB_VMODE_RGB888PACK 0x104
+#define DOVEFB_VMODE_BGR888PACK 0x105
+#define DOVEFB_VMODE_RGB888UNPACK 0x106
+#define DOVEFB_VMODE_BGR888UNPACK 0x107
+#define DOVEFB_VMODE_RGBA888 0x108
+#define DOVEFB_VMODE_BGRA888 0x109
+
+#define DOVEFB_VMODE_YUV422PACKED 0x0
+#define DOVEFB_VMODE_YUV422PACKED_SWAPUV 0x1
+#define DOVEFB_VMODE_YUV422PACKED_SWAPYUorV 0x2
+#define DOVEFB_VMODE_YUV422PLANAR 0x3
+#define DOVEFB_VMODE_YUV422PLANAR_SWAPUV 0x4
+#define DOVEFB_VMODE_YUV422PLANAR_SWAPYUorV 0x5
+#define DOVEFB_VMODE_YUV420PLANAR 0x6
+#define DOVEFB_VMODE_YUV420PLANAR_SWAPUV 0x7
+#define DOVEFB_VMODE_YUV420PLANAR_SWAPYUorV 0x8
+
+#define DOVEFB_HWCMODE_1BITMODE 0x0
+#define DOVEFB_HWCMODE_2BITMODE 0x1
+
+#define DOVEFB_DISABLE_COLORKEY_MODE 0x0
+#define DOVEFB_ENABLE_Y_COLORKEY_MODE 0x1
+#define DOVEFB_ENABLE_U_COLORKEY_MODE 0x2
+#define DOVEFB_ENABLE_V_COLORKEY_MODE 0x4
+#define DOVEFB_ENABLE_RGB_COLORKEY_MODE 0x3
+#define DOVEFB_ENABLE_R_COLORKEY_MODE 0x5
+#define DOVEFB_ENABLE_G_COLORKEY_MODE 0x6
+#define DOVEFB_ENABLE_B_COLORKEY_MODE 0x7
+
+#define DOVEFB_VID_PATH_ALPHA 0x0
+#define DOVEFB_GRA_PATH_ALPHA 0x1
+#define DOVEFB_CONFIG_ALPHA 0x2
+
+#define DOVEFB_SYNC_COLORKEY_TO_CHROMA 1
+#define DOVEFB_SYNC_CHROMA_TO_COLORKEY 2
+
+/* Compatible to pxa168. */
+#define FB_IOCTL_SET_COLORKEYnALPHA _IO(FB_IOC_MAGIC, 13)
+#define FB_IOCTL_GET_COLORKEYnALPHA _IO(FB_IOC_MAGIC, 14)
+#define FB_VID_PATH_ALPHA 0x0
+#define FB_GRA_PATH_ALPHA 0x1
+#define FB_CONFIG_ALPHA 0x2
+
+#define FB_SYNC_COLORKEY_TO_CHROMA 1
+#define FB_SYNC_CHROMA_TO_COLORKEY 2
+
+#define DOVEFB_FB_NUM 2
+
+/* ---------------------------------------------- */
+/* Data Structure */
+/* ---------------------------------------------- */
+struct _sEdidInfo {
+ int connect; /* is monitor connected */
+ /* =0, monitor is disconnected.
+ =1, monitor is connected and EDID is ready.
+ =2, return fake EDID.
+ =3, monitor is connected, but EDID failed. */
+ int change; /* is edid data changed */
+ int extension; /* the number of extension edid block */
+ int interval; /* the interval to check edid */
+};
+/*
+ * The follow structures are used to pass data from
+ * user space into the kernel for the creation of
+ * overlay surfaces and setting the video mode.
+ */
+
+#define DOVEFBVideoMode signed int
+
+struct _sViewPortInfo {
+ unsigned short srcWidth; /* video source size */
+ unsigned short srcHeight;
+ unsigned short zoomXSize; /* size after zooming */
+ unsigned short zoomYSize;
+ unsigned short ycPitch;
+ unsigned short uvPitch;
+};
+
+struct _sViewPortOffset {
+ unsigned short xOffset; /* position on screen */
+ unsigned short yOffset;
+};
+
+struct _sVideoBufferAddr {
+ unsigned char frameID; /* which frame wants */
+ unsigned char *startAddr; /* new buffer (PA) */
+ unsigned char *inputData; /* input buf address (VA) */
+ unsigned int length; /* input data's length */
+};
+
+struct dovefb_chroma {
+ u_char mode;
+ u_char y_alpha;
+ u_char y;
+ u_char y1;
+ u_char y2;
+ u_char u_alpha;
+ u_char u;
+ u_char u1;
+ u_char u2;
+ u_char v_alpha;
+ u_char v;
+ u_char v1;
+ u_char v2;
+};
+
+struct _sColorKeyNAlpha {
+ unsigned int mode;
+ unsigned int alphapath;
+ unsigned int config;
+ unsigned int Y_ColorAlpha;
+ unsigned int U_ColorAlpha;
+ unsigned int V_ColorAlpha;
+};
+
+struct _sOvlySurface {
+ DOVEFBVideoMode videoMode;
+ struct _sViewPortInfo viewPortInfo;
+ struct _sViewPortOffset viewPortOffset;
+ struct _sVideoBufferAddr videoBufferAddr;
+};
+
+struct _sCursorConfig {
+ unsigned char enable; /* enable cursor or not */
+ unsigned char mode; /* 1bit or 2bit mode */
+ unsigned int color1; /* foreground color */
+ unsigned int color2; /* background color */
+ unsigned short xoffset;
+ unsigned short yoffset;
+ unsigned short width;
+ unsigned short height;
+ unsigned char *pBuffer; /* cursor data */
+};
+
+#define SHM_NORMAL 0x01
+#define SHM_VMETA 0x02
+#define SHM_SOFTWARE_MAP 0x04
+
+struct shm_private_info {
+ unsigned int method;
+ unsigned int fbid;
+ unsigned int format;
+ unsigned int width;
+ unsigned int height;
+ unsigned long fb_pa;
+};
+
+/* MAX bytes per yuv pixel. */
+#define MAX_YUV_PIXEL 2
+
+/* Dumb interface */
+#define DOVEFB_PINS_DUMB_24 0
+#define DOVEFB_PINS_DUMB_18_SPI 1
+#define DOVEFB_PINS_DUMB_18_GPIO 2
+#define DOVEFB_PINS_DUMB_16_SPI 3
+#define DOVEFB_PINS_DUMB_16_GPIO 4
+#define DOVEFB_PINS_DUMB_12_SPI_GPIO 5
+#define DOVEFB_PINS_SMART_18_SPI 6
+#define DOVEFB_PINS_SMART_16_SPI 7
+#define DOVEFB_PINS_SMART_8_SPI_GPIO 8
+
+/* Dumb interface pin allocation */
+#define DOVEFB_DUMB_PANEL_RGB565 0
+#define DOVEFB_DUMB_PANEL_RGB565_UPPER 1
+#define DOVEFB_DUMB_PANEL_RGB666 2
+#define DOVEFB_DUMB_PANEL_RGB666_UPPER 3
+#define DOVEFB_DUMB_PANEL_RGB444 4
+#define DOVEFB_DUMB_PANEL_RGB444_UPPER 5
+#define DOVEFB_DUMB_PANEL_RGB888 6
+
+/* Max fb buffer. 2048x2048-32bits */
+#define DEFAULT_FB_SIZE (2048 * 2048 * 4)
+
+/*
+ * Buffer pixel format
+ * bit0 is for rb swap.
+ * bit12 is for Y UorV swap
+ */
+#if 0
+#define PIX_FMT_RGB565 0
+#define PIX_FMT_BGR565 1
+#define PIX_FMT_RGB1555 2
+#define PIX_FMT_BGR1555 3
+#define PIX_FMT_RGB888PACK 4
+#define PIX_FMT_BGR888PACK 5
+#define PIX_FMT_RGB888UNPACK 6
+#define PIX_FMT_BGR888UNPACK 7
+#define PIX_FMT_RGBA888 8
+#define PIX_FMT_BGRA888 9
+#define PIX_FMT_YUV422PACK 10
+#define PIX_FMT_YVU422PACK 11
+#define PIX_FMT_YUV422PLANAR 12
+#define PIX_FMT_YVU422PLANAR 13
+#define PIX_FMT_YUV420PLANAR 14
+#define PIX_FMT_YVU420PLANAR 15
+#define PIX_FMT_PSEUDOCOLOR 20
+#define PIX_FMT_UYVY422PACK (0x1000|PIX_FMT_YUV422PACK)
+#endif
+#ifdef __KERNEL__
+#include <linux/interrupt.h>
+
+enum dovefb_type {
+ DOVEFB_GFX_PLANE,
+ DOVEFB_OVLY_PLANE
+};
+
+#define MRVL_AXI_CLK 0
+#define MRVL_EXT_CLK0 1
+#define MRVL_PLL_CLK 2
+#define MRVL_EXT_CLK1 3
+
+struct dovefb_layer_info {
+ struct device *dev;
+ enum dovefb_type type;
+ struct dovefb_info *info;
+ struct fb_info *fb_info;
+
+ void *reg_base;
+
+ unsigned long new_addr;
+ dma_addr_t fb_start_dma;
+ void *fb_start;
+ int fb_size;
+ atomic_t w_intr;
+ wait_queue_head_t w_intr_wq;
+ struct mutex access_ok;
+ struct _sOvlySurface surface;
+ struct _sColorKeyNAlpha ckey_alpha;
+
+ unsigned char *hwc_buf;
+ unsigned int pseudo_palette[16];
+ struct tasklet_struct tasklet;
+ char *mode_option;
+
+ int ddc_polling_disable;
+ struct timer_list get_edid_timer;
+ unsigned char* raw_edid;
+ struct _sEdidInfo edid_info;
+ struct work_struct work_queue;
+
+ int pix_fmt;
+ unsigned is_blanked:1;
+ unsigned cursor_enabled:1;
+ unsigned cursor_cfg:1;
+ unsigned active:1;
+ unsigned enabled:1;
+ unsigned checkbuf_timer_exist:1;
+
+ /*
+ * 0: DMA mem is from DMA region.
+ * 1: DMA mem is from normal region.
+ */
+ unsigned mem_status:1;
+
+ /*
+ * current frame id for mapping to user.
+ */
+ int cur_fbid;
+ int src_mode;
+
+ unsigned int reserved;
+};
+
+/*
+ * Dove LCD controller private state.
+ */
+struct dovefb_info {
+ struct device *dev;
+ int id;
+
+ void *reg_base;
+ struct dovefb_layer_info *gfx_plane;
+ struct dovefb_layer_info *vid_plane;
+
+ struct fb_videomode dft_vmode;
+ struct fb_videomode out_vmode;
+ int fixed_output;
+
+ char *mode_option;
+ struct clk *clk;
+ int clk_src;
+ int io_pin_allocation;
+
+ int pix_fmt;
+ unsigned edid:1;
+ unsigned panel_rbswap:1;
+ unsigned edid_en:1;
+
+ /* Hardware cursor related registers */
+ unsigned int LCD_SPU_HWC_HPXL_VLN_saved_value;
+ unsigned int LCD_SPU_ALPHA_COLOR1_saved_value;
+ unsigned int LCD_SPU_ALPHA_COLOR2_saved_value;
+
+ /* Colorkey related registers */
+ unsigned int LCD_SPU_COLORKEY_Y_saved_value;
+ unsigned int LCD_SPU_COLORKEY_U_saved_value;
+ unsigned int LCD_SPU_COLORKEY_V_saved_value;
+ unsigned int LCD_SPU_DMA_CTRL1_saved_value;
+ unsigned int LCD_SPU_ADV_REG_saved_value;
+};
+
+/*
+ * Dove fb machine information
+ */
+struct dovefb_mach_info {
+ char id_gfx[16];
+ char id_ovly[16];
+ int clk_src;
+ int accurate_clk;
+ char *clk_name;
+ int num_modes;
+ struct fb_videomode *modes;
+
+ /*
+ * Pix_fmt
+ */
+ unsigned pix_fmt;
+
+ /*
+ * I/O pin allocation.
+ */
+ unsigned io_pin_allocation:4;
+
+ /*
+ * auto poll EDID data periodically
+ */
+ unsigned ddc_polling_disable:1;
+
+ /*
+ * Monitor sense
+ */
+ int (*mon_sense)(int *connect_status);
+
+ /*
+ * I2C bus and address to read DDC data through. -1 not available
+ */
+ int ddc_i2c_adapter;
+ int ddc_i2c_address;
+
+ /*
+ * secondary i2c pair for two display on same LCD.
+ */
+ int secondary_ddc_mode;
+ int ddc_i2c_adapter_2nd;
+ int ddc_i2c_address_2nd;
+
+ /*
+ * Dumb panel -- assignment of R/G/B component info to the 24
+ * available external data lanes.
+ */
+ unsigned panel_rgb_type:4;
+ unsigned panel_rgb_reverse_lanes:1;
+
+ /*
+ * Dumb panel -- GPIO output data.
+ */
+ unsigned gpio_output_mask:8;
+ unsigned gpio_output_data:8;
+
+ /*
+ * Dumb panel -- configurable output signal polarity.
+ */
+ unsigned invert_composite_blank:1;
+ unsigned invert_pix_val_ena:1;
+ unsigned invert_pixclock:1;
+ unsigned invert_vsync:1;
+ unsigned invert_hsync:1;
+ unsigned panel_rbswap:1;
+ unsigned active:1;
+ unsigned enable_lcd0:1;
+};
+
+struct dovebl_platform_data;
+
+int clcd_platform_init(struct dovefb_mach_info *lcd0_dmi_data,
+ struct dovefb_mach_info *lcd0_vid_dmi_data,
+ struct dovefb_mach_info *lcd1_dmi_data,
+ struct dovefb_mach_info *lcd1_vid_dmi_data,
+ struct dovebl_platform_data *backlight_data);
+
+
+#endif /* _KERNEL_ */
+#endif /* _DOVEFB_H_ */
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp b/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp
index 5cdc226..1c14f3e 100644
--- a/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp
+++ b/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp
@@ -33,6 +33,7 @@
#endif
#include "Video/DVDVideoCodecFFmpeg.h"
#include "Video/DVDVideoCodecOpenMax.h"
+#include "Video/DVDVideoCodecGStreamer.h"
#include "Video/DVDVideoCodecLibMpeg2.h"
#if defined(HAVE_LIBCRYSTALHD)
#include "Video/DVDVideoCodecCrystalHD.h"
@@ -162,8 +163,17 @@ CDVDVideoCodec* CDVDFactoryCodec::CreateVideoCodec(CDVDStreamInfo &hint, unsigne
#elif defined(_LINUX) && !defined(__APPLE__)
hwSupport += "VAAPI:no ";
#endif
+#if defined(HAVE_LIBGSTREAMER)
+ hwSupport += "GStreamer:yes ";
+#else
+ hwSupport += "GStreamer:no ";
+#endif
CLog::Log(LOGDEBUG, "CDVDFactoryCodec: compiled in hardware support: %s", hwSupport.c_str());
+#if defined(HAVE_LIBGSTREAMER)
+ CLog::Log(LOGINFO, "Trying GStreamer Video Decoder...");
+ if ( (pCodec = OpenCodec(new CDVDVideoCodecGStreamer(), hint, options)) ) return pCodec;
+#endif
// dvd's have weird still-frames in it, which is not fully supported in ffmpeg
if(hint.stills && (hint.codec == CODEC_ID_MPEG2VIDEO || hint.codec == CODEC_ID_MPEG1VIDEO))
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecGStreamer.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecGStreamer.cpp
new file mode 100644
index 0000000..582d451
--- /dev/null
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecGStreamer.cpp
@@ -0,0 +1,450 @@
+/*
+ * Copyright (C) 2005-2011 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+typedef unsigned char byte;
+#if (defined HAVE_CONFIG_H) && (!defined WIN32)
+ #include "config.h"
+#endif
+#undef byte
+#include "DVDVideoCodecGStreamer.h"
+#include "DVDStreamInfo.h"
+#include "DVDClock.h"
+#include <gst/app/gstappsrc.h>
+#include <gst/app/gstappsink.h>
+
+bool CDVDVideoCodecGStreamer::gstinitialized = false;
+
+CDVDVideoCodecGStreamer::CDVDVideoCodecGStreamer()
+{
+ if (gstinitialized == false)
+ {
+ gst_init (NULL, NULL);
+ gstinitialized = true;
+ }
+
+ m_initialized = false;
+ m_pictureBuffer = NULL;
+ m_pictureBufferTbr = NULL;
+ m_pictureBufferTbr1 = NULL;
+
+ m_decoder = NULL;
+ m_needData = true;
+ m_dropState = false;
+ m_AppSrc = NULL;
+ m_AppSrcCaps = NULL;
+ m_ptsinvalid = true;
+
+ m_timebase = 1000.0;
+}
+
+CDVDVideoCodecGStreamer::~CDVDVideoCodecGStreamer()
+{
+ Dispose();
+}
+
+bool CDVDVideoCodecGStreamer::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options)
+{
+ Dispose();
+
+ m_ptsinvalid = hints.ptsinvalid;
+
+ m_AppSrcCaps = CreateVideoCaps(hints, options);
+
+ if (m_AppSrcCaps)
+ {
+ m_decoder = new CGstDecoder(this);
+ m_AppSrc = m_decoder->Open(m_AppSrcCaps);
+ }
+
+ return (m_AppSrc != NULL);
+}
+
+void CDVDVideoCodecGStreamer::Dispose()
+{
+
+ if (0)//m_AppSrc)
+ {
+ GstFlowReturn ret;
+ g_signal_emit_by_name(m_AppSrc, "end-of-stream", &ret);
+
+ if (ret != GST_FLOW_OK)
+ printf("GStreamer: OnDispose. Flow error %i\n", ret);
+ GstStateChangeReturn state;
+ state = gst_element_get_state(m_AppSrc, NULL, NULL, GST_CLOCK_TIME_NONE);
+
+ gst_object_unref(m_AppSrc);
+ m_AppSrc = NULL;
+ }
+ m_AppSrc = NULL;
+// if (m_decoder)
+// m_decoder->DisposePipeline();
+ while (m_pictureQueue.size())
+ {
+ gst_buffer_unref(m_pictureQueue.front());
+ m_pictureQueue.pop();
+ }
+
+ if (m_pictureBuffer)
+ {
+ printf ("Disposing buffer at 0x%x\n",m_pictureBuffer->data);
+ gst_buffer_unref(m_pictureBuffer);
+ m_pictureBuffer = NULL;
+ }
+ if (m_pictureBufferTbr)
+ {
+ printf ("Disposing buffer at 0x%x\n",m_pictureBufferTbr->data);
+ gst_buffer_unref(m_pictureBufferTbr);
+ m_pictureBufferTbr = NULL;
+ }
+ if (m_pictureBufferTbr1)
+ {
+ printf ("Disposing buffer at 0x%x\n",m_pictureBufferTbr1->data);
+ gst_buffer_unref(m_pictureBufferTbr1);
+ m_pictureBufferTbr1 = NULL;
+ }
+ if (m_AppSrcCaps)
+ {
+ gst_caps_unref(m_AppSrcCaps);
+ m_AppSrcCaps = NULL;
+ }
+
+ if (m_decoder)
+ {
+ printf ("Stopping thread...");
+ m_decoder->StopThread();
+ printf ("Done\n");
+ delete m_decoder;
+ m_decoder = NULL;
+
+ m_initialized = false;
+ }
+ while (m_pictureQueue.size())
+ {
+ gst_buffer_unref(m_pictureQueue.front());
+ m_pictureQueue.pop();
+ }
+
+ printf ("Everything should be disposed now\n");
+}
+
+int CDVDVideoCodecGStreamer::Decode(BYTE* pData, int iSize, double dts, double pts)
+{
+ CSingleLock lock(m_monitorLock);
+ int result = 0;
+ int queueSize = m_pictureQueue.size();
+ GstBuffer *buffer = NULL;
+ if (pData)
+ {
+ buffer = gst_buffer_new_and_alloc(iSize);
+ if (buffer)
+ {
+ memcpy(GST_BUFFER_DATA(buffer), pData, iSize);
+
+ GST_BUFFER_TIMESTAMP(buffer) = pts * 1000.0;
+
+ GstFlowReturn ret;
+ g_signal_emit_by_name(m_AppSrc, "push-buffer", buffer, &ret);
+
+ if (ret != GST_FLOW_OK)
+ printf("GStreamer: OnDecode. Flow error %i\n", ret);
+
+ gst_buffer_unref(buffer);
+ } else printf ("WARNING - Couldn't allocate GST buffer\n");
+ }
+
+#if 0
+ // Rabeeh - invsetigate the following
+ if (m_pictureBufferTbr1)
+ {
+// printf ("Disposing buffer 0x%x in ::Decode\n",m_pictureBuffer->data);
+ // This code runs all the time, but seems in the wrong place !!!
+ gst_buffer_unref(m_pictureBufferTbr1);
+ m_pictureBufferTbr1 = NULL;
+ }
+#endif
+ if ((queueSize < 34)) {// && (m_needData == true)) {
+ result |= VC_BUFFER;
+ }
+ if (queueSize > 0 ) {
+ result |= VC_PICTURE;
+ }
+ { static int counter=0;
+ counter++;
+ if (!(counter%20)) printf ("Queue size is %d\n",queueSize);
+ return result;
+ }
+}
+
+void CDVDVideoCodecGStreamer::Reset()
+{
+ GstPad *pad;
+ CSingleLock lock(m_monitorLock);
+ GstStateChangeReturn state;
+ int disposed = 0;
+ printf ("Enter reset\n");
+#if 0
+ pad = gst_element_get_pad (m_AppSrc, "src");
+ if (pad) {
+ gst_pad_push_event (pad, gst_event_new_flush_start());
+ state = gst_element_get_state(m_AppSrc, NULL, NULL, GST_CLOCK_TIME_NONE);
+ gst_pad_push_event (pad, gst_event_new_flush_stop());
+ state = gst_element_get_state(m_AppSrc, NULL, NULL, GST_CLOCK_TIME_NONE);
+ }
+#endif
+ while (m_pictureQueue.size())
+ {
+ gst_buffer_unref(m_pictureQueue.front());
+ m_pictureQueue.pop();
+ disposed++;
+ }
+ if (m_pictureBuffer)
+ {
+ gst_buffer_unref(m_pictureBuffer);
+ m_pictureBuffer = NULL;
+ disposed ++;
+ }
+ if (m_pictureBufferTbr)
+ {
+ gst_buffer_unref(m_pictureBufferTbr);
+ m_pictureBufferTbr = NULL;
+ disposed ++;
+ }
+ if (m_pictureBufferTbr1)
+ {
+ gst_buffer_unref(m_pictureBufferTbr1);
+ m_pictureBufferTbr1 = NULL;
+ disposed ++;
+ }
+ m_decoder->Seek(m_AppSrc);
+ if (disposed) printf ("In %s - Disposed %d frames\n",__FUNCTION__,disposed);
+
+}
+
+bool CDVDVideoCodecGStreamer::GetPicture(DVDVideoPicture* pDvdVideoPicture)
+{
+ static int counter1=0, counter2=0,counter3=0;
+ CSingleLock lock(m_monitorLock);
+ counter1++;
+ if (m_pictureQueue.size())
+ {
+ counter2++;
+ // Rabeeh - invsetigate the following
+ if (m_pictureBufferTbr1)
+ {
+ gst_buffer_unref(m_pictureBufferTbr1);
+ }
+ m_pictureBufferTbr1 = m_pictureBufferTbr;
+ m_pictureBufferTbr = m_pictureBuffer;
+ m_pictureBuffer = m_pictureQueue.front();
+ m_pictureQueue.pop();
+ }
+ else
+ {
+ counter3++;
+ return false;
+ }
+ GstCaps *caps = gst_buffer_get_caps(m_pictureBuffer);
+ if (caps == NULL)
+ {
+ printf("GStreamer: No caps on decoded buffer\n");
+ return false;
+ }
+
+ GstStructure *structure = gst_caps_get_structure (caps, 0);
+ int width = 0, height = 0;
+ if (structure == NULL ||
+ !gst_structure_get_int (structure, "width", (int *) &width) ||
+ !gst_structure_get_int (structure, "height", (int *) &height))
+ {
+ printf("GStreamer: invalid caps on decoded buffer\n");
+ return false;
+ }
+
+ pDvdVideoPicture->iDisplayWidth = pDvdVideoPicture->iWidth = width;
+ pDvdVideoPicture->iDisplayHeight = pDvdVideoPicture->iHeight = height;
+
+// pDvdVideoPicture->format = DVDVideoPicture::FMT_YUV420P;
+ pDvdVideoPicture->format = DVDVideoPicture::FMT_UYVY;
+
+#define ALIGN(x, n) (((x) + (n) - 1) & (~((n) - 1)))
+// printf ("Sending up picture buffer at 0x%x\n",m_pictureBuffer->data);
+ pDvdVideoPicture->data[0] = m_pictureBuffer->data;
+ pDvdVideoPicture->iLineSize[0] = ALIGN (width, 4);
+ pDvdVideoPicture->data[1] = pDvdVideoPicture->data[0] + pDvdVideoPicture->iLineSize[0] * ALIGN (height, 2);
+ pDvdVideoPicture->iLineSize[1] = ALIGN (width, 8) / 2;
+ pDvdVideoPicture->data[2] = (BYTE *)m_pictureBuffer;
+//pDvdVideoPicture->data[1] + pDvdVideoPicture->iLineSize[1] * ALIGN (height, 2) / 2;
+ pDvdVideoPicture->iLineSize[2] = pDvdVideoPicture->iLineSize[1];
+ static int counter = 0;
+#undef ALIGN
+
+ pDvdVideoPicture->dts = DVD_NOPTS_VALUE;
+ if (GST_BUFFER_TIMESTAMP_IS_VALID(m_pictureBuffer))
+ pDvdVideoPicture->pts = ((double)GST_BUFFER_TIMESTAMP(m_pictureBuffer) / 1000.0);
+ else pDvdVideoPicture->pts = DVD_NOPTS_VALUE;
+ if (GST_BUFFER_DURATION_IS_VALID(m_pictureBuffer))
+ pDvdVideoPicture->iDuration = (double)GST_BUFFER_DURATION(m_pictureBuffer) / 1000.0;
+ if (0){//!(counter1%20)) {
+ printf ("Counters %d %d %d (pts/dts/duration for this frame %f / %f / %f)\n",counter1,counter2,counter3, pDvdVideoPicture->pts,pDvdVideoPicture->dts,(double)GST_BUFFER_DURATION(m_pictureBuffer) / 1000.0);
+ printf ("Total ready pictures %d\n",m_pictureQueue.size());
+ }
+ return true;
+}
+
+void CDVDVideoCodecGStreamer::SetDropState(bool bDrop)
+{
+ CSingleLock lock(m_monitorLock);
+ if (bDrop != m_dropState) printf ("%s Notice - Called set drop state %d\n",__FUNCTION__,bDrop);
+ m_dropState = bDrop;
+ if (m_dropState)
+ {
+ int disposed=0;
+ if /*while*/ (m_pictureQueue.size() > 1) // Keep last frame
+ {
+ gst_buffer_unref(m_pictureQueue.front());
+ m_pictureQueue.pop();
+ disposed++;
+ }
+#if 0
+ if (m_pictureBuffer)
+ {
+ gst_buffer_unref(m_pictureBuffer);
+ m_pictureBuffer = NULL;
+ }
+ if (m_pictureBufferTbr)
+ {
+ gst_buffer_unref(m_pictureBufferTbr);
+ m_pictureBufferTbr = NULL;
+ }
+ if (m_pictureBufferTbr1)
+ {
+ gst_buffer_unref(m_pictureBufferTbr1);
+ m_pictureBufferTbr1 = NULL;
+ }
+#endif
+ if (disposed) printf ("Disposed %d frames\n",disposed);
+ }
+}
+
+const char *CDVDVideoCodecGStreamer::GetName()
+{
+ return "GStreamer";
+}
+
+void CDVDVideoCodecGStreamer::OnDecodedBuffer(GstBuffer *buffer)
+{
+ if (buffer)
+ {
+// if (m_dropState) gst_buffer_unref(buffer);
+ CSingleLock lock(m_monitorLock);
+ m_pictureQueue.push(buffer);
+ }
+ else
+ printf("GStreamer: Received null buffer?\n");
+}
+
+void CDVDVideoCodecGStreamer::OnNeedData()
+{
+// if (m_needData == false) printf ("Setting m_needData to true\n");
+ m_needData = true;
+}
+
+void CDVDVideoCodecGStreamer::OnEnoughData()
+{
+// if (m_needData == true) printf ("Setting m_needData to false\n");
+ m_needData = false;
+}
+
+GstCaps *CDVDVideoCodecGStreamer::CreateVideoCaps(CDVDStreamInfo &hints, CDVDCodecOptions &options)
+{
+ GstCaps *caps = NULL;
+ GstCaps *caps_extra = NULL;
+ printf ("Codec ID = %d\n",hints.codec);
+ switch (hints.codec)
+ {
+ case CODEC_ID_H264:
+ caps = gst_caps_new_simple ("video/x-h264", NULL);
+ gst_caps_set_simple(caps,
+ "width", G_TYPE_INT, hints.width,
+ "height", G_TYPE_INT, hints.height,
+ "framerate", GST_TYPE_FRACTION,
+ (hints.vfr ? 0 : hints.fpsrate),
+ (hints.vfr ? 1 : hints.fpsscale),
+ NULL);
+ break;
+ case CODEC_ID_WMV3:
+ caps = gst_caps_new_simple ("video/x-wmv", NULL);
+ gst_caps_set_simple(caps,
+ "wmversion", G_TYPE_INT, 3,
+ "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('W', 'M', 'V', '3'),
+ NULL);
+ break;
+ case CODEC_ID_VC1:
+ caps = gst_caps_new_simple ("video/x-wmv", NULL);
+ gst_caps_set_simple(caps,
+ "wmversion", G_TYPE_INT, 3,
+ "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('W', 'V', 'C', '1'),
+ NULL);
+ break;
+#if 0
+ case CODEC_ID_MPEG4:
+ caps = gst_caps_new_simple ("video/mpeg", NULL);
+ gst_caps_set_simple(caps,
+ "mpegversion", G_TYPE_INT, 4,
+// "systemstream", G_TYPE_BOOLEAN, FALSE,
+ NULL);
+ break;
+#endif
+ case CODEC_ID_MPEG2VIDEO:
+ caps = gst_caps_new_simple ("video/mpeg", NULL);
+ gst_caps_set_simple(caps,
+ "mpegversion", G_TYPE_INT, 2,
+// "systemstream", G_TYPE_BOOLEAN, FALSE,
+ NULL);
+ break;
+ default:
+ printf("GStreamer: codec: unknown = %i\n", hints.codec);
+ return NULL;
+ }
+
+ if (caps)
+ {
+ gst_caps_set_simple(caps,
+ "width", G_TYPE_INT, hints.width,
+ "height", G_TYPE_INT, hints.height,
+ "framerate", GST_TYPE_FRACTION,
+ (hints.vfr ? 0 : hints.fpsrate),
+ (hints.vfr ? 1 : hints.fpsscale),
+ NULL);
+
+ if (hints.extradata && hints.extrasize > 0)
+ {
+ GstBuffer *data = NULL;
+ data = gst_buffer_new_and_alloc(hints.extrasize);
+ memcpy(GST_BUFFER_DATA(data), hints.extradata, hints.extrasize);
+
+ gst_caps_set_simple(caps, "codec_data", GST_TYPE_BUFFER, data, NULL);
+ gst_buffer_unref(data);
+ }
+ }
+
+ return caps;
+}
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecGStreamer.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecGStreamer.h
new file mode 100644
index 0000000..67bd61c
--- /dev/null
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecGStreamer.h
@@ -0,0 +1,73 @@
+#pragma once
+/*
+ * Copyright (C) 2005-2011 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "GstDecoder.h"
+#include <queue>
+#include "DVDVideoCodec.h"
+// #include "utils/SingleLock.h"
+//#include "threads/SingleLock.h" // Rabeeh
+//#include <gst/gst.h>
+// #include "utils/Thread.h"
+//#include "threads/Thread.h" // Rabeeh
+
+class CGstDecoder;
+
+class CDVDVideoCodecGStreamer : public CDVDVideoCodec, public IGstDecoderCallback
+{
+public:
+ CDVDVideoCodecGStreamer();
+ virtual ~CDVDVideoCodecGStreamer();
+ virtual bool Open(CDVDStreamInfo &hints, CDVDCodecOptions &options);
+ virtual void Dispose();
+ virtual int Decode(BYTE* pData, int iSize, double dts, double pts);
+ virtual void Reset();
+ virtual bool GetPicture(DVDVideoPicture* pDvdVideoPicture);
+ virtual void SetDropState(bool bDrop);
+ virtual const char* GetName();
+
+ void OnDecodedBuffer(GstBuffer *buffer);
+ void OnNeedData();
+ void OnEnoughData();
+
+private:
+ static GstCaps *CreateVideoCaps(CDVDStreamInfo &hints, CDVDCodecOptions &options);
+
+ static bool gstinitialized;
+
+ bool m_initialized;
+
+ std::queue<GstBuffer *> m_pictureQueue;
+ GstBuffer *m_pictureBuffer;
+ GstBuffer *m_pictureBufferTbr;
+ GstBuffer *m_pictureBufferTbr1;
+ CCriticalSection m_needBuffer;
+ CCriticalSection m_monitorLock;
+
+ CGstDecoder *m_decoder;
+ GstElement *m_AppSrc;
+ GstCaps *m_AppSrcCaps;
+ double m_timebase;
+
+ volatile bool m_needData;
+ bool m_dropState;
+ bool m_ptsinvalid;
+};
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/GstDecoder.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/GstDecoder.cpp
new file mode 100644
index 0000000..914aacb
--- /dev/null
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/GstDecoder.cpp
@@ -0,0 +1,315 @@
+/*
+ * Copyright (C) 2005-2011 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+/*
+ * Rabeeh - TODO -
+ * 1. Add better reset implementation instead of flushing by seeking
+ * 2. Add delay for pipeline gstreamer creation and wait for paused state
+ * The reason is that there is always hickups when video starts to play
+ * since XBMC starts sending frames for decoding, but gstreamer pipe
+ * still not ready.
+ * 3. Fix proper pipe closing. There seems to be missing 30 frames at the
+ * end of every playback. The reason is that gstreamer is done on decoding
+ * but video renderer is still showing those decoded frames.
+ * 4. Change ffmpegcolorspace in gstreamer to output either YUV420, UYVU and
+ * other supported dove-overlay video layer color formats (I420 is YUV420
+ * but with swapped color space etc...)
+ */
+
+#include "GstDecoder.h"
+#include <gst/app/gstappsrc.h>
+#include <gst/app/gstappsink.h>
+
+CGstDecoder::CGstDecoder(IGstDecoderCallback *callback) : m_callback(callback)
+{
+ m_loop = NULL;
+ m_pipeline = NULL;
+}
+
+CGstDecoder::~CGstDecoder()
+{
+ if (m_pipeline)
+ {
+ gst_object_unref(m_pipeline);
+ m_pipeline = NULL;
+ }
+}
+
+GstElement *CGstDecoder::Open(GstCaps *sourceCapabilities)
+{
+ m_loop = g_main_loop_new (NULL, FALSE);
+ if (m_loop == NULL)
+ return false;
+
+ gchar *capsString = gst_caps_to_string(sourceCapabilities);
+
+ printf("GStreamer: The capabilities from source are %s\n", capsString);
+
+ gchar *pipelineString = g_strdup_printf("appsrc caps=\"%s\" name=\"AppSrc\" stream-type=\"seekable\" ! decodebin2 ! ffmpegcolorspace ! appsink caps=\"video/x-raw-yuv,format=(fourcc)UYVY\" name=\"AppSink\" sync=\"false\" async=\"true\"", capsString);
+ printf("GStreamer: Entire pipeline is %s\n", pipelineString);
+
+ m_pipeline = gst_parse_launch(pipelineString, NULL);
+ g_free(capsString);
+ g_free(pipelineString);
+
+ if (m_pipeline == NULL)
+ return NULL;
+
+ GstBus *bus = gst_element_get_bus(m_pipeline);
+ gst_bus_add_watch (bus, (GstBusFunc)BusCallback, this);
+ gst_object_unref (bus);
+
+ GstElement *AppSrc = gst_bin_get_by_name(GST_BIN(m_pipeline), "AppSrc");
+
+ if (AppSrc)
+ {
+ g_signal_connect(AppSrc, "need-data", G_CALLBACK (OnNeedData), this);
+ g_signal_connect(AppSrc, "enough-data", G_CALLBACK (OnEnoughData), this);
+ g_signal_connect(AppSrc, "seek-data", G_CALLBACK (OnSeekData), this);
+
+ }
+ else
+ printf("GStreamer: Failure to hook up to AppSrc\n");
+
+ GstElement *AppSink = gst_bin_get_by_name(GST_BIN(m_pipeline), "AppSink");
+ if (AppSink)
+ {
+ g_object_set(G_OBJECT(AppSink), "emit-signals", TRUE, "sync", FALSE, NULL);
+ g_signal_connect(AppSink, "new-buffer", G_CALLBACK(CGstDecoder::OnDecodedBuffer), this);
+ gst_object_unref(AppSink);
+ }
+ else printf("GStreamer: Failure to hook up to AppSink\n");
+
+ Create();
+ m_wait_timeout = 20; // CrystalHD uses 1;
+ return AppSrc;
+}
+
+bool CGstDecoder::Seek(GstElement *element)
+{
+ if (!gst_element_seek (m_pipeline, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH,
+ GST_SEEK_TYPE_NONE, 0,
+ GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE)) {
+ g_print ("Seek failed!\n");
+ }
+}
+
+void CGstDecoder::DisposePipeline(void)
+{
+ if (m_pipeline) {
+ printf ("DisposePipeline\n");
+ gst_element_set_state(m_pipeline, GST_STATE_NULL);
+ gst_element_get_state(m_pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
+ printf ("OK\n");
+ }
+}
+
+void CGstDecoder::StopThread(bool bWait)
+{
+// printf ("Called StopThread (bWait = %d)\n",bWait);
+// gst_element_set_state(m_pipeline, GST_STATE_NULL);
+// gst_element_get_state(m_pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
+// printf ("Called StopThread (bWait = %d)\n",bWait);
+ g_main_loop_quit(m_loop);
+ printf ("Called StopThread (bWait = %d)\n",bWait);
+// Sleep(1000);
+ CThread::StopThread(bWait);
+}
+
+void CGstDecoder::Process()
+{
+ printf ("Putting STATE to PLAYING\n");
+ gst_element_set_state(m_pipeline, GST_STATE_PLAYING);
+ gst_element_get_state(m_pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
+ g_main_loop_run(m_loop);
+ gst_element_set_state(m_pipeline, GST_STATE_NULL);
+ gst_object_unref (m_pipeline);
+ m_pipeline = NULL;
+// gst_element_get_state(m_pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
+}
+
+void CGstDecoder::OnDecodedBuffer(GstElement *appsink, void *data)
+{
+ CGstDecoder *decoder = (CGstDecoder *)data;
+
+ GstBuffer *buffer = gst_app_sink_pull_buffer(GST_APP_SINK(appsink));
+ if (buffer)
+ {
+ if (decoder->m_callback)
+ decoder->m_callback->OnDecodedBuffer(buffer);
+ else
+ gst_buffer_unref(buffer);
+ }
+ else
+ printf("GStreamer: OnDecodedBuffer - Null Buffer\n");
+}
+
+void CGstDecoder::OnNeedData(GstElement *appsrc, guint size, void *data)
+{
+ CGstDecoder *decoder = (CGstDecoder *)data;
+
+ if (decoder->m_callback)
+ decoder->m_callback->OnNeedData();
+}
+
+/* This callback is called when appsrc has enough data and we can stop sending.
+ * We remove the idle handler from the mainloop */
+gboolean CGstDecoder::OnSeekData (GstElement *appsrc, guint64 position, void *data)
+{
+ static int counter=0;
+ counter ++;
+// printf ("Requested to seek to %lld\n",position);
+// if (counter == 2) while(1){};
+ return TRUE;
+}
+
+/* This callback is called when appsrc has enough data and we can stop sending.
+ * We remove the idle handler from the mainloop */
+void CGstDecoder::OnEnoughData (GstElement *appsrc, void *data)
+{
+ CGstDecoder *decoder = (CGstDecoder *)data;
+
+ if (decoder->m_callback)
+ decoder->m_callback->OnEnoughData();
+}
+
+gboolean CGstDecoder::BusCallback(GstBus *bus, GstMessage *msg, gpointer data)
+{
+ CGstDecoder *decoder = (CGstDecoder *)data;
+ gchar *str;
+
+ switch (GST_MESSAGE_TYPE(msg))
+ {
+ case GST_MESSAGE_EOS:
+ g_print ("GStreamer: End of stream\n");
+ g_main_loop_quit(decoder->m_loop);
+ break;
+
+ case GST_MESSAGE_ERROR:
+ GError *error;
+
+ gst_message_parse_error (msg, &error, &str);
+ g_free (str);
+
+ g_printerr ("GStreamer: Error - %s %s\n", str, error->message);
+ g_error_free (error);
+
+ g_main_loop_quit(decoder->m_loop);
+ break;
+
+ case GST_MESSAGE_WARNING:
+ GError *warning;
+
+ gst_message_parse_error (msg, &warning, &str);
+ g_free (str);
+
+ g_printerr ("GStreamer: Warning - %s %s\n", str, warning->message);
+ g_error_free (warning);
+ break;
+
+ case GST_MESSAGE_INFO:
+ GError *info;
+
+ gst_message_parse_error (msg, &info, &str);
+ g_free (str);
+
+ g_printerr ("GStreamer: Info - %s %s\n", str, info->message);
+ g_error_free (info);
+ break;
+
+ case GST_MESSAGE_TAG:
+ printf("GStreamer: Message TAG\n");
+ break;
+ case GST_MESSAGE_BUFFERING:
+ printf("GStreamer: Message BUFFERING\n");
+ break;
+ case GST_MESSAGE_STATE_CHANGED:
+ printf("GStreamer: Message STATE_CHANGED\n");
+ GstState old_state, new_state;
+ gst_message_parse_state_changed (msg, &old_state, &new_state, NULL);
+ printf("GStreamer: Element %s changed state from %s to %s.\n",
+ GST_OBJECT_NAME (msg->src),
+ gst_element_state_get_name (old_state),
+ gst_element_state_get_name (new_state));
+ break;
+ case GST_MESSAGE_STATE_DIRTY:
+ printf("GStreamer: Message STATE_DIRTY\n");
+ break;
+ case GST_MESSAGE_STEP_DONE:
+ printf("GStreamer: Message STEP_DONE\n");
+ break;
+ case GST_MESSAGE_CLOCK_PROVIDE:
+ printf("GStreamer: Message CLOCK_PROVIDE\n");
+ break;
+ case GST_MESSAGE_CLOCK_LOST:
+ printf("GStreamer: Message CLOCK_LOST\n");
+ break;
+ case GST_MESSAGE_NEW_CLOCK:
+ printf("GStreamer: Message NEW_CLOCK\n");
+ break;
+ case GST_MESSAGE_STRUCTURE_CHANGE:
+ printf("GStreamer: Message STRUCTURE_CHANGE\n");
+ break;
+ case GST_MESSAGE_STREAM_STATUS:
+ printf("GStreamer: Message STREAM_STATUS\n");
+ break;
+ case GST_MESSAGE_APPLICATION:
+ printf("GStreamer: Message APPLICATION\n");
+ break;
+ case GST_MESSAGE_ELEMENT:
+ printf("GStreamer: Message ELEMENT\n");
+ break;
+ case GST_MESSAGE_SEGMENT_START:
+ printf("GStreamer: Message SEGMENT_START\n");
+ break;
+ case GST_MESSAGE_SEGMENT_DONE:
+ printf("GStreamer: Message SEGMENT_DONE\n");
+ break;
+ case GST_MESSAGE_DURATION:
+ printf("GStreamer: Message DURATION\n");
+ break;
+ case GST_MESSAGE_LATENCY:
+ printf("GStreamer: Message LATENCY\n");
+ break;
+ case GST_MESSAGE_ASYNC_START:
+ printf("GStreamer: Message ASYNC_START\n");
+ break;
+ case GST_MESSAGE_ASYNC_DONE:
+ printf("GStreamer: Message ASYNC_DONE\n");
+ break;
+ case GST_MESSAGE_REQUEST_STATE:
+ printf("GStreamer: Message REQUEST_STATE\n");
+ break;
+ case GST_MESSAGE_STEP_START:
+ printf("GStreamer: Message STEP_START\n");
+ break;
+#if 0 /* Breaks build for now */
+ case GST_MESSAGE_QOS:
+ printf("GStreamer: Message QOS\n");
+ break;
+#endif
+ default:
+ printf("GStreamer: Unknown message %i\n", GST_MESSAGE_TYPE(msg));
+ break;
+ }
+
+ return TRUE;
+}
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/GstDecoder.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/GstDecoder.h
new file mode 100644
index 0000000..832730d
--- /dev/null
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/GstDecoder.h
@@ -0,0 +1,64 @@
+#pragma once
+/*
+ * Copyright (C) 2005-2011 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#undef byte
+#include <gst/gst.h>
+#include <queue>
+/* Thread.h seems not to like FALSE/TRUE. Need to fix this, but for now a workaround */
+#undef FALSE
+#undef TRUE
+#include "threads/Thread.h"
+
+class IGstDecoderCallback
+{
+public:
+ virtual void OnDecodedBuffer(GstBuffer *buffer) = 0;
+ virtual void OnNeedData() = 0;
+ virtual void OnEnoughData() = 0;
+};
+
+class CGstDecoder : public CThread
+{
+public:
+ CGstDecoder(IGstDecoderCallback *callback);
+ ~CGstDecoder();
+
+ GstElement *Open(GstCaps *sourceCapabilities);
+ virtual void StopThread(bool bWait = true);
+ virtual void DisposePipeline(void);
+ bool Seek(GstElement *);
+
+protected:
+ virtual void Process();
+private:
+ static void OnDecodedBuffer(GstElement *appsink, void *data);
+ static void OnNeedData(GstElement *appsrc, guint size, void *data);
+ static void OnEnoughData (GstElement *appsrc, void *data);
+ static gboolean OnSeekData (GstElement *appsrc, guint64 position, void *data);
+ static gboolean BusCallback(GstBus *bus, GstMessage *msg, gpointer data);
+
+ GstElement *m_pipeline;
+ GMainLoop *m_loop;
+ unsigned int m_wait_timeout;
+
+ IGstDecoderCallback *m_callback;
+};
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in b/xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in
index 1dce256..315a98a 100644
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in
@@ -27,6 +27,12 @@ SRCS += OpenMax.cpp \
DVDVideoCodecOpenMax.cpp \
endif
+ifeq (@USE_GSTREAMER@,1)
+SRCS += GstDecoder.cpp \
+ DVDVideoCodecGStreamer.cpp \
+
+endif
+
LIB=Video.a
diff --git a/xbmc/utils/MathUtils.h b/xbmc/utils/MathUtils.h
index 47517b5..3ed74dd 100644
--- a/xbmc/utils/MathUtils.h
+++ b/xbmc/utils/MathUtils.h
@@ -63,7 +63,7 @@ namespace MathUtils
sar i, 1
}
#else
-#if defined(__powerpc__) || defined(__ppc__)
+#if defined(__powerpc__) || defined(__ppc__) || defined(__arm__) /* Rabeeh - hack to workaround compiler ICE */
i = floor(x + round_to_nearest);
#elif defined(__arm__)
// From 'ARM®v7-M Architecture Reference Manual' page A7-569:
diff --git a/xbmc/windowing/WinEventsSDL.cpp b/xbmc/windowing/WinEventsSDL.cpp
index afff390..591b2c6 100644
--- a/xbmc/windowing/WinEventsSDL.cpp
+++ b/xbmc/windowing/WinEventsSDL.cpp
@@ -36,6 +36,7 @@
#endif
#if defined(_LINUX) && !defined(__APPLE__)
+typedef int Status; /* Rabeeh - somehow Status typedef is missing, leads error in XKBlib.h */
#include <X11/Xlib.h>
#include <X11/XKBlib.h>
#include "input/XBMC_keysym.h"
diff --git a/xbmc/windowing/X11/WinSystemX11GLES.cpp b/xbmc/windowing/X11/WinSystemX11GLES.cpp
index a94906d..ce32a67 100644
--- a/xbmc/windowing/X11/WinSystemX11GLES.cpp
+++ b/xbmc/windowing/X11/WinSystemX11GLES.cpp
@@ -34,8 +34,12 @@
using namespace std;
// Comment out one of the following defines to select the colourspace to use
-//#define RGBA8888
+#ifdef HAS_DOVE_OVERLAY
+/* For dove we use 32 bit per pixel on graphics overlay */
+#define RGBA8888
+#else
#define RGB565
+#endif
#if defined(RGBA8888)
#define RSIZE 8
@@ -385,11 +389,13 @@ bool CWinSystemX11GLES::RefreshEGLContext()
if (m_eglContext)
eglDestroyContext(m_eglDisplay, m_eglContext);
+#ifndef HAS_DOVE_OVERLAY /* Dove GL engine doesn't like the following. Probably EGL_NO_CONTEXT flag */
if ((m_eglContext = eglCreateContext(m_eglDisplay, eglConfig, EGL_NO_CONTEXT, contextAttributes)) == EGL_NO_CONTEXT)
{
CLog::Log(LOGERROR, "EGL Error: Could not create context");
return false;
}
+#endif
if ((m_eglContext = eglCreateContext(m_eglDisplay, eglConfig, m_eglContext, contextAttributes)) == EGL_NO_CONTEXT)
{
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment