Skip to content

Commit 5ccac34

Browse files
committed
rework FFmpeg macros
1 parent b10d36c commit 5ccac34

2 files changed

Lines changed: 47 additions & 25 deletions

File tree

src/torchcodec/_core/FFMPEGCommon.cpp

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,10 @@ std::string get_ffmpeg_error_string_from_error_code(int error_code) {
5555
}
5656

5757
int64_t get_duration(const AVFrame& av_frame) {
58-
#if LIBAVUTIL_VERSION_MAJOR < 58
59-
return av_frame.pkt_duration;
60-
#else
58+
#if FFMPEG_HAS_FRAME_DURATION
6159
return av_frame.duration;
60+
#else
61+
return av_frame.pkt_duration;
6262
#endif
6363
}
6464

@@ -76,16 +76,16 @@ int64_t get_pts_or_dts(const AVFrame& av_frame) {
7676
}
7777

7878
void set_duration(AVFrame& av_frame, int64_t duration) {
79-
#if LIBAVUTIL_VERSION_MAJOR < 58
80-
av_frame.pkt_duration = duration;
81-
#else
79+
#if FFMPEG_HAS_FRAME_DURATION
8280
av_frame.duration = duration;
81+
#else
82+
av_frame.pkt_duration = duration;
8383
#endif
8484
}
8585

8686
const int* get_supported_sample_rates(const AVCodec& av_codec) {
8787
const int* supported_sample_rates = nullptr;
88-
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 13, 100) // FFmpeg >= 7.1
88+
#if FFMPEG_HAS_SUPPORTED_CONFIG
8989
int num_sample_rates = 0;
9090
int ret = avcodec_get_supported_config(
9191
nullptr,
@@ -106,7 +106,7 @@ const int* get_supported_sample_rates(const AVCodec& av_codec) {
106106

107107
const AVPixelFormat* get_supported_pixel_formats(const AVCodec& av_codec) {
108108
const AVPixelFormat* supported_pixel_formats = nullptr;
109-
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 13, 100) // FFmpeg >= 7.1
109+
#if FFMPEG_HAS_SUPPORTED_CONFIG
110110
int num_pixel_formats = 0;
111111
int ret = avcodec_get_supported_config(
112112
nullptr,
@@ -128,7 +128,7 @@ const AVPixelFormat* get_supported_pixel_formats(const AVCodec& av_codec) {
128128
const AVSampleFormat* get_supported_output_sample_formats(
129129
const AVCodec& av_codec) {
130130
const AVSampleFormat* supported_sample_formats = nullptr;
131-
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 13, 100) // FFmpeg >= 7.1
131+
#if FFMPEG_HAS_SUPPORTED_CONFIG
132132
int num_sample_formats = 0;
133133
int ret = avcodec_get_supported_config(
134134
nullptr,
@@ -148,9 +148,7 @@ const AVSampleFormat* get_supported_output_sample_formats(
148148
return supported_sample_formats;
149149
}
150150

151-
#if !( \
152-
LIBAVFILTER_VERSION_MAJOR > 8 || \
153-
(LIBAVFILTER_VERSION_MAJOR == 8 && LIBAVFILTER_VERSION_MINOR >= 44))
151+
#if !FFMPEG_HAS_CH_LAYOUT
154152
// FFmpeg 4 leaves channel_layout unset (0) on some decoded frames even though
155153
// .channels is correct. Everything we feed to swresample needs a real layout,
156154
// so fall back to the default layout for that channel count.
@@ -163,8 +161,7 @@ int64_t get_channel_layout(const AVFrame& av_frame) {
163161
#endif
164162

165163
int get_num_channels(const AVFrame& av_frame) {
166-
#if LIBAVFILTER_VERSION_MAJOR > 8 || \
167-
(LIBAVFILTER_VERSION_MAJOR == 8 && LIBAVFILTER_VERSION_MINOR >= 44)
164+
#if FFMPEG_HAS_CH_LAYOUT
168165
return av_frame.ch_layout.nb_channels;
169166
#else
170167
int num_channels = av_get_channel_layout_nb_channels(av_frame.channel_layout);
@@ -176,8 +173,7 @@ int get_num_channels(const AVFrame& av_frame) {
176173
}
177174

178175
int get_num_channels(const SharedAVCodecContext& av_codec_context) {
179-
#if LIBAVFILTER_VERSION_MAJOR > 8 || \
180-
(LIBAVFILTER_VERSION_MAJOR == 8 && LIBAVFILTER_VERSION_MINOR >= 44)
176+
#if FFMPEG_HAS_CH_LAYOUT
181177
return av_codec_context->ch_layout.nb_channels;
182178
#else
183179
return av_codec_context->channels;
@@ -186,8 +182,7 @@ int get_num_channels(const SharedAVCodecContext& av_codec_context) {
186182

187183
int get_num_channels(const AVCodecParameters* codecpar) {
188184
STD_TORCH_CHECK(codecpar != nullptr, "codecpar is null");
189-
#if LIBAVFILTER_VERSION_MAJOR > 8 || \
190-
(LIBAVFILTER_VERSION_MAJOR == 8 && LIBAVFILTER_VERSION_MINOR >= 44)
185+
#if FFMPEG_HAS_CH_LAYOUT
191186
return codecpar->ch_layout.nb_channels;
192187
#else
193188
return codecpar->channels;
@@ -197,7 +192,7 @@ int get_num_channels(const AVCodecParameters* codecpar) {
197192
void set_default_channel_layout(
198193
UniqueAVCodecContext& av_codec_context,
199194
int num_channels) {
200-
#if LIBAVFILTER_VERSION_MAJOR > 7 // FFmpeg > 4
195+
#if FFMPEG_HAS_CH_LAYOUT
201196
AVChannelLayout channel_layout;
202197
av_channel_layout_default(&channel_layout, num_channels);
203198
av_codec_context->ch_layout = channel_layout;
@@ -209,7 +204,7 @@ void set_default_channel_layout(
209204
}
210205

211206
void set_default_channel_layout(AVFrame& av_frame, int num_channels) {
212-
#if LIBAVFILTER_VERSION_MAJOR > 7 // FFmpeg > 4
207+
#if FFMPEG_HAS_CH_LAYOUT
213208
AVChannelLayout channel_layout;
214209
av_channel_layout_default(&channel_layout, num_channels);
215210
av_frame.ch_layout = channel_layout;
@@ -221,7 +216,7 @@ void set_default_channel_layout(AVFrame& av_frame, int num_channels) {
221216
}
222217

223218
void validate_num_channels(const AVCodec& av_codec, int num_channels) {
224-
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 13, 100) // FFmpeg >= 7.1
219+
#if FFMPEG_HAS_SUPPORTED_CONFIG
225220
std::stringstream supported_num_channels;
226221
const AVChannelLayout* supported_layouts = nullptr;
227222
int num_layouts = 0;
@@ -246,7 +241,7 @@ void validate_num_channels(const AVCodec& av_codec, int num_channels) {
246241
return;
247242
}
248243
}
249-
#elif LIBAVFILTER_VERSION_MAJOR > 7 // FFmpeg > 4
244+
#elif FFMPEG_HAS_CH_LAYOUT
250245
if (av_codec.ch_layouts == nullptr) {
251246
// If we can't validate, we must assume it'll be fine. If not, FFmpeg will
252247
// eventually raise.
@@ -301,7 +296,7 @@ void validate_num_channels(const AVCodec& av_codec, int num_channels) {
301296
}
302297

303298
namespace {
304-
#if LIBAVFILTER_VERSION_MAJOR > 7 // FFmpeg > 4
299+
#if FFMPEG_HAS_CH_LAYOUT
305300

306301
// Returns:
307302
// - the src_av_frame's channel layout if src_av_frame has out_num_channels
@@ -341,7 +336,7 @@ void set_channel_layout(
341336
AVFrame& dst_av_frame,
342337
const AVFrame& src_av_frame,
343338
int out_num_channels) {
344-
#if LIBAVFILTER_VERSION_MAJOR > 7 // FFmpeg > 4
339+
#if FFMPEG_HAS_CH_LAYOUT
345340
AVChannelLayout out_layout =
346341
get_output_channel_layout(out_num_channels, src_av_frame);
347342
auto status = av_channel_layout_copy(&dst_av_frame.ch_layout, &out_layout);
@@ -392,7 +387,7 @@ SwrContext* create_swr_context(
392387
int out_num_channels) {
393388
SwrContext* swr_context = nullptr;
394389
int status = AVSUCCESS;
395-
#if LIBAVFILTER_VERSION_MAJOR > 7 // FFmpeg > 4
390+
#if FFMPEG_HAS_CH_LAYOUT
396391
AVChannelLayout out_layout =
397392
get_output_channel_layout(out_num_channels, src_av_frame);
398393
status = swr_alloc_set_opts2(

src/torchcodec/_core/FFMPEGCommon.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,33 @@ extern "C" {
3131
#include <libswscale/swscale.h>
3232
}
3333

34+
// FFmpeg 5.1 replaced the .channels + .channel_layout pair on AVFrame and
35+
// AVCodecContext with a single AVChannelLayout .ch_layout, and added the
36+
// av_channel_layout_* / swr_alloc_set_opts2() APIs that go with it.
37+
// libavutil 57.24 is the real marker, but libavfilter 8.44 is the equivalent
38+
// and is what this codebase has always tested against.
39+
#if LIBAVFILTER_VERSION_MAJOR > 8 || \
40+
(LIBAVFILTER_VERSION_MAJOR == 8 && LIBAVFILTER_VERSION_MINOR >= 44)
41+
#define FFMPEG_HAS_CH_LAYOUT 1
42+
#else
43+
#define FFMPEG_HAS_CH_LAYOUT 0
44+
#endif
45+
46+
// FFmpeg 7.1 added avcodec_get_supported_config(), replacing the codec's
47+
// pix_fmts / sample_fmts / supported_samplerates / ch_layouts arrays.
48+
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 13, 100)
49+
#define FFMPEG_HAS_SUPPORTED_CONFIG 1
50+
#else
51+
#define FFMPEG_HAS_SUPPORTED_CONFIG 0
52+
#endif
53+
54+
// FFmpeg 6 renamed AVFrame.pkt_duration to AVFrame.duration.
55+
#if LIBAVUTIL_VERSION_MAJOR < 58
56+
#define FFMPEG_HAS_FRAME_DURATION 0
57+
#else
58+
#define FFMPEG_HAS_FRAME_DURATION 1
59+
#endif
60+
3461
namespace facebook::torchcodec {
3562

3663
// FFMPEG uses special delete functions for some structures. These template

0 commit comments

Comments
 (0)