Created
August 3, 2012 10:52
-
-
Save danielvijge/3246636 to your computer and use it in GitHub Desktop.
XBMC for CuBox (GStreamer version) - based on https://github.com/rabeeh/xbmc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 ([email protected]) | |
+ * | |
+ * 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 <[email protected]> | |
+ * | |
+ * 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