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