[beast: 2/3] BSE: work around vorbisfile-1.3.4 pcm_seek crashes
- From: Tim Janik <timj src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [beast: 2/3] BSE: work around vorbisfile-1.3.4 pcm_seek crashes
- Date: Wed, 9 Sep 2015 08:14:40 +0000 (UTC)
commit 6a7473cc5a217353800962fd9dd85a44e57990be
Author: Tim Janik <timj gnu org>
Date: Wed Sep 9 01:47:33 2015 +0200
BSE: work around vorbisfile-1.3.4 pcm_seek crashes
The crashes can occour for small vorbis files when pcm_seek(_page)
gets close to EOF. To avoid this situation, we force a raw seek to
the file start before attempting a pcm_seek. This effectively
doubles seeking time but avoids crashes in most cases.
bse/gsldatahandle-vorbis.cc | 27 ++++++++++++++++++++++-----
1 files changed, 22 insertions(+), 5 deletions(-)
---
diff --git a/bse/gsldatahandle-vorbis.cc b/bse/gsldatahandle-vorbis.cc
index 67b68d1..fa19f4d 100644
--- a/bse/gsldatahandle-vorbis.cc
+++ b/bse/gsldatahandle-vorbis.cc
@@ -5,6 +5,7 @@
#include <ogg/ogg.h>
#include <vorbis/vorbisfile.h>
#include <errno.h>
+#include "../configure.h"
/* --- defines --- */
@@ -135,6 +136,23 @@ static ov_callbacks vfile_ov_callbacks = {
vfile_tell,
};
+static int
+dh_vorbis_page_seek (VorbisHandle *vhandle, int64 pos)
+{
+ int err;
+#if VORBISFILE_BADSEEK == 1
+ // libvorbisfile-1.3.4 and earlier like to segfault while seeking around EOF on small files
+ // so ov_pcm_seek and ov_pcm_seek_page cannot be used reliably, this is a crude workaround
+ err = ov_raw_seek (&vhandle->ofile, 0);
+ if (err != 0)
+ printerr ("%s: %s: %d\n", __func__, "ov_raw_seek", err);
+#endif
+ err = ov_pcm_seek_page (&vhandle->ofile, pos);
+ if (err != 0)
+ printerr ("%s: %s: %d\n", __func__, "ov_pcm_seek_page", err);
+ return err;
+}
+
static Bse::ErrorType
dh_vorbis_open (GslDataHandle *dhandle,
GslDataHandleSetup *setup)
@@ -200,7 +218,7 @@ dh_vorbis_open (GslDataHandle *dhandle,
n = ov_pcm_total (&vhandle->ofile, vhandle->bitstream);
vi = ov_info (&vhandle->ofile, vhandle->bitstream);
- if (n > 0 && vi && vi->channels && ov_pcm_seek (&vhandle->ofile, vhandle->soffset) >= 0)
+ if (n > 0 && vi && vi->channels && dh_vorbis_page_seek (vhandle, vhandle->soffset) >= 0)
{
setup->n_channels = vi->channels;
setup->n_values = n * setup->n_channels;
@@ -225,8 +243,7 @@ dh_vorbis_open (GslDataHandle *dhandle,
}
static GslLong
-dh_vorbis_coarse_seek (GslDataHandle *dhandle,
- GslLong voffset)
+dh_vorbis_coarse_seek (GslDataHandle *dhandle, GslLong voffset)
{
VorbisHandle *vhandle = (VorbisHandle*) dhandle;
GslLong opos = vhandle->pcm_pos, pos = voffset / dhandle->setup.n_channels;
@@ -237,10 +254,10 @@ dh_vorbis_coarse_seek (GslDataHandle *dhandle,
if (pos < vhandle->pcm_pos ||
pos >= vhandle->pcm_pos + vhandle->pcm_length + SEEK_BY_READ_AHEAD (vhandle))
{
- gint err = ov_pcm_seek_page (&vhandle->ofile, vhandle->soffset + pos);
+ int err = dh_vorbis_page_seek (vhandle, vhandle->soffset + pos);
if (err) /* eek */
- err = ov_pcm_seek_page (&vhandle->ofile, vhandle->soffset);
+ err = dh_vorbis_page_seek (vhandle, vhandle->soffset);
else
vhandle->pcm_pos = ov_pcm_tell (&vhandle->ofile) - vhandle->soffset;
if (err || vhandle->pcm_pos < 0) /* urg, we're completely screwed */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]