Index: head/multimedia/kodi/Makefile =================================================================== --- head/multimedia/kodi/Makefile (revision 452023) +++ head/multimedia/kodi/Makefile (revision 452024) @@ -1,220 +1,224 @@ # $FreeBSD$ PORTNAME= kodi DISTVERSION= 17.3 PORTREVISION= 2 CATEGORIES= multimedia java MAINTAINER= mickael.maillot@gmail.com COMMENT= Award winning media center application LICENSE= GPLv2 BUILD_DEPENDS= enca:converters/enca \ gawk:lang/gawk \ gperf:devel/gperf \ cmake:devel/cmake \ zip:archivers/zip \ nasm:devel/nasm \ swig3.0:devel/swig30 LIB_DEPENDS= libass.so:multimedia/libass \ libFLAC.so:audio/flac \ libcdio.so:sysutils/libcdio \ libcrossguid.so:devel/libcrossguid \ libcurl.so:ftp/curl \ libdbus-1.so:devel/dbus \ libdcadec.so:multimedia/libdcadec \ libenca.so:converters/enca \ libexpat.so:textproc/expat2\ libfontconfig.so:x11-fonts/fontconfig \ libfreetype.so:print/freetype2 \ libfribidi.so:converters/fribidi \ libgcrypt.so:security/libgcrypt \ libgmp.so:math/gmp \ libgpg-error.so:security/libgpg-error \ libgnutls.so:security/gnutls \ libidn.so:dns/libidn \ libinotify.so:devel/libinotify \ libjasper.so:graphics/jasper \ libltdl.so:devel/libltdl \ liblzo2.so:archivers/lzo2 \ libmodplug.so:audio/libmodplug \ libmpeg2.so:multimedia/libmpeg2 \ libnettle.so:security/nettle \ libogg.so:audio/libogg \ libp11-kit.so:security/p11-kit \ libpcre.so:devel/pcre \ libpng.so:graphics/png \ libsamplerate.so:audio/libsamplerate \ libsqlite3.so:databases/sqlite3 \ libtag.so:audio/taglib \ libtasn1.so:security/libtasn1 \ libtiff.so:graphics/tiff \ libtinyxml.so:textproc/tinyxml \ libtspi.so:security/trousers \ libunistring.so:devel/libunistring \ libuuid.so:misc/e2fsprogs-libuuid \ libvorbis.so:audio/libvorbis \ libxslt.so:textproc/libxslt \ libyajl.so:devel/yajl RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}sqlite3>0:databases/py-sqlite3 ONLY_FOR_ARCHS= amd64 armv6 armv7 i386 KODI_ARCH_i386= x86 KODI_ARCH_amd64=x86_64 KODI_ARCH_armv6=armv6 KODI_ARCH_armv7=armv7 USES= autoreconf:build compiler:c++11-lib gettext gmake iconv jpeg \ libtool pkgconfig python:-2.7 ssl GNU_CONFIGURE= yes USE_JAVA= yes USE_GNOME= libxml2 USE_LDCONFIG= yes JAVA_BUILD= jre NOPRECIOUSMAKEVARS= yes CONFIGURE_ENV= OPENSSL_LIBS="-L${OPENSSLLIB}" \ OPENSSL_CFLAGS="-I${OPENSSLINC}" KODI_CODENAME= Krypton FFMPEG_VERS= 3.1.6 LIBDVDCSS_TAGNAME= 2f12236 LIBDVDNAV_TAGNAME= 981488f LIBDVDREAD_TAGNAME= 17d99db USE_GITHUB= yes GH_TUPLE= xbmc:xbmc:${PORTVERSION}-${KODI_CODENAME} \ xbmc:FFmpeg:${FFMPEG_VERS}-${KODI_CODENAME}:ffmpeg/tools/depends/target/ffmpeg \ xbmc:libdvdcss:${LIBDVDCSS_TAGNAME}:libdvdcss/tools/depends/target/libdvdcss/native \ xbmc:libdvdnav:${LIBDVDNAV_TAGNAME}:libdvdnav/tools/depends/target/libdvdnav/native \ xbmc:libdvdread:${LIBDVDREAD_TAGNAME}:libdvdread/tools/depends/target/libdvdread/native PLIST_SUB= ARCH=${KODI_ARCH_${ARCH}} OPTIONS_SUB= yes OPTIONS_DEFINE= AIRPLAY AIRTUNES AVAHI CEC DOCS \ LIBBLURAY LIRC MYSQL NFS NONFREE PULSEAUDIO RTMP \ - SFTP SMB VAAPI VDPAU WEBSERVER + SFTP SNDIO SMB VAAPI VDPAU WEBSERVER OPTIONS_SINGLE= RPI OPTIONS_SINGLE_RPI= RPI1 RPI2 OPTIONS_EXCLUDE_armv6= LIRC VAAPI VDPAU OPTIONS_EXCLUDE_armv7= LIRC VAAPI VDPAU OPTIONS_EXCLUDE_amd64= RPI1 RPI2 OPTIONS_EXCLUDE_i386= RPI1 RPI2 AIRPLAY_DESC= AirPlay support via libplist AIRTUNES_DESC= AirTunes support via libshairplay CEC_DESC= CEC adapter support NONFREE_DESC= Enable non-free components (rar, ccx, ffmpeg) SFTP_DESC= SSH SFTP support via libssh RPI1_DESC= build for RPI1-B (cpu=arm1176jzf-s) RPI2_DESC= build for RPI2 (cpu=cortex-a7, neon enabled) OPTIONS_DEFAULT= AIRPLAY AIRTUNES AVAHI CEC LIBBLURAY LIRC \ MYSQL NFS RTMP SFTP SMB VAAPI VDPAU WEBSERVER OPTIONS_DEFAULT_armv6= RPI1 OPTIONS_DEFAULT_armv7= RPI1 AIRPLAY_LIB_DEPENDS= libplist.so:devel/libplist AIRPLAY_CONFIGURE_ENABLE= airplay AIRTUNES_LIB_DEPENDS= libshairplay.so:audio/shairplay AIRTUNES_CONFIGURE_ENABLE= airtunes AVAHI_LIB_DEPENDS= libavahi-client.so:net/avahi-app AVAHI_CONFIGURE_ENABLE= avahi CEC_BUILD_DEPENDS= libcec>=3.1.0:multimedia/libcec CEC_LIB_DEPENDS= libcec.so:multimedia/libcec CEC_CONFIGURE_ENABLE= libcec LIBBLURAY_LIB_DEPENDS= libbluray.so:multimedia/libbluray LIBBLURAY_CONFIGURE_ENABLE= libbluray LIRC_RUN_DEPENDS= lircd:comms/lirc MYSQL_USES= mysql MYSQL_CONFIGURE_ENABLE= mysql NFS_LIB_DEPENDS= libnfs.so:net/libnfs NFS_CONFIGURE_ENABLE= nfs NONFREE_CONFIGURE_ENABLE= non-free NONFREE_VARS= NO_CDROM="Restricted binary distribution" \ NO_PACKAGE="Restricted binary distribution" PULSEAUDIO_LIB_DEPENDS= libpulse.so:audio/pulseaudio PULSEAUDIO_CONFIGURE_ENABLE= pulse RPI1_CONFIGURE_ON= --with-platform=raspberry-pi RPI2_CONFIGURE_ON= --with-platform=raspberry-pi2 RTMP_LIB_DEPENDS= librtmp.so:multimedia/librtmp RTMP_CONFIGURE_ENABLE= rtmp + +SNDIO_LIB_DEPENDS= libsndio.so:audio/sndio +SNDIO_CONFIGURE_ENABLE= sndio +SNDIO_EXTRA_PATCHES= ${PATCHDIR}/extra-patch-sndio SMB_USES= samba:lib SMB_CONFIGURE_ENABLE= samba VAAPI_LIB_DEPENDS= libva.so:multimedia/libva VAAPI_CONFIGURE_ENABLE= vaapi VDPAU_LIB_DEPENDS= libvdpau.so:multimedia/libvdpau VDPAU_CONFIGURE_ENABLE= vdpau WEBSERVER_LIB_DEPENDS= libmicrohttpd.so:www/libmicrohttpd WEBSERVER_CONFIGURE_ENABLE= webserver SFTP_BUILD_DEPENDS= ${LOCALBASE}/lib/libssh.so:security/libssh SFTP_RUN_DEPENDS= ${LOCALBASE}/lib/libssh.so:security/libssh SFTP_CONFIGURE_ENABLE= ssh CONFIGURE_ARGS+= --disable-debug --disable-alsa --disable-texturepacker .include .if ${ARCH} != armv6 && ${ARCH} != armv7 BUILD_DEPENDS+= gtk-update-icon-cache:x11-toolkits/gtk20 LIB_DEPENDS+= libdrm.so:graphics/libdrm RUN_DEPENDS+= glxinfo:graphics/mesa-demos \ xdpyinfo:x11/xdpyinfo USE_XORG= x11 xcb xext xmu xrandr xt xtst USE_GL= egl gl glu glew USE_SDL= image sdl2 INSTALLS_ICONS= yes PLIST_SUB+= ARM="@comment " PLIST_SUB+= X86="" .else # armv6 || armv7 (rpi1 and rpi2 only) EXTRA_PATCHES= ${FILESDIR}/extra-armv6_hal CONFIGURE_ARGS+= --enable-player=omxplayer LIB_DEPENDS+= libEGL.so:misc/raspberrypi-userland \ libhal.so:sysutils/hal \ libtiff.so:graphics/tiff PLIST_SUB+= ARM="" PLIST_SUB+= X86="@comment " SUB_FILES= pkg-message .endif post-patch: ${REINPLACE_CMD} 's;make;gmake;' \ ${WRKSRC}/bootstrap \ ${WRKSRC}/codegenerator.mk \ ${WRKSRC}/xbmc/Makefile.in ${REINPLACE_CMD} 's;which swig;&3.0;' ${WRKSRC}/codegenerator.mk ${RM} ${WRKSRC}/system/settings/rbp2.xml.orig pre-configure: cd ${WRKSRC} && ${SH} ./bootstrap post-install: ${INSTALL_MAN} ${WRKSRC}/docs/manpages/kodi.bin.1 ${STAGEDIR}${MAN1PREFIX}/man/man1 (cd ${STAGEDIR}${MAN1PREFIX}/man/man1 && ${LN} -sf kodi.bin.1.gz kodi.1.gz) ${STRIP_CMD} ${STAGEDIR}${PREFIX}/lib/kodi/kodi.bin ${FIND} ${STAGEDIR}${PREFIX}/lib/kodi -name '*.so' -or -name '*.xbs' -or -name '*.vis' \ | ${XARGS} ${STRIP_CMD} .if ${ARCH} != armv6 && ${ARCH} != armv7 ${STRIP_CMD} ${STAGEDIR}${PREFIX}/lib/kodi/kodi-xrandr .endif .include Index: head/multimedia/kodi/files/extra-patch-sndio =================================================================== --- head/multimedia/kodi/files/extra-patch-sndio (nonexistent) +++ head/multimedia/kodi/files/extra-patch-sndio (revision 452024) @@ -0,0 +1,542 @@ +diff --git configure.ac configure.ac +index 47eb1d9e33..c61564bb0e 100644 +--- configure.ac ++++ configure.ac +@@ -315,6 +315,12 @@ AC_ARG_ENABLE([pulse], + [use_pulse=$enableval], + [use_pulse=auto]) + ++AC_ARG_ENABLE([sndio], ++ [AS_HELP_STRING([--enable-sndio], ++ [enable sndio support (default is auto)])], ++ [use_sndio=$enableval], ++ [use_sndio=auto]) ++ + AC_ARG_ENABLE([ssh], + [AS_HELP_STRING([--disable-ssh], + [disable SSH SFTP support (default is enabled)])], +@@ -1210,6 +1216,22 @@ else + USE_PULSE=0 + fi + ++# sndio ++if test "x$use_sndio" != "xno"; then ++ USE_SNDIO=0 ++ AC_CHECK_HEADER(sndio.h, HAVE_SNDIO="yes", HAVE_SNDIO="no") ++ if test "x$HAVE_SNDIO" = "xyes"; then ++ AC_CHECK_LIB(sndio, sio_open, HAVE_SNDIO="yes", HAVE_SNDIO="no", []) ++ if test "x$HAVE_SNDIO" = "xyes"; then ++ LIBS="$LIBS -lsndio" ++ USE_SNDIO=1 ++ AC_DEFINE([HAVE_SNDIO],[1],[sndio enabled]) ++ fi ++ fi ++else ++ USE_SNDIO=0 ++fi ++ + # avahi + if test "$use_avahi" = "yes"; then + AC_CHECK_LIB([avahi-common], [main],, +@@ -1924,6 +1946,12 @@ else + final_message="$final_message\n PulseAudio:\tNo" + fi + ++if test "$use_sndio" = "yes"; then ++ final_message="$final_message\n Sndio Support:\tYes" ++else ++ final_message="$final_message\n Sndio Support:\tNo" ++fi ++ + # Google Test Framework + if test "$configure_gtest" = "yes"; then + AC_MSG_NOTICE($gtest_enabled) +@@ -2247,6 +2275,8 @@ AC_SUBST(USE_AIRPLAY) + AC_SUBST(USE_OPENMAX) + AC_SUBST(USE_PULSE) + AC_SUBST(HAVE_LIBPULSE) ++AC_SUBST(USE_SNDIO) ++AC_SUBST(HAVE_SNDIO) + AC_SUBST(USE_ALSA) + AC_SUBST(USE_TEXTUREPACKER) + AC_SUBST(TEXTUREPACKER) +diff --git xbmc/cores/AudioEngine/AESinkFactory.cpp xbmc/cores/AudioEngine/AESinkFactory.cpp +index d7b05cdbfe..617b5dba83 100644 +--- xbmc/cores/AudioEngine/AESinkFactory.cpp ++++ xbmc/cores/AudioEngine/AESinkFactory.cpp +@@ -36,6 +36,9 @@ + #if defined(HAS_ALSA) + #include "Sinks/AESinkALSA.h" + #endif ++ #if defined(HAS_SNDIO) ++ #include "Sinks/AESinkSNDIO.h" ++ #endif + #if defined(TARGET_FREEBSD) + #include "Sinks/AESinkOSS.h" + #endif +@@ -77,6 +80,9 @@ + #if defined(HAS_ALSA) + driver == "ALSA" || + #endif ++ #if defined(HAS_SNDIO) ++ driver == "SNDIO" || ++ #endif + #if defined(TARGET_FREEBSD) + driver == "OSS" || + #endif +@@ -116,11 +122,15 @@ IAESink *CAESinkFactory::TrySink(std::string &driver, std::string &device, AEAud + sink = new CAESinkDARWINIOS(); + #elif defined(TARGET_DARWIN_OSX) + sink = new CAESinkDARWINOSX(); +-#elif defined(TARGET_LINUX) || defined(TARGET_FREEBSD) ++#elif defined(TARGET_LINUX) || defined(TARGET_FREEBSD) || defined(TARGET_OPENBSD) + #if defined(HAS_PULSEAUDIO) + if (driver == "PULSE") + sink = new CAESinkPULSE(); + #endif ++ #if defined(HAS_SNDIO) ++ if (driver == "SNDIO") ++ sink = new CAESinkSNDIO(); ++ #endif + #if defined(HAS_ALSA) + if (driver == "ALSA") + sink = new CAESinkALSA(); +@@ -236,6 +246,10 @@ void CAESinkFactory::EnumerateEx(AESinkInfoList &list, bool force) + if (envSink == "PULSE") + CAESinkPULSE::EnumerateDevicesEx(info.m_deviceInfoList, force); + #endif ++ #if defined(HAS_SNDIO) ++ if (envSink == "SNDIO") ++ CAESinkSNDIO::EnumerateDevicesEx(info.m_deviceInfoList, force); ++ #endif + #if defined(HAS_ALSA) + if (envSink == "ALSA") + CAESinkALSA::EnumerateDevicesEx(info.m_deviceInfoList, force); +@@ -264,6 +278,17 @@ void CAESinkFactory::EnumerateEx(AESinkInfoList &list, bool force) + } + #endif + ++ #if defined(HAS_SNDIO) ++ info.m_deviceInfoList.clear(); ++ info.m_sinkName = "SNDIO"; ++ CAESinkSNDIO::EnumerateDevicesEx(info.m_deviceInfoList, force); ++ if(!info.m_deviceInfoList.empty()) ++ { ++ list.push_back(info); ++ return; ++ } ++ #endif ++ + #if defined(HAS_ALSA) + info.m_deviceInfoList.clear(); + info.m_sinkName = "ALSA"; +diff --git xbmc/cores/AudioEngine/Makefile.in xbmc/cores/AudioEngine/Makefile.in +index 7aab111f81..788786e2d1 100644 +--- xbmc/cores/AudioEngine/Makefile.in ++++ xbmc/cores/AudioEngine/Makefile.in +@@ -55,6 +55,9 @@ SRCS += Sinks/AESinkOSS.cpp + ifeq (@USE_PULSE@,1) + SRCS += Sinks/AESinkPULSE.cpp + endif ++ifeq (@USE_SNDIO@,1) ++SRCS += Sinks/AESinkSNDIO.cpp ++endif + endif + + SRCS += DSPAddons/ActiveAEDSP.cpp +diff --git xbmc/cores/AudioEngine/Sinks/AESinkSNDIO.cpp xbmc/cores/AudioEngine/Sinks/AESinkSNDIO.cpp +new file mode 100644 +index 0000000000..879b9a90a3 +--- /dev/null ++++ xbmc/cores/AudioEngine/Sinks/AESinkSNDIO.cpp +@@ -0,0 +1,313 @@ ++/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*- */ ++/* ++ * Copyright (C) 2010-2013 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, see ++ * . ++ * ++ */ ++ ++#include "system.h" ++#ifdef HAS_SNDIO ++#include "AESinkSNDIO.h" ++#include "cores/AudioEngine/Utils/AEUtil.h" ++#include "utils/log.h" ++ ++#include ++ ++#ifndef nitems ++#define nitems(x) (sizeof((x))/sizeof((x)[0])) ++#endif ++ ++static enum AEChannel channelMap[] = ++{ ++ AE_CH_FL, ++ AE_CH_FR, ++ AE_CH_BL, ++ AE_CH_BR, ++ AE_CH_FC, ++ AE_CH_LFE, ++ AE_CH_SL, ++ AE_CH_SR, ++}; ++ ++struct sndio_formats ++{ ++ AEDataFormat fmt; ++ unsigned int bits; ++ unsigned int bps; ++ unsigned int sig; ++ unsigned int le; ++ unsigned int msb; ++}; ++ ++static struct sndio_formats formats[] = ++{ ++ { AE_FMT_S32LE, 32, 4, 1, 1, 1 }, ++ { AE_FMT_S32BE, 32, 4, 1, 0, 1 }, ++ ++ { AE_FMT_S24LE4, 24, 4, 1, 1, 0 }, ++ { AE_FMT_S24BE4, 24, 4, 1, 0, 0 }, ++ { AE_FMT_S24LE4, 24, 4, 1, 1, 1 }, ++ { AE_FMT_S24BE4, 24, 4, 1, 0, 1 }, ++ ++ { AE_FMT_S24LE3, 24, 3, 1, 1, 0 }, ++ { AE_FMT_S24BE3, 24, 3, 1, 0, 0 }, ++ { AE_FMT_S24LE3, 24, 3, 1, 1, 1 }, ++ { AE_FMT_S24BE3, 24, 3, 1, 0, 1 }, ++ ++ { AE_FMT_S16LE, 16, 2, 1, 1, 1 }, ++ { AE_FMT_S16LE, 16, 2, 1, 1, 0 }, ++ { AE_FMT_S16BE, 16, 2, 1, 0, 1 }, ++ { AE_FMT_S16BE, 16, 2, 1, 0, 0 }, ++ ++ { AE_FMT_U8, 8, 1, 0, 0, 0 }, ++ { AE_FMT_U8, 8, 1, 0, 0, 1 }, ++ { AE_FMT_U8, 8, 1, 0, 1, 0 }, ++ { AE_FMT_U8, 8, 1, 0, 1, 1 }, ++}; ++ ++static AEDataFormat lookupDataFormat(int bits, int bps, int sig, int le, int msb) ++{ ++ for (size_t i = 0; i < nitems(formats); i++) ++ { ++ if (bits == formats[i].bits && ++ bps == formats[i].bps && ++ sig == formats[i].sig && ++ le == formats[i].le && ++ msb == formats[i].msb) ++ { ++ return formats[i].fmt; ++ } ++ } ++ return AE_FMT_INVALID; ++} ++ ++void CAESinkSNDIO::AudioFormatToPar(AEAudioFormat& format) ++{ ++ sio_initpar(&par); ++ ++ par.rate = format.m_sampleRate; ++ par.xrun = SIO_IGNORE; ++ par.pchan = format.m_channelLayout.Count(); ++ ++ for (size_t i = 0; i < nitems(formats); i++) ++ { ++ if (formats[i].fmt == format.m_dataFormat) ++ { ++ par.bits = formats[i].bits; ++ par.sig = formats[i].sig; ++ par.le = formats[i].le; ++ par.msb = formats[i].msb; ++ par.bps = formats[i].bps; ++ return; ++ } ++ } ++ ++ /* Default to AE_FMT_S16LE */ ++ par.bits = 16; ++ par.bps = SIO_BPS(16); ++ par.sig = 1; ++ par.le = 1; ++ par.msb = 0; ++} ++ ++bool CAESinkSNDIO::ParToAudioFormat(AEAudioFormat& format) ++{ ++ AEDataFormat dataFormat = lookupDataFormat(par.bits, par.bps, par.sig, par.le, par.msb); ++ if (dataFormat == AE_FMT_INVALID) ++ { ++ CLog::Log(LOGERROR, "CAESinkSNDIO::ParToAudioFormat - invalid data format"); ++ return false; ++ } ++ ++ if (par.pchan > nitems(channelMap)) ++ { ++ CLog::Log(LOGERROR, "CAESinkSNDIO::ParToAudioFormat - too many channels: %d", par.pchan); ++ return false; ++ } ++ ++ CAEChannelInfo info; ++ for (unsigned int i = 0; i < par.pchan; i++) ++ info += channelMap[i]; ++ format.m_channelLayout = info; ++ format.m_dataFormat = dataFormat; ++ format.m_sampleRate = par.rate; ++ format.m_frameSize = par.bps * par.pchan; ++ format.m_frames = par.bufsz / format.m_frameSize; ++ ++ return true; ++} ++ ++CAESinkSNDIO::CAESinkSNDIO() ++{ ++ m_hdl = nullptr; ++} ++ ++CAESinkSNDIO::~CAESinkSNDIO() ++{ ++ Deinitialize(); ++} ++ ++bool CAESinkSNDIO::Initialize(AEAudioFormat &format, std::string &device) ++{ ++ if ((m_hdl = sio_open(SIO_DEVANY, SIO_PLAY, 0)) == nullptr) ++ { ++ CLog::Log(LOGERROR, "CAESinkSNDIO::Initialize - Failed to open device"); ++ return false; ++ } ++ ++ AudioFormatToPar(format); ++ if (!sio_setpar(m_hdl, &par) || ++ !sio_getpar(m_hdl, &par) || ++ !ParToAudioFormat(format)) ++ { ++ CLog::Log(LOGERROR, "CAESinkSNDIO::Initialize - could not negotiate parameters"); ++ return false; ++ } ++ ++ played = written = 0; ++ ++ sio_onmove(m_hdl, CAESinkSNDIO::OnmoveCb, this); ++ ++ if (!sio_start(m_hdl)) ++ { ++ CLog::Log(LOGERROR, "CAESinkSNDIO::Initialize - sio_start failed"); ++ return false; ++ } ++ ++ return true; ++} ++ ++void CAESinkSNDIO::Deinitialize() ++{ ++ if (m_hdl != nullptr) ++ { ++ sio_close(m_hdl); ++ m_hdl = nullptr; ++ } ++} ++ ++void CAESinkSNDIO::Stop() ++{ ++ if (!m_hdl) ++ return; ++ ++ if (!sio_stop(m_hdl)) ++ CLog::Log(LOGERROR, "CAESinkSNDIO::Stop - Failed"); ++ ++ written = played = 0; ++} ++ ++void CAESinkSNDIO::OnmoveCb(void *arg, int delta) { ++ CAESinkSNDIO* self = static_cast(arg); ++ self->played += delta; ++} ++ ++void CAESinkSNDIO::GetDelay(AEDelayStatus& status) ++{ ++ unsigned int frameSize = par.bps * par.pchan; ++ double delay = 1.0 * ((written / frameSize) - played) / par.rate; ++ status.SetDelay(delay); ++} ++ ++unsigned int CAESinkSNDIO::AddPackets(uint8_t **data, unsigned int frames, unsigned int offset) ++{ ++ if (!m_hdl) ++ return INT_MAX; ++ ++ unsigned int frameSize = par.bps * par.pchan; ++ size_t size = frames * frameSize; ++ void *buffer = data[0] + offset * frameSize; ++ size_t wrote = sio_write(m_hdl, buffer, size); ++ written += wrote; ++ return wrote / frameSize; ++} ++ ++void CAESinkSNDIO::Drain() ++{ ++ if(!m_hdl) ++ return; ++ ++ if (!sio_stop(m_hdl) || !sio_start(m_hdl)) ++ CLog::Log(LOGERROR, "CAESinkSNDIO::Drain - failed"); ++ ++ written = played = 0; ++} ++ ++void CAESinkSNDIO::EnumerateDevicesEx(AEDeviceInfoList &list, bool force) ++{ ++ struct sio_hdl *hdl; ++ struct sio_cap cap; ++ ++ if ((hdl = sio_open(SIO_DEVANY, SIO_PLAY, 0)) == nullptr) ++ { ++ CLog::Log(LOGERROR, "CAESinkSNDIO::EnumerateDevicesEx - sio_open"); ++ return; ++ } ++ ++ if (!sio_getcap(hdl, &cap)) ++ { ++ CLog::Log(LOGERROR, "CAESinkSNDIO::EnumerateDevicesEx - sio_getcap"); ++ return; ++ } ++ ++ sio_close(hdl); ++ hdl = nullptr; ++ ++ for (unsigned int i = 0; i < cap.nconf; i++) ++ { ++ CAEDeviceInfo info; ++ sio_cap::sio_conf conf = cap.confs[i]; ++ ++ info.m_deviceName = SIO_DEVANY; ++ info.m_displayName = "sndio"; ++ info.m_displayNameExtra = "#" + std::to_string(i); ++ info.m_deviceType = AE_DEVTYPE_PCM; ++ ++ unsigned int maxchan = 0; ++ for (unsigned int j = 0; j < SIO_NCHAN; j++) ++ { ++ if (conf.pchan & (1 << j)) ++ maxchan = MAX(maxchan, cap.pchan[j]); ++ } ++ ++ maxchan = MIN(maxchan, nitems(channelMap)); ++ for (unsigned int j = 0; j < maxchan; j++) ++ info.m_channels += channelMap[j]; ++ ++ for (unsigned int j = 0; j < SIO_NRATE; j++) ++ { ++ if (conf.rate & (1 << j)) ++ { ++ info.m_sampleRates.push_back(cap.rate[j]); ++ } ++ } ++ ++ for (unsigned int j = 0; j < SIO_NENC; j++) ++ { ++ if (conf.enc & (1 << j)) ++ { ++ AEDataFormat format = lookupDataFormat(cap.enc[j].bits, cap.enc[j].bps, cap.enc[j].sig, cap.enc[j].le, cap.enc[j].msb); ++ if (format != AE_FMT_INVALID) ++ info.m_dataFormats.push_back(format); ++ } ++ } ++ ++ list.push_back(info); ++ } ++} ++ ++#endif +diff --git xbmc/cores/AudioEngine/Sinks/AESinkSNDIO.h xbmc/cores/AudioEngine/Sinks/AESinkSNDIO.h +new file mode 100644 +index 0000000000..55719cd305 +--- /dev/null ++++ xbmc/cores/AudioEngine/Sinks/AESinkSNDIO.h +@@ -0,0 +1,57 @@ ++/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*- */ ++#pragma once ++/* ++ * Copyright (C) 2010-2013 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, see ++ * . ++ * ++ */ ++ ++#include "cores/AudioEngine/Interfaces/AESink.h" ++#include "cores/AudioEngine/Utils/AEDeviceInfo.h" ++#include ++#include ++ ++#include "threads/CriticalSection.h" ++ ++class CAESinkSNDIO : public IAESink ++{ ++public: ++ virtual const char *GetName() { return "sndio"; } ++ ++ CAESinkSNDIO(); ++ virtual ~CAESinkSNDIO(); ++ ++ virtual bool Initialize(AEAudioFormat &format, std::string &device); ++ virtual void Deinitialize(); ++ ++ virtual void Stop(); ++ virtual void GetDelay(AEDelayStatus& status); ++ virtual double GetCacheTotal() { return 0.0; } ++ virtual unsigned int AddPackets(uint8_t **data, unsigned int frames, unsigned int offset); ++ virtual void Drain(); ++ static void EnumerateDevicesEx(AEDeviceInfoList &list, bool force = false); ++private: ++ void AudioFormatToPar(AEAudioFormat& format); ++ bool ParToAudioFormat(AEAudioFormat& format); ++ static void OnmoveCb(void *arg, int delta); ++ ++ struct sio_hdl *m_hdl; ++ struct sio_par par; ++ ssize_t played; ++ ssize_t written; ++}; ++ +diff --git xbmc/system.h xbmc/system.h +index d426ade093..ed01ab53fd 100644 +--- xbmc/system.h ++++ xbmc/system.h +@@ -172,6 +172,9 @@ + #ifdef HAVE_LIBPULSE + #define HAS_PULSEAUDIO + #endif ++#ifdef HAVE_SNDIO ++#define HAS_SNDIO ++#endif + #ifdef HAVE_ALSA + #define HAS_ALSA + #endif Property changes on: head/multimedia/kodi/files/extra-patch-sndio ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property