From 26c7ff9317352fa2113e6b85b1c9a7a9c6d3f709 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Tue, 4 Oct 2011 20:47:16 +0200 Subject: [PATCH] Add libmodplug support. --- Changelog | 1 + MAINTAINERS | 1 + configure | 5 ++ libavformat/Makefile | 1 + libavformat/allformats.c | 3 ++ libavformat/libmodplug.c | 110 +++++++++++++++++++++++++++++++++++++++ libavformat/version.h | 2 +- 7 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 libavformat/libmodplug.c diff --git a/Changelog b/Changelog index dafcff4b4d..255b0a4e8e 100644 --- a/Changelog +++ b/Changelog @@ -61,6 +61,7 @@ easier to use. The changes are: - Apple ProRes decoder - CELT in Ogg demuxing - G.723.1 demuxer and decoder +- libmodplug support (--enable-libmodplug) version 0.8: diff --git a/MAINTAINERS b/MAINTAINERS index 4b0fcae8e2..319a79ae68 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -287,6 +287,7 @@ Muxers/Demuxers: img2.c Michael Niedermayer iss.c Stefan Gehrer jvdec.c Peter Ross + libmodplug.c Clément Bœsch libnut.c Oded Shimon lmlm4.c Ivo van Poorten lxfdec.c Tomas Härdin diff --git a/configure b/configure index 0c407fc72a..852e65f455 100755 --- a/configure +++ b/configure @@ -176,6 +176,7 @@ External library support: --enable-libfaac enable FAAC support via libfaac [no] --enable-libfreetype enable libfreetype [no] --enable-libgsm enable GSM support via libgsm [no] + --enable-libmodplug enable ModPlug via libmodplug [no] --enable-libmp3lame enable MP3 encoding via libmp3lame [no] --enable-libnut enable NUT (de)muxing via libnut, native (de)muxer exists [no] @@ -1003,6 +1004,7 @@ CONFIG_LIST=" libfaac libfreetype libgsm + libmodplug libmp3lame libnut libopencore_amrnb @@ -1495,6 +1497,7 @@ libgsm_decoder_deps="libgsm" libgsm_encoder_deps="libgsm" libgsm_ms_decoder_deps="libgsm" libgsm_ms_encoder_deps="libgsm" +libmodplug_decode_deps="libmodplug" libmp3lame_encoder_deps="libmp3lame" libopencore_amrnb_decoder_deps="libopencore_amrnb" libopencore_amrnb_encoder_deps="libopencore_amrnb" @@ -3026,6 +3029,7 @@ enabled libdirac && require_pkg_config dirac \ enabled libfaac && require2 libfaac "stdint.h faac.h" faacEncGetVersion -lfaac enabled libfreetype && require_pkg_config freetype2 "ft2build.h freetype/freetype.h" FT_Init_FreeType enabled libgsm && require libgsm gsm/gsm.h gsm_create -lgsm +enabled libmodplug && require libmodplug libmodplug/modplug.h ModPlug_Load -lmodplug enabled libmp3lame && require "libmp3lame >= 3.98.3" lame/lame.h lame_set_VBR_quality -lmp3lame enabled libnut && require libnut libnut.h nut_demuxer_init -lnut enabled libopencore_amrnb && require libopencore_amrnb opencore-amrnb/interf_dec.h Decoder_Interface_init -lopencore-amrnb @@ -3352,6 +3356,7 @@ echo "libdirac enabled ${libdirac-no}" echo "libfaac enabled ${libfaac-no}" echo "libaacplus enabled ${libaacplus-no}" echo "libgsm enabled ${libgsm-no}" +echo "libmodplug enabled ${libmodplug-no}" echo "libmp3lame enabled ${libmp3lame-no}" echo "libnut enabled ${libnut-no}" echo "libopencore-amrnb support ${libopencore_amrnb-no}" diff --git a/libavformat/Makefile b/libavformat/Makefile index 5f3bf4dde1..0251944bd8 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -324,6 +324,7 @@ OBJS-$(CONFIG_YUV4MPEGPIPE_MUXER) += yuv4mpeg.o OBJS-$(CONFIG_YUV4MPEGPIPE_DEMUXER) += yuv4mpeg.o # external libraries +OBJS-$(CONFIG_LIBMODPLUG_DEMUXER) += libmodplug.o OBJS-$(CONFIG_LIBNUT_DEMUXER) += libnut.o riff.o OBJS-$(CONFIG_LIBNUT_MUXER) += libnut.o riff.o diff --git a/libavformat/allformats.c b/libavformat/allformats.c index 94421aba07..ca4a3d1b4b 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -242,6 +242,9 @@ void av_register_all(void) REGISTER_MUXDEMUX (YUV4MPEGPIPE, yuv4mpegpipe); /* external libraries */ +#if CONFIG_LIBMODPLUG + REGISTER_DEMUXER (LIBMODPLUG, libmodplug); +#endif REGISTER_MUXDEMUX (LIBNUT, libnut); /* protocols */ diff --git a/libavformat/libmodplug.c b/libavformat/libmodplug.c new file mode 100644 index 0000000000..c10c5002d1 --- /dev/null +++ b/libavformat/libmodplug.c @@ -0,0 +1,110 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** +* @file +* ModPlug demuxer +* @todo ModPlug options (noise reduction, reverb, bass boost, ...) +* @todo metadata +*/ + +#include +#include "avformat.h" + +typedef struct ModPlugContext { + ModPlugFile *f; + uint8_t buf[5 * 1<<20]; ///< input file content, 5M max +} ModPlugContext; + +static int modplug_read_header(AVFormatContext *s, AVFormatParameters *ap) +{ + AVStream *st; + AVIOContext *pb = s->pb; + ModPlug_Settings settings; + ModPlugContext *modplug = s->priv_data; + + int sz = avio_read(pb, modplug->buf, sizeof modplug->buf); + + ModPlug_GetSettings(&settings); + settings.mChannels = 2; + settings.mBits = 16; + settings.mFrequency = 44100; + settings.mResamplingMode = MODPLUG_RESAMPLE_FIR; // best quality + settings.mLoopCount = 0; // prevents looping forever + ModPlug_SetSettings(&settings); + + modplug->f = ModPlug_Load(modplug->buf, sz); + if (!modplug->f) + return AVERROR_INVALIDDATA; + + st = av_new_stream(s, 0); + if (!st) + return AVERROR(ENOMEM); + av_set_pts_info(st, 64, 1, 1000); + st->duration = ModPlug_GetLength(modplug->f); + st->codec->codec_type = AVMEDIA_TYPE_AUDIO; + st->codec->codec_id = CODEC_ID_PCM_S16LE; + st->codec->channels = settings.mChannels; + st->codec->sample_rate = settings.mFrequency; + return 0; +} + +static int modplug_read_packet(AVFormatContext *s, AVPacket *pkt) +{ + int ret, n; + ModPlugContext *modplug = s->priv_data; + uint8_t buf[512]; + + n = ModPlug_Read(modplug->f, buf, sizeof buf); + if (n <= 0) + return AVERROR(EIO); + + ret = av_new_packet(pkt, n); + if (ret) + return ret; + pkt->pts = pkt->dts = AV_NOPTS_VALUE; + pkt->size = n; + memcpy(pkt->data, buf, n); + return 0; +} + +static int modplug_read_close(AVFormatContext *s) +{ + ModPlugContext *modplug = s->priv_data; + ModPlug_Unload(modplug->f); + return 0; +} + +static int modplug_read_seek(AVFormatContext *s, int stream_idx, int64_t ts, int flags) +{ + const ModPlugContext *modplug = s->priv_data; + ModPlug_Seek(modplug->f, (int)ts); + return 0; +} + +AVInputFormat ff_libmodplug_demuxer = { + .name = "libmodplug", + .long_name = NULL_IF_CONFIG_SMALL("ModPlug demuxer"), + .priv_data_size = sizeof(ModPlugContext), + .read_header = modplug_read_header, + .read_packet = modplug_read_packet, + .read_close = modplug_read_close, + .read_seek = modplug_read_seek, + .extensions = "669,abc,amf,ams,dbm,dmf,dsm,far,it,mdl,med,mid,mod,mt2,mtm,okt,psm,ptm,s3m,stm,ult,umx,xm" + ",itgz,itr,itz,mdgz,mdr,mdz,s3gz,s3r,s3z,xmgz,xmr,xmz", // compressed mods +}; diff --git a/libavformat/version.h b/libavformat/version.h index cf988102f9..b166e1a896 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -24,7 +24,7 @@ #include "libavutil/avutil.h" #define LIBAVFORMAT_VERSION_MAJOR 53 -#define LIBAVFORMAT_VERSION_MINOR 13 +#define LIBAVFORMAT_VERSION_MINOR 14 #define LIBAVFORMAT_VERSION_MICRO 0 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \