[xcode] Circumvent ffmpeg 6 ALAC encoding problem

The default ffmpeg ALAC encoder, "alac", requires fixed frames of size 4096,
but the Airplay 2 implementation feeds it with frames of size 352. Before
ffmpeg 6 this worked, but not any more. Seems a frame size check has been
added.

This commit doesn't fix this, but circumvents the ffmpeg error by modifying the
frame size that ffmpeg checks.

Fixes issue #1640
This commit is contained in:
ejurgensen 2023-08-17 23:09:41 +02:00
parent 7f2e05284b
commit 941fab9023

View File

@ -48,6 +48,7 @@
#define USE_CONST_AVCODEC (LIBAVFORMAT_VERSION_MAJOR > 59) || ((LIBAVFORMAT_VERSION_MAJOR == 59) && (LIBAVFORMAT_VERSION_MINOR > 15)) #define USE_CONST_AVCODEC (LIBAVFORMAT_VERSION_MAJOR > 59) || ((LIBAVFORMAT_VERSION_MAJOR == 59) && (LIBAVFORMAT_VERSION_MINOR > 15))
#define USE_NO_CLEAR_AVFMT_NOFILE (LIBAVFORMAT_VERSION_MAJOR > 59) || ((LIBAVFORMAT_VERSION_MAJOR == 59) && (LIBAVFORMAT_VERSION_MINOR > 15)) #define USE_NO_CLEAR_AVFMT_NOFILE (LIBAVFORMAT_VERSION_MAJOR > 59) || ((LIBAVFORMAT_VERSION_MAJOR == 59) && (LIBAVFORMAT_VERSION_MINOR > 15))
#define USE_CH_LAYOUT (LIBAVCODEC_VERSION_MAJOR > 59) || ((LIBAVCODEC_VERSION_MAJOR == 59) && (LIBAVCODEC_VERSION_MINOR > 24)) #define USE_CH_LAYOUT (LIBAVCODEC_VERSION_MAJOR > 59) || ((LIBAVCODEC_VERSION_MAJOR == 59) && (LIBAVCODEC_VERSION_MINOR > 24))
#define USE_ALAC_FRAME_SIZE_HACK (LIBAVCODEC_VERSION_MAJOR > 59) || ((LIBAVCODEC_VERSION_MAJOR == 59) && (LIBAVCODEC_VERSION_MINOR > 31))
// Interval between ICY metadata checks for streams, in seconds // Interval between ICY metadata checks for streams, in seconds
#define METADATA_ICY_INTERVAL 5 #define METADATA_ICY_INTERVAL 5
@ -545,6 +546,16 @@ stream_add(struct encode_ctx *ctx, struct stream_ctx *s, enum AVCodecID codec_id
goto error; goto error;
} }
// airplay.c "misuses" the ffmpeg alac encoder in that it pushes frames with
// 352 samples even though the encoder wants 4096 (and doesn't have variable
// frame capability). This worked with no issues until ffmpeg 6, where it
// seems a frame size check was added. The below circumvents the check, but is
// dirty because we shouldn't be writing to this data element.
#if USE_ALAC_FRAME_SIZE_HACK
if (codec_id == AV_CODEC_ID_ALAC)
s->codec->frame_size = 352;
#endif
// Copy the codec parameters we just set to the stream, so the muxer knows them // Copy the codec parameters we just set to the stream, so the muxer knows them
ret = avcodec_parameters_from_context(s->stream->codecpar, s->codec); ret = avcodec_parameters_from_context(s->stream->codecpar, s->codec);
if (ret < 0) if (ret < 0)