OpenShot Library | libopenshot 1.1.1
Loading...
Searching...
No Matches
FFmpegUtilities.h
Go to the documentation of this file.
1
9// Copyright (c) 2008-2024 OpenShot Studios, LLC
10//
11// SPDX-License-Identifier: LGPL-3.0-or-later
12
13#ifndef OPENSHOT_FFMPEG_UTILITIES_H
14#define OPENSHOT_FFMPEG_UTILITIES_H
15
16#include "Exceptions.h"
17#include "OpenShotVersion.h" // For FFMPEG_USE_SWRESAMPLE
18
19// Required for libavformat to build on Windows
20#ifndef INT64_C
21#define INT64_C(c) (c ## LL)
22#define UINT64_C(c) (c ## ULL)
23#endif
24
25#ifndef IS_FFMPEG_3_2
26#define IS_FFMPEG_3_2 (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 64, 101))
27#endif
28
29#ifndef USE_HW_ACCEL
30#define USE_HW_ACCEL (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 107, 100))
31#endif
32
33#ifndef USE_SW
34#define USE_SW FFMPEG_USE_SWRESAMPLE
35#endif
36
37#define HAVE_CH_LAYOUT (LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 28, 100))
38
39// Include the FFmpeg headers
40extern "C" {
41 #include <libavcodec/avcodec.h>
42 #include <libavformat/avformat.h>
43 #include <libavutil/display.h>
44
45#if (LIBAVFORMAT_VERSION_MAJOR >= 57)
46 #include <libavutil/hwcontext.h> //PM
47#endif
48 #include <libswscale/swscale.h>
49
50#if USE_SW
51 #include <libswresample/swresample.h>
52#else
53 #include <libavresample/avresample.h>
54#endif
55
56 #include <libavutil/mathematics.h>
57 #include <libavutil/pixfmt.h>
58 #include <libavutil/pixdesc.h>
59
60 // libavutil changed folders at some point
61#if LIBAVFORMAT_VERSION_MAJOR >= 53
62 #include <libavutil/opt.h>
63#else
64 #include <libavcodec/opt.h>
65#endif
66
67 // channel header refactored
68#if LIBAVFORMAT_VERSION_MAJOR >= 54
69 #include <libavutil/channel_layout.h>
70#endif
71
72#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(55, 0, 0)
73 #include <libavutil/spherical.h>
74#endif
75
76#if IS_FFMPEG_3_2
77 #include "libavutil/imgutils.h"
78#endif
79}
80
81// This was removed from newer versions of FFmpeg (but still used in libopenshot)
82#ifndef AVCODEC_MAX_AUDIO_FRAME_SIZE
83 // 1 second of 48khz 32bit audio
84 #define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000
85#endif
86#ifndef AV_ERROR_MAX_STRING_SIZE
87 #define AV_ERROR_MAX_STRING_SIZE 64
88#endif
89#ifndef AUDIO_PACKET_ENCODING_SIZE
90 // 48khz * S16 (2 bytes) * max channels (8)
91 #define AUDIO_PACKET_ENCODING_SIZE 768000
92#endif
93
94// This wraps an unsafe C macro to be C++ compatible function
95inline static const std::string av_err2string(int errnum)
96{
97 char errbuf[AV_ERROR_MAX_STRING_SIZE];
98 av_strerror(errnum, errbuf, AV_ERROR_MAX_STRING_SIZE);
99 return static_cast<std::string>(errbuf);
100}
101
102// Redefine the C macro to use our new C++ function
103#undef av_err2str
104#define av_err2str(errnum) av_err2string(errnum).c_str()
105
106// Define this for compatibility
107#ifndef PixelFormat
108 #define PixelFormat AVPixelFormat
109#endif
110#ifndef PIX_FMT_RGBA
111 #define PIX_FMT_RGBA AV_PIX_FMT_RGBA
112#endif
113#ifndef PIX_FMT_NONE
114 #define PIX_FMT_NONE AV_PIX_FMT_NONE
115#endif
116#ifndef PIX_FMT_RGB24
117 #define PIX_FMT_RGB24 AV_PIX_FMT_RGB24
118#endif
119#ifndef PIX_FMT_YUV420P
120 #define PIX_FMT_YUV420P AV_PIX_FMT_YUV420P
121#endif
122#ifndef PIX_FMT_YUV444P
123 #define PIX_FMT_YUV444P AV_PIX_FMT_YUV444P
124#endif
125#ifndef AV_PROFILE_H264_BASELINE
126 #ifdef FF_PROFILE_H264_BASELINE
127 #define AV_PROFILE_H264_BASELINE FF_PROFILE_H264_BASELINE
128 #endif
129#endif
130#ifndef AV_PROFILE_H264_CONSTRAINED
131 #ifdef FF_PROFILE_H264_CONSTRAINED
132 #define AV_PROFILE_H264_CONSTRAINED FF_PROFILE_H264_CONSTRAINED
133 #endif
134#endif
135#ifndef AV_PROFILE_H264_CONSTRAINED_BASELINE
136 #if defined(AV_PROFILE_H264_BASELINE) && defined(AV_PROFILE_H264_CONSTRAINED)
137 #define AV_PROFILE_H264_CONSTRAINED_BASELINE (AV_PROFILE_H264_BASELINE | AV_PROFILE_H264_CONSTRAINED)
138 #elif defined(FF_PROFILE_H264_CONSTRAINED_BASELINE)
139 #define AV_PROFILE_H264_CONSTRAINED_BASELINE FF_PROFILE_H264_CONSTRAINED_BASELINE
140 #endif
141#endif
142
143// Does ffmpeg pixel format contain an alpha channel?
144inline static bool ffmpeg_has_alpha(PixelFormat pix_fmt) {
145 const AVPixFmtDescriptor *fmt_desc = av_pix_fmt_desc_get(pix_fmt);
146 return bool(fmt_desc->flags & AV_PIX_FMT_FLAG_ALPHA);
147}
148
149// Allocate and populate an AVCodecContext from stream codec parameters.
150inline static AVCodecContext* ffmpeg_get_codec_context(AVStream *av_stream, const AVCodec *av_codec) {
151 AVCodecContext *context = avcodec_alloc_context3(av_codec);
152 if (context)
153 avcodec_parameters_to_context(context, av_stream->codecpar);
154 return context;
155}
156
157#if HAVE_CH_LAYOUT
158inline static AVChannelLayout ffmpeg_default_channel_layout(int channels) {
159 AVChannelLayout layout = {};
160 if (channels > 0)
161 av_channel_layout_default(&layout, channels);
162 return layout;
163}
164
165inline static AVChannelLayout ffmpeg_get_valid_channel_layout(
166 const AVChannelLayout &layout, int fallback_channels) {
167 AVChannelLayout normalized = {};
168 if (layout.nb_channels > 0 && av_channel_layout_check(&layout) == 1) {
169 av_channel_layout_copy(&normalized, &layout);
170 return normalized;
171 }
172 return ffmpeg_default_channel_layout(fallback_channels);
173}
174
175inline static uint64_t ffmpeg_channel_layout_mask(const AVChannelLayout &layout) {
176 return layout.order == AV_CHANNEL_ORDER_NATIVE ? layout.u.mask : 0;
177}
178#endif
179
180// Access stream side data across FFmpeg API changes.
181inline static const uint8_t* ffmpeg_stream_get_side_data(
182 const AVStream *stream, enum AVPacketSideDataType type, size_t *size) {
183#if (LIBAVFORMAT_VERSION_MAJOR >= 61)
184 const AVPacketSideData *side_data = av_packet_side_data_get(
185 stream->codecpar->coded_side_data,
186 stream->codecpar->nb_coded_side_data,
187 type);
188 if (!side_data) {
189 if (size)
190 *size = 0;
191 return nullptr;
192 }
193 if (size)
194 *size = side_data->size;
195 return side_data->data;
196#else
197 #if defined(__GNUC__) || defined(__clang__)
198 #pragma GCC diagnostic push
199 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
200 #endif
201 #if (LIBAVFORMAT_VERSION_MAJOR >= 59)
202 const uint8_t *data = av_stream_get_side_data(stream, type, size);
203 #else
204 int old_size = 0;
205 const uint8_t *data = av_stream_get_side_data(
206 const_cast<AVStream*>(stream), type, &old_size);
207 if (size)
208 *size = old_size >= 0 ? static_cast<size_t>(old_size) : 0;
209 #endif
210 #if defined(__GNUC__) || defined(__clang__)
211 #pragma GCC diagnostic pop
212 #endif
213 return data;
214#endif
215}
216
217// Add stream side data across FFmpeg API changes.
218inline static int ffmpeg_stream_add_side_data(
219 AVStream *stream, enum AVPacketSideDataType type, uint8_t *data, size_t size) {
220#if (LIBAVFORMAT_VERSION_MAJOR >= 61)
221 AVPacketSideData *side_data = av_packet_side_data_add(
222 &stream->codecpar->coded_side_data,
223 &stream->codecpar->nb_coded_side_data,
224 type,
225 data,
226 size,
227 0);
228 return side_data ? 0 : AVERROR(ENOMEM);
229#else
230 #if defined(__GNUC__) || defined(__clang__)
231 #pragma GCC diagnostic push
232 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
233 #endif
234 int result = av_stream_add_side_data(stream, type, data, size);
235 #if defined(__GNUC__) || defined(__clang__)
236 #pragma GCC diagnostic pop
237 #endif
238 return result;
239#endif
240}
241// FFmpeg's libavutil/common.h defines an RSHIFT incompatible with Ruby's
242// definition in ruby/config.h, so we move it to FF_RSHIFT
243#ifdef RSHIFT
244 #define FF_RSHIFT(a, b) RSHIFT(a, b)
245 #undef RSHIFT
246#endif
247
248// libswresample/libavresample API switching
249#if USE_SW
250 #define SWR_CONVERT(ctx, out, linesize, out_count, in, linesize2, in_count) \
251 swr_convert(ctx, out, out_count, (const uint8_t **)in, in_count)
252 #define SWR_ALLOC() swr_alloc()
253 #define SWR_CLOSE(ctx) {}
254 #define SWR_FREE(ctx) swr_free(ctx)
255 #define SWR_INIT(ctx) swr_init(ctx)
256 #define SWRCONTEXT SwrContext
257
258#else
259 #define SWR_CONVERT(ctx, out, linesize, out_count, in, linesize2, in_count) \
260 avresample_convert(ctx, out, linesize, out_count, (uint8_t **)in, linesize2, in_count)
261 #define SWR_ALLOC() avresample_alloc_context()
262 #define SWR_CLOSE(ctx) avresample_close(ctx)
263 #define SWR_FREE(ctx) avresample_free(ctx)
264 #define SWR_INIT(ctx) avresample_open(ctx)
265 #define SWRCONTEXT AVAudioResampleContext
266#endif
267
268
269#if (LIBAVFORMAT_VERSION_MAJOR >= 58)
270 #define AV_REGISTER_ALL
271 #define AVCODEC_REGISTER_ALL
272 #define AV_FILENAME url
273 #define AV_SET_FILENAME(oc, f) oc->AV_FILENAME = av_strdup(f)
274 #define MY_INPUT_BUFFER_PADDING_SIZE AV_INPUT_BUFFER_PADDING_SIZE
275 #define AV_ALLOCATE_FRAME() av_frame_alloc()
276 #define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) \
277 av_image_alloc(av_frame->data, av_frame->linesize, width, height, pix_fmt, 32)
278 #define AV_RESET_FRAME(av_frame) av_frame_unref(av_frame)
279 #define AV_FREE_FRAME(av_frame) av_frame_free(av_frame)
280 #define AV_FREE_PACKET(av_packet) av_packet_unref(av_packet)
281 #define AV_FREE_CONTEXT(av_context) avcodec_free_context(&av_context)
282 #define AV_GET_CODEC_TYPE(av_stream) av_stream->codecpar->codec_type
283 #define AV_FIND_DECODER_CODEC_ID(av_stream) av_stream->codecpar->codec_id
284 #define AV_GET_CODEC_CONTEXT(av_stream, av_codec) ffmpeg_get_codec_context(av_stream, av_codec)
285 #define AV_GET_CODEC_PAR_CONTEXT(av_stream, av_codec) av_codec;
286 #define AV_GET_CODEC_FROM_STREAM(av_stream,codec_in)
287 #define AV_GET_CODEC_ATTRIBUTES(av_stream, av_context) av_stream->codecpar
288 #define AV_GET_CODEC_PIXEL_FORMAT(av_stream, av_context) (AVPixelFormat) av_stream->codecpar->format
289 #define AV_GET_SAMPLE_FORMAT(av_stream, av_context) av_stream->codecpar->format
290 #define AV_GET_IMAGE_SIZE(pix_fmt, width, height) \
291 av_image_get_buffer_size(pix_fmt, width, height, 1)
292 #define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, height) \
293 av_image_fill_arrays(av_frame->data, av_frame->linesize, buffer, pix_fmt, width, height, 1)
294 #define AV_OUTPUT_CONTEXT(output_context, path) avformat_alloc_output_context2( output_context, NULL, NULL, path)
295 #define AV_OPTION_FIND(priv_data, name) av_opt_find(priv_data, name, NULL, 0, 0)
296 #define AV_OPTION_SET( av_stream, priv_data, name, value, avcodec) \
297 av_opt_set(priv_data, name, value, 0); \
298 avcodec_parameters_from_context(av_stream->codecpar, avcodec);
299 #define ALLOC_CODEC_CTX(ctx, codec, stream) \
300 ctx = avcodec_alloc_context3(codec);
301 #define AV_COPY_PARAMS_FROM_CONTEXT(av_stream, av_codec_ctx) \
302 avcodec_parameters_from_context(av_stream->codecpar, av_codec_ctx);
303
304#elif IS_FFMPEG_3_2
305 #define AV_REGISTER_ALL av_register_all();
306 #define AVCODEC_REGISTER_ALL avcodec_register_all();
307 #define AV_FILENAME filename
308 #define AV_SET_FILENAME(oc, f) snprintf(oc->AV_FILENAME, sizeof(oc->AV_FILENAME), "%s", f)
309 #define MY_INPUT_BUFFER_PADDING_SIZE FF_INPUT_BUFFER_PADDING_SIZE
310 #define AV_ALLOCATE_FRAME() av_frame_alloc()
311 #define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) \
312 av_image_alloc(av_frame->data, av_frame->linesize, width, height, pix_fmt, 32)
313 #define AV_RESET_FRAME(av_frame) av_frame_unref(av_frame)
314 #define AV_FREE_FRAME(av_frame) av_frame_free(av_frame)
315 #define AV_FREE_PACKET(av_packet) av_packet_unref(av_packet)
316 #define AV_FREE_CONTEXT(av_context) avcodec_free_context(&av_context)
317 #define AV_GET_CODEC_TYPE(av_stream) av_stream->codecpar->codec_type
318 #define AV_FIND_DECODER_CODEC_ID(av_stream) av_stream->codecpar->codec_id
319 #define AV_GET_CODEC_CONTEXT(av_stream, av_codec) ffmpeg_get_codec_context(av_stream, av_codec)
320 #define AV_GET_CODEC_PAR_CONTEXT(av_stream, av_codec) av_codec;
321 #define AV_GET_CODEC_FROM_STREAM(av_stream,codec_in)
322 #define AV_GET_CODEC_ATTRIBUTES(av_stream, av_context) av_stream->codecpar
323 #define AV_GET_CODEC_PIXEL_FORMAT(av_stream, av_context) \
324 (AVPixelFormat) av_stream->codecpar->format
325 #define AV_GET_SAMPLE_FORMAT(av_stream, av_context) av_stream->codecpar->format
326 #define AV_GET_IMAGE_SIZE(pix_fmt, width, height) av_image_get_buffer_size(pix_fmt, width, height, 1)
327 #define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, height) \
328 av_image_fill_arrays(av_frame->data, av_frame->linesize, buffer, pix_fmt, width, height, 1)
329 #define AV_OUTPUT_CONTEXT(output_context, path) \
330 avformat_alloc_output_context2( output_context, NULL, NULL, path)
331 #define AV_OPTION_FIND(priv_data, name) av_opt_find(priv_data, name, NULL, 0, 0)
332 #define AV_OPTION_SET( av_stream, priv_data, name, value, avcodec) \
333 av_opt_set(priv_data, name, value, 0); \
334 avcodec_parameters_from_context(av_stream->codecpar, avcodec);
335 #define ALLOC_CODEC_CTX(ctx, codec, stream) \
336 ctx = avcodec_alloc_context3(codec);
337 #define AV_COPY_PARAMS_FROM_CONTEXT(av_stream, av_codec) \
338 avcodec_parameters_from_context(av_stream->codecpar, av_codec);
339
340#elif LIBAVFORMAT_VERSION_MAJOR >= 55
341 #define AV_REGISTER_ALL av_register_all();
342 #define AVCODEC_REGISTER_ALL avcodec_register_all();
343 #define AV_FILENAME filename
344 #define AV_SET_FILENAME(oc, f) snprintf(oc->AV_FILENAME, sizeof(oc->AV_FILENAME), "%s", f)
345 #define MY_INPUT_BUFFER_PADDING_SIZE FF_INPUT_BUFFER_PADDING_SIZE
346 #define AV_ALLOCATE_FRAME() av_frame_alloc()
347 #define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) \
348 avpicture_alloc((AVPicture *) av_frame, pix_fmt, width, height)
349 #define AV_RESET_FRAME(av_frame) av_frame_unref(av_frame)
350 #define AV_FREE_FRAME(av_frame) av_frame_free(av_frame)
351 #define AV_FREE_PACKET(av_packet) av_packet_unref(av_packet)
352 #define AV_FREE_CONTEXT(av_context) avcodec_close(av_context)
353 #define AV_GET_CODEC_TYPE(av_stream) av_stream->codec->codec_type
354 #define AV_FIND_DECODER_CODEC_ID(av_stream) av_stream->codec->codec_id
355 #define AV_GET_CODEC_CONTEXT(av_stream, av_codec) av_stream->codec
356 #define AV_GET_CODEC_PAR_CONTEXT(av_stream, av_codec) av_stream->codec
357 #define AV_GET_CODEC_FROM_STREAM(av_stream, codec_in) codec_in = av_stream->codec;
358 #define AV_GET_CODEC_ATTRIBUTES(av_stream, av_context) av_context
359 #define AV_GET_CODEC_PIXEL_FORMAT(av_stream, av_context) av_context->pix_fmt
360 #define AV_GET_SAMPLE_FORMAT(av_stream, av_context) av_context->sample_fmt
361 #define AV_GET_IMAGE_SIZE(pix_fmt, width, height) avpicture_get_size(pix_fmt, width, height)
362 #define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, height) \
363 avpicture_fill((AVPicture *) av_frame, buffer, pix_fmt, width, height)
364 #define AV_OUTPUT_CONTEXT(output_context, path) oc = avformat_alloc_context()
365 #define AV_OPTION_FIND(priv_data, name) av_opt_find(priv_data, name, NULL, 0, 0)
366 #define AV_OPTION_SET(av_stream, priv_data, name, value, avcodec) av_opt_set (priv_data, name, value, 0)
367 #define ALLOC_CODEC_CTX(ctx, av_codec, stream) \
368 avcodec_get_context_defaults3(av_st->codec, av_codec); \
369 ctx = av_st->codec;
370 #define AV_COPY_PARAMS_FROM_CONTEXT(av_stream, av_codec)
371
372#else
373 #define AV_REGISTER_ALL av_register_all();
374 #define AVCODEC_REGISTER_ALL avcodec_register_all();
375 #define AV_FILENAME filename
376 #define AV_SET_FILENAME(oc, f) snprintf(oc->AV_FILENAME, sizeof(oc->AV_FILENAME), "%s", f)
377 #define MY_INPUT_BUFFER_PADDING_SIZE FF_INPUT_BUFFER_PADDING_SIZE
378 #define AV_ALLOCATE_FRAME() avcodec_alloc_frame()
379 #define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) \
380 avpicture_alloc((AVPicture *) av_frame, pix_fmt, width, height)
381 #define AV_RESET_FRAME(av_frame) avcodec_get_frame_defaults(av_frame)
382 #define AV_FREE_FRAME(av_frame) avcodec_free_frame(av_frame)
383 #define AV_FREE_PACKET(av_packet) av_free_packet(av_packet)
384 #define AV_FREE_CONTEXT(av_context) avcodec_close(av_context)
385 #define AV_GET_CODEC_TYPE(av_stream) av_stream->codec->codec_type
386 #define AV_FIND_DECODER_CODEC_ID(av_stream) av_stream->codec->codec_id
387 #define AV_GET_CODEC_CONTEXT(av_stream, av_codec) av_stream->codec
388 #define AV_GET_CODEC_PAR_CONTEXT(av_stream, av_codec) av_stream->codec
389 #define AV_GET_CODEC_FROM_STREAM(av_stream, codec_in ) codec_in = av_stream->codec;
390 #define AV_GET_CODEC_ATTRIBUTES(av_stream, av_context) av_context
391 #define AV_GET_CODEC_PIXEL_FORMAT(av_stream, av_context) av_context->pix_fmt
392 #define AV_GET_SAMPLE_FORMAT(av_stream, av_context) av_context->sample_fmt
393 #define AV_GET_IMAGE_SIZE(pix_fmt, width, height) avpicture_get_size(pix_fmt, width, height)
394 #define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, height) \
395 avpicture_fill((AVPicture *) av_frame, buffer, pix_fmt, width, height)
396 #define AV_OUTPUT_CONTEXT(output_context, path) oc = avformat_alloc_context()
397 #define AV_OPTION_FIND(priv_data, name) av_opt_find(priv_data, name, NULL, 0, 0)
398 #define AV_OPTION_SET(av_stream, priv_data, name, value, avcodec) av_opt_set (priv_data, name, value, 0)
399 #define ALLOC_CODEC_CTX(ctx, av_codec, stream) \
400 avcodec_get_context_defaults3(stream->codec, av_codec); \
401 ctx = stream->codec;
402 #define AV_COPY_PARAMS_FROM_CONTEXT(av_stream, av_codec)
403#endif
404
405// Aligned memory allocation helpers (cross-platform)
406#if defined(_WIN32)
407#include <malloc.h>
408#endif
409
410// FFmpeg 7.1 introduced this API at libavcodec 61.13.100. FFmpeg 7.0
411// still needs the AVCodec fields, as do older supported releases.
412#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 13, 100)
413template<typename T>
414inline static const T* ffmpeg_codec_config(const AVCodec* codec,
415 const AVCodecContext* context,
416 AVCodecConfig config) {
417 const void* values = nullptr;
418 const int result = avcodec_get_supported_config(context, codec, config, 0,
419 &values, nullptr);
420 // A successful NULL list means unrestricted support. A failed query must
421 // not silently turn into unrestricted support or a default format.
422 if (result < 0)
423 throw openshot::InvalidCodec("Could not query codec capabilities: " + av_err2string(result), "");
424 return static_cast<const T*>(values);
425}
426#endif
427
428inline static const AVPixelFormat* ffmpeg_codec_pix_fmts(const AVCodec* codec,
429 const AVCodecContext* context) {
430#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 13, 100)
431 return ffmpeg_codec_config<AVPixelFormat>(codec, context, AV_CODEC_CONFIG_PIX_FORMAT);
432#else
433 (void)context;
434 return codec->pix_fmts;
435#endif
436}
437
438inline static const int* ffmpeg_codec_sample_rates(const AVCodec* codec,
439 const AVCodecContext* context) {
440#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 13, 100)
441 return ffmpeg_codec_config<int>(codec, context, AV_CODEC_CONFIG_SAMPLE_RATE);
442#else
443 (void)context;
444 return codec->supported_samplerates;
445#endif
446}
447
448inline static const AVSampleFormat* ffmpeg_codec_sample_fmts(const AVCodec* codec,
449 const AVCodecContext* context) {
450#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 13, 100)
451 return ffmpeg_codec_config<AVSampleFormat>(codec, context, AV_CODEC_CONFIG_SAMPLE_FORMAT);
452#else
453 (void)context;
454 return codec->sample_fmts;
455#endif
456}
457
458// AVChannelLayout itself is unavailable before FFmpeg 5.1. Guard the whole
459// declaration, not only the function body.
460#if HAVE_CH_LAYOUT
461inline static const AVChannelLayout* ffmpeg_codec_ch_layouts(const AVCodec* codec,
462 const AVCodecContext* context) {
463#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 13, 100)
464 return ffmpeg_codec_config<AVChannelLayout>(codec, context, AV_CODEC_CONFIG_CHANNEL_LAYOUT);
465#else
466 (void)context;
467 return codec->ch_layouts;
468#endif
469}
470#endif
471
472inline static void* aligned_malloc(size_t size, size_t alignment = 32)
473{
474#if defined(_WIN32)
475 return _aligned_malloc(size, alignment);
476#elif defined(__APPLE__) || defined(__linux__)
477 void* ptr = nullptr;
478 if (posix_memalign(&ptr, alignment, size) != 0)
479 return nullptr;
480 return ptr;
481#else
482#error "aligned_malloc not implemented on this platform"
483#endif
484}
485
486#endif // OPENSHOT_FFMPEG_UTILITIES_H
Header file for all Exception classes.
#define AV_ERROR_MAX_STRING_SIZE
#define PixelFormat
Header file that includes the version number of libopenshot.
Exception when no valid codec is found for a file.
Definition Exceptions.h:179