mirror of
git://slackware.nl/current.git
synced 2024-12-27 09:59:16 +01:00
8713bd99bf
ap/diffstat-1.66-x86_64-1.txz: Upgraded. ap/moc-2.6_alpha3-x86_64-3.txz: Rebuilt. Recompiled against ffmpeg-6.1.1. ap/vim-9.1.0061-x86_64-1.txz: Upgraded. d/nv-codec-headers-12.1.14.0-x86_64-1.txz: Added. Needed to build support for nvidia hardware decoders/encoders on newer GPUs. gst-plugins-bad can use it too. Thanks to Heinz Wiesinger. kde/digikam-8.2.0-x86_64-4.txz: Rebuilt. Recompiled against ffmpeg-6.1.1. kde/ffmpegthumbs-23.08.4-x86_64-2.txz: Rebuilt. Recompiled against ffmpeg-6.1.1. kde/k3b-23.08.4-x86_64-2.txz: Rebuilt. Recompiled against ffmpeg-6.1.1. kde/kfilemetadata-5.114.0-x86_64-2.txz: Rebuilt. Recompiled against ffmpeg-6.1.1. kde/kpipewire-5.27.10-x86_64-2.txz: Rebuilt. Recompiled against ffmpeg-6.1.1. l/Imath-3.1.10-x86_64-1.txz: Upgraded. l/alsa-plugins-1.2.7.1-x86_64-3.txz: Rebuilt. Recompiled against ffmpeg-6.1.1. l/ffmpeg-6.1.1-x86_64-1.txz: Upgraded. Shared library .so-version bump. Added some new build options in the SlackBuild. Use shaderc instead of glslang. Build against libgcrypt to enable support for RTMP[E]. Enable support for lcms2. Build against libass, libplacebo, and nv-codec-headers. Thanks to Heinz Wiesinger. l/gegl-0.4.46-x86_64-4.txz: Rebuilt. Recompiled against ffmpeg-6.1.1. l/gst-plugins-bad-free-1.22.9-x86_64-2.txz: Rebuilt. Recompiled against libass-0.17.1. l/gst-plugins-libav-1.22.9-x86_64-2.txz: Rebuilt. Recompiled against ffmpeg-6.1.1. l/libass-0.17.1-x86_64-1.txz: Added. Adds ASS/SSA subtitle renderer (commonly used in the anime community). adapted SlackBuild from SBo, original by Larry Hajali/Matteo Bernardini. MPlayer and gst-plugins-bad can use it too. Thanks to Heinz Wiesinger. l/libplacebo-6.338.2-x86_64-1.txz: Added. Adds various hardware accelerated filters such as HDR -> SDR tone mapping. adapted SlackBuild from SBo, original by Hunter Sezen/Christoph Willing. Thanks to Heinz Wiesinger. l/mlt-7.22.0-x86_64-2.txz: Rebuilt. Recompiled against ffmpeg-6.1.1. l/netpbm-11.05.02-x86_64-1.txz: Upgraded. l/opencv-4.9.0-x86_64-2.txz: Rebuilt. Recompiled against ffmpeg-6.1.1. l/pipewire-1.0.1-x86_64-2.txz: Rebuilt. Recompiled against ffmpeg-6.1.1. l/qt5-5.15.12_20240103_b8fd1448-x86_64-3.txz: Rebuilt. Recompiled against ffmpeg-6.1.1. x/pixman-0.43.2-x86_64-1.txz: Upgraded. xap/MPlayer-20240127-x86_64-1.txz: Upgraded. Compiled against ffmpeg-6.1.1 and libass-0.17.1. xap/audacious-plugins-4.3.1-x86_64-2.txz: Rebuilt. Recompiled against ffmpeg-6.1.1. xap/ffmpegthumbnailer-2.2.2-x86_64-5.txz: Rebuilt. Recompiled against ffmpeg-6.1.1. xap/freerdp-2.11.5-x86_64-2.txz: Rebuilt. Recompiled against ffmpeg-6.1.1. xap/ssr-0.4.4-x86_64-2.txz: Rebuilt. Recompiled against ffmpeg-6.1.1. xap/vim-gvim-9.1.0061-x86_64-1.txz: Upgraded. xap/xine-lib-1.2.13-x86_64-6.txz: Rebuilt. Recompiled against ffmpeg-6.1.1. xap/xscreensaver-6.08-x86_64-2.txz: Rebuilt. Recompiled against ffmpeg-6.1.1. extra/tigervnc/tigervnc-1.13.1-x86_64-4.txz: Rebuilt. Recompiled against ffmpeg-6.1.1.
586 lines
14 KiB
Diff
586 lines
14 KiB
Diff
From 9cff5bc22740bf80e59b76f20ccaa2888d9d6426 Mon Sep 17 00:00:00 2001
|
|
From: Elimar Riesebieter <riesebie@lxtec.de>
|
|
Date: Sun, 27 Nov 2016 12:12:43 +0100
|
|
Subject: [PATCH] Refreshed opus patch from Tomasz Golinski
|
|
<tomaszg@alpha.uwb.edu.pl>
|
|
|
|
---
|
|
decoder_plugins/Makefile.am | 4 +
|
|
decoder_plugins/decoders.m4 | 1 +
|
|
decoder_plugins/opus/Makefile.am | 6 +
|
|
decoder_plugins/opus/opus.c | 473 +++++++++++++++++++++++++++++++++++++++
|
|
decoder_plugins/opus/opus.m4 | 25 +++
|
|
options.c | 4 +-
|
|
6 files changed, 511 insertions(+), 2 deletions(-)
|
|
create mode 100644 decoder_plugins/opus/Makefile.am
|
|
create mode 100644 decoder_plugins/opus/opus.c
|
|
create mode 100644 decoder_plugins/opus/opus.m4
|
|
|
|
diff --git a/decoder_plugins/Makefile.am b/decoder_plugins/Makefile.am
|
|
index 32a6376..d746099 100644
|
|
--- a/decoder_plugins/Makefile.am
|
|
+++ b/decoder_plugins/Makefile.am
|
|
@@ -16,6 +16,10 @@ if BUILD_vorbis
|
|
SUBDIRS += vorbis
|
|
endif
|
|
|
|
+if BUILD_opus
|
|
+ SUBDIRS += opus
|
|
+endif
|
|
+
|
|
if BUILD_flac
|
|
SUBDIRS += flac
|
|
endif
|
|
diff --git a/decoder_plugins/decoders.m4 b/decoder_plugins/decoders.m4
|
|
index 77bc2b3..a851967 100644
|
|
--- a/decoder_plugins/decoders.m4
|
|
+++ b/decoder_plugins/decoders.m4
|
|
@@ -20,6 +20,7 @@ m4_include(decoder_plugins/flac/flac.m4)
|
|
m4_include(decoder_plugins/modplug/modplug.m4)
|
|
m4_include(decoder_plugins/mp3/mp3.m4)
|
|
m4_include(decoder_plugins/musepack/musepack.m4)
|
|
+m4_include(decoder_plugins/opus/opus.m4)
|
|
m4_include(decoder_plugins/sidplay2/sidplay2.m4)
|
|
m4_include(decoder_plugins/sndfile/sndfile.m4)
|
|
m4_include(decoder_plugins/speex/speex.m4)
|
|
diff --git a/decoder_plugins/opus/Makefile.am b/decoder_plugins/opus/Makefile.am
|
|
new file mode 100644
|
|
index 0000000..d0c183d
|
|
--- /dev/null
|
|
+++ b/decoder_plugins/opus/Makefile.am
|
|
@@ -0,0 +1,6 @@
|
|
+lib_LTLIBRARIES = libopus_decoder.la
|
|
+libdir = $(plugindir)/$(DECODER_PLUGIN_DIR)
|
|
+libopus_decoder_la_LDFLAGS = @PLUGIN_LDFLAGS@
|
|
+libopus_decoder_la_LIBADD = $(OPUSFILE_LIBS)
|
|
+libopus_decoder_la_CFLAGS = $(OPUSFILE_CFLAGS) -I$(top_srcdir)
|
|
+libopus_decoder_la_SOURCES = opus.c
|
|
diff --git a/decoder_plugins/opus/opus.c b/decoder_plugins/opus/opus.c
|
|
new file mode 100644
|
|
index 0000000..6cc9d55
|
|
--- /dev/null
|
|
+++ b/decoder_plugins/opus/opus.c
|
|
@@ -0,0 +1,473 @@
|
|
+/*
|
|
+ * MOC - music on console
|
|
+ * Copyright (C) 2002 - 2005 Damian Pietras <daper@daper.net>
|
|
+ *
|
|
+ * 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 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ */
|
|
+
|
|
+#ifdef HAVE_CONFIG_H
|
|
+#include "config.h"
|
|
+#endif
|
|
+
|
|
+#include <string.h>
|
|
+#include <strings.h>
|
|
+#include <stdio.h>
|
|
+#include <errno.h>
|
|
+#include <assert.h>
|
|
+#include <opusfile.h>
|
|
+
|
|
+#define DEBUG
|
|
+
|
|
+#include "common.h"
|
|
+#include "log.h"
|
|
+#include "decoder.h"
|
|
+#include "io.h"
|
|
+#include "audio.h"
|
|
+
|
|
+
|
|
+struct opus_data
|
|
+{
|
|
+ struct io_stream *stream;
|
|
+ OggOpusFile *of;
|
|
+ int last_section;
|
|
+ opus_int32 bitrate;
|
|
+ opus_int32 avg_bitrate;
|
|
+ int duration;
|
|
+ struct decoder_error error;
|
|
+ int ok; /* was this stream successfully opened? */
|
|
+ int tags_change; /* the tags were changed from the last call of
|
|
+ ogg_current_tags */
|
|
+ struct file_tags *tags;
|
|
+};
|
|
+
|
|
+
|
|
+static void get_comment_tags (OggOpusFile *of, struct file_tags *info)
|
|
+{
|
|
+ int i;
|
|
+ const OpusTags *comments;
|
|
+
|
|
+ comments = op_tags (of, -1);
|
|
+ for (i = 0; i < comments->comments; i++) {
|
|
+ if (!strncasecmp(comments->user_comments[i], "title=",
|
|
+ strlen ("title=")))
|
|
+ info->title = xstrdup(comments->user_comments[i]
|
|
+ + strlen ("title="));
|
|
+ else if (!strncasecmp(comments->user_comments[i],
|
|
+ "artist=", strlen ("artist=")))
|
|
+ info->artist = xstrdup (
|
|
+ comments->user_comments[i]
|
|
+ + strlen ("artist="));
|
|
+ else if (!strncasecmp(comments->user_comments[i],
|
|
+ "album=", strlen ("album=")))
|
|
+ info->album = xstrdup (
|
|
+ comments->user_comments[i]
|
|
+ + strlen ("album="));
|
|
+ else if (!strncasecmp(comments->user_comments[i],
|
|
+ "tracknumber=",
|
|
+ strlen ("tracknumber=")))
|
|
+ info->track = atoi (comments->user_comments[i]
|
|
+ + strlen ("tracknumber="));
|
|
+ else if (!strncasecmp(comments->user_comments[i],
|
|
+ "track=", strlen ("track=")))
|
|
+ info->track = atoi (comments->user_comments[i]
|
|
+ + strlen ("track="));
|
|
+ }
|
|
+}
|
|
+
|
|
+/* Return a malloc()ed description of an op_*() error. */
|
|
+static char *opus_str_error (const int code)
|
|
+{
|
|
+ char *err;
|
|
+
|
|
+ switch (code) {
|
|
+ case OP_FALSE:
|
|
+ err = "Request was not successful";
|
|
+ break;
|
|
+ case OP_EOF:
|
|
+ err = "End Of File";
|
|
+ break;
|
|
+ case OP_HOLE:
|
|
+ err = "Hole in stream";
|
|
+ break;
|
|
+ case OP_EREAD:
|
|
+ err = "An underlying read, seek, or tell operation failed.";
|
|
+ break;
|
|
+ case OP_EFAULT:
|
|
+ err = "Internal (Opus) logic fault";
|
|
+ break;
|
|
+ case OP_EIMPL:
|
|
+ err = "Unimplemented feature";
|
|
+ break;
|
|
+ case OP_EINVAL:
|
|
+ err = "Invalid argument";
|
|
+ break;
|
|
+ case OP_ENOTFORMAT:
|
|
+ err = "Not an Opus file";
|
|
+ break;
|
|
+ case OP_EBADHEADER:
|
|
+ err = "Invalid or corrupt header";
|
|
+ break;
|
|
+ case OP_EVERSION:
|
|
+ err = "Opus header version mismatch";
|
|
+ break;
|
|
+ case OP_EBADPACKET:
|
|
+ err = "An audio packet failed to decode properly";
|
|
+ break;
|
|
+ case OP_ENOSEEK:
|
|
+ err = "Requested seeking in unseekable stream";
|
|
+ break;
|
|
+ case OP_EBADTIMESTAMP:
|
|
+ err = "File timestamps fail sanity tests";
|
|
+ break;
|
|
+ default:
|
|
+ err = "Unknown error";
|
|
+ }
|
|
+
|
|
+ return xstrdup (err);
|
|
+}
|
|
+
|
|
+
|
|
+/* Fill info structure with data from ogg comments */
|
|
+static void opus_tags (const char *file_name, struct file_tags *info,
|
|
+ const int tags_sel)
|
|
+{
|
|
+ OggOpusFile *of;
|
|
+ int err_code;
|
|
+
|
|
+ // op_test() is faster than op_open(), but we can't read file time with it.
|
|
+ if (tags_sel & TAGS_TIME) {
|
|
+ of = op_open_file(file_name,&err_code);
|
|
+ if (err_code < 0) {
|
|
+ char *opus_err = opus_str_error (err_code);
|
|
+
|
|
+ logit ("Can't open %s: %s", file_name, opus_err);
|
|
+ free (opus_err);
|
|
+ op_free(of);
|
|
+
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+ else {
|
|
+ of = op_open_file(file_name,&err_code);
|
|
+ if (err_code < 0) {
|
|
+ char *opus_err = opus_str_error (err_code);
|
|
+
|
|
+ logit ("Can't open %s: %s", file_name, opus_err);
|
|
+ free (opus_err);
|
|
+ op_free (of);
|
|
+
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (tags_sel & TAGS_COMMENTS)
|
|
+ get_comment_tags (of, info);
|
|
+
|
|
+ if (tags_sel & TAGS_TIME) {
|
|
+ ogg_int64_t opus_time;
|
|
+
|
|
+ opus_time = op_pcm_total (of, -1);
|
|
+ if (opus_time >= 0)
|
|
+ info->time = opus_time / 48000;
|
|
+ debug("Duration tags: %d, samples %lld",info->time,(long long)opus_time);
|
|
+ }
|
|
+
|
|
+ op_free (of);
|
|
+}
|
|
+
|
|
+static int read_callback (void *datasource, unsigned char *ptr, int bytes)
|
|
+{
|
|
+ ssize_t res;
|
|
+
|
|
+ res = io_read (datasource, ptr, bytes);
|
|
+
|
|
+ if (res < 0) {
|
|
+ logit ("Read error");
|
|
+ res = -1;
|
|
+ }
|
|
+
|
|
+ return res;
|
|
+}
|
|
+
|
|
+static int seek_callback (void *datasource, opus_int64 offset, int whence)
|
|
+{
|
|
+ debug ("Seek request to %ld (%s)", (long)offset,
|
|
+ whence == SEEK_SET ? "SEEK_SET"
|
|
+ : (whence == SEEK_CUR ? "SEEK_CUR" : "SEEK_END"));
|
|
+ return io_seek (datasource, offset, whence)<0 ? -1 : 0;
|
|
+}
|
|
+
|
|
+static int close_callback (void *datasource ATTR_UNUSED)
|
|
+{
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static opus_int64 tell_callback (void *datasource)
|
|
+{
|
|
+ return io_tell (datasource);
|
|
+}
|
|
+
|
|
+static void opus_open_stream_internal (struct opus_data *data)
|
|
+{
|
|
+ int res;
|
|
+ OpusFileCallbacks callbacks = {
|
|
+ read_callback,
|
|
+ seek_callback,
|
|
+ tell_callback,
|
|
+ close_callback
|
|
+ };
|
|
+
|
|
+ data->tags = tags_new ();
|
|
+
|
|
+ data->of = op_open_callbacks(data->stream, &callbacks, NULL, 0, &res);
|
|
+ if (res < 0) {
|
|
+ char *opus_err = opus_str_error (res);
|
|
+
|
|
+ decoder_error (&data->error, ERROR_FATAL, 0, "%s",
|
|
+ opus_err);
|
|
+ debug ("op_open error: %s", opus_err);
|
|
+ free (opus_err);
|
|
+ op_free (data->of);
|
|
+ data->of = NULL;
|
|
+ io_close (data->stream);
|
|
+ }
|
|
+ else {
|
|
+ ogg_int64_t samples;
|
|
+ data->last_section = -1;
|
|
+ data->avg_bitrate = op_bitrate (data->of, -1) / 1000;
|
|
+ data->bitrate = data->avg_bitrate;
|
|
+ samples = op_pcm_total (data->of, -1);
|
|
+ if (samples == OP_EINVAL)
|
|
+ data->duration = -1;
|
|
+ else
|
|
+ data->duration =samples/48000;
|
|
+ debug("Duration: %d, samples %lld",data->duration,(long long)samples);
|
|
+ data->ok = 1;
|
|
+ get_comment_tags (data->of, data->tags);
|
|
+ }
|
|
+}
|
|
+
|
|
+static void *opus_open (const char *file)
|
|
+{
|
|
+ struct opus_data *data;
|
|
+ data = (struct opus_data *)xmalloc (sizeof(struct opus_data));
|
|
+ data->ok = 0;
|
|
+
|
|
+ decoder_error_init (&data->error);
|
|
+ data->tags_change = 0;
|
|
+ data->tags = NULL;
|
|
+
|
|
+ data->stream = io_open (file, 1);
|
|
+ if (!io_ok(data->stream)) {
|
|
+ decoder_error (&data->error, ERROR_FATAL, 0,
|
|
+ "Can't load Opus: %s",
|
|
+ io_strerror(data->stream));
|
|
+ io_close (data->stream);
|
|
+ }
|
|
+ else
|
|
+ opus_open_stream_internal (data);
|
|
+
|
|
+ return data;
|
|
+}
|
|
+
|
|
+static int opus_can_decode (struct io_stream *stream)
|
|
+{
|
|
+ char buf[36];
|
|
+
|
|
+ if (io_peek (stream, buf, 36) == 36 && !memcmp (buf, "OggS", 4)
|
|
+ && !memcmp (buf + 28, "OpusHead", 8))
|
|
+ return 1;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void *opus_open_stream (struct io_stream *stream)
|
|
+{
|
|
+ struct opus_data *data;
|
|
+
|
|
+ data = (struct opus_data *)xmalloc (sizeof(struct opus_data));
|
|
+ data->ok = 0;
|
|
+
|
|
+ decoder_error_init (&data->error);
|
|
+ data->stream = stream;
|
|
+ opus_open_stream_internal (data);
|
|
+
|
|
+ return data;
|
|
+}
|
|
+
|
|
+static void opus_close (void *prv_data)
|
|
+{
|
|
+ struct opus_data *data = (struct opus_data *)prv_data;
|
|
+
|
|
+ if (data->ok) {
|
|
+ op_free (data->of);
|
|
+ io_close (data->stream);
|
|
+ }
|
|
+
|
|
+ decoder_error_clear (&data->error);
|
|
+ if (data->tags)
|
|
+ tags_free (data->tags);
|
|
+ free (data);
|
|
+}
|
|
+
|
|
+static int opus_seek (void *prv_data, int sec)
|
|
+{
|
|
+ struct opus_data *data = (struct opus_data *)prv_data;
|
|
+
|
|
+ assert (sec >= 0);
|
|
+
|
|
+ return op_pcm_seek (data->of, sec * (ogg_int64_t)48000)<0 ? -1 : sec;
|
|
+}
|
|
+
|
|
+static int opus_decodeX (void *prv_data, char *buf, int buf_len,
|
|
+ struct sound_params *sound_params)
|
|
+{
|
|
+ struct opus_data *data = (struct opus_data *)prv_data;
|
|
+ int ret;
|
|
+ int current_section;
|
|
+ int bitrate;
|
|
+
|
|
+ decoder_error_clear (&data->error);
|
|
+
|
|
+ while (1) {
|
|
+#ifdef HAVE_OPUSFILE_FLOAT
|
|
+ ret = op_read_float(data->of, (float *)buf, buf_len/sizeof(float), ¤t_section);
|
|
+debug("opus float!");
|
|
+#else
|
|
+ ret = op_read(data->of, (opus_int16 *)buf, buf_len/sizeof(opus_int16), ¤t_section);
|
|
+debug("opus fixed!");
|
|
+#endif
|
|
+ if (ret == 0)
|
|
+ return 0;
|
|
+ if (ret < 0) {
|
|
+ decoder_error (&data->error, ERROR_STREAM, 0,
|
|
+ "Error in the stream!");
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ if (current_section != data->last_section) {
|
|
+ logit ("section change or first section");
|
|
+
|
|
+ data->last_section = current_section;
|
|
+ data->tags_change = 1;
|
|
+ tags_free (data->tags);
|
|
+ data->tags = tags_new ();
|
|
+ get_comment_tags (data->of, data->tags);
|
|
+ }
|
|
+
|
|
+ sound_params->channels = op_channel_count (data->of, current_section);
|
|
+ sound_params->rate = 48000;
|
|
+#ifdef HAVE_OPUSFILE_FLOAT
|
|
+ sound_params->fmt = SFMT_FLOAT;
|
|
+ ret *= sound_params->channels * sizeof(float);
|
|
+#else
|
|
+ sound_params->fmt = SFMT_S16 | SFMT_NE;
|
|
+ ret *= sound_params->channels * sizeof(opus_int16);
|
|
+#endif
|
|
+ /* Update the bitrate information */
|
|
+ bitrate = op_bitrate_instant (data->of);
|
|
+ if (bitrate > 0)
|
|
+ data->bitrate = bitrate / 1000;
|
|
+
|
|
+ break;
|
|
+ }
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static int opus_current_tags (void *prv_data, struct file_tags *tags)
|
|
+{
|
|
+ struct opus_data *data = (struct opus_data *)prv_data;
|
|
+
|
|
+ tags_copy (tags, data->tags);
|
|
+
|
|
+ if (data->tags_change) {
|
|
+ data->tags_change = 0;
|
|
+ return 1;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+static int opus_get_bitrate (void *prv_data)
|
|
+{
|
|
+ struct opus_data *data = (struct opus_data *)prv_data;
|
|
+
|
|
+ return data->bitrate;
|
|
+}
|
|
+
|
|
+static int opus_get_avg_bitrate (void *prv_data)
|
|
+{
|
|
+ struct opus_data *data = (struct opus_data *)prv_data;
|
|
+
|
|
+ return data->avg_bitrate;
|
|
+}
|
|
+
|
|
+static int opus_get_duration (void *prv_data)
|
|
+{
|
|
+
|
|
+ struct opus_data *data = (struct opus_data *)prv_data;
|
|
+
|
|
+ return data->duration;
|
|
+}
|
|
+
|
|
+static struct io_stream *opus_get_stream (void *prv_data)
|
|
+{
|
|
+ struct opus_data *data = (struct opus_data *)prv_data;
|
|
+
|
|
+ return data->stream;
|
|
+}
|
|
+
|
|
+static void opus_get_name (const char *file ATTR_UNUSED, char buf[4])
|
|
+{
|
|
+ strcpy (buf, "OPS");
|
|
+}
|
|
+
|
|
+static int opus_our_format_ext (const char *ext)
|
|
+{
|
|
+ return !strcasecmp (ext, "opus");
|
|
+}
|
|
+
|
|
+static void opus_get_error (void *prv_data, struct decoder_error *error)
|
|
+{
|
|
+ struct opus_data *data = (struct opus_data *)prv_data;
|
|
+
|
|
+ decoder_error_copy (error, &data->error);
|
|
+}
|
|
+
|
|
+static int opus_our_mime (const char *mime)
|
|
+{
|
|
+ return !strcasecmp (mime, "audio/ogg")
|
|
+ || !strcasecmp (mime, "audio/ogg; codecs=opus");
|
|
+}
|
|
+
|
|
+static struct decoder opus_decoder = {
|
|
+ DECODER_API_VERSION,
|
|
+ NULL,
|
|
+ NULL,
|
|
+ opus_open,
|
|
+ opus_open_stream,
|
|
+ opus_can_decode,
|
|
+ opus_close,
|
|
+ opus_decodeX,
|
|
+ opus_seek,
|
|
+ opus_tags,
|
|
+ opus_get_bitrate,
|
|
+ opus_get_duration,
|
|
+ opus_get_error,
|
|
+ opus_our_format_ext,
|
|
+ opus_our_mime,
|
|
+ opus_get_name,
|
|
+ opus_current_tags,
|
|
+ opus_get_stream,
|
|
+ opus_get_avg_bitrate
|
|
+};
|
|
+
|
|
+struct decoder *plugin_init ()
|
|
+{
|
|
+ return &opus_decoder;
|
|
+}
|
|
diff --git a/decoder_plugins/opus/opus.m4 b/decoder_plugins/opus/opus.m4
|
|
new file mode 100644
|
|
index 0000000..08cceb9
|
|
--- /dev/null
|
|
+++ b/decoder_plugins/opus/opus.m4
|
|
@@ -0,0 +1,25 @@
|
|
+dnl opus
|
|
+
|
|
+AC_ARG_WITH(opus, AS_HELP_STRING([--without-opus],
|
|
+ [Compile without Opus support]))
|
|
+
|
|
+ if test "x$with_opus" != "xno"
|
|
+ then
|
|
+ PKG_CHECK_MODULES(OPUSFILE,
|
|
+ [opusfile >= 0.1],
|
|
+ [AC_SUBST(OPUSFILE_LIBS)
|
|
+ AC_SUBST(OPUSFILE_CFLAGS)
|
|
+ want_opus="yes"
|
|
+ DECODER_PLUGINS="$DECODER_PLUGINS opus"],
|
|
+ [true])
|
|
+ if test "x$want_opus" = "xyes"
|
|
+ then
|
|
+ AC_SEARCH_LIBS(op_read_float, opusfile,
|
|
+ [AC_DEFINE([HAVE_OPUSFILE_FLOAT], 1,
|
|
+ [Define to 1 if you have the `op_read_float' function.])])
|
|
+ fi
|
|
+
|
|
+ fi
|
|
+
|
|
+AM_CONDITIONAL([BUILD_opus], [test "$want_opus"])
|
|
+AC_CONFIG_FILES([decoder_plugins/opus/Makefile])
|
|
diff --git a/options.c b/options.c
|
|
index 62835ac..bb97b94 100644
|
|
--- a/options.c
|
|
+++ b/options.c
|
|
@@ -659,9 +659,9 @@ void options_init ()
|
|
"audio/aac(aac):audio/aacp(aac):audio/m4a(ffmpeg):"
|
|
"audio/wav(sndfile,*):"
|
|
"ogg(vorbis,*,ffmpeg):oga(vorbis,*,ffmpeg):ogv(ffmpeg):"
|
|
- "application/ogg(vorbis):audio/ogg(vorbis):"
|
|
+ "application/ogg(vorbis,opus):audio/ogg(vorbis,opus):"
|
|
"flac(flac,*,ffmpeg):"
|
|
- "opus(ffmpeg):"
|
|
+ "opus(opus,ffmpeg):"
|
|
"spx(speex)",
|
|
CHECK_FUNCTION);
|
|
|
|
--
|
|
2.10.2
|
|
|