diff options
author | Timo Teräs <timo.teras@iki.fi> | 2016-02-26 14:04:23 +0000 |
---|---|---|
committer | Timo Teräs <timo.teras@iki.fi> | 2016-02-26 14:05:08 +0000 |
commit | c26e30a092c94e6906ec4269a8e4dca1dba29319 (patch) | |
tree | e75495d242249d4dfe374f2bb9af2a0978a0b04b /main/omxplayer | |
parent | 7d8502437b7c4bf90b4271af410a9dad6f8e6156 (diff) | |
download | aports-c26e30a092c94e6906ec4269a8e4dca1dba29319.tar.bz2 aports-c26e30a092c94e6906ec4269a8e4dca1dba29319.tar.xz |
main/omxplayer: update alsa player patch
- add support for live resampling using speexdsp
- fix few bugs
Diffstat (limited to 'main/omxplayer')
-rw-r--r-- | main/omxplayer/APKBUILD | 14 | ||||
-rw-r--r-- | main/omxplayer/omxplayer-alsa.patch | 163 |
2 files changed, 97 insertions, 80 deletions
diff --git a/main/omxplayer/APKBUILD b/main/omxplayer/APKBUILD index 38428b7677..1d7475525e 100644 --- a/main/omxplayer/APKBUILD +++ b/main/omxplayer/APKBUILD @@ -2,14 +2,14 @@ pkgname=omxplayer pkgver=0.20160206 _commitid=19efb03b881da0bcc70632eaf7f7292edcf33eeb -pkgrel=0 +pkgrel=1 pkgdesc="Commandline OMX player for Raspberry Pi" url="https://github.com/popcornmix/omxplayer" arch="armhf" license="GPLv2" depends="ttf-freefont" makedepends="linux-headers raspberrypi-dev ffmpeg-dev pcre-dev - boost-dev freetype-dev dbus-dev alsa-lib-dev" + boost-dev freetype-dev dbus-dev alsa-lib-dev speexdsp-dev" install="" subpackages="$pkgname-doc $pkgname-dbg" source="omxplayer-$pkgver.tar.gz::https://github.com/popcornmix/omxplayer/archive/$_commitid.tar.gz @@ -39,9 +39,9 @@ build() { cd "$_srcdir" cat <<EOF > Makefile.include INCLUDES:=-I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux -INCLUDES+=$(pkg-config --cflags freetype2 dbus-1) +INCLUDES+=$(pkg-config --cflags freetype2 dbus-1 speexdsp) LDFLAGS:=-L/opt/vc/lib -Wl,-rpath,/opt/vc/lib -LDFLAGS+=$(pkg-config --libs freetype2 dbus-1) +LDFLAGS+=$(pkg-config --libs freetype2 dbus-1 speexdsp) STRIP:=echo EOF make omxplayer.bin omxplayer.1 @@ -63,7 +63,7 @@ a900cdded87b7df503c6599ac43bd8de issue-260.patch c858882036b9fb03859edf7ce4a1d942 issue-297.patch d8f335e1dff4b34faf36c25ad2c2b881 fix-makefile.patch 9ebd96155288809fe0a657cf491e433f default-font.patch -24bc3d0db0fcbd547bec6df454937940 omxplayer-alsa.patch +930ff50f91bc2a7c24661b6313581868 omxplayer-alsa.patch b4054a311d76aef91aa10bacd68bc9c4 omxplayer.initd 80e37e7ac04402808015084e26e6072d omxplayer.confd" sha256sums="bfdcd411e759f7791ceace6c700b5ee6f5a6e8b34abbc261f01c32b8e71d559e omxplayer-0.20160206.tar.gz @@ -71,7 +71,7 @@ sha256sums="bfdcd411e759f7791ceace6c700b5ee6f5a6e8b34abbc261f01c32b8e71d559e om 389c97df4919a3fe4d115f092cb256246e33374150102f0e2cb9ce11456cadb1 issue-297.patch 799b0aba6aef8c665a685777cd912268315309d0d74ce76be5fdfd0dcffbb422 fix-makefile.patch 2bab3d05b12d730737220b8c0052498a34bbebc12b7beb8afb3c054beb0fb3bb default-font.patch -dd547f952cdc6d96f565694993817075803a05d4d16c6b51e982244f8980445c omxplayer-alsa.patch +2dedced50fd1d40aadade37651abfb1edeb36de3d6446e1308bd98404069276f omxplayer-alsa.patch e2db0f7ffbe2488dd69ee0bfad006bd863f418554f078ca3432f643de7589d2f omxplayer.initd 530eb9aa50e72fb4828af410b965e0ec7653d1bed87aa86bf04fc340ff3232bd omxplayer.confd" sha512sums="be14f94876a47b107aea13a23379c0be1df245f064f03b7de7e8cd18fd42a3f5c3a6f2b95a1aa791290c8ea6c202dd9885a76a61d1a56a9a0f6d20dc84e2fa7a omxplayer-0.20160206.tar.gz @@ -79,6 +79,6 @@ c349eea5f7c513a07d82a6cf6467c4d21bcb29c053bc5e39d8f675b1212db9beef0abf5248d50ac5 2a8a6def1e09f726cba58c0b9109fa6c4fbd4a3b4f1d27d200488f262a0e0978579d83db7fe24f1d3e03beef318c3674ed79cbd2f1994c4551a59c9fe0f63489 issue-297.patch 3210242f9b834ffec9d3077d5a25caf8be84aa7f4f13c73eb7f61c0a406ec787e4055951fc5a6236f1da7897c95db94a5e11e25d1b3e859a6ea67f31fc6eb517 fix-makefile.patch 8aa58aaa07453186302dc68d92f28c1b50bf0f8fccd50359640a7fc8339b233b32a0c8c02284a9974599e56d69cc557acc25e76e6438c6d64d15afd9c1788a8e default-font.patch -7f12f253321ef25e9645514451b0d57f1d6ec1cada372884d3aa2a1d1529f385490fe0f656f00af7e3bb567c56ba60d4cc310007658841d6e17c92c55ba8184a omxplayer-alsa.patch +911defaed9ca6d0ef1f919517d0cdc0dc6b1c979595cb508958928c892e55c0361cc9929d1fb5bea8ccb3d3556d9028e9c8adf47783a83701f53972a984c1887 omxplayer-alsa.patch 3ddd32235d87a46478d0237ee9b253edeb75729e377b09a33069ecdca2ee230d2851f308897ee75ff69a9f3bdd2876f490bc1667a572dce1c186f80fddcf6df3 omxplayer.initd 4f906ada035869a0e515e7615056b18b0f6906ce4b3a2d34081c0efa79bb9455380f729e7c5270180f5ace89c53a7ac7c93f609e6761825f639f44aa22346bb2 omxplayer.confd" diff --git a/main/omxplayer/omxplayer-alsa.patch b/main/omxplayer/omxplayer-alsa.patch index e1b25f6ed9..931c59fdc7 100644 --- a/main/omxplayer/omxplayer-alsa.patch +++ b/main/omxplayer/omxplayer-alsa.patch @@ -1,21 +1,3 @@ -From 5ff66870da7d3376cba3a927bcb173b87bff9fb5 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi> -Date: Tue, 9 Feb 2016 15:25:41 +0200 -Subject: [PATCH] preliminary alsa support - ---- - Makefile | 5 +- - OMXAudio.cpp | 5 +- - OMXAudio.h | 1 + - OMXCore.cpp | 11 + - README.md | 1 + - linux/OMXAlsa.cpp | 1275 +++++++++++++++++++++++++++++++++++++++++++++++++++++ - linux/OMXAlsa.h | 11 + - omxplayer.cpp | 6 +- - 8 files changed, 1310 insertions(+), 5 deletions(-) - create mode 100644 linux/OMXAlsa.cpp - create mode 100644 linux/OMXAlsa.h - diff --git a/Makefile b/Makefile index 9fc45de..5337ee7 100644 --- a/Makefile @@ -122,10 +104,10 @@ index 726127c..cc718b1 100644 -s --stats Pts and buffer stats diff --git a/linux/OMXAlsa.cpp b/linux/OMXAlsa.cpp new file mode 100644 -index 0000000..b19ef31 +index 0000000..fe51eb1 --- /dev/null +++ b/linux/OMXAlsa.cpp -@@ -0,0 +1,1275 @@ +@@ -0,0 +1,1313 @@ +/* + * OMX IL Alsa Sink component + * Copyright (c) 2016 Timo Teräs @@ -136,7 +118,6 @@ index 0000000..b19ef31 + * any later version. + * + * TODO: -+ * - rate changing, test --live for speed control handling + * - timeouts for state transition failures + */ + @@ -147,6 +128,7 @@ index 0000000..b19ef31 +#include <stdlib.h> +#include <pthread.h> +#include <alsa/asoundlib.h> ++#include <speex/speex_resampler.h> +#include <IL/OMX_Core.h> +#include <IL/OMX_Component.h> +#include <IL/OMX_Broadcom.h> @@ -226,11 +208,6 @@ index 0000000..b19ef31 + q->num++; +} + -+static void *gomxq_peek(GOMX_QUEUE *q) -+{ -+ return q->head; -+} -+ +static void *gomxq_dequeue(GOMX_QUEUE *q) +{ + void *item = q->head; @@ -620,7 +597,8 @@ index 0000000..b19ef31 + void *buf; + + if (port->tunnel_supplier) { -+ CINFO(comp, port, "waiting for supplier buffers"); ++ CINFO(comp, port, "waiting for supplier buffers (%d / %d)", ++ (int)port->tunnel_supplierq.num, (int)port->num_buffers); + while (port->tunnel_supplierq.num != port->num_buffers) + pthread_cond_wait(&port->cond_idle, &comp->mutex); + @@ -634,7 +612,7 @@ index 0000000..b19ef31 + } + } else { + /* Wait client / tunnel supplier to allocate buffers */ -+ CINFO(comp, port, "waiting buffers to be freed"); ++ CINFO(comp, port, "waiting %d buffers to be freed", (int)port->num_buffers); + while (port->num_buffers > 0) + pthread_cond_wait(&port->cond_no_buffers, &comp->mutex); + } @@ -809,8 +787,7 @@ index 0000000..b19ef31 + + switch (cmd->cmd) { + case OMX_CommandFlush: -+ if (port->flush) -+ r = port->flush(comp, port); ++ if (port->flush) r = port->flush(comp, port); + break; + case OMX_CommandPortEnable: + port->def.bEnabled = OMX_TRUE; @@ -820,6 +797,7 @@ index 0000000..b19ef31 + break; + case OMX_CommandPortDisable: + port->def.bEnabled = OMX_FALSE; ++ if (port->flush) port->flush(comp, port); + r = __gomx_port_unpopulate(comp, port); + break; + default: @@ -995,7 +973,8 @@ index 0000000..b19ef31 + GOMX_QUEUE playq; + pthread_cond_t cond_play; + size_t frame_size, sample_rate, play_queue_size; -+ int64_t starttime, timescale; ++ int64_t starttime; ++ int32_t timescale; + OMX_AUDIO_PARAM_PCMMODETYPE pcm; + snd_pcm_format_t pcm_format; + char device_name[16]; @@ -1145,12 +1124,17 @@ index 0000000..b19ef31 + OMX_HANDLETYPE hComponent = (OMX_HANDLETYPE) comp; + OMX_ALSASINK *sink = (OMX_ALSASINK *) hComponent; + OMX_BUFFERHEADERTYPE *buf; ++ GOMX_PORT *audio_port = &comp->ports[OMXALSA_PORT_AUDIO]; + GOMX_PORT *clock_port = &comp->ports[OMXALSA_PORT_CLOCK]; -+ snd_pcm_t *dev; ++ snd_pcm_t *dev = 0; + snd_pcm_sframes_t n; + snd_pcm_hw_params_t *hwp; + snd_pcm_uframes_t buffer_size, period_size, period_size_max; ++ SpeexResamplerState *resampler = 0; ++ spx_int16_t *resample_buf = 0; ++ size_t resample_bufsz; + unsigned int rate; ++ int32_t timescale; + int err; + + CINFO(comp, 0, "worker started"); @@ -1189,19 +1173,35 @@ index 0000000..b19ef31 + sink->frame_size = (sink->pcm.nChannels * sink->pcm.nBitPerSample) >> 3; + sink->sample_rate = rate; + ++ resampler = speex_resampler_init(sink->pcm.nChannels, rate, rate, 1, 0); ++ if (!resampler) goto err; ++ ++ resample_bufsz = audio_port->def.nBufferSize * 2; ++ resample_buf = (spx_int16_t *) malloc(resample_bufsz); ++ if (!resample_buf) goto err; ++ + CINFO(comp, 0, "sample_rate %d, frame_size %d", rate, sink->frame_size); + + pthread_mutex_lock(&comp->mutex); + while (comp->wanted_state == OMX_StateExecuting) { -+ buf = (OMX_BUFFERHEADERTYPE*) gomxq_peek(&sink->playq); -+ if (!buf || sink->timescale == 0) { ++ buf = 0; ++ if (sink->timescale) ++ buf = (OMX_BUFFERHEADERTYPE*) gomxq_dequeue(&sink->playq); ++ if (!buf) { + pthread_cond_wait(&sink->cond_play, &comp->mutex); + continue; + } + -+ pthread_mutex_unlock(&comp->mutex); -+ if (buf->nOffset == 0 && clock_port->tunnel_comp && -+ !(buf->nFlags & OMX_BUFFERFLAG_TIME_UNKNOWN)) { ++ if (resampler && timescale != sink->timescale) { ++ int in_rate = (int64_t)rate * sink->timescale >> 16; ++ timescale = sink->timescale; ++ if (timescale > 0x20000) timescale = 0x20000; ++ CDEBUG(comp, 0, "resampler: %d -> %d", in_rate, rate); ++ speex_resampler_set_rate(resampler, in_rate, rate); ++ } ++ ++ sink->play_queue_size -= buf->nFilledLen; ++ if (clock_port->tunnel_comp && !(buf->nFlags & OMX_BUFFERFLAG_TIME_UNKNOWN)) { + OMX_TIME_CONFIG_TIMESTAMPTYPE tst; + int64_t pts = omx_ticks_to_s64(buf->nTimeStamp); + snd_pcm_sframes_t delay = 0; @@ -1209,64 +1209,84 @@ index 0000000..b19ef31 + omx_init(tst); + tst.nPortIndex = clock_port->tunnel_port; + tst.nTimestamp = buf->nTimeStamp; -+ ++ if (resampler && buf->nFlags & OMX_BUFFERFLAG_STARTTIME) ++ speex_resampler_reset_mem(resampler); + if (buf->nFlags & (OMX_BUFFERFLAG_STARTTIME|OMX_BUFFERFLAG_DISCONTINUITY)) { -+ OMX_SetConfig(clock_port->tunnel_comp, OMX_IndexConfigTimeClientStartTime, &tst); -+ sink->starttime = pts; + CINFO(comp, 0, "STARTTIME nTimeStamp=%llx", pts); ++ sink->starttime = pts; + } ++ + snd_pcm_delay(dev, &delay); ++ if (resampler) ++ delay += speex_resampler_get_input_latency(resampler); ++ + pts -= (int64_t)delay * OMX_TICKS_PER_SECOND / sink->sample_rate; ++ ++ pthread_mutex_unlock(&comp->mutex); ++ if (buf->nFlags & (OMX_BUFFERFLAG_STARTTIME|OMX_BUFFERFLAG_DISCONTINUITY)) ++ OMX_SetConfig(clock_port->tunnel_comp, OMX_IndexConfigTimeClientStartTime, &tst); + if (pts >= sink->starttime) { + tst.nTimestamp = omx_ticks_from_s64(pts); + OMX_SetConfig(clock_port->tunnel_comp, OMX_IndexConfigTimeCurrentAudioReference, &tst); + } ++ pthread_mutex_lock(&comp->mutex); + } + -+ n = 0; + if (buf->nFlags & (OMX_BUFFERFLAG_DECODEONLY|OMX_BUFFERFLAG_CODECCONFIG|OMX_BUFFERFLAG_DATACORRUPT)) { + CDEBUG(comp, 0, "skipping: %d bytes, flags %x", buf->nFilledLen, buf->nFlags); -+ n = buf->nFilledLen; -+ } else if (buf->nFilledLen) { -+ n = snd_pcm_writei(dev, buf->pBuffer + buf->nOffset, buf->nFilledLen / sink->frame_size); -+ if (n < 0) { -+ if (n != -EPIPE) { -+ CINFO(comp, 0, "alsa error: %ld", n); -+ pthread_mutex_lock(&comp->mutex); -+ break; ++ } else { ++ spx_int16_t *in_ptr; ++ uint8_t *out_ptr; ++ spx_uint32_t in_len, out_len; ++ pthread_mutex_unlock(&comp->mutex); ++ ++ in_ptr = (spx_int16_t *)(buf->pBuffer + buf->nOffset); ++ in_len = buf->nFilledLen / sink->frame_size; ++ ++ if (resampler) { ++ out_len = resample_bufsz / sink->frame_size; ++ speex_resampler_process_interleaved_int( ++ resampler, ++ in_ptr, &in_len, ++ resample_buf, &out_len); ++ out_ptr = (uint8_t *) resample_buf; ++ } else { ++ out_ptr = (uint8_t *) in_ptr; ++ out_len = in_len; ++ } ++ ++ while (out_len > 0) { ++ n = snd_pcm_writei(dev, out_ptr, out_len); ++ if (n < 0) { ++ CINFO(comp, 0, "alsa error: %ld: %s", n, snd_strerror(n)); ++ snd_pcm_prepare(dev); ++ n = 0; + } -+ CINFO(comp, 0, "underrun"); -+ snd_pcm_prepare(dev); -+ n = 0; ++ out_len -= n; ++ n *= sink->frame_size; ++ out_ptr += n; + } -+ n *= sink->frame_size; ++ pthread_mutex_lock(&comp->mutex); + } -+ pthread_mutex_lock(&comp->mutex); + -+ buf->nOffset += n; -+ buf->nFilledLen -= n; -+ sink->play_queue_size -= n; -+ -+ if (!buf->nFilledLen) { -+ __gomx_process_mark(comp, buf); -+ if (buf->nFlags & OMX_BUFFERFLAG_EOS) { -+ CDEBUG(comp, 0, "end-of-stream"); -+ __gomx_event(comp, OMX_EventBufferFlag, OMXALSA_PORT_AUDIO, buf->nFlags, 0); -+ } -+ if (gomxq_peek(&sink->playq) == (void*) buf) { -+ buf = (OMX_BUFFERHEADERTYPE*) gomxq_dequeue(&sink->playq); -+ __gomx_empty_buffer_done(comp, buf); -+ } ++ __gomx_process_mark(comp, buf); ++ if (buf->nFlags & OMX_BUFFERFLAG_EOS) { ++ CDEBUG(comp, 0, "end-of-stream"); ++ __gomx_event(comp, OMX_EventBufferFlag, OMXALSA_PORT_AUDIO, buf->nFlags, 0); + } ++ __gomx_empty_buffer_done(comp, buf); + } + pthread_mutex_unlock(&comp->mutex); +cleanup: + if (dev) snd_pcm_close(dev); ++ if (resampler) speex_resampler_destroy(resampler); ++ free(resample_buf); + CINFO(comp, 0, "worker stopped"); + return 0; + +alsa_error: + CINFO(comp, 0, "ALSA error: %s", snd_strerror(err)); ++err: + pthread_mutex_lock(&comp->mutex); + /* FIXME: Current we just go to invalid state, but we might go + * back to Idle with ErrorResourcesPreempted and let the client @@ -1280,8 +1300,8 @@ index 0000000..b19ef31 +static OMX_ERRORTYPE omxalsasink_audio_do_buffer(GOMX_COMPONENT *comp, GOMX_PORT *port, OMX_BUFFERHEADERTYPE *buf) +{ + OMX_ALSASINK *sink = (OMX_ALSASINK *) comp; -+ gomxq_enqueue(&sink->playq, (void *) buf); + sink->play_queue_size += buf->nFilledLen; ++ gomxq_enqueue(&sink->playq, (void *) buf); + pthread_cond_signal(&sink->cond_play); + return OMX_ErrorNone; +} @@ -1291,8 +1311,8 @@ index 0000000..b19ef31 + OMX_ALSASINK *sink = (OMX_ALSASINK *) comp; + OMX_BUFFERHEADERTYPE *buf; + while ((buf = (OMX_BUFFERHEADERTYPE *) gomxq_dequeue(&sink->playq)) != 0) { -+ __gomx_empty_buffer_done(comp, buf); + sink->play_queue_size -= buf->nFilledLen; ++ __gomx_empty_buffer_done(comp, buf); + } + return OMX_ErrorNone; +} @@ -1449,6 +1469,3 @@ index 3b5e6d2..4032ba3 100644 case 'i': m_dump_format = true; m_dump_format_exit = true; --- -2.7.1 - |