aboutsummaryrefslogtreecommitdiffstats
path: root/main/omxplayer
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2016-02-26 14:04:23 +0000
committerTimo Teräs <timo.teras@iki.fi>2016-02-26 14:05:08 +0000
commitc26e30a092c94e6906ec4269a8e4dca1dba29319 (patch)
treee75495d242249d4dfe374f2bb9af2a0978a0b04b /main/omxplayer
parent7d8502437b7c4bf90b4271af410a9dad6f8e6156 (diff)
downloadaports-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/APKBUILD14
-rw-r--r--main/omxplayer/omxplayer-alsa.patch163
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
-