[xcode] Align how ffmpeg API checks are done

This commit is contained in:
ejurgensen 2022-10-22 16:35:01 +02:00
parent 4ff850cd3d
commit 684f55f603
3 changed files with 30 additions and 28 deletions

View File

@ -240,12 +240,6 @@ OWNTONE_MODULES_CHECK([OWNTONE], [LIBAV],
[libavformat/avformat.h]) [libavformat/avformat.h])
]) ])
AS_IF([test "$is_ffmpeg" = "yes"],
[PKG_CHECK_EXISTS([libavcodec >= 59.24.100],
[AC_DEFINE([HAVE_FFMPEG_CH_LAYOUT], 1,
[Define to 1 if ffmpeg-libavcodec defines new 5.1.x ch_layout])])]
)
AC_CHECK_SIZEOF([void *]) AC_CHECK_SIZEOF([void *])
dnl --- Begin configuring the options --- dnl --- Begin configuring the options ---

View File

@ -452,7 +452,8 @@ scan_metadata_ffmpeg(struct media_file_info *mfi, const char *file)
codec_id = ctx->streams[i]->codecpar->codec_id; codec_id = ctx->streams[i]->codecpar->codec_id;
sample_rate = ctx->streams[i]->codecpar->sample_rate; sample_rate = ctx->streams[i]->codecpar->sample_rate;
sample_fmt = ctx->streams[i]->codecpar->format; sample_fmt = ctx->streams[i]->codecpar->format;
#ifdef HAVE_FFMPEG_CH_LAYOUT // Matches USE_CH_LAYOUT in transcode.c
#if (LIBAVCODEC_VERSION_MAJOR > 59) || ((LIBAVCODEC_VERSION_MAJOR == 59) && (LIBAVCODEC_VERSION_MINOR > 24))
channels = ctx->streams[i]->codecpar->ch_layout.nb_channels; channels = ctx->streams[i]->codecpar->ch_layout.nb_channels;
#else #else
channels = ctx->streams[i]->codecpar->channels; channels = ctx->streams[i]->codecpar->channels;

View File

@ -42,6 +42,13 @@
#include "misc.h" #include "misc.h"
#include "transcode.h" #include "transcode.h"
// Switches for compability with ffmpeg's ever changing API
#define USE_IMAGE2PIPE (LIBAVFORMAT_VERSION_MAJOR > 58) || ((LIBAVFORMAT_VERSION_MAJOR == 58) && (LIBAVFORMAT_VERSION_MINOR > 29))
#define USE_CONST_AVFORMAT (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_CH_LAYOUT (LIBAVCODEC_VERSION_MAJOR > 59) || ((LIBAVCODEC_VERSION_MAJOR == 59) && (LIBAVCODEC_VERSION_MINOR > 24))
// 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
// Maximum number of streams in a file that we will accept // Maximum number of streams in a file that we will accept
@ -80,7 +87,7 @@ struct settings_ctx
// Audio settings // Audio settings
enum AVCodecID audio_codec; enum AVCodecID audio_codec;
int sample_rate; int sample_rate;
#ifdef HAVE_FFMPEG_CH_LAYOUT #if USE_CH_LAYOUT
AVChannelLayout channel_layout; AVChannelLayout channel_layout;
#else #else
uint64_t channel_layout; uint64_t channel_layout;
@ -268,7 +275,7 @@ init_settings(struct settings_ctx *settings, enum transcode_profile profile, str
// With ffmpeg 4.3 (> libavformet 58.29) "image2" only works for actual file // With ffmpeg 4.3 (> libavformet 58.29) "image2" only works for actual file
// output. It's possible we should have used "image2pipe" all along, but since // output. It's possible we should have used "image2pipe" all along, but since
// "image2" has been working we only replace it going forward. // "image2" has been working we only replace it going forward.
#if (LIBAVFORMAT_VERSION_MAJOR > 58) || ((LIBAVFORMAT_VERSION_MAJOR == 58) && (LIBAVFORMAT_VERSION_MINOR > 29)) #if USE_IMAGE2PIPE
settings->format = "image2pipe"; settings->format = "image2pipe";
#else #else
settings->format = "image2"; settings->format = "image2";
@ -283,7 +290,7 @@ init_settings(struct settings_ctx *settings, enum transcode_profile profile, str
settings->encode_video = 1; settings->encode_video = 1;
settings->silent = 1; settings->silent = 1;
// See explanation above // See explanation above
#if (LIBAVFORMAT_VERSION_MAJOR > 58) || ((LIBAVFORMAT_VERSION_MAJOR == 58) && (LIBAVFORMAT_VERSION_MINOR > 29)) #if USE_IMAGE2PIPE
settings->format = "image2pipe"; settings->format = "image2pipe";
#else #else
settings->format = "image2"; settings->format = "image2";
@ -296,7 +303,7 @@ init_settings(struct settings_ctx *settings, enum transcode_profile profile, str
settings->encode_video = 1; settings->encode_video = 1;
settings->silent = 1; settings->silent = 1;
// See explanation above // See explanation above
#if (LIBAVFORMAT_VERSION_MAJOR > 58) || ((LIBAVFORMAT_VERSION_MAJOR == 58) && (LIBAVFORMAT_VERSION_MINOR > 29)) #if USE_IMAGE2PIPE
settings->format = "image2pipe"; settings->format = "image2pipe";
#else #else
settings->format = "image2"; settings->format = "image2";
@ -317,7 +324,7 @@ init_settings(struct settings_ctx *settings, enum transcode_profile profile, str
if (quality && quality->channels) if (quality && quality->channels)
{ {
#ifdef HAVE_FFMPEG_CH_LAYOUT #if USE_CH_LAYOUT
av_channel_layout_default(&settings->channel_layout, quality->channels); av_channel_layout_default(&settings->channel_layout, quality->channels);
#else #else
settings->channel_layout = av_get_default_channel_layout(quality->channels); settings->channel_layout = av_get_default_channel_layout(quality->channels);
@ -345,7 +352,7 @@ stream_settings_set(struct stream_ctx *s, struct settings_ctx *settings, enum AV
if (type == AVMEDIA_TYPE_AUDIO) if (type == AVMEDIA_TYPE_AUDIO)
{ {
s->codec->sample_rate = settings->sample_rate; s->codec->sample_rate = settings->sample_rate;
#ifdef HAVE_FFMPEG_CH_LAYOUT #if USE_CH_LAYOUT
av_channel_layout_copy(&s->codec->ch_layout, &(settings->channel_layout)); av_channel_layout_copy(&s->codec->ch_layout, &(settings->channel_layout));
#else #else
s->codec->channel_layout = settings->channel_layout; s->codec->channel_layout = settings->channel_layout;
@ -464,7 +471,7 @@ static int
stream_add(struct encode_ctx *ctx, struct stream_ctx *s, enum AVCodecID codec_id) stream_add(struct encode_ctx *ctx, struct stream_ctx *s, enum AVCodecID codec_id)
{ {
const AVCodecDescriptor *codec_desc; const AVCodecDescriptor *codec_desc;
#if (LIBAVFORMAT_VERSION_MAJOR > 59) || ((LIBAVFORMAT_VERSION_MAJOR == 59) && (LIBAVFORMAT_VERSION_MINOR > 15)) #if USE_CONST_AVCODEC
const AVCodec *encoder; const AVCodec *encoder;
#else #else
// Not const before ffmpeg 5.0 // Not const before ffmpeg 5.0
@ -933,14 +940,14 @@ avio_evbuffer_close(AVIOContext *s)
static int static int
open_decoder(AVCodecContext **dec_ctx, unsigned int *stream_index, struct decode_ctx *ctx, enum AVMediaType type) open_decoder(AVCodecContext **dec_ctx, unsigned int *stream_index, struct decode_ctx *ctx, enum AVMediaType type)
{ {
#if (LIBAVFORMAT_VERSION_MAJOR > 59) || ((LIBAVFORMAT_VERSION_MAJOR == 59) && (LIBAVFORMAT_VERSION_MINOR > 15)) #if USE_CONST_AVCODEC
const AVCodec *decoder; const AVCodec *decoder;
#else #else
// Not const before ffmpeg 5.0 // Not const before ffmpeg 5.0
AVCodec *decoder; AVCodec *decoder;
#endif #endif
AVDictionary *options = NULL; AVDictionary *options = NULL;
#ifdef HAVE_FFMPEG_CH_LAYOUT #if USE_CH_LAYOUT
char downmix_layout[64]; char downmix_layout[64];
#endif #endif
int ret; int ret;
@ -971,7 +978,7 @@ open_decoder(AVCodecContext **dec_ctx, unsigned int *stream_index, struct decode
if (type == AVMEDIA_TYPE_AUDIO) if (type == AVMEDIA_TYPE_AUDIO)
{ {
(*dec_ctx)->request_sample_fmt = ctx->settings.sample_format; (*dec_ctx)->request_sample_fmt = ctx->settings.sample_format;
#ifdef HAVE_FFMPEG_CH_LAYOUT #if USE_CH_LAYOUT
// option types is a string - see AV_OPT_TYPE_CHLAYOUT handling in ffmpeg:libavutil/opt.c // option types is a string - see AV_OPT_TYPE_CHLAYOUT handling in ffmpeg:libavutil/opt.c
av_channel_layout_describe(&ctx->settings.channel_layout, downmix_layout, sizeof(downmix_layout)); av_channel_layout_describe(&ctx->settings.channel_layout, downmix_layout, sizeof(downmix_layout));
av_dict_set(&options, "downmix", downmix_layout, 0); av_dict_set(&options, "downmix", downmix_layout, 0);
@ -996,7 +1003,7 @@ open_input(struct decode_ctx *ctx, const char *path, struct transcode_evbuf_io *
{ {
AVDictionary *options = NULL; AVDictionary *options = NULL;
AVCodecContext *dec_ctx; AVCodecContext *dec_ctx;
#if (LIBAVFORMAT_VERSION_MAJOR > 59) || ((LIBAVFORMAT_VERSION_MAJOR == 59) && (LIBAVFORMAT_VERSION_MINOR > 15)) #if USE_CONST_AVFORMAT
const AVInputFormat *ifmt; const AVInputFormat *ifmt;
#else #else
// Not const before ffmpeg 5.0 // Not const before ffmpeg 5.0
@ -1121,7 +1128,7 @@ close_input(struct decode_ctx *ctx)
static int static int
open_output(struct encode_ctx *ctx, struct decode_ctx *src_ctx) open_output(struct encode_ctx *ctx, struct decode_ctx *src_ctx)
{ {
#if (LIBAVFORMAT_VERSION_MAJOR > 59) || ((LIBAVFORMAT_VERSION_MAJOR == 59) && (LIBAVFORMAT_VERSION_MINOR > 15)) #if USE_CONST_AVFORMAT
const AVOutputFormat *oformat; const AVOutputFormat *oformat;
#else #else
// Not const before ffmpeg 5.0 // Not const before ffmpeg 5.0
@ -1136,7 +1143,7 @@ open_output(struct encode_ctx *ctx, struct decode_ctx *src_ctx)
return -1; return -1;
} }
#if (LIBAVFORMAT_VERSION_MAJOR > 59) || ((LIBAVFORMAT_VERSION_MAJOR == 59) && (LIBAVFORMAT_VERSION_MINOR > 15)) #if USE_NO_CLEAR_AVFMT_NOFILE
CHECK_ERRNO(L_XCODE, avformat_alloc_output_context2(&ctx->ofmt_ctx, oformat, NULL, NULL)); CHECK_ERRNO(L_XCODE, avformat_alloc_output_context2(&ctx->ofmt_ctx, oformat, NULL, NULL));
#else #else
// Clear AVFMT_NOFILE bit, it is not allowed as we will set our own AVIOContext. // Clear AVFMT_NOFILE bit, it is not allowed as we will set our own AVIOContext.
@ -1229,7 +1236,7 @@ open_filter(struct stream_ctx *out_stream, struct stream_ctx *in_stream)
AVFilterContext *buffersink_ctx; AVFilterContext *buffersink_ctx;
AVFilterGraph *filter_graph; AVFilterGraph *filter_graph;
char args[512]; char args[512];
#ifdef HAVE_FFMPEG_CH_LAYOUT #if USE_CH_LAYOUT
char buf[64]; char buf[64];
#endif #endif
int ret; int ret;
@ -1247,7 +1254,7 @@ open_filter(struct stream_ctx *out_stream, struct stream_ctx *in_stream)
goto out_fail; goto out_fail;
} }
#ifdef HAVE_FFMPEG_CH_LAYOUT #if USE_CH_LAYOUT
// Some AIFF files only have a channel number, not a layout // Some AIFF files only have a channel number, not a layout
if (in_stream->codec->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC) if (in_stream->codec->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC)
av_channel_layout_default(&in_stream->codec->ch_layout, in_stream->codec->ch_layout.nb_channels); av_channel_layout_default(&in_stream->codec->ch_layout, in_stream->codec->ch_layout.nb_channels);
@ -1279,7 +1286,7 @@ open_filter(struct stream_ctx *out_stream, struct stream_ctx *in_stream)
DPRINTF(E_DBG, L_XCODE, "Created 'in' filter: %s\n", args); DPRINTF(E_DBG, L_XCODE, "Created 'in' filter: %s\n", args);
#ifdef HAVE_FFMPEG_CH_LAYOUT #if USE_CH_LAYOUT
if (out_stream->codec->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC) if (out_stream->codec->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC)
av_channel_layout_default(&out_stream->codec->ch_layout, out_stream->codec->ch_layout.nb_channels); av_channel_layout_default(&out_stream->codec->ch_layout, out_stream->codec->ch_layout.nb_channels);
@ -1528,7 +1535,7 @@ transcode_encode_setup(enum transcode_profile profile, struct media_quality *qua
} }
} }
#ifdef HAVE_FFMPEG_CH_LAYOUT #if USE_CH_LAYOUT
// Caller did not specify channels -> use same as source // Caller did not specify channels -> use same as source
if (!av_channel_layout_check(&ctx->settings.channel_layout) && ctx->settings.encode_audio) if (!av_channel_layout_check(&ctx->settings.channel_layout) && ctx->settings.encode_audio)
{ {
@ -1606,7 +1613,7 @@ transcode_decode_setup_raw(enum transcode_profile profile, struct media_quality
{ {
const AVCodecDescriptor *codec_desc; const AVCodecDescriptor *codec_desc;
struct decode_ctx *ctx; struct decode_ctx *ctx;
#if (LIBAVFORMAT_VERSION_MAJOR > 59) || ((LIBAVFORMAT_VERSION_MAJOR == 59) && (LIBAVFORMAT_VERSION_MINOR > 15)) #if USE_CONST_AVCODEC
const AVCodec *decoder; const AVCodec *decoder;
#else #else
// Not const before ffmpeg 5.0 // Not const before ffmpeg 5.0
@ -1835,7 +1842,7 @@ transcode_encode(struct evbuffer *evbuf, struct encode_ctx *ctx, transcode_frame
start_length = evbuffer_get_length(ctx->obuf); start_length = evbuffer_get_length(ctx->obuf);
// Really crappy way of detecting if frame is audio, video or something else // Really crappy way of detecting if frame is audio, video or something else
#ifdef HAVE_FFMPEG_CH_LAYOUT #if USE_CH_LAYOUT
if (f->ch_layout.nb_channels && f->sample_rate) if (f->ch_layout.nb_channels && f->sample_rate)
#else #else
if (f->channel_layout && f->sample_rate) if (f->channel_layout && f->sample_rate)
@ -1927,7 +1934,7 @@ transcode_frame_new(void *data, size_t size, int nsamples, struct media_quality
f->sample_rate = quality->sample_rate; f->sample_rate = quality->sample_rate;
f->nb_samples = nsamples; f->nb_samples = nsamples;
#ifdef HAVE_FFMPEG_CH_LAYOUT #if USE_CH_LAYOUT
av_channel_layout_default(&f->ch_layout, quality->channels); av_channel_layout_default(&f->ch_layout, quality->channels);
#else #else
f->channel_layout = av_get_default_channel_layout(quality->channels); f->channel_layout = av_get_default_channel_layout(quality->channels);
@ -2091,7 +2098,7 @@ transcode_encode_query(struct encode_ctx *ctx, const char *query)
else if (strcmp(query, "channels") == 0) else if (strcmp(query, "channels") == 0)
{ {
if (ctx->audio_stream.stream) if (ctx->audio_stream.stream)
#ifdef HAVE_FFMPEG_CH_LAYOUT #if USE_CH_LAYOUT
return ctx->audio_stream.stream->codecpar->ch_layout.nb_channels; return ctx->audio_stream.stream->codecpar->ch_layout.nb_channels;
#else #else
return ctx->audio_stream.stream->codecpar->channels; return ctx->audio_stream.stream->codecpar->channels;