|
|
@@ -0,0 +1,481 @@
|
|
|
+#pragma once
|
|
|
+
|
|
|
+/**
|
|
|
+ * FFmpeg Version Compatibility Header
|
|
|
+ * This file provides compatibility macros and functions for different FFmpeg versions
|
|
|
+ * Supports FFmpeg 3.x, 4.x, 5.x, 6.x, and 7.x
|
|
|
+ */
|
|
|
+
|
|
|
+extern "C" {
|
|
|
+#include <libavcodec/avcodec.h>
|
|
|
+#include <libavformat/avformat.h>
|
|
|
+#include <libavdevice/avdevice.h>
|
|
|
+#include <libavutil/channel_layout.h>
|
|
|
+#include <libavcodec/bsf.h>
|
|
|
+}
|
|
|
+
|
|
|
+// FFmpeg version detection
|
|
|
+#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(58, 9, 100)
|
|
|
+ #define FFMPEG_VERSION_MAJOR 3
|
|
|
+#elif LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(59, 0, 100)
|
|
|
+ #define FFMPEG_VERSION_MAJOR 4
|
|
|
+#elif LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(60, 0, 100)
|
|
|
+ #define FFMPEG_VERSION_MAJOR 5
|
|
|
+#elif LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(61, 0, 100)
|
|
|
+ #define FFMPEG_VERSION_MAJOR 6
|
|
|
+#else
|
|
|
+ #define FFMPEG_VERSION_MAJOR 7
|
|
|
+#endif
|
|
|
+
|
|
|
+// Compatibility functions for deprecated functions
|
|
|
+inline void ffmpeg_register_all() {
|
|
|
+#if FFMPEG_VERSION_MAJOR < 4
|
|
|
+ av_register_all();
|
|
|
+#endif
|
|
|
+ // No-op in FFmpeg 4.0+
|
|
|
+}
|
|
|
+
|
|
|
+inline void ffmpeg_register_devices() {
|
|
|
+#if FFMPEG_VERSION_MAJOR < 4
|
|
|
+ avdevice_register_all();
|
|
|
+#endif
|
|
|
+ // No-op in FFmpeg 4.0+
|
|
|
+}
|
|
|
+
|
|
|
+// Compatibility for AVInputFormat/AVOutputFormat
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 4
|
|
|
+ using FFmpegInputFormat = const AVInputFormat;
|
|
|
+ using FFmpegOutputFormat = const AVOutputFormat;
|
|
|
+#else
|
|
|
+ using FFmpegInputFormat = AVInputFormat;
|
|
|
+ using FFmpegOutputFormat = AVOutputFormat;
|
|
|
+#endif
|
|
|
+
|
|
|
+// Compatibility for AVCodec pointer
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 7
|
|
|
+ using FFmpegCodec = const AVCodec;
|
|
|
+#else
|
|
|
+ using FFmpegCodec = AVCodec;
|
|
|
+#endif
|
|
|
+
|
|
|
+// Compatibility for av_err2str macro (C++ safe version)
|
|
|
+#ifdef __cplusplus
|
|
|
+#undef av_err2str
|
|
|
+#ifdef _MSC_VER
|
|
|
+#include <malloc.h>
|
|
|
+#define av_err2str(errnum) av_make_error_string((char*)_alloca(AV_ERROR_MAX_STRING_SIZE), AV_ERROR_MAX_STRING_SIZE, errnum)
|
|
|
+#else
|
|
|
+#define av_err2str(errnum) av_make_error_string((char*)__builtin_alloca(AV_ERROR_MAX_STRING_SIZE), AV_ERROR_MAX_STRING_SIZE, errnum)
|
|
|
+#endif
|
|
|
+#endif
|
|
|
+
|
|
|
+// Compatibility for bitstream filter context
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 6
|
|
|
+ using AVBitStreamFilterContext = AVBSFContext;
|
|
|
+#endif
|
|
|
+
|
|
|
+// Compatibility functions for codec context access
|
|
|
+inline AVMediaType ffmpeg_get_codec_type(AVStream* stream) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 4
|
|
|
+ return stream->codecpar->codec_type;
|
|
|
+#else
|
|
|
+ return stream->codec->codec_type;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+inline AVCodecID ffmpeg_get_codec_id(AVStream* stream) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 4
|
|
|
+ return stream->codecpar->codec_id;
|
|
|
+#else
|
|
|
+ return stream->codec->codec_id;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+inline int ffmpeg_get_codec_width(AVStream* stream) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 4
|
|
|
+ return stream->codecpar->width;
|
|
|
+#else
|
|
|
+ return stream->codec->width;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+inline int ffmpeg_get_codec_height(AVStream* stream) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 4
|
|
|
+ return stream->codecpar->height;
|
|
|
+#else
|
|
|
+ return stream->codec->height;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+inline AVPixelFormat ffmpeg_get_codec_pix_fmt(AVStream* stream) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 4
|
|
|
+ return static_cast<AVPixelFormat>(stream->codecpar->format);
|
|
|
+#else
|
|
|
+ return stream->codec->pix_fmt;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+inline int ffmpeg_get_codec_sample_rate(AVStream* stream) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 4
|
|
|
+ return stream->codecpar->sample_rate;
|
|
|
+#else
|
|
|
+ return stream->codec->sample_rate;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+inline int ffmpeg_get_codec_channels(AVStream* stream) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 7
|
|
|
+ return stream->codecpar->ch_layout.nb_channels;
|
|
|
+#elif FFMPEG_VERSION_MAJOR >= 4
|
|
|
+ return stream->codecpar->channels;
|
|
|
+#else
|
|
|
+ return stream->codec->channels;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+inline uint64_t ffmpeg_get_codec_channel_layout(AVStream* stream) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 7
|
|
|
+ // In FFmpeg 7, use ch_layout.u.mask directly if it's a mask layout
|
|
|
+ if (stream->codecpar->ch_layout.order == AV_CHANNEL_ORDER_NATIVE) {
|
|
|
+ return stream->codecpar->ch_layout.u.mask;
|
|
|
+ } else {
|
|
|
+ // For non-mask layouts, return a default stereo layout
|
|
|
+ return AV_CH_LAYOUT_STEREO;
|
|
|
+ }
|
|
|
+#elif FFMPEG_VERSION_MAJOR >= 4
|
|
|
+ return stream->codecpar->channel_layout;
|
|
|
+#else
|
|
|
+ return stream->codec->channel_layout;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+inline AVSampleFormat ffmpeg_get_codec_sample_fmt(AVStream* stream) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 4
|
|
|
+ return static_cast<AVSampleFormat>(stream->codecpar->format);
|
|
|
+#else
|
|
|
+ return stream->codec->sample_fmt;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+// Compatibility for channel layout functions
|
|
|
+inline uint64_t ffmpeg_get_default_channel_layout(int channels) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 7
|
|
|
+ AVChannelLayout ch_layout;
|
|
|
+ av_channel_layout_default(&ch_layout, channels);
|
|
|
+ if (ch_layout.order == AV_CHANNEL_ORDER_NATIVE) {
|
|
|
+ return ch_layout.u.mask;
|
|
|
+ } else {
|
|
|
+ // Fallback for common channel counts
|
|
|
+ switch (channels) {
|
|
|
+ case 1: return AV_CH_LAYOUT_MONO;
|
|
|
+ case 2: return AV_CH_LAYOUT_STEREO;
|
|
|
+ case 6: return AV_CH_LAYOUT_5POINT1;
|
|
|
+ case 8: return AV_CH_LAYOUT_7POINT1;
|
|
|
+ default: return AV_CH_LAYOUT_STEREO;
|
|
|
+ }
|
|
|
+ }
|
|
|
+#else
|
|
|
+ return av_get_default_channel_layout(channels);
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+// Compatibility for filter registration
|
|
|
+inline void ffmpeg_register_filters() {
|
|
|
+#if FFMPEG_VERSION_MAJOR < 4
|
|
|
+ avfilter_register_all();
|
|
|
+#endif
|
|
|
+ // No-op in FFmpeg 4.0+
|
|
|
+}
|
|
|
+
|
|
|
+// Compatibility for channel layout string functions
|
|
|
+inline int ffmpeg_get_channel_layout_string(char *buf, int buf_size, int nb_channels, uint64_t channel_layout) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 7
|
|
|
+ (void)nb_channels; // Suppress unused parameter warning
|
|
|
+ AVChannelLayout ch_layout;
|
|
|
+ av_channel_layout_from_mask(&ch_layout, channel_layout);
|
|
|
+ return av_channel_layout_describe(&ch_layout, buf, buf_size);
|
|
|
+#else
|
|
|
+ av_get_channel_layout_string(buf, buf_size, nb_channels, channel_layout);
|
|
|
+ return strlen(buf);
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+// Compatibility for AVFrame channels access
|
|
|
+inline int ffmpeg_get_frame_channels(AVFrame* frame) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 7
|
|
|
+ return frame->ch_layout.nb_channels;
|
|
|
+#else
|
|
|
+ return frame->channels;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+// Compatibility for av_samples_get_buffer_size
|
|
|
+inline int ffmpeg_get_buffer_size(enum AVSampleFormat sample_fmt, int nb_channels, int nb_samples, int align) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 7
|
|
|
+ return av_samples_get_buffer_size(nullptr, nb_channels, nb_samples, sample_fmt, align);
|
|
|
+#else
|
|
|
+ return av_samples_get_buffer_size(nullptr, nb_channels, nb_samples, sample_fmt, align);
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+// Compatibility for codec context creation from stream
|
|
|
+inline AVCodecContext* ffmpeg_get_codec_context(AVStream* stream) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 4
|
|
|
+ const AVCodec* codec = avcodec_find_decoder(stream->codecpar->codec_id);
|
|
|
+ if (!codec) return nullptr;
|
|
|
+
|
|
|
+ AVCodecContext* ctx = avcodec_alloc_context3(codec);
|
|
|
+ if (!ctx) return nullptr;
|
|
|
+
|
|
|
+ if (avcodec_parameters_to_context(ctx, stream->codecpar) < 0) {
|
|
|
+ avcodec_free_context(&ctx);
|
|
|
+ return nullptr;
|
|
|
+ }
|
|
|
+
|
|
|
+ return ctx;
|
|
|
+#else
|
|
|
+ return stream->codec;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+// Compatibility for setting stream codec parameters
|
|
|
+inline void ffmpeg_set_stream_codec_id(AVStream* stream, enum AVCodecID codec_id) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 4
|
|
|
+ stream->codecpar->codec_id = codec_id;
|
|
|
+#else
|
|
|
+ stream->codec->codec_id = codec_id;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+inline void ffmpeg_set_stream_codec_type(AVStream* stream, enum AVMediaType codec_type) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 4
|
|
|
+ stream->codecpar->codec_type = codec_type;
|
|
|
+#else
|
|
|
+ stream->codec->codec_type = codec_type;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+inline void ffmpeg_set_stream_bit_rate(AVStream* stream, int64_t bit_rate) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 4
|
|
|
+ stream->codecpar->bit_rate = bit_rate;
|
|
|
+#else
|
|
|
+ stream->codec->bit_rate = bit_rate;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+inline void ffmpeg_set_stream_pix_fmt(AVStream* stream, enum AVPixelFormat pix_fmt) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 4
|
|
|
+ stream->codecpar->format = pix_fmt;
|
|
|
+#else
|
|
|
+ stream->codec->pix_fmt = pix_fmt;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+inline void ffmpeg_set_stream_dimensions(AVStream* stream, int width, int height) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 4
|
|
|
+ stream->codecpar->width = width;
|
|
|
+ stream->codecpar->height = height;
|
|
|
+#else
|
|
|
+ stream->codec->width = width;
|
|
|
+ stream->codec->height = height;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+// Compatibility for stream codec parameters
|
|
|
+inline int ffmpeg_copy_codec_params_to_stream(AVStream* stream, AVCodecContext* codec_ctx) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 4
|
|
|
+ return avcodec_parameters_from_context(stream->codecpar, codec_ctx);
|
|
|
+#else
|
|
|
+ return 0; // No-op for older versions
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+// Compatibility for extradata access
|
|
|
+inline uint8_t* ffmpeg_get_extradata(AVStream* stream) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 4
|
|
|
+ return stream->codecpar->extradata;
|
|
|
+#else
|
|
|
+ return stream->codec->extradata;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+inline int ffmpeg_get_extradata_size(AVStream* stream) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 4
|
|
|
+ return stream->codecpar->extradata_size;
|
|
|
+#else
|
|
|
+ return stream->codec->extradata_size;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+inline void ffmpeg_set_stream_extradata(AVStream* stream, uint8_t* data, int size) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 4
|
|
|
+ stream->codecpar->extradata = data;
|
|
|
+ stream->codecpar->extradata_size = size;
|
|
|
+#else
|
|
|
+ stream->codec->extradata = data;
|
|
|
+ stream->codec->extradata_size = size;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+// Compatibility for AVCodecContext channels and channel_layout
|
|
|
+inline void ffmpeg_set_codec_channels(AVCodecContext* ctx, int channels) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 7
|
|
|
+ av_channel_layout_default(&ctx->ch_layout, channels);
|
|
|
+#else
|
|
|
+ ctx->channels = channels;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+inline void ffmpeg_set_codec_channel_layout(AVCodecContext* ctx, uint64_t channel_layout) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 7
|
|
|
+ av_channel_layout_from_mask(&ctx->ch_layout, channel_layout);
|
|
|
+#else
|
|
|
+ ctx->channel_layout = channel_layout;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+inline int ffmpeg_get_codec_context_channels(AVCodecContext* ctx) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 7
|
|
|
+ return ctx->ch_layout.nb_channels;
|
|
|
+#else
|
|
|
+ return ctx->channels;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+// Compatibility for swr_alloc_set_opts
|
|
|
+inline SwrContext* ffmpeg_swr_alloc_set_opts(SwrContext *s,
|
|
|
+ int64_t out_ch_layout, enum AVSampleFormat out_sample_fmt, int out_sample_rate,
|
|
|
+ int64_t in_ch_layout, enum AVSampleFormat in_sample_fmt, int in_sample_rate,
|
|
|
+ int log_offset, void *log_ctx) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 7
|
|
|
+ SwrContext *swr_ctx = swr_alloc();
|
|
|
+ if (!swr_ctx) return NULL;
|
|
|
+
|
|
|
+ AVChannelLayout out_ch_layout_new, in_ch_layout_new;
|
|
|
+ av_channel_layout_from_mask(&out_ch_layout_new, out_ch_layout);
|
|
|
+ av_channel_layout_from_mask(&in_ch_layout_new, in_ch_layout);
|
|
|
+
|
|
|
+ av_opt_set_chlayout(swr_ctx, "ochl", &out_ch_layout_new, 0);
|
|
|
+ av_opt_set_int(swr_ctx, "osf", out_sample_fmt, 0);
|
|
|
+ av_opt_set_int(swr_ctx, "osr", out_sample_rate, 0);
|
|
|
+ av_opt_set_chlayout(swr_ctx, "ichl", &in_ch_layout_new, 0);
|
|
|
+ av_opt_set_int(swr_ctx, "isf", in_sample_fmt, 0);
|
|
|
+ av_opt_set_int(swr_ctx, "isr", in_sample_rate, 0);
|
|
|
+
|
|
|
+ av_channel_layout_uninit(&out_ch_layout_new);
|
|
|
+ av_channel_layout_uninit(&in_ch_layout_new);
|
|
|
+
|
|
|
+ return swr_ctx;
|
|
|
+#else
|
|
|
+ return swr_alloc_set_opts(s, out_ch_layout, out_sample_fmt, out_sample_rate,
|
|
|
+ in_ch_layout, in_sample_fmt, in_sample_rate,
|
|
|
+ log_offset, log_ctx);
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+// Compatibility for codec parameters setting
|
|
|
+inline int ffmpeg_av_samples_alloc(uint8_t **audio_data, int *linesize, int nb_channels,
|
|
|
+ int nb_samples, enum AVSampleFormat sample_fmt, int align) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 7
|
|
|
+ return av_samples_alloc_array_and_samples(&audio_data, linesize, nb_channels, nb_samples, sample_fmt, align);
|
|
|
+#else
|
|
|
+ return av_samples_alloc(audio_data, linesize, nb_channels, nb_samples, sample_fmt, align);
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+inline void ffmpeg_set_frame_channel_layout(AVFrame* frame, AVCodecContext* codec_ctx) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 7
|
|
|
+ av_channel_layout_copy(&frame->ch_layout, &codec_ctx->ch_layout);
|
|
|
+#else
|
|
|
+ frame->channel_layout = codec_ctx->channel_layout;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+inline void ffmpeg_set_stream_codec_params(AVStream* stream, AVCodecContext* codec_ctx) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 7
|
|
|
+ stream->codecpar->codec_id = codec_ctx->codec_id;
|
|
|
+ stream->codecpar->bit_rate = codec_ctx->bit_rate;
|
|
|
+ stream->codecpar->width = codec_ctx->width;
|
|
|
+ stream->codecpar->height = codec_ctx->height;
|
|
|
+ stream->codecpar->format = codec_ctx->pix_fmt;
|
|
|
+ stream->codecpar->sample_rate = codec_ctx->sample_rate;
|
|
|
+ av_channel_layout_copy(&stream->codecpar->ch_layout, &codec_ctx->ch_layout);
|
|
|
+ stream->time_base = codec_ctx->time_base;
|
|
|
+#elif FFMPEG_VERSION_MAJOR >= 4
|
|
|
+ stream->codecpar->codec_id = codec_ctx->codec_id;
|
|
|
+ stream->codecpar->bit_rate = codec_ctx->bit_rate;
|
|
|
+ stream->codecpar->width = codec_ctx->width;
|
|
|
+ stream->codecpar->height = codec_ctx->height;
|
|
|
+ stream->codecpar->format = codec_ctx->pix_fmt;
|
|
|
+ stream->codecpar->sample_rate = codec_ctx->sample_rate;
|
|
|
+ stream->codecpar->channels = codec_ctx->channels;
|
|
|
+ stream->codecpar->channel_layout = codec_ctx->channel_layout;
|
|
|
+ stream->time_base = codec_ctx->time_base;
|
|
|
+#else
|
|
|
+ *(stream->codec) = *codec_ctx;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+// Additional compatibility functions for missing identifiers
|
|
|
+inline int ffmpeg_get_channels(AVCodecContext* ctx) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 7
|
|
|
+ return ctx->ch_layout.nb_channels;
|
|
|
+#else
|
|
|
+ return ctx->channels;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+inline void ffmpeg_set_channels(AVCodecContext* ctx, int channels) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 7
|
|
|
+ av_channel_layout_default(&ctx->ch_layout, channels);
|
|
|
+#else
|
|
|
+ ctx->channels = channels;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+inline void ffmpeg_set_channel_layout(AVCodecContext* ctx, uint64_t channel_layout) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 7
|
|
|
+ av_channel_layout_from_mask(&ctx->ch_layout, channel_layout);
|
|
|
+#else
|
|
|
+ ctx->channel_layout = channel_layout;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+inline void ffmpeg_set_frame_channels(AVFrame* frame, int channels) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 7
|
|
|
+ av_channel_layout_default(&frame->ch_layout, channels);
|
|
|
+#else
|
|
|
+ frame->channels = channels;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+inline void ffmpeg_set_frame_channel_layout(AVFrame* frame, uint64_t channel_layout) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 7
|
|
|
+ av_channel_layout_from_mask(&frame->ch_layout, channel_layout);
|
|
|
+#else
|
|
|
+ frame->channel_layout = channel_layout;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+inline void ffmpeg_set_frame_pkt_pts(AVFrame* frame, int64_t pts) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 7
|
|
|
+ frame->pts = pts;
|
|
|
+#else
|
|
|
+ frame->pkt_pts = pts;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+// Compatibility for bitstream filter initialization
|
|
|
+inline AVBitStreamFilterContext* ffmpeg_bitstream_filter_init(const char* name) {
|
|
|
+#if FFMPEG_VERSION_MAJOR >= 6
|
|
|
+ const AVBitStreamFilter* bsf = av_bsf_get_by_name(name);
|
|
|
+ if (!bsf) return nullptr;
|
|
|
+
|
|
|
+ AVBSFContext* ctx = nullptr;
|
|
|
+ if (av_bsf_alloc(bsf, &ctx) < 0) return nullptr;
|
|
|
+
|
|
|
+ return ctx;
|
|
|
+#else
|
|
|
+ return av_bitstream_filter_init(name);
|
|
|
+#endif
|
|
|
+}
|