aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorB. Watson <urchlay@slackware.uk>2025-06-05 05:31:41 -0400
committerWilly Sudiarto Raharjo <willysr@slackbuilds.org>2025-06-07 12:27:19 +0700
commitdc28f82f0acefb1cf26fb31128488efce3fd852c (patch)
tree6684f300870e67d8bae19d42068eb4bebf7bb63e
parent36ff8b3640dfb1e8d1fd1fc968d8cd0bbfb3248c (diff)
games/alephone: Updated for version 20250302.
Signed-off-by: B. Watson <urchlay@slackware.uk> Signed-off-by: Willy Sudiarto Raharjo <willysr@slackbuilds.org>
-rw-r--r--games/alephone/alephone.SlackBuild12
-rw-r--r--games/alephone/alephone.info6
-rw-r--r--games/alephone/ffmpeg7.diff525
3 files changed, 537 insertions, 6 deletions
diff --git a/games/alephone/alephone.SlackBuild b/games/alephone/alephone.SlackBuild
index cb646e4074..d4c6be6d94 100644
--- a/games/alephone/alephone.SlackBuild
+++ b/games/alephone/alephone.SlackBuild
@@ -6,6 +6,7 @@
# Licensed under the WTFPL. See http://www.wtfpl.net/txt/copying/ for details.
+# 20250605 bkw: update for 20250302, including patch for -current
# 20241025 bkw: update for 20240822
# 20240808 bkw: update for 20240712
# 20240320 bkw: update for 20240119
@@ -22,7 +23,7 @@
cd $(dirname $0) ; CWD=$(pwd)
PRGNAM=alephone
-VERSION=${VERSION:-20240822}
+VERSION=${VERSION:-20250302}
BUILD=${BUILD:-1}
TAG=${TAG:-_SBo}
PKGTYPE=${PKGTYPE:-tgz}
@@ -69,8 +70,13 @@ rm -rf $SRCNAM-$VERSION
tar xvf $CWD/$SRCNAM-$VERSION.tar.bz2
cd $SRCNAM-$VERSION
chown -R root:root .
-find -L . -perm /111 -a \! -perm 755 -a -exec chmod 755 {} \+ -o \
- \! -perm /111 -a \! -perm 644 -a -exec chmod 644 {} \+
+find -L . -perm /111 -a \! -perm 755 -a -exec chmod 755 {} + -o \
+ \! -perm /111 -a \! -perm 644 -a -exec chmod 644 {} +
+
+# 20250605 bkw: this patch comes from Brent Spillner. It's needed on
+# Slackware-current, and does no harm on 15.0. At some point, upstream
+# will support newer ffmpeg and this patch will go away.
+patch -p1 < $CWD/ffmpeg7.diff
[ "${FFMPEG:-yes}" = "no" ] && EXTRAOPT=--without-ffmpeg
diff --git a/games/alephone/alephone.info b/games/alephone/alephone.info
index ea54adf4e1..712f354f93 100644
--- a/games/alephone/alephone.info
+++ b/games/alephone/alephone.info
@@ -1,8 +1,8 @@
PRGNAM="alephone"
-VERSION="20240822"
+VERSION="20250302"
HOMEPAGE="https://alephone.lhowon.org/"
-DOWNLOAD="https://github.com/Aleph-One-Marathon/alephone/releases/download/release-20240822/AlephOne-20240822.tar.bz2"
-MD5SUM="52f298ca8e75da9fcb0ba072b234ff11"
+DOWNLOAD="https://github.com/Aleph-One-Marathon/alephone/releases/download/release-20250302/AlephOne-20250302.tar.bz2"
+MD5SUM="7d535bdae5f0b65a5c7f663940ba1d77"
DOWNLOAD_x86_64=""
MD5SUM_x86_64=""
REQUIRES="lua zziplib"
diff --git a/games/alephone/ffmpeg7.diff b/games/alephone/ffmpeg7.diff
new file mode 100644
index 0000000000..74541b8469
--- /dev/null
+++ b/games/alephone/ffmpeg7.diff
@@ -0,0 +1,525 @@
+diff --git a/Source_Files/FFmpeg/Movie.cpp b/Source_Files/FFmpeg/Movie.cpp
+index d78b0a88..c95bfe27 100644
+--- a/Source_Files/FFmpeg/Movie.cpp
++++ b/Source_Files/FFmpeg/Movie.cpp
+@@ -114,10 +114,27 @@ static int get_cpu_count(void)
+ return cpu_count;
+ }
+
++#define AV_FIFO_BUFFER_SIZE (1<<18)
++#if USE_NEW_AV_FIFO_API
++ #define AV_FIFO_POLL_DELAY_MS 1
++ #define AV_FIFO_MAX_WAIT_MS 10
++
++ #ifdef __WIN32__
++ #define SleepForMlliseconds Sleep
++ #else
++ #include <unistd.h>
++ #define SleepForMilliseconds(X) usleep(1000 * (X))
++ #endif
++#endif
++
+ struct libav_vars {
+ bool inited;
+
++#if USE_NEW_AV_FIFO_API
++ AVFifo *audio_fifo;
++#else
+ AVFifoBuffer *audio_fifo;
++#endif
+
+ SDL_ffmpegFile* ffmpeg_file;
+ SDL_ffmpegAudioFrame* audio_frame;
+@@ -279,7 +296,11 @@ bool Movie::Setup()
+
+ if (avformat_write_header(av->ffmpeg_file->_ffmpeg, 0) < 0) { ThrowUserError("Could not write header"); return false; }
+
+- av->audio_fifo = av_fifo_alloc(262144);
++#if USE_NEW_AV_FIFO_API
++ av->audio_fifo = av_fifo_alloc2(AV_FIFO_BUFFER_SIZE / AV_FIFO_CHUNK_SIZE, AV_FIFO_CHUNK_SIZE, 0);
++#else
++ av->audio_fifo = av_fifo_alloc(AV_FIFO_BUFFER_SIZE);
++#endif
+ if (!av->audio_fifo) { ThrowUserError("Could not allocate audio fifo"); return false; }
+
+ // set up our threads and intermediate storage
+@@ -335,18 +356,56 @@ void Movie::EncodeVideo(bool last)
+
+ void Movie::EncodeAudio(bool last)
+ {
+- av_fifo_generic_write(av->audio_fifo, &audiobuf[0], audiobuf.size(), NULL);
++#if USE_NEW_AV_FIFO_API
++ size_t max_write = audiobuf.size();
++ size_t written_so_far = 0, sleep_counter = 0;
++
++ while (written_so_far < max_write) {
++ int writable = MAX(av_fifo_can_write(av->audio_fifo) * AV_FIFO_CHUNK_SIZE, max_write - written_so_far);
++
++ if (!writable) {
++ if (sleep_counter * AV_FIFO_POLL_DELAY_MS >= AV_FIFO_MAX_WAIT_MS)
++ break;
++ SleepForMilliseconds(AV_FIFO_POLL_DELAY_MS);
++ sleep_counter++;
++ } else {
++ if (av_fifo_write(av->audio_fifo, &audiobuf[0], writable) < 0)
++ break;
++ written_so_far += writable;
++ sleep_counter = 0;
++ }
++ }
++#else
++ av_fifo_generic_write(av->audio_fifo, &audiobuf[0], audiobuf.size(), NULL);
++#endif
++
+ auto acodec = av->ffmpeg_file->audioStream->_ctx;
+
+ // bps: bytes per sample
++#if USE_NEW_AV_FIFO_API
++ int channels = acodec->ch_layout.nb_channels;
++#else
+ int channels = acodec->channels;
++#endif
+
+- int max_read = acodec->frame_size * in_bps * channels;
+- int min_read = last ? in_bps * channels : max_read;
++ size_t max_read = acodec->frame_size * in_bps * channels;
++ size_t min_read = last ? in_bps * channels : max_read;
++
++#if USE_NEW_AV_FIFO_API
++ size_t read_so_far = 0;
++ while (read_so_far < max_read && av_fifo_can_read(av->audio_fifo) >= min_read)
++ {
++ int read_bytes = av->audio_frame->size = MIN(AV_FIFO_CHUNK_SIZE * av_fifo_can_read(av->audio_fifo), max_read);
++
++ if (av_fifo_read(av->audio_fifo, av->audio_frame->buffer, read_bytes) < 0)
++ break;
++ read_so_far += read_bytes;
++#else
+ while (av_fifo_size(av->audio_fifo) >= min_read)
+ {
+ int read_bytes = av->audio_frame->size = MIN(av_fifo_size(av->audio_fifo), max_read);
+ av_fifo_generic_read(av->audio_fifo, av->audio_frame->buffer, read_bytes, NULL);
++#endif
+ SDL_ffmpegAddAudioFrame(av->ffmpeg_file, av->audio_frame, &av->audio_counter, last);
+ }
+ }
+@@ -466,8 +525,12 @@ void Movie::StopRecording()
+ }
+ if (av->audio_fifo)
+ {
++#if USE_NEW_AV_FIFO_API
++ av_fifo_freep2(&av->audio_fifo);
++#else
+ av_fifo_free(av->audio_fifo);
+- av->audio_fifo = NULL;
++ av->audio_fifo = NULL;
++#endif
+ }
+
+ moviefile = "";
+diff --git a/Source_Files/FFmpeg/SDL_ffmpeg.c b/Source_Files/FFmpeg/SDL_ffmpeg.c
+index 73740e25..eb6322bc 100644
+--- a/Source_Files/FFmpeg/SDL_ffmpeg.c
++++ b/Source_Files/FFmpeg/SDL_ffmpeg.c
+@@ -444,6 +444,19 @@ SDL_ffmpegFile* SDL_ffmpegOpen( const char* filename )
+ }
+ else
+ {
++ int rv = 0;
++#if USE_NEW_AV_FIFO_API
++ int channel_layout = stream->_ffmpeg->codecpar->ch_layout.u.mask ? stream->_ffmpeg->codecpar->ch_layout.u.mask :
++ (stream->_ffmpeg->codecpar->ch_layout.nb_channels == 2 ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO);
++ AVChannelLayout in_layout, out_layout;
++
++ in_layout = out_layout = stream->_ffmpeg->codecpar->ch_layout;
++ in_layout.u.mask = out_layout.u.mask = channel_layout;
++ rv = swr_alloc_set_opts2(&stream->swr_context, &out_layout, AV_SAMPLE_FMT_FLT,
++ stream->_ffmpeg->codecpar->sample_rate, &in_layout,
++ stream->_ffmpeg->codecpar->format, stream->_ffmpeg->codecpar->sample_rate,
++ 0, NULL);
++#else
+ int channel_layout = stream->_ffmpeg->codecpar->channel_layout ? stream->_ffmpeg->codecpar->channel_layout :
+ (stream->_ffmpeg->codecpar->channels == 2 ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO);
+
+@@ -451,8 +464,9 @@ SDL_ffmpegFile* SDL_ffmpegOpen( const char* filename )
+ stream->_ffmpeg->codecpar->sample_rate, channel_layout,
+ stream->_ffmpeg->codecpar->format, stream->_ffmpeg->codecpar->sample_rate,
+ 0, NULL);
++#endif
+
+- if (!stream->swr_context || swr_init(stream->swr_context) < 0) {
++ if (rv < 0 || !stream->swr_context || swr_init(stream->swr_context) < 0) {
+ free(stream);
+ SDL_ffmpegSetError("could not initialize resampler");
+ continue;
+@@ -648,7 +662,11 @@ int SDL_ffmpegAddAudioFrame( SDL_ffmpegFile *file, SDL_ffmpegAudioFrame *frame,
+
+ // convert
+ int32_t write_bps = av_get_bytes_per_sample(acodec->sample_fmt);
++#if USE_NEW_AV_FIFO_API
++ int32_t read_samples = frame->size / (av_get_bytes_per_sample(file->audioStream->audioFormat) * acodec->ch_layout.nb_channels);
++#else
+ int32_t read_samples = frame->size / (av_get_bytes_per_sample(file->audioStream->audioFormat) * acodec->channels);
++#endif
+ int32_t write_samples = read_samples;
+ if (read_samples < acodec->frame_size)
+ {
+@@ -665,9 +683,14 @@ int SDL_ffmpegAddAudioFrame( SDL_ffmpegFile *file, SDL_ffmpegAudioFrame *frame,
+ av_frame_unref(audio_frame);
+
+ //Needed since ffmpeg 4.4
++#if USE_NEW_AV_FIFO_API
++ audio_frame->ch_layout.nb_channels = acodec->ch_layout.nb_channels;
++ audio_frame->ch_layout.u.mask = acodec->ch_layout.u.mask;
++#else
+ audio_frame->channels = acodec->channels;
+- audio_frame->format = acodec->sample_fmt;
+ audio_frame->channel_layout = acodec->channel_layout;
++#endif
++ audio_frame->format = acodec->sample_fmt;
+ audio_frame->sample_rate = acodec->sample_rate;
+ audio_frame->nb_samples = write_samples;
+
+@@ -675,10 +698,17 @@ int SDL_ffmpegAddAudioFrame( SDL_ffmpegFile *file, SDL_ffmpegAudioFrame *frame,
+ audio_frame->pts = av_rescale_q(*frameCounter, avSampleRate, acodec->time_base);
+
+ *frameCounter += write_samples;
++#if USE_NEW_AV_FIFO_API
++ int asize = avcodec_fill_audio_frame(audio_frame, acodec->ch_layout.nb_channels,
++ acodec->sample_fmt,
++ frame->conversionBuffer[0],
++ write_samples * write_bps * acodec->ch_layout.nb_channels, 1);
++#else
+ int asize = avcodec_fill_audio_frame(audio_frame, acodec->channels,
+ acodec->sample_fmt,
+ frame->conversionBuffer[0],
+ write_samples * write_bps * acodec->channels, 1);
++#endif
+
+ if (asize >= 0)
+ {
+@@ -762,10 +792,18 @@ SDL_ffmpegAudioFrame* SDL_ffmpegCreateAudioFrame( SDL_ffmpegFile *file, uint32_t
+
+ if ( file->type == SDL_ffmpegOutputStream )
+ {
++#if USE_NEW_AV_FIFO_API
++ bytes = file->audioStream->encodeAudioInputSize * av_get_bytes_per_sample(file->audioStream->audioFormat) * file->audioStream->_ctx->ch_layout.nb_channels;
++#else
+ bytes = file->audioStream->encodeAudioInputSize * av_get_bytes_per_sample(file->audioStream->audioFormat) * file->audioStream->_ctx->channels;
++#endif
+
+ // allocate conversion buffer only when output, input does it differently
++#if USE_NEW_AV_FIFO_API
++ if (av_samples_alloc_array_and_samples(&frame->conversionBuffer, NULL, file->audioStream->_ctx->ch_layout.nb_channels, file->audioStream->encodeAudioInputSize, file->audioStream->_ctx->sample_fmt, 0) < 0)
++#else
+ if (av_samples_alloc_array_and_samples(&frame->conversionBuffer, NULL, file->audioStream->_ctx->channels, file->audioStream->encodeAudioInputSize, file->audioStream->_ctx->sample_fmt, 0) < 0)
++#endif
+ {
+ return 0;
+ }
+@@ -1355,7 +1393,11 @@ SDL_AudioSpec SDL_ffmpegGetAudioSpec( SDL_ffmpegFile *file, uint16_t samples, SD
+ spec.userdata = file;
+ spec.callback = callback;
+ spec.freq = file->audioStream->_ctx->sample_rate;
++#if USE_NEW_AV_FIFO_API
++ spec.channels = ( uint8_t )file->audioStream->_ctx->ch_layout.nb_channels;
++#else
+ spec.channels = ( uint8_t )file->audioStream->_ctx->channels;
++#endif
+ }
+ else
+ {
+@@ -1687,8 +1729,13 @@ SDL_ffmpegStream* SDL_ffmpegAddAudioStream( SDL_ffmpegFile *file, SDL_ffmpegCode
+ stream->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
+ stream->codecpar->sample_rate = codec.sampleRate;
+ stream->codecpar->format = AV_SAMPLE_FMT_FLTP;
++#if USE_NEW_AV_FIFO_API
++ stream->codecpar->ch_layout.nb_channels = codec.channels;
++ stream->codecpar->ch_layout.u.mask = codec.channels == 2 ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO;
++#else
+ stream->codecpar->channels = codec.channels;
+ stream->codecpar->channel_layout = codec.channels == 2 ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO;
++#endif
+
+ if (avcodec_parameters_to_context(context, stream->codecpar) < 0)
+ {
+@@ -1721,6 +1768,11 @@ SDL_ffmpegStream* SDL_ffmpegAddAudioStream( SDL_ffmpegFile *file, SDL_ffmpegCode
+
+ if ( str )
+ {
++#if USE_NEW_AV_FIFO_API
++ AVChannelLayout in_layout, out_layout;
++#endif
++ int rv = 0;
++
+ /* we set our stream to zero */
+ memset( str, 0, sizeof( SDL_ffmpegStream ) );
+
+@@ -1734,10 +1786,16 @@ SDL_ffmpegStream* SDL_ffmpegAddAudioStream( SDL_ffmpegFile *file, SDL_ffmpegCode
+ str->audioFormat = codec.audioFormat;
+
+ // init resampler
++#if USE_NEW_AV_FIFO_API
++ in_layout = out_layout = context->ch_layout;
++ rv = swr_alloc_set_opts2(&str->swr_context, &out_layout, context->sample_fmt, context->sample_rate,
++ &in_layout, str->audioFormat, context->sample_rate, 0, NULL);
++#else
+ str->swr_context = swr_alloc_set_opts(str->swr_context, context->channel_layout, context->sample_fmt, context->sample_rate,
+ context->channel_layout, str->audioFormat, context->sample_rate, 0, NULL);
++#endif
+
+- if (!str->swr_context || swr_init(str->swr_context) < 0)
++ if (rv < 0 || !str->swr_context || swr_init(str->swr_context) < 0)
+ {
+ SDL_ffmpegSetError("could not initialize resampler");
+ return 0;
+@@ -1745,9 +1803,15 @@ SDL_ffmpegStream* SDL_ffmpegAddAudioStream( SDL_ffmpegFile *file, SDL_ffmpegCode
+
+ str->mutex = SDL_CreateMutex();
+
++#if USE_NEW_AV_FIFO_API
++ str->sampleBufferSize = av_samples_get_buffer_size(0, stream->codecpar->ch_layout.nb_channels, stream->codecpar->frame_size, AV_SAMPLE_FMT_FLT, 0);
++
++ if (av_samples_alloc((uint8_t**)(&str->sampleBuffer), 0, stream->codecpar->ch_layout.nb_channels, stream->codecpar->frame_size, AV_SAMPLE_FMT_FLT, 0) < 0)
++#else
+ str->sampleBufferSize = av_samples_get_buffer_size(0, stream->codecpar->channels, stream->codecpar->frame_size, AV_SAMPLE_FMT_FLT, 0);
+
+ if (av_samples_alloc((uint8_t**)(&str->sampleBuffer), 0, stream->codecpar->channels, stream->codecpar->frame_size, AV_SAMPLE_FMT_FLT, 0) < 0)
++#endif
+ {
+ SDL_ffmpegSetError("could not allocate samples for audio buffer");
+ return 0;
+@@ -1757,7 +1821,11 @@ SDL_ffmpegStream* SDL_ffmpegAddAudioStream( SDL_ffmpegFile *file, SDL_ffmpegCode
+ support to compute the input frame size in samples */
+ if ( stream->codecpar->frame_size <= 1 )
+ {
++#if USE_NEW_AV_FIFO_API
++ str->encodeAudioInputSize = str->sampleBufferSize / stream->codecpar->ch_layout.nb_channels;
++#else
+ str->encodeAudioInputSize = str->sampleBufferSize / stream->codecpar->channels;
++#endif
+
+ switch ( stream->codecpar->codec_id )
+ {
+@@ -1946,7 +2014,11 @@ int SDL_ffmpegDecodeAudioFrame( SDL_ffmpegFile *file, AVPacket *pack, SDL_ffmpeg
+ {
+ int audioSize = AVCODEC_MAX_AUDIO_FRAME_SIZE * sizeof( float );
+
++#if USE_NEW_AV_FIFO_API
++ int channels = file->audioStream->_ctx->ch_layout.nb_channels;
++#else
+ int channels = file->audioStream->_ctx->channels;
++#endif
+ enum AVSampleFormat format = AV_SAMPLE_FMT_FLT;
+ int bps = av_get_bytes_per_sample(format);
+
+@@ -2020,10 +2092,14 @@ int SDL_ffmpegDecodeAudioFrame( SDL_ffmpegFile *file, AVPacket *pack, SDL_ffmpeg
+ AVFrame* convertedFrame = file->audioStream->encodeFrame;
+
+ while (avcodec_receive_frame(avctx, dframe) == 0) {
+-
++#if USE_NEW_AV_FIFO_API
++ dframe->ch_layout.u.mask |= dframe->ch_layout.nb_channels == 2 ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO;
++ convertedFrame->ch_layout.u.mask = dframe->ch_layout.u.mask;
++#else
+ dframe->channel_layout |= dframe->channels == 2 ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO;
+- convertedFrame->nb_samples = dframe->nb_samples;
+ convertedFrame->channel_layout = dframe->channel_layout;
++#endif
++ convertedFrame->nb_samples = dframe->nb_samples;
+ convertedFrame->sample_rate = dframe->sample_rate;
+ convertedFrame->format = AV_SAMPLE_FMT_FLT;
+
+@@ -2036,15 +2112,27 @@ int SDL_ffmpegDecodeAudioFrame( SDL_ffmpegFile *file, AVPacket *pack, SDL_ffmpeg
+ int planar = av_sample_fmt_is_planar(convertedFrame->format);
+ int plane_size;
+
++#if USE_NEW_AV_FIFO_API
++ int data_size = av_samples_get_buffer_size(&plane_size, convertedFrame->ch_layout.nb_channels, convertedFrame->nb_samples, convertedFrame->format, 1);
++#else
+ int data_size = av_samples_get_buffer_size(&plane_size, convertedFrame->channels, convertedFrame->nb_samples, convertedFrame->format, 1);
++#endif
+
+ memcpy(file->audioStream->sampleBuffer, convertedFrame->extended_data[0], plane_size);
+ audioSize = plane_size;
++#if USE_NEW_AV_FIFO_API
++ if (planar && convertedFrame->ch_layout.nb_channels > 1)
++#else
+ if (planar && convertedFrame->channels > 1)
++#endif
+ {
+ int8_t* out = file->audioStream->sampleBuffer + plane_size;
+ int ch;
++#if USE_NEW_AV_FIFO_API
++ for (ch = 1; ch < convertedFrame->ch_layout.nb_channels; ch++)
++#else
+ for (ch = 1; ch < convertedFrame->channels; ch++)
++#endif
+ {
+ memcpy(out, convertedFrame->extended_data[ch], plane_size);
+ out += plane_size;
+diff --git a/Source_Files/FFmpeg/SDL_ffmpeg.h b/Source_Files/FFmpeg/SDL_ffmpeg.h
+index 26d5c92b..253e48a5 100644
+--- a/Source_Files/FFmpeg/SDL_ffmpeg.h
++++ b/Source_Files/FFmpeg/SDL_ffmpeg.h
+@@ -40,6 +40,14 @@ extern "C" {
+ #define EXPORT
+ // #endif
+
++// The avutil FIFO API underwent major changes in version 57.20.100
++// (cf. https://git.videolan.org/?p=ffmpeg.git;a=blob_plain;f=doc/APIchanges;hb=n7.0 )
++#include <libavutil/version.h>
++#if LIBAVUTIL_VERSION_MAJOR > 57 || LIBAVUTIL_VERSION_MAJOR == 57 && LIBAVUTIL_VERSION_MINOR >= 20
++ #define USE_NEW_AV_FIFO_API 1
++ #define AV_FIFO_CHUNK_SIZE 4
++#endif
++
+ enum SDL_ffmpegStreamType
+ {
+ SDL_ffmpegUninitialized = 0,
+diff --git a/Source_Files/Sound/FFmpegDecoder.cpp b/Source_Files/Sound/FFmpegDecoder.cpp
+index a166155b..a97c405b 100644
+--- a/Source_Files/Sound/FFmpegDecoder.cpp
++++ b/Source_Files/Sound/FFmpegDecoder.cpp
+@@ -50,10 +50,16 @@ extern "C"
+ }
+ #endif
+
++#define AV_FIFO_BUFFER_SIZE (1<<19)
++
+ struct ffmpeg_vars {
+ SDL_ffmpegFile* file;
+ SDL_ffmpegAudioFrame* frame;
++#if USE_NEW_AV_FIFO_API
++ AVFifo *fifo;
++#else
+ AVFifoBuffer *fifo;
++#endif
+ bool started;
+ };
+ typedef struct ffmpeg_vars ffmpeg_vars_t;
+@@ -64,14 +70,22 @@ FFmpegDecoder::FFmpegDecoder() :
+ av = new ffmpeg_vars_t;
+ memset(av, 0, sizeof(ffmpeg_vars_t));
+
+- av->fifo = av_fifo_alloc(524288);
++#if USE_NEW_AV_FIFO_API
++ av->fifo = av_fifo_alloc2(AV_FIFO_BUFFER_SIZE / AV_FIFO_CHUNK_SIZE, AV_FIFO_CHUNK_SIZE, 0);
++#else
++ av->fifo = av_fifo_alloc(AV_FIFO_BUFFER_SIZE);
++#endif
+ }
+
+ FFmpegDecoder::~FFmpegDecoder()
+ {
+ Close();
+ if (av && av->fifo)
++#if USE_NEW_AV_FIFO_API
++ av_fifo_freep2(&av->fifo);
++#else
+ av_fifo_free(av->fifo);
++#endif
+ }
+
+ bool FFmpegDecoder::Open(FileSpecifier& File)
+@@ -99,30 +113,47 @@ bool FFmpegDecoder::Open(FileSpecifier& File)
+ return false;
+ }
+
++#if USE_NEW_AV_FIFO_API
++ channels = av->file->audioStream->_ffmpeg->codecpar->ch_layout.nb_channels;
++#else
+ channels = av->file->audioStream->_ffmpeg->codecpar->channels;
++#endif
+ rate = av->file->audioStream->_ffmpeg->codecpar->sample_rate;
+ return true;
+ }
+
+ int32 FFmpegDecoder::Decode(uint8* buffer, int32 max_length)
+ {
+- int32 total_bytes_read = 0;
+- uint8* cur = buffer;
++ size_t total_bytes_read = 0;
++
+ while (total_bytes_read < max_length)
+ {
++#if USE_NEW_AV_FIFO_API
++ size_t fifo_chunks_waiting = av_fifo_can_read(av->fifo);
++ if (!fifo_chunks_waiting)
++ {
++ if (!GetAudio())
++ break;
++ fifo_chunks_waiting = av_fifo_can_read(av->fifo);
++ }
++ size_t chunks_to_read = std::min(fifo_chunks_waiting * AV_FIFO_CHUNK_SIZE, (max_length - total_bytes_read + AV_FIFO_CHUNK_SIZE - 1) / AV_FIFO_CHUNK_SIZE);
++ if (!chunks_to_read || av_fifo_read(av->fifo, buffer + total_bytes_read, chunks_to_read) < 0)
++ break;
++ total_bytes_read += chunks_to_read * AV_FIFO_CHUNK_SIZE;
++#else
+ int32 fifo_size = av_fifo_size(av->fifo);
+ if (!fifo_size)
+ {
+ if (!GetAudio())
+ break;
+ fifo_size = av_fifo_size(av->fifo);
+- }
+- int bytes_read = std::min(fifo_size, max_length - total_bytes_read);
+- av_fifo_generic_read(av->fifo, cur, bytes_read, NULL);
++ }
++ int bytes_read = std::min(fifo_size, max_length - (int) total_bytes_read);
++ av_fifo_generic_read(av->fifo, buffer + total_bytes_read, bytes_read, NULL);
+ total_bytes_read += bytes_read;
+- cur += bytes_read;
++#endif
+ }
+-
++
+ memset(&buffer[total_bytes_read], 0, max_length - total_bytes_read);
+ return total_bytes_read;
+ }
+@@ -132,7 +163,11 @@ void FFmpegDecoder::Rewind()
+ if (av->started)
+ {
+ SDL_ffmpegSeekRelative(av->file, 0);
++#if USE_NEW_AV_FIFO_API
++ av_fifo_reset2(av->fifo);
++#else
+ av_fifo_reset(av->fifo);
++#endif
+ av->started = false;
+ }
+ }
+@@ -144,15 +179,32 @@ void FFmpegDecoder::Close()
+ if (av && av->frame)
+ SDL_ffmpegFreeAudioFrame(av->frame);
+ if (av && av->fifo)
++#if USE_NEW_AV_FIFO_API
++ av_fifo_reset2(av->fifo);
++#else
+ av_fifo_reset(av->fifo);
++#endif
+ if (av)
+ av->started = false;
+ }
+
+ bool FFmpegDecoder::GetAudio()
+ {
+- if (!SDL_ffmpegGetAudioFrame(av->file, av->frame)) return false;
++ if (!SDL_ffmpegGetAudioFrame(av->file, av->frame))
++ return false;
++#if USE_NEW_AV_FIFO_API
++ for (size_t bytes_written = 0; bytes_written < av->frame->size; )
++ {
++ size_t free_chunks_in_fifo = av_fifo_can_write(av->fifo);
++ size_t chunks_to_write = std::min((av->frame->size - bytes_written + AV_FIFO_CHUNK_SIZE - 1) / AV_FIFO_CHUNK_SIZE, free_chunks_in_fifo);
++ if (!free_chunks_in_fifo || av_fifo_write(av->fifo, av->frame->buffer + bytes_written, chunks_to_write) < 0)
++ break;
++ bytes_written += chunks_to_write * AV_FIFO_CHUNK_SIZE;
++ }
++#else
+ av_fifo_generic_write(av->fifo, av->frame->buffer, av->frame->size, NULL);
++#endif
++
+ av->started = true;
+ return true;
+ }