Received: from out1.migadu.com (out1.migadu.com [91.121.223.63]) by nld3-dev1.alpinelinux.org (Postfix) with ESMTPS id 662D17810EC for ; Thu, 27 Jan 2022 19:35:48 +0000 (UTC) X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=biobuf.link; s=key1; t=1643311746; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=hFkJUKtwIaFQGMxOjYF3MH6NvAVw6hi8I+ITEi5WGcw=; b=KJsYFHiH9s3LaEpUnhaA+n2SeXIf2LJAUypj3bVkP9VOxejby8iI70UCmhWlJ4rJIVlotZ 3Df6bxjO4/BjcefSxnrDoUhm2AIckn/JCmEckVfWTNYrr9WvtZmXwV6KzTdFOKEnL8c9Ky bmqriutabfFtJqBD+cYebQoNoMEWtwg= From: james palmer To: alpine-aports@lists.alpinelinux.org Cc: james palmer Subject: [PATCH v2] community/mpv: add sndio output support (ported from an openbsd patch) Date: Thu, 27 Jan 2022 19:28:59 +0000 Message-Id: <20220127192859.8780-1-james@biobuf.link> In-Reply-To: <164331018194.985.4544828696511371264.gitlab.30064.05a8c00352a8946ce958175f829e35431c316d6f@listserv.local> References: <164331018194.985.4544828696511371264.gitlab.30064.05a8c00352a8946ce958175f829e35431c316d6f@listserv.local> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Migadu-Flow: FLOW_OUT X-Migadu-Auth-User: biobuf.link --- community/mpv/APKBUILD | 10 +- community/mpv/sndio.patch | 377 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 384 insertions(+), 3 deletions(-) create mode 100644 community/mpv/sndio.patch diff --git a/community/mpv/APKBUILD b/community/mpv/APKBUILD index d644626250..c2d3346a22 100644 --- a/community/mpv/APKBUILD +++ b/community/mpv/APKBUILD @@ -5,7 +5,7 @@ # Maintainer: Natanael Copa pkgname=mpv pkgver=0.34.1 -pkgrel=1 +pkgrel=2 pkgdesc="Video player based on MPlayer/mplayer2" url="https://mpv.io/" license="GPL-2.0-or-later" @@ -43,6 +43,7 @@ makedepends=" py3-docutils python3 shaderc-dev + sndio-dev ttf-dejavu uchardet-dev vulkan-headers @@ -61,7 +62,8 @@ subpackages=" $pkgname-bash-completion $pkgname-zsh-completion " -source="https://github.com/mpv-player/mpv/archive/v$pkgver/mpv-$pkgver.tar.gz" +source="https://github.com/mpv-player/mpv/archive/v$pkgver/mpv-$pkgver.tar.gz + sndio.patch" # secfixes: # 0.27.0-r3: @@ -91,7 +93,8 @@ build() { --enable-vulkan \ --enable-uchardet \ --enable-cdda \ - --enable-dvdnav + --enable-dvdnav \ + --enable-sndio python3 waf build } @@ -114,4 +117,5 @@ package() { sha512sums=" 77ea349d6999f8cce9b5cce4cebd3506a224fc18ab08d22dd16bd34c34d012bb170879b268ddd62db40d116b4cc0b2d9d651b8097f387ed9115c426834cac77e mpv-0.34.1.tar.gz +84bed23d81115efa82f4fd97259e4b0bc9a9d727c8354d79de85d2f74622cefa0d0e34d84fe6ddce110bcf783ef587564009eacb0697ef243cb0180b45d7392e sndio.patch " diff --git a/community/mpv/sndio.patch b/community/mpv/sndio.patch new file mode 100644 index 0000000000..71d0b53d7e --- /dev/null +++ b/community/mpv/sndio.patch @@ -0,0 +1,377 @@ +--- a/audio/out/ao.c ++++ b/audio/out/ao.c +@@ -51,6 +51,7 @@ + extern const struct ao_driver audio_out_pcm; + extern const struct ao_driver audio_out_lavc; + extern const struct ao_driver audio_out_sdl; ++extern const struct ao_driver audio_out_sndio; + + static const struct ao_driver * const audio_out_drivers[] = { + // native: +@@ -87,6 +88,9 @@ + #endif + #if HAVE_SDL2_AUDIO + &audio_out_sdl, ++#endif ++#if HAVE_SNDIO ++ &audio_out_sndio, + #endif + &audio_out_null, + #if HAVE_COREAUDIO +--- a/DOCS/man/ao.rst ++++ b/DOCS/man/ao.rst +@@ -216,5 +216,11 @@ Available audio output drivers are: + ``no-waveheader`` option - with ``waveheader`` it's broken, because + it will write a WAVE header every time the file is opened. + ++``sndio`` ++ Audio output to the OpenBSD sndio sound system ++ ++ (Note: only supports mono, stereo, 4.0, 5.1 and 7.1 channel ++ layouts.) ++ + ``wasapi`` + Audio output to the Windows Audio Session API. +--- /dev/null ++++ b/audio/out/ao_sndio.c +@@ -0,0 +1,317 @@ ++/* ++ * Copyright (c) 2008 Alexandre Ratchov ++ * Copyright (c) 2013 Christian Neukirchen ++ * Copyright (c) 2020 Rozhuk Ivan ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#include "config.h" ++ ++#include ++#include ++#include ++#include ++ ++#include "options/m_option.h" ++#include "common/msg.h" ++ ++#include "audio/format.h" ++#include "ao.h" ++#include "internal.h" ++ ++struct priv { ++ struct sio_hdl *hdl; ++ struct sio_par par; ++ int delay; ++ bool playing; ++ int vol; ++ int havevol; ++ struct pollfd *pfd; ++}; ++ ++ ++static const struct mp_chmap sndio_layouts[MP_NUM_CHANNELS + 1] = { ++ {0}, /* empty */ ++ {1, {MP_SPEAKER_ID_FL}}, /* mono */ ++ MP_CHMAP2(FL, FR), /* stereo */ ++ {0}, /* 2.1 */ ++ MP_CHMAP4(FL, FR, BL, BR), /* 4.0 */ ++ {0}, /* 5.0 */ ++ MP_CHMAP6(FL, FR, BL, BR, FC, LFE), /* 5.1 */ ++ {0}, /* 6.1 */ ++ MP_CHMAP8(FL, FR, BL, BR, FC, LFE, SL, SR), /* 7.1 */ ++ /* Above is the fixed channel assignment for sndio, since we need to ++ * fill all channels and cannot insert silence, not all layouts are ++ * supported. ++ * NOTE: MP_SPEAKER_ID_NA could be used to add padding channels. */ ++}; ++ ++static void uninit(struct ao *ao); ++ ++ ++/* Make libsndio call movecb(). */ ++static void process_events(struct ao *ao) ++{ ++ struct priv *p = ao->priv; ++ ++ if (!p->playing) ++ return; ++ int n = sio_pollfd(p->hdl, p->pfd, POLLOUT); ++ while (poll(p->pfd, n, 0) < 0 && errno == EINTR) {} ++ ++ sio_revents(p->hdl, p->pfd); ++} ++ ++/* Call-back invoked to notify of the hardware position. */ ++static void movecb(void *addr, int delta) ++{ ++ struct ao *ao = addr; ++ struct priv *p = ao->priv; ++ ++ p->delay -= delta; ++} ++ ++/* Call-back invoked to notify about volume changes. */ ++static void volcb(void *addr, unsigned newvol) ++{ ++ struct ao *ao = addr; ++ struct priv *p = ao->priv; ++ ++ p->vol = newvol; ++} ++ ++static int init(struct ao *ao) ++{ ++ struct priv *p = ao->priv; ++ struct mp_chmap_sel sel = {0}; ++ size_t i; ++ struct af_to_par { ++ int format, bits, sig; ++ }; ++ static const struct af_to_par af_to_par[] = { ++ {AF_FORMAT_U8, 8, 0}, ++ {AF_FORMAT_S16, 16, 1}, ++ {AF_FORMAT_S32, 32, 1}, ++ }; ++ const struct af_to_par *ap; ++ const char *device = ((ao->device) ? ao->device : SIO_DEVANY); ++ ++ /* Opening device. */ ++ MP_VERBOSE(ao, "Using '%s' audio device.\n", device); ++ p->hdl = sio_open(device, SIO_PLAY, 0); ++ if (p->hdl == NULL) { ++ MP_ERR(ao, "Can't open audio device %s.\n", device); ++ goto err_out; ++ } ++ ++ sio_initpar(&p->par); ++ ++ /* Selecting sound format. */ ++ ao->format = af_fmt_from_planar(ao->format); ++ for (i = 0, ap = af_to_par;; i++, ap++) { ++ if (i == MP_ARRAY_SIZE(af_to_par)) { ++ MP_VERBOSE(ao, "unsupported format\n"); ++ p->par.bits = 16; ++ p->par.sig = 1; ++ p->par.le = SIO_LE_NATIVE; ++ break; ++ } ++ if (ap->format == ao->format) { ++ p->par.bits = ap->bits; ++ p->par.sig = ap->sig; ++ if (ap->bits > 8) ++ p->par.le = SIO_LE_NATIVE; ++ if (ap->bits != SIO_BPS(ap->bits)) ++ p->par.bps = ap->bits / 8; ++ break; ++ } ++ } ++ ++ p->par.rate = ao->samplerate; ++ ++ /* Channels count. */ ++ for (i = 0; i < MP_ARRAY_SIZE(sndio_layouts); i++) { ++ mp_chmap_sel_add_map(&sel, &sndio_layouts[i]); ++ } ++ if (!ao_chmap_sel_adjust(ao, &sel, &ao->channels)) ++ goto err_out; ++ ++ p->par.pchan = ao->channels.num; ++#ifdef __FreeBSD__ ++ /* OSS wrapper have bad defaults, overwrite it. */ ++ p->par.appbufsz = ((p->par.rate * 25) / 1000); /* 25 ms. */ ++#endif ++ if (!sio_setpar(p->hdl, &p->par)) { ++ MP_ERR(ao, "couldn't set params\n"); ++ goto err_out; ++ } ++ ++ /* Get current sound params. */ ++ if (!sio_getpar(p->hdl, &p->par)) { ++ MP_ERR(ao, "couldn't get params\n"); ++ goto err_out; ++ } ++ if (p->par.bps > 1 && p->par.le != SIO_LE_NATIVE) { ++ MP_ERR(ao, "swapped endian output not supported\n"); ++ goto err_out; ++ } ++ ++ /* Update sound params. */ ++ if (p->par.bits == 8 && p->par.bps == 1 && !p->par.sig) { ++ ao->format = AF_FORMAT_U8; ++ } else if (p->par.bits == 16 && p->par.bps == 2 && p->par.sig) { ++ ao->format = AF_FORMAT_S16; ++ } else if ((p->par.bits == 32 || p->par.msb) && p->par.bps == 4 && p->par.sig) { ++ ao->format = AF_FORMAT_S32; ++ } else { ++ MP_ERR(ao, "couldn't set format\n"); ++ goto err_out; ++ } ++ ++ p->havevol = sio_onvol(p->hdl, volcb, ao); ++ sio_onmove(p->hdl, movecb, ao); ++ ++ p->pfd = calloc(sio_nfds(p->hdl), sizeof(struct pollfd)); ++ if (!p->pfd) ++ goto err_out; ++ ++ ao->device_buffer = p->par.bufsz; ++ MP_VERBOSE(ao, "bufsz = %i, appbufsz = %i, round = %i\n", ++ p->par.bufsz, p->par.appbufsz, p->par.round); ++ ++ p->delay = 0; ++ p->playing = false; ++ if (!sio_start(p->hdl)) { ++ MP_ERR(ao, "start: sio_start() fail.\n"); ++ goto err_out; ++ } ++ ++ return 0; ++ ++err_out: ++ uninit(ao); ++ return -1; ++} ++ ++static void uninit(struct ao *ao) ++{ ++ struct priv *p = ao->priv; ++ ++ if (p->hdl) { ++ sio_close(p->hdl); ++ p->hdl = NULL; ++ } ++ free(p->pfd); ++ p->pfd = NULL; ++ p->playing = false; ++} ++ ++static int control(struct ao *ao, enum aocontrol cmd, void *arg) ++{ ++ struct priv *p = ao->priv; ++ ao_control_vol_t *vol = arg; ++ ++ switch (cmd) { ++ case AOCONTROL_GET_VOLUME: ++ if (!p->havevol) ++ return CONTROL_FALSE; ++ vol->left = vol->right = p->vol * 100 / SIO_MAXVOL; ++ break; ++ case AOCONTROL_SET_VOLUME: ++ if (!p->havevol) ++ return CONTROL_FALSE; ++ sio_setvol(p->hdl, vol->left * SIO_MAXVOL / 100); ++ break; ++ default: ++ return CONTROL_UNKNOWN; ++ } ++ return CONTROL_OK; ++} ++ ++static void reset(struct ao *ao) ++{ ++ struct priv *p = ao->priv; ++ ++ process_events(ao); ++ p->delay = 0; ++ p->playing = false; ++ ++ /* XXX: some times may block here then sndiod used. */ ++ if (!sio_stop(p->hdl)) { ++ MP_ERR(ao, "reset: couldn't sio_stop()\n"); ++reinit: ++ /* Without this device will never work again. */ ++ MP_WARN(ao, "Force reinitialize audio device.\n"); ++ uninit(ao); ++ init(ao); ++ return; ++ } ++ if (!sio_start(p->hdl)) { ++ MP_ERR(ao, "reset: sio_start() fail.\n"); ++ goto reinit; ++ } ++} ++ ++static void start(struct ao *ao) ++{ ++ struct priv *p = ao->priv; ++ ++ p->playing = true; ++ process_events(ao); ++} ++ ++static bool audio_write(struct ao *ao, void **data, int samples) ++{ ++ struct priv *p = ao->priv; ++ const size_t size = (samples * ao->sstride); ++ size_t rc; ++ ++ rc = sio_write(p->hdl, data[0], size); ++ if (rc != size) { ++ MP_WARN(ao, "audio_write: unexpected partial write: required: %zu, written: %zu.\n", ++ size, rc); ++ reset(ao); ++ p->playing = false; ++ return false; ++ } ++ p->delay += samples; ++ process_events(ao); ++ ++ return true; ++} ++ ++static void get_state(struct ao *ao, struct mp_pcm_state *state) ++{ ++ struct priv *p = ao->priv; ++ ++ process_events(ao); ++ ++ state->free_samples = (ao->device_buffer - p->delay); ++ state->queued_samples = p->delay; ++ state->delay = (p->delay / (double)p->par.rate); ++ state->playing = p->playing; ++} ++ ++const struct ao_driver audio_out_sndio = { ++ .name = "sndio", ++ .description = "sndio audio output", ++ .init = init, ++ .uninit = uninit, ++ .control = control, ++ .reset = reset, ++ .start = start, ++ .write = audio_write, ++ .get_state = get_state, ++ .priv_size = sizeof(struct priv), ++}; +--- a/wscript ++++ b/wscript +@@ -473,6 +473,10 @@ + 'desc': 'WASAPI audio output', + 'deps': 'os-win32 || os-cygwin', + 'func': check_cc(fragment=load_fragment('wasapi.c')), ++ }, { ++ 'name': '--sndio', ++ 'desc': 'sndio audio output', ++ 'func': check_pkg_config('sndio') + } + ] + +--- a/wscript_build.py ++++ b/wscript_build.py +@@ -248,6 +248,7 @@ + ( "audio/out/ao_pcm.c" ), + ( "audio/out/ao_pulse.c", "pulse" ), + ( "audio/out/ao_sdl.c", "sdl2-audio" ), ++ ( "audio/out/ao_sndio.c", "sndio" ), + ( "audio/out/ao_wasapi.c", "wasapi" ), + ( "audio/out/ao_wasapi_changenotify.c", "wasapi" ), + ( "audio/out/ao_wasapi_utils.c", "wasapi" ), -- 2.35.0