OpenShot Library | libopenshot  0.4.0
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 "OpenShotVersion.h" // For FFMPEG_USE_SWRESAMPLE
17 
18 // Required for libavformat to build on Windows
19 #ifndef INT64_C
20 #define INT64_C(c) (c ## LL)
21 #define UINT64_C(c) (c ## ULL)
22 #endif
23 
24 #ifndef IS_FFMPEG_3_2
25 #define IS_FFMPEG_3_2 (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 64, 101))
26 #endif
27 
28 #ifndef USE_HW_ACCEL
29 #define USE_HW_ACCEL (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 107, 100))
30 #endif
31 
32 #ifndef USE_SW
33 #define USE_SW FFMPEG_USE_SWRESAMPLE
34 #endif
35 
36 #define HAVE_CH_LAYOUT (LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 28, 100))
37 
38 // Include the FFmpeg headers
39 extern "C" {
40  #include <libavcodec/avcodec.h>
41  #include <libavformat/avformat.h>
42  #include <libavutil/display.h>
43 
44 #if (LIBAVFORMAT_VERSION_MAJOR >= 57)
45  #include <libavutil/hwcontext.h> //PM
46 #endif
47  #include <libswscale/swscale.h>
48 
49 #if USE_SW
50  #include <libswresample/swresample.h>
51 #else
52  #include <libavresample/avresample.h>
53 #endif
54 
55  #include <libavutil/mathematics.h>
56  #include <libavutil/pixfmt.h>
57  #include <libavutil/pixdesc.h>
58 
59  // libavutil changed folders at some point
60 #if LIBAVFORMAT_VERSION_MAJOR >= 53
61  #include <libavutil/opt.h>
62 #else
63  #include <libavcodec/opt.h>
64 #endif
65 
66  // channel header refactored
67 #if LIBAVFORMAT_VERSION_MAJOR >= 54
68  #include <libavutil/channel_layout.h>
69 #endif
70 
71 #if IS_FFMPEG_3_2
72  #include "libavutil/imgutils.h"
73 #endif
74 }
75 
76 // This was removed from newer versions of FFmpeg (but still used in libopenshot)
77 #ifndef AVCODEC_MAX_AUDIO_FRAME_SIZE
78  // 1 second of 48khz 32bit audio
79  #define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000
80 #endif
81 #ifndef AV_ERROR_MAX_STRING_SIZE
82  #define AV_ERROR_MAX_STRING_SIZE 64
83 #endif
84 #ifndef AUDIO_PACKET_ENCODING_SIZE
85  // 48khz * S16 (2 bytes) * max channels (8)
86  #define AUDIO_PACKET_ENCODING_SIZE 768000
87 #endif
88 
89 // This wraps an unsafe C macro to be C++ compatible function
90 inline static const std::string av_err2string(int errnum)
91 {
92  char errbuf[AV_ERROR_MAX_STRING_SIZE];
93  av_strerror(errnum, errbuf, AV_ERROR_MAX_STRING_SIZE);
94  return static_cast<std::string>(errbuf);
95 }
96 
97 // Redefine the C macro to use our new C++ function
98 #undef av_err2str
99 #define av_err2str(errnum) av_err2string(errnum).c_str()
100 
101 // Define this for compatibility
102 #ifndef PixelFormat
103  #define PixelFormat AVPixelFormat
104 #endif
105 #ifndef PIX_FMT_RGBA
106  #define PIX_FMT_RGBA AV_PIX_FMT_RGBA
107 #endif
108 #ifndef PIX_FMT_NONE
109  #define PIX_FMT_NONE AV_PIX_FMT_NONE
110 #endif
111 #ifndef PIX_FMT_RGB24
112  #define PIX_FMT_RGB24 AV_PIX_FMT_RGB24
113 #endif
114 #ifndef PIX_FMT_YUV420P
115  #define PIX_FMT_YUV420P AV_PIX_FMT_YUV420P
116 #endif
117 #ifndef PIX_FMT_YUV444P
118  #define PIX_FMT_YUV444P AV_PIX_FMT_YUV444P
119 #endif
120 
121 // Does ffmpeg pixel format contain an alpha channel?
122 inline static bool ffmpeg_has_alpha(PixelFormat pix_fmt) {
123  const AVPixFmtDescriptor *fmt_desc = av_pix_fmt_desc_get(pix_fmt);
124  return bool(fmt_desc->flags & AV_PIX_FMT_FLAG_ALPHA);
125 }
126 
127 // FFmpeg's libavutil/common.h defines an RSHIFT incompatible with Ruby's
128 // definition in ruby/config.h, so we move it to FF_RSHIFT
129 #ifdef RSHIFT
130  #define FF_RSHIFT(a, b) RSHIFT(a, b)
131  #undef RSHIFT
132 #endif
133 
134 // libswresample/libavresample API switching
135 #if USE_SW
136  #define SWR_CONVERT(ctx, out, linesize, out_count, in, linesize2, in_count) \
137  swr_convert(ctx, out, out_count, (const uint8_t **)in, in_count)
138  #define SWR_ALLOC() swr_alloc()
139  #define SWR_CLOSE(ctx) {}
140  #define SWR_FREE(ctx) swr_free(ctx)
141  #define SWR_INIT(ctx) swr_init(ctx)
142  #define SWRCONTEXT SwrContext
143 
144 #else
145  #define SWR_CONVERT(ctx, out, linesize, out_count, in, linesize2, in_count) \
146  avresample_convert(ctx, out, linesize, out_count, (uint8_t **)in, linesize2, in_count)
147  #define SWR_ALLOC() avresample_alloc_context()
148  #define SWR_CLOSE(ctx) avresample_close(ctx)
149  #define SWR_FREE(ctx) avresample_free(ctx)
150  #define SWR_INIT(ctx) avresample_open(ctx)
151  #define SWRCONTEXT AVAudioResampleContext
152 #endif
153 
154 
155 #if (LIBAVFORMAT_VERSION_MAJOR >= 58)
156  #define AV_REGISTER_ALL
157  #define AVCODEC_REGISTER_ALL
158  #define AV_FILENAME url
159  #define AV_SET_FILENAME(oc, f) oc->AV_FILENAME = av_strdup(f)
160  #define MY_INPUT_BUFFER_PADDING_SIZE AV_INPUT_BUFFER_PADDING_SIZE
161  #define AV_ALLOCATE_FRAME() av_frame_alloc()
162  #define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) \
163  av_image_alloc(av_frame->data, av_frame->linesize, width, height, pix_fmt, 1)
164  #define AV_RESET_FRAME(av_frame) av_frame_unref(av_frame)
165  #define AV_FREE_FRAME(av_frame) av_frame_free(av_frame)
166  #define AV_FREE_PACKET(av_packet) av_packet_unref(av_packet)
167  #define AV_FREE_CONTEXT(av_context) avcodec_free_context(&av_context)
168  #define AV_GET_CODEC_TYPE(av_stream) av_stream->codecpar->codec_type
169  #define AV_FIND_DECODER_CODEC_ID(av_stream) av_stream->codecpar->codec_id
170  #define AV_GET_CODEC_CONTEXT(av_stream, av_codec) \
171  ({ AVCodecContext *context = avcodec_alloc_context3(av_codec); \
172  avcodec_parameters_to_context(context, av_stream->codecpar); \
173  context; })
174  #define AV_GET_CODEC_PAR_CONTEXT(av_stream, av_codec) av_codec;
175  #define AV_GET_CODEC_FROM_STREAM(av_stream,codec_in)
176  #define AV_GET_CODEC_ATTRIBUTES(av_stream, av_context) av_stream->codecpar
177  #define AV_GET_CODEC_PIXEL_FORMAT(av_stream, av_context) (AVPixelFormat) av_stream->codecpar->format
178  #define AV_GET_SAMPLE_FORMAT(av_stream, av_context) av_stream->codecpar->format
179  #define AV_GET_IMAGE_SIZE(pix_fmt, width, height) \
180  av_image_get_buffer_size(pix_fmt, width, height, 1)
181  #define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, height) \
182  av_image_fill_arrays(av_frame->data, av_frame->linesize, buffer, pix_fmt, width, height, 1)
183  #define AV_OUTPUT_CONTEXT(output_context, path) avformat_alloc_output_context2( output_context, NULL, NULL, path)
184  #define AV_OPTION_FIND(priv_data, name) av_opt_find(priv_data, name, NULL, 0, 0)
185  #define AV_OPTION_SET( av_stream, priv_data, name, value, avcodec) \
186  av_opt_set(priv_data, name, value, 0); \
187  avcodec_parameters_from_context(av_stream->codecpar, avcodec);
188  #define ALLOC_CODEC_CTX(ctx, codec, stream) \
189  ctx = avcodec_alloc_context3(codec);
190  #define AV_COPY_PARAMS_FROM_CONTEXT(av_stream, av_codec_ctx) \
191  avcodec_parameters_from_context(av_stream->codecpar, av_codec_ctx);
192 
193 #elif IS_FFMPEG_3_2
194  #define AV_REGISTER_ALL av_register_all();
195  #define AVCODEC_REGISTER_ALL avcodec_register_all();
196  #define AV_FILENAME filename
197  #define AV_SET_FILENAME(oc, f) snprintf(oc->AV_FILENAME, sizeof(oc->AV_FILENAME), "%s", f)
198  #define MY_INPUT_BUFFER_PADDING_SIZE FF_INPUT_BUFFER_PADDING_SIZE
199  #define AV_ALLOCATE_FRAME() av_frame_alloc()
200  #define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) \
201  av_image_alloc(av_frame->data, av_frame->linesize, width, height, pix_fmt, 1)
202  #define AV_RESET_FRAME(av_frame) av_frame_unref(av_frame)
203  #define AV_FREE_FRAME(av_frame) av_frame_free(av_frame)
204  #define AV_FREE_PACKET(av_packet) av_packet_unref(av_packet)
205  #define AV_FREE_CONTEXT(av_context) avcodec_free_context(&av_context)
206  #define AV_GET_CODEC_TYPE(av_stream) av_stream->codecpar->codec_type
207  #define AV_FIND_DECODER_CODEC_ID(av_stream) av_stream->codecpar->codec_id
208  #define AV_GET_CODEC_CONTEXT(av_stream, av_codec) \
209  ({ AVCodecContext *context = avcodec_alloc_context3(av_codec); \
210  avcodec_parameters_to_context(context, av_stream->codecpar); \
211  context; })
212  #define AV_GET_CODEC_PAR_CONTEXT(av_stream, av_codec) av_codec;
213  #define AV_GET_CODEC_FROM_STREAM(av_stream,codec_in)
214  #define AV_GET_CODEC_ATTRIBUTES(av_stream, av_context) av_stream->codecpar
215  #define AV_GET_CODEC_PIXEL_FORMAT(av_stream, av_context) \
216  (AVPixelFormat) av_stream->codecpar->format
217  #define AV_GET_SAMPLE_FORMAT(av_stream, av_context) av_stream->codecpar->format
218  #define AV_GET_IMAGE_SIZE(pix_fmt, width, height) av_image_get_buffer_size(pix_fmt, width, height, 1)
219  #define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, height) \
220  av_image_fill_arrays(av_frame->data, av_frame->linesize, buffer, pix_fmt, width, height, 1)
221  #define AV_OUTPUT_CONTEXT(output_context, path) \
222  avformat_alloc_output_context2( output_context, NULL, NULL, path)
223  #define AV_OPTION_FIND(priv_data, name) av_opt_find(priv_data, name, NULL, 0, 0)
224  #define AV_OPTION_SET( av_stream, priv_data, name, value, avcodec) \
225  av_opt_set(priv_data, name, value, 0); \
226  avcodec_parameters_from_context(av_stream->codecpar, avcodec);
227  #define ALLOC_CODEC_CTX(ctx, codec, stream) \
228  ctx = avcodec_alloc_context3(codec);
229  #define AV_COPY_PARAMS_FROM_CONTEXT(av_stream, av_codec) \
230  avcodec_parameters_from_context(av_stream->codecpar, av_codec);
231 
232 #elif LIBAVFORMAT_VERSION_MAJOR >= 55
233  #define AV_REGISTER_ALL av_register_all();
234  #define AVCODEC_REGISTER_ALL avcodec_register_all();
235  #define AV_FILENAME filename
236  #define AV_SET_FILENAME(oc, f) snprintf(oc->AV_FILENAME, sizeof(oc->AV_FILENAME), "%s", f)
237  #define MY_INPUT_BUFFER_PADDING_SIZE FF_INPUT_BUFFER_PADDING_SIZE
238  #define AV_ALLOCATE_FRAME() av_frame_alloc()
239  #define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) \
240  avpicture_alloc((AVPicture *) av_frame, pix_fmt, width, height)
241  #define AV_RESET_FRAME(av_frame) av_frame_unref(av_frame)
242  #define AV_FREE_FRAME(av_frame) av_frame_free(av_frame)
243  #define AV_FREE_PACKET(av_packet) av_packet_unref(av_packet)
244  #define AV_FREE_CONTEXT(av_context) avcodec_close(av_context)
245  #define AV_GET_CODEC_TYPE(av_stream) av_stream->codec->codec_type
246  #define AV_FIND_DECODER_CODEC_ID(av_stream) av_stream->codec->codec_id
247  #define AV_GET_CODEC_CONTEXT(av_stream, av_codec) av_stream->codec
248  #define AV_GET_CODEC_PAR_CONTEXT(av_stream, av_codec) av_stream->codec
249  #define AV_GET_CODEC_FROM_STREAM(av_stream, codec_in) codec_in = av_stream->codec;
250  #define AV_GET_CODEC_ATTRIBUTES(av_stream, av_context) av_context
251  #define AV_GET_CODEC_PIXEL_FORMAT(av_stream, av_context) av_context->pix_fmt
252  #define AV_GET_SAMPLE_FORMAT(av_stream, av_context) av_context->sample_fmt
253  #define AV_GET_IMAGE_SIZE(pix_fmt, width, height) avpicture_get_size(pix_fmt, width, height)
254  #define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, height) \
255  avpicture_fill((AVPicture *) av_frame, buffer, pix_fmt, width, height)
256  #define AV_OUTPUT_CONTEXT(output_context, path) oc = avformat_alloc_context()
257  #define AV_OPTION_FIND(priv_data, name) av_opt_find(priv_data, name, NULL, 0, 0)
258  #define AV_OPTION_SET(av_stream, priv_data, name, value, avcodec) av_opt_set (priv_data, name, value, 0)
259  #define ALLOC_CODEC_CTX(ctx, av_codec, stream) \
260  avcodec_get_context_defaults3(av_st->codec, av_codec); \
261  ctx = av_st->codec;
262  #define AV_COPY_PARAMS_FROM_CONTEXT(av_stream, av_codec)
263 
264 #else
265  #define AV_REGISTER_ALL av_register_all();
266  #define AVCODEC_REGISTER_ALL avcodec_register_all();
267  #define AV_FILENAME filename
268  #define AV_SET_FILENAME(oc, f) snprintf(oc->AV_FILENAME, sizeof(oc->AV_FILENAME), "%s", f)
269  #define MY_INPUT_BUFFER_PADDING_SIZE FF_INPUT_BUFFER_PADDING_SIZE
270  #define AV_ALLOCATE_FRAME() avcodec_alloc_frame()
271  #define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) \
272  avpicture_alloc((AVPicture *) av_frame, pix_fmt, width, height)
273  #define AV_RESET_FRAME(av_frame) avcodec_get_frame_defaults(av_frame)
274  #define AV_FREE_FRAME(av_frame) avcodec_free_frame(av_frame)
275  #define AV_FREE_PACKET(av_packet) av_free_packet(av_packet)
276  #define AV_FREE_CONTEXT(av_context) avcodec_close(av_context)
277  #define AV_GET_CODEC_TYPE(av_stream) av_stream->codec->codec_type
278  #define AV_FIND_DECODER_CODEC_ID(av_stream) av_stream->codec->codec_id
279  #define AV_GET_CODEC_CONTEXT(av_stream, av_codec) av_stream->codec
280  #define AV_GET_CODEC_PAR_CONTEXT(av_stream, av_codec) av_stream->codec
281  #define AV_GET_CODEC_FROM_STREAM(av_stream, codec_in ) codec_in = av_stream->codec;
282  #define AV_GET_CODEC_ATTRIBUTES(av_stream, av_context) av_context
283  #define AV_GET_CODEC_PIXEL_FORMAT(av_stream, av_context) av_context->pix_fmt
284  #define AV_GET_SAMPLE_FORMAT(av_stream, av_context) av_context->sample_fmt
285  #define AV_GET_IMAGE_SIZE(pix_fmt, width, height) avpicture_get_size(pix_fmt, width, height)
286  #define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, height) \
287  avpicture_fill((AVPicture *) av_frame, buffer, pix_fmt, width, height)
288  #define AV_OUTPUT_CONTEXT(output_context, path) oc = avformat_alloc_context()
289  #define AV_OPTION_FIND(priv_data, name) av_opt_find(priv_data, name, NULL, 0, 0)
290  #define AV_OPTION_SET(av_stream, priv_data, name, value, avcodec) av_opt_set (priv_data, name, value, 0)
291  #define ALLOC_CODEC_CTX(ctx, av_codec, stream) \
292  avcodec_get_context_defaults3(stream->codec, av_codec); \
293  ctx = stream->codec;
294  #define AV_COPY_PARAMS_FROM_CONTEXT(av_stream, av_codec)
295 #endif
296 
297 
298 #endif // OPENSHOT_FFMPEG_UTILITIES_H
PixelFormat
#define PixelFormat
Definition: FFmpegUtilities.h:103
OpenShotVersion.h
Header file that includes the version number of libopenshot.
AV_ERROR_MAX_STRING_SIZE
#define AV_ERROR_MAX_STRING_SIZE
Definition: FFmpegUtilities.h:82