OpenShot Library | libopenshot  0.2.6
FFmpegUtilities.h
Go to the documentation of this file.
1 /**
2  * @file
3  * @brief Header file for FFmpegUtilities
4  * @author Jonathan Thomas <jonathan@openshot.org>
5  *
6  * @ref License
7  */
8 
9 /* LICENSE
10  *
11  * Copyright (c) 2008-2019 OpenShot Studios, LLC
12  * <http://www.openshotstudios.com/>. This file is part of
13  * OpenShot Library (libopenshot), an open-source project dedicated to
14  * delivering high quality video editing and animation solutions to the
15  * world. For more information visit <http://www.openshot.org/>.
16  *
17  * OpenShot Library (libopenshot) is free software: you can redistribute it
18  * and/or modify it under the terms of the GNU Lesser General Public License
19  * as published by the Free Software Foundation, either version 3 of the
20  * License, or (at your option) any later version.
21  *
22  * OpenShot Library (libopenshot) is distributed in the hope that it will be
23  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25  * GNU Lesser General Public License for more details.
26  *
27  * You should have received a copy of the GNU Lesser General Public License
28  * along with OpenShot Library. If not, see <http://www.gnu.org/licenses/>.
29  */
30 
31 #ifndef OPENSHOT_FFMPEG_UTILITIES_H
32 #define OPENSHOT_FFMPEG_UTILITIES_H
33 
34 #include "OpenShotVersion.h" // For FFMPEG_USE_SWRESAMPLE
35 
36 // Required for libavformat to build on Windows
37 #ifndef INT64_C
38 #define INT64_C(c) (c ## LL)
39 #define UINT64_C(c) (c ## ULL)
40 #endif
41 
42 #ifndef IS_FFMPEG_3_2
43 #define IS_FFMPEG_3_2 (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 64, 101))
44 #endif
45 
46 #ifndef USE_HW_ACCEL
47 #define USE_HW_ACCEL (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 107, 100))
48 #endif
49 
50 #ifndef USE_SW
51 #define USE_SW FFMPEG_USE_SWRESAMPLE
52 #endif
53 
54 // Include the FFmpeg headers
55 extern "C" {
56  #include <libavcodec/avcodec.h>
57  #include <libavformat/avformat.h>
58 
59 #if (LIBAVFORMAT_VERSION_MAJOR >= 57)
60  #include <libavutil/hwcontext.h> //PM
61 #endif
62  #include <libswscale/swscale.h>
63 
64 #if USE_SW
65  #include <libswresample/swresample.h>
66 #else
67  #include <libavresample/avresample.h>
68 #endif
69 
70  #include <libavutil/mathematics.h>
71  #include <libavutil/pixfmt.h>
72  #include <libavutil/pixdesc.h>
73 
74  // libavutil changed folders at some point
75 #if LIBAVFORMAT_VERSION_MAJOR >= 53
76  #include <libavutil/opt.h>
77 #else
78  #include <libavcodec/opt.h>
79 #endif
80 
81  // channel header refactored
82 #if LIBAVFORMAT_VERSION_MAJOR >= 54
83  #include <libavutil/channel_layout.h>
84 #endif
85 
86 #if IS_FFMPEG_3_2
87  #include "libavutil/imgutils.h"
88 #endif
89 }
90 
91 // This was removed from newer versions of FFmpeg (but still used in libopenshot)
92 #ifndef AVCODEC_MAX_AUDIO_FRAME_SIZE
93  // 1 second of 48khz 32bit audio
94  #define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000
95 #endif
96 #ifndef AV_ERROR_MAX_STRING_SIZE
97  #define AV_ERROR_MAX_STRING_SIZE 64
98 #endif
99 #ifndef AUDIO_PACKET_ENCODING_SIZE
100  // 48khz * S16 (2 bytes) * max channels (8)
101  #define AUDIO_PACKET_ENCODING_SIZE 768000
102 #endif
103 
104 // This wraps an unsafe C macro to be C++ compatible function
105 inline static const std::string av_err2string(int errnum)
106 {
107  char errbuf[AV_ERROR_MAX_STRING_SIZE];
108  av_strerror(errnum, errbuf, AV_ERROR_MAX_STRING_SIZE);
109  return static_cast<std::string>(errbuf);
110 }
111 
112 // Redefine the C macro to use our new C++ function
113 #undef av_err2str
114 #define av_err2str(errnum) av_err2string(errnum).c_str()
115 
116 // Define this for compatibility
117 #ifndef PixelFormat
118  #define PixelFormat AVPixelFormat
119 #endif
120 #ifndef PIX_FMT_RGBA
121  #define PIX_FMT_RGBA AV_PIX_FMT_RGBA
122 #endif
123 #ifndef PIX_FMT_NONE
124  #define PIX_FMT_NONE AV_PIX_FMT_NONE
125 #endif
126 #ifndef PIX_FMT_RGB24
127  #define PIX_FMT_RGB24 AV_PIX_FMT_RGB24
128 #endif
129 #ifndef PIX_FMT_YUV420P
130  #define PIX_FMT_YUV420P AV_PIX_FMT_YUV420P
131 #endif
132 #ifndef PIX_FMT_YUV444P
133  #define PIX_FMT_YUV444P AV_PIX_FMT_YUV444P
134 #endif
135 
136 // Does ffmpeg pixel format contain an alpha channel?
137 inline static bool ffmpeg_has_alpha(PixelFormat pix_fmt) {
138  const AVPixFmtDescriptor *fmt_desc = av_pix_fmt_desc_get(pix_fmt);
139  return bool(fmt_desc->flags & AV_PIX_FMT_FLAG_ALPHA);
140 }
141 
142 // FFmpeg's libavutil/common.h defines an RSHIFT incompatible with Ruby's
143 // definition in ruby/config.h, so we move it to FF_RSHIFT
144 #ifdef RSHIFT
145  #define FF_RSHIFT(a, b) RSHIFT(a, b)
146  #undef RSHIFT
147 #endif
148 
149 // libswresample/libavresample API switching
150 #if USE_SW
151  #define SWR_CONVERT(ctx, out, linesize, out_count, in, linesize2, in_count) \
152  swr_convert(ctx, out, out_count, (const uint8_t **)in, in_count)
153  #define SWR_ALLOC() swr_alloc()
154  #define SWR_CLOSE(ctx) {}
155  #define SWR_FREE(ctx) swr_free(ctx)
156  #define SWR_INIT(ctx) swr_init(ctx)
157  #define SWRCONTEXT SwrContext
158 
159 #else
160  #define SWR_CONVERT(ctx, out, linesize, out_count, in, linesize2, in_count) \
161  avresample_convert(ctx, out, linesize, out_count, (uint8_t **)in, linesize2, in_count)
162  #define SWR_ALLOC() avresample_alloc_context()
163  #define SWR_CLOSE(ctx) avresample_close(ctx)
164  #define SWR_FREE(ctx) avresample_free(ctx)
165  #define SWR_INIT(ctx) avresample_open(ctx)
166  #define SWRCONTEXT AVAudioResampleContext
167 #endif
168 
169 
170 #if (LIBAVFORMAT_VERSION_MAJOR >= 58)
171  #define AV_REGISTER_ALL
172  #define AVCODEC_REGISTER_ALL
173  #define AV_FILENAME url
174  #define AV_SET_FILENAME(oc, f) oc->AV_FILENAME = av_strdup(f)
175  #define MY_INPUT_BUFFER_PADDING_SIZE AV_INPUT_BUFFER_PADDING_SIZE
176  #define AV_ALLOCATE_FRAME() av_frame_alloc()
177  #define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) \
178  av_image_alloc(av_frame->data, av_frame->linesize, width, height, pix_fmt, 1)
179  #define AV_RESET_FRAME(av_frame) av_frame_unref(av_frame)
180  #define AV_FREE_FRAME(av_frame) av_frame_free(av_frame)
181  #define AV_FREE_PACKET(av_packet) av_packet_unref(av_packet)
182  #define AV_FREE_CONTEXT(av_context) avcodec_free_context(&av_context)
183  #define AV_GET_CODEC_TYPE(av_stream) av_stream->codecpar->codec_type
184  #define AV_FIND_DECODER_CODEC_ID(av_stream) av_stream->codecpar->codec_id
185  #define AV_GET_CODEC_CONTEXT(av_stream, av_codec) \
186  ({ AVCodecContext *context = avcodec_alloc_context3(av_codec); \
187  avcodec_parameters_to_context(context, av_stream->codecpar); \
188  context; })
189  #define AV_GET_CODEC_PAR_CONTEXT(av_stream, av_codec) av_codec;
190  #define AV_GET_CODEC_FROM_STREAM(av_stream,codec_in)
191  #define AV_GET_CODEC_ATTRIBUTES(av_stream, av_context) av_stream->codecpar
192  #define AV_GET_CODEC_PIXEL_FORMAT(av_stream, av_context) (AVPixelFormat) av_stream->codecpar->format
193  #define AV_GET_SAMPLE_FORMAT(av_stream, av_context) av_stream->codecpar->format
194  #define AV_GET_IMAGE_SIZE(pix_fmt, width, height) \
195  av_image_get_buffer_size(pix_fmt, width, height, 1)
196  #define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, height) \
197  av_image_fill_arrays(av_frame->data, av_frame->linesize, buffer, pix_fmt, width, height, 1)
198  #define AV_OUTPUT_CONTEXT(output_context, path) avformat_alloc_output_context2( output_context, NULL, NULL, path)
199  #define AV_OPTION_FIND(priv_data, name) av_opt_find(priv_data, name, NULL, 0, 0)
200  #define AV_OPTION_SET( av_stream, priv_data, name, value, avcodec) \
201  av_opt_set(priv_data, name, value, 0); \
202  avcodec_parameters_from_context(av_stream->codecpar, avcodec);
203  #define AV_FORMAT_NEW_STREAM(oc, st_codec_ctx, av_codec, av_st) \
204  av_st = avformat_new_stream(oc, NULL);\
205  if (!av_st) \
206  throw OutOfMemory("Could not allocate memory for the video stream.", path); \
207  c = avcodec_alloc_context3(av_codec); \
208  st_codec_ctx = c; \
209  av_st->codecpar->codec_id = av_codec->id;
210  #define AV_COPY_PARAMS_FROM_CONTEXT(av_stream, av_codec_ctx) \
211  avcodec_parameters_from_context(av_stream->codecpar, av_codec_ctx);
212 
213 #elif IS_FFMPEG_3_2
214  #define AV_REGISTER_ALL av_register_all();
215  #define AVCODEC_REGISTER_ALL avcodec_register_all();
216  #define AV_FILENAME filename
217  #define AV_SET_FILENAME(oc, f) snprintf(oc->AV_FILENAME, sizeof(oc->AV_FILENAME), "%s", f)
218  #define MY_INPUT_BUFFER_PADDING_SIZE FF_INPUT_BUFFER_PADDING_SIZE
219  #define AV_ALLOCATE_FRAME() av_frame_alloc()
220  #define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) \
221  av_image_alloc(av_frame->data, av_frame->linesize, width, height, pix_fmt, 1)
222  #define AV_RESET_FRAME(av_frame) av_frame_unref(av_frame)
223  #define AV_FREE_FRAME(av_frame) av_frame_free(av_frame)
224  #define AV_FREE_PACKET(av_packet) av_packet_unref(av_packet)
225  #define AV_FREE_CONTEXT(av_context) avcodec_free_context(&av_context)
226  #define AV_GET_CODEC_TYPE(av_stream) av_stream->codecpar->codec_type
227  #define AV_FIND_DECODER_CODEC_ID(av_stream) av_stream->codecpar->codec_id
228  #define AV_GET_CODEC_CONTEXT(av_stream, av_codec) \
229  ({ AVCodecContext *context = avcodec_alloc_context3(av_codec); \
230  avcodec_parameters_to_context(context, av_stream->codecpar); \
231  context; })
232  #define AV_GET_CODEC_PAR_CONTEXT(av_stream, av_codec) av_codec;
233  #define AV_GET_CODEC_FROM_STREAM(av_stream,codec_in)
234  #define AV_GET_CODEC_ATTRIBUTES(av_stream, av_context) av_stream->codecpar
235  #define AV_GET_CODEC_PIXEL_FORMAT(av_stream, av_context) \
236  (AVPixelFormat) av_stream->codecpar->format
237  #define AV_GET_SAMPLE_FORMAT(av_stream, av_context) av_stream->codecpar->format
238  #define AV_GET_IMAGE_SIZE(pix_fmt, width, height) av_image_get_buffer_size(pix_fmt, width, height, 1)
239  #define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, height) \
240  av_image_fill_arrays(av_frame->data, av_frame->linesize, buffer, pix_fmt, width, height, 1)
241  #define AV_OUTPUT_CONTEXT(output_context, path) \
242  avformat_alloc_output_context2( output_context, NULL, NULL, path)
243  #define AV_OPTION_FIND(priv_data, name) av_opt_find(priv_data, name, NULL, 0, 0)
244  #define AV_OPTION_SET( av_stream, priv_data, name, value, avcodec) \
245  av_opt_set(priv_data, name, value, 0); \
246  avcodec_parameters_from_context(av_stream->codecpar, avcodec);
247  #define AV_FORMAT_NEW_STREAM(oc, st_codec, av_codec, av_st) \
248  av_st = avformat_new_stream(oc, NULL);\
249  if (!av_st) \
250  throw OutOfMemory("Could not allocate memory for the video stream.", path); \
251  _Pragma ("GCC diagnostic push"); \
252  _Pragma ("GCC diagnostic ignored \"-Wdeprecated-declarations\""); \
253  avcodec_get_context_defaults3(av_st->codec, av_codec); \
254  c = av_st->codec; \
255  _Pragma ("GCC diagnostic pop"); \
256  st_codec = c;
257  #define AV_COPY_PARAMS_FROM_CONTEXT(av_stream, av_codec) \
258  avcodec_parameters_from_context(av_stream->codecpar, av_codec);
259 
260 #elif LIBAVFORMAT_VERSION_MAJOR >= 55
261  #define AV_REGISTER_ALL av_register_all();
262  #define AVCODEC_REGISTER_ALL avcodec_register_all();
263  #define AV_FILENAME filename
264  #define AV_SET_FILENAME(oc, f) snprintf(oc->AV_FILENAME, sizeof(oc->AV_FILENAME), "%s", f)
265  #define MY_INPUT_BUFFER_PADDING_SIZE FF_INPUT_BUFFER_PADDING_SIZE
266  #define AV_ALLOCATE_FRAME() av_frame_alloc()
267  #define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) \
268  avpicture_alloc((AVPicture *) av_frame, pix_fmt, width, height)
269  #define AV_RESET_FRAME(av_frame) av_frame_unref(av_frame)
270  #define AV_FREE_FRAME(av_frame) av_frame_free(av_frame)
271  #define AV_FREE_PACKET(av_packet) av_packet_unref(av_packet)
272  #define AV_FREE_CONTEXT(av_context) avcodec_close(av_context)
273  #define AV_GET_CODEC_TYPE(av_stream) av_stream->codec->codec_type
274  #define AV_FIND_DECODER_CODEC_ID(av_stream) av_stream->codec->codec_id
275  #define AV_GET_CODEC_CONTEXT(av_stream, av_codec) av_stream->codec
276  #define AV_GET_CODEC_PAR_CONTEXT(av_stream, av_codec) av_stream->codec
277  #define AV_GET_CODEC_FROM_STREAM(av_stream, codec_in) codec_in = av_stream->codec;
278  #define AV_GET_CODEC_ATTRIBUTES(av_stream, av_context) av_context
279  #define AV_GET_CODEC_PIXEL_FORMAT(av_stream, av_context) av_context->pix_fmt
280  #define AV_GET_SAMPLE_FORMAT(av_stream, av_context) av_context->sample_fmt
281  #define AV_GET_IMAGE_SIZE(pix_fmt, width, height) avpicture_get_size(pix_fmt, width, height)
282  #define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, height) \
283  avpicture_fill((AVPicture *) av_frame, buffer, pix_fmt, width, height)
284  #define AV_OUTPUT_CONTEXT(output_context, path) oc = avformat_alloc_context()
285  #define AV_OPTION_FIND(priv_data, name) av_opt_find(priv_data, name, NULL, 0, 0)
286  #define AV_OPTION_SET(av_stream, priv_data, name, value, avcodec) av_opt_set (priv_data, name, value, 0)
287  #define AV_FORMAT_NEW_STREAM( oc, av_context, av_codec, av_st) \
288  av_st = avformat_new_stream(oc, av_codec); \
289  if (!av_st) \
290  throw OutOfMemory("Could not allocate memory for the video stream.", path); \
291  avcodec_get_context_defaults3(av_st->codec, av_codec); \
292  c = av_st->codec;
293  #define AV_COPY_PARAMS_FROM_CONTEXT(av_stream, av_codec)
294 
295 #else
296  #define AV_REGISTER_ALL av_register_all();
297  #define AVCODEC_REGISTER_ALL avcodec_register_all();
298  #define AV_FILENAME filename
299  #define AV_SET_FILENAME(oc, f) snprintf(oc->AV_FILENAME, sizeof(oc->AV_FILENAME), "%s", f)
300  #define MY_INPUT_BUFFER_PADDING_SIZE FF_INPUT_BUFFER_PADDING_SIZE
301  #define AV_ALLOCATE_FRAME() avcodec_alloc_frame()
302  #define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) \
303  avpicture_alloc((AVPicture *) av_frame, pix_fmt, width, height)
304  #define AV_RESET_FRAME(av_frame) avcodec_get_frame_defaults(av_frame)
305  #define AV_FREE_FRAME(av_frame) avcodec_free_frame(av_frame)
306  #define AV_FREE_PACKET(av_packet) av_free_packet(av_packet)
307  #define AV_FREE_CONTEXT(av_context) avcodec_close(av_context)
308  #define AV_GET_CODEC_TYPE(av_stream) av_stream->codec->codec_type
309  #define AV_FIND_DECODER_CODEC_ID(av_stream) av_stream->codec->codec_id
310  #define AV_GET_CODEC_CONTEXT(av_stream, av_codec) av_stream->codec
311  #define AV_GET_CODEC_PAR_CONTEXT(av_stream, av_codec) av_stream->codec
312  #define AV_GET_CODEC_FROM_STREAM(av_stream, codec_in ) codec_in = av_stream->codec;
313  #define AV_GET_CODEC_ATTRIBUTES(av_stream, av_context) av_context
314  #define AV_GET_CODEC_PIXEL_FORMAT(av_stream, av_context) av_context->pix_fmt
315  #define AV_GET_SAMPLE_FORMAT(av_stream, av_context) av_context->sample_fmt
316  #define AV_GET_IMAGE_SIZE(pix_fmt, width, height) avpicture_get_size(pix_fmt, width, height)
317  #define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, height) \
318  avpicture_fill((AVPicture *) av_frame, buffer, pix_fmt, width, height)
319  #define AV_OUTPUT_CONTEXT(output_context, path) oc = avformat_alloc_context()
320  #define AV_OPTION_FIND(priv_data, name) av_opt_find(priv_data, name, NULL, 0, 0)
321  #define AV_OPTION_SET(av_stream, priv_data, name, value, avcodec) av_opt_set (priv_data, name, value, 0)
322  #define AV_FORMAT_NEW_STREAM( oc, av_context, av_codec, av_st) \
323  av_st = avformat_new_stream(oc, av_codec); \
324  if (!av_st) \
325  throw OutOfMemory("Could not allocate memory for the video stream.", path); \
326  avcodec_get_context_defaults3(av_st->codec, av_codec); \
327  c = av_st->codec;
328  #define AV_COPY_PARAMS_FROM_CONTEXT(av_stream, av_codec)
329 #endif
330 
331 
332 #endif // OPENSHOT_FFMPEG_UTILITIES_H
#define AV_ERROR_MAX_STRING_SIZE
#define PixelFormat
Header file that includes the version number of libopenshot.