FFmpeg  4.3
internal.h
Go to the documentation of this file.
1 /*
2  * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 /**
22  * @file
23  * common internal API header
24  */
25 
26 #ifndef AVUTIL_INTERNAL_H
27 #define AVUTIL_INTERNAL_H
28 
29 #if !defined(DEBUG) && !defined(NDEBUG)
30 # define NDEBUG
31 #endif
32 
33 // This can be enabled to allow detection of additional integer overflows with ubsan
34 //#define CHECKED
35 
36 #include <limits.h>
37 #include <stdint.h>
38 #include <stddef.h>
39 #include <assert.h>
40 #include "config.h"
41 #include "attributes.h"
42 #include "timer.h"
43 #include "cpu.h"
44 #include "dict.h"
45 #include "macros.h"
46 #include "mem.h"
47 #include "pixfmt.h"
48 #include "version.h"
49 
50 #if ARCH_X86
51 # include "x86/emms.h"
52 #endif
53 
54 #ifndef emms_c
55 # define emms_c() do {} while(0)
56 #endif
57 
58 #ifndef attribute_align_arg
59 #if ARCH_X86_32 && AV_GCC_VERSION_AT_LEAST(4,2)
60 # define attribute_align_arg __attribute__((force_align_arg_pointer))
61 #else
62 # define attribute_align_arg
63 #endif
64 #endif
65 
66 #if defined(_WIN32) && CONFIG_SHARED && !defined(BUILDING_avutil)
67 # define av_export_avutil __declspec(dllimport)
68 #else
69 # define av_export_avutil
70 #endif
71 
72 #if HAVE_PRAGMA_DEPRECATED
73 # if defined(__ICL) || defined (__INTEL_COMPILER)
74 # define FF_DISABLE_DEPRECATION_WARNINGS __pragma(warning(push)) __pragma(warning(disable:1478))
75 # define FF_ENABLE_DEPRECATION_WARNINGS __pragma(warning(pop))
76 # elif defined(_MSC_VER)
77 # define FF_DISABLE_DEPRECATION_WARNINGS __pragma(warning(push)) __pragma(warning(disable:4996))
78 # define FF_ENABLE_DEPRECATION_WARNINGS __pragma(warning(pop))
79 # else
80 # define FF_DISABLE_DEPRECATION_WARNINGS _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
81 # define FF_ENABLE_DEPRECATION_WARNINGS _Pragma("GCC diagnostic pop")
82 # endif
83 #else
84 # define FF_DISABLE_DEPRECATION_WARNINGS
85 # define FF_ENABLE_DEPRECATION_WARNINGS
86 #endif
87 
88 
89 #define FF_MEMORY_POISON 0x2a
90 
91 #define MAKE_ACCESSORS(str, name, type, field) \
92  type av_##name##_get_##field(const str *s) { return s->field; } \
93  void av_##name##_set_##field(str *s, type v) { s->field = v; }
94 
95 // Some broken preprocessors need a second expansion
96 // to be forced to tokenize __VA_ARGS__
97 #define E1(x) x
98 
99 /* Check if the hard coded offset of a struct member still matches reality.
100  * Induce a compilation failure if not.
101  */
102 #define AV_CHECK_OFFSET(s, m, o) struct check_##o { \
103  int x_##o[offsetof(s, m) == o? 1: -1]; \
104  }
105 
106 #define LOCAL_ALIGNED_A(a, t, v, s, o, ...) \
107  uint8_t la_##v[sizeof(t s o) + (a)]; \
108  t (*v) o = (void *)FFALIGN((uintptr_t)la_##v, a)
109 
110 #define LOCAL_ALIGNED_D(a, t, v, s, o, ...) \
111  DECLARE_ALIGNED(a, t, la_##v) s o; \
112  t (*v) o = la_##v
113 
114 #define LOCAL_ALIGNED(a, t, v, ...) LOCAL_ALIGNED_##a(t, v, __VA_ARGS__)
115 
116 #if HAVE_LOCAL_ALIGNED
117 # define LOCAL_ALIGNED_4(t, v, ...) E1(LOCAL_ALIGNED_D(4, t, v, __VA_ARGS__,,))
118 #else
119 # define LOCAL_ALIGNED_4(t, v, ...) E1(LOCAL_ALIGNED_A(4, t, v, __VA_ARGS__,,))
120 #endif
121 
122 #if HAVE_LOCAL_ALIGNED
123 # define LOCAL_ALIGNED_8(t, v, ...) E1(LOCAL_ALIGNED_D(8, t, v, __VA_ARGS__,,))
124 #else
125 # define LOCAL_ALIGNED_8(t, v, ...) E1(LOCAL_ALIGNED_A(8, t, v, __VA_ARGS__,,))
126 #endif
127 
128 #if HAVE_LOCAL_ALIGNED
129 # define LOCAL_ALIGNED_16(t, v, ...) E1(LOCAL_ALIGNED_D(16, t, v, __VA_ARGS__,,))
130 #else
131 # define LOCAL_ALIGNED_16(t, v, ...) E1(LOCAL_ALIGNED_A(16, t, v, __VA_ARGS__,,))
132 #endif
133 
134 #if HAVE_LOCAL_ALIGNED
135 # define LOCAL_ALIGNED_32(t, v, ...) E1(LOCAL_ALIGNED_D(32, t, v, __VA_ARGS__,,))
136 #else
137 # define LOCAL_ALIGNED_32(t, v, ...) E1(LOCAL_ALIGNED_A(32, t, v, __VA_ARGS__,,))
138 #endif
139 
140 #define FF_ALLOC_OR_GOTO(ctx, p, size, label)\
141 {\
142  p = av_malloc(size);\
143  if (!(p) && (size) != 0) {\
144  av_log(ctx, AV_LOG_ERROR, "Cannot allocate memory.\n");\
145  goto label;\
146  }\
147 }
148 
149 #define FF_ALLOCZ_OR_GOTO(ctx, p, size, label)\
150 {\
151  p = av_mallocz(size);\
152  if (!(p) && (size) != 0) {\
153  av_log(ctx, AV_LOG_ERROR, "Cannot allocate memory.\n");\
154  goto label;\
155  }\
156 }
157 
158 #define FF_ALLOC_ARRAY_OR_GOTO(ctx, p, nelem, elsize, label)\
159 {\
160  p = av_malloc_array(nelem, elsize);\
161  if (!p) {\
162  av_log(ctx, AV_LOG_ERROR, "Cannot allocate memory.\n");\
163  goto label;\
164  }\
165 }
166 
167 #define FF_ALLOCZ_ARRAY_OR_GOTO(ctx, p, nelem, elsize, label)\
168 {\
169  p = av_mallocz_array(nelem, elsize);\
170  if (!p) {\
171  av_log(ctx, AV_LOG_ERROR, "Cannot allocate memory.\n");\
172  goto label;\
173  }\
174 }
175 
176 #include "libm.h"
177 
178 /**
179  * Return NULL if CONFIG_SMALL is true, otherwise the argument
180  * without modification. Used to disable the definition of strings
181  * (for example AVCodec long_names).
182  */
183 #if CONFIG_SMALL
184 # define NULL_IF_CONFIG_SMALL(x) NULL
185 #else
186 # define NULL_IF_CONFIG_SMALL(x) x
187 #endif
188 
189 /**
190  * Define a function with only the non-default version specified.
191  *
192  * On systems with ELF shared libraries, all symbols exported from
193  * FFmpeg libraries are tagged with the name and major version of the
194  * library to which they belong. If a function is moved from one
195  * library to another, a wrapper must be retained in the original
196  * location to preserve binary compatibility.
197  *
198  * Functions defined with this macro will never be used to resolve
199  * symbols by the build-time linker.
200  *
201  * @param type return type of function
202  * @param name name of function
203  * @param args argument list of function
204  * @param ver version tag to assign function
205  */
206 #if HAVE_SYMVER_ASM_LABEL
207 # define FF_SYMVER(type, name, args, ver) \
208  type ff_##name args __asm__ (EXTERN_PREFIX #name "@" ver); \
209  type ff_##name args
210 #elif HAVE_SYMVER_GNU_ASM
211 # define FF_SYMVER(type, name, args, ver) \
212  __asm__ (".symver ff_" #name "," EXTERN_PREFIX #name "@" ver); \
213  type ff_##name args; \
214  type ff_##name args
215 #endif
216 
217 /**
218  * Return NULL if a threading library has not been enabled.
219  * Used to disable threading functions in AVCodec definitions
220  * when not needed.
221  */
222 #if HAVE_THREADS
223 # define ONLY_IF_THREADS_ENABLED(x) x
224 #else
225 # define ONLY_IF_THREADS_ENABLED(x) NULL
226 #endif
227 
228 /**
229  * Log a generic warning message about a missing feature.
230  *
231  * @param[in] avc a pointer to an arbitrary struct of which the first
232  * field is a pointer to an AVClass struct
233  * @param[in] msg string containing the name of the missing feature
234  */
235 void avpriv_report_missing_feature(void *avc,
236  const char *msg, ...) av_printf_format(2, 3);
237 
238 /**
239  * Log a generic warning message about a missing feature.
240  * Additionally request that a sample showcasing the feature be uploaded.
241  *
242  * @param[in] avc a pointer to an arbitrary struct of which the first field is
243  * a pointer to an AVClass struct
244  * @param[in] msg string containing the name of the missing feature
245  */
246 void avpriv_request_sample(void *avc,
247  const char *msg, ...) av_printf_format(2, 3);
248 
249 #if HAVE_LIBC_MSVCRT
250 #include <crtversion.h>
251 #if defined(_VC_CRT_MAJOR_VERSION) && _VC_CRT_MAJOR_VERSION < 14
252 #pragma comment(linker, "/include:" EXTERN_PREFIX "avpriv_strtod")
253 #pragma comment(linker, "/include:" EXTERN_PREFIX "avpriv_snprintf")
254 #endif
255 
256 #define avpriv_open ff_open
257 #define avpriv_tempfile ff_tempfile
258 #define PTRDIFF_SPECIFIER "Id"
259 #define SIZE_SPECIFIER "Iu"
260 #else
261 #define PTRDIFF_SPECIFIER "td"
262 #define SIZE_SPECIFIER "zu"
263 #endif
264 
265 #ifdef DEBUG
266 # define ff_dlog(ctx, ...) av_log(ctx, AV_LOG_DEBUG, __VA_ARGS__)
267 #else
268 # define ff_dlog(ctx, ...) do { if (0) av_log(ctx, AV_LOG_DEBUG, __VA_ARGS__); } while (0)
269 #endif
270 
271 // For debuging we use signed operations so overflows can be detected (by ubsan)
272 // For production we use unsigned so there are no undefined operations
273 #ifdef CHECKED
274 #define SUINT int
275 #define SUINT32 int32_t
276 #else
277 #define SUINT unsigned
278 #define SUINT32 uint32_t
279 #endif
280 
281 /**
282  * Clip and convert a double value into the long long amin-amax range.
283  * This function is needed because conversion of floating point to integers when
284  * it does not fit in the integer's representation does not necessarily saturate
285  * correctly (usually converted to a cvttsd2si on x86) which saturates numbers
286  * > INT64_MAX to INT64_MIN. The standard marks such conversions as undefined
287  * behavior, allowing this sort of mathematically bogus conversions. This provides
288  * a safe alternative that is slower obviously but assures safety and better
289  * mathematical behavior.
290  * @param a value to clip
291  * @param amin minimum value of the clip range
292  * @param amax maximum value of the clip range
293  * @return clipped value
294  */
295 static av_always_inline av_const int64_t ff_rint64_clip(double a, int64_t amin, int64_t amax)
296 {
297  int64_t res;
298 #if defined(HAVE_AV_CONFIG_H) && defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2
299  if (amin > amax) abort();
300 #endif
301  // INT64_MAX+1,INT64_MIN are exactly representable as IEEE doubles
302  // do range checks first
303  if (a >= 9223372036854775808.0)
304  return amax;
305  if (a <= -9223372036854775808.0)
306  return amin;
307 
308  // safe to call llrint and clip accordingly
309  res = llrint(a);
310  if (res > amax)
311  return amax;
312  if (res < amin)
313  return amin;
314  return res;
315 }
316 
317 /**
318  * A wrapper for open() setting O_CLOEXEC.
319  */
321 int avpriv_open(const char *filename, int flags, ...);
322 
323 /**
324  * Wrapper to work around the lack of mkstemp() on mingw.
325  * Also, tries to create file in /tmp first, if possible.
326  * *prefix can be a character constant; *filename will be allocated internally.
327  * @return file descriptor of opened file (or negative value corresponding to an
328  * AVERROR code on error)
329  * and opened file name in **filename.
330  * @note On very old libcs it is necessary to set a secure umask before
331  * calling this, av_tempfile() can't call umask itself as it is used in
332  * libraries and could interfere with the calling application.
333  */
334 int avpriv_tempfile(const char *prefix, char **filename, int log_offset, void *log_ctx);
335 
336 int avpriv_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt);
337 
339 {
340  if (!w)
341  return 0;
342 
343  while ((unsigned)x > (unsigned)w) {
344  x = -x;
345  if (x < 0)
346  x += 2 * w;
347  }
348  return x;
349 }
350 
351 void ff_check_pixfmt_descriptors(void);
352 
353 /**
354  * Set a dictionary value to an ISO-8601 compliant timestamp string.
355  *
356  * @param s AVFormatContext
357  * @param key metadata key
358  * @param timestamp unix timestamp in microseconds
359  * @return <0 on error
360  */
361 int avpriv_dict_set_timestamp(AVDictionary **dict, const char *key, int64_t timestamp);
362 
363 // Helper macro for AV_PIX_FMT_FLAG_PSEUDOPAL deprecation. Code inside FFmpeg
364 // should always use FF_PSEUDOPAL. Once the public API flag gets removed, all
365 // code using it is dead code.
366 #if FF_API_PSEUDOPAL
367 #define FF_PSEUDOPAL AV_PIX_FMT_FLAG_PSEUDOPAL
368 #else
369 #define FF_PSEUDOPAL 0
370 #endif
371 
372 #endif /* AVUTIL_INTERNAL_H */
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
libm.h
avpriv_set_systematic_pal2
int avpriv_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt)
Definition: imgutils.c:152
av_const
#define av_const
Definition: attributes.h:84
AVDictionary
Definition: dict.c:30
macros.h
x
FFmpeg Automated Testing Environment ************************************Introduction Using FATE from your FFmpeg source directory Submitting the results to the FFmpeg result aggregation server Uploading new samples to the fate suite FATE makefile targets and variables Makefile targets Makefile variables Examples Introduction **************FATE is an extended regression suite on the client side and a means for results aggregation and presentation on the server side The first part of this document explains how you can use FATE from your FFmpeg source directory to test your ffmpeg binary The second part describes how you can run FATE to submit the results to FFmpeg’s FATE server In any way you can have a look at the publicly viewable FATE results by visiting this as it can be seen if some test on some platform broke with their recent contribution This usually happens on the platforms the developers could not test on The second part of this document describes how you can run FATE to submit your results to FFmpeg’s FATE server If you want to submit your results be sure to check that your combination of OS and compiler is not already listed on the above mentioned website In the third part you can find a comprehensive listing of FATE makefile targets and variables Using FATE from your FFmpeg source directory **********************************************If you want to run FATE on your machine you need to have the samples in place You can get the samples via the build target fate rsync Use this command from the top level source this will cause FATE to fail NOTE To use a custom wrapper to run the pass ‘ target exec’ to ‘configure’ or set the TARGET_EXEC Make variable Submitting the results to the FFmpeg result aggregation server ****************************************************************To submit your results to the server you should run fate through the shell script ‘tests fate sh’ from the FFmpeg sources This script needs to be invoked with a configuration file as its first argument tests fate sh path to fate_config A configuration file template with comments describing the individual configuration variables can be found at ‘doc fate_config sh template’ Create a configuration that suits your based on the configuration template The ‘slot’ configuration variable can be any string that is not yet but it is suggested that you name it adhering to the following pattern ‘ARCH OS COMPILER COMPILER VERSION’ The configuration file itself will be sourced in a shell therefore all shell features may be used This enables you to setup the environment as you need it for your build For your first test runs the ‘fate_recv’ variable should be empty or commented out This will run everything as normal except that it will omit the submission of the results to the server The following files should be present in $workdir as specified in the configuration it may help to try out the ‘ssh’ command with one or more ‘ v’ options You should get detailed output concerning your SSH configuration and the authentication process The only thing left is to automate the execution of the fate sh script and the synchronisation of the samples directory Uploading new samples to the fate suite *****************************************If you need a sample uploaded send a mail to samples request This is for developers who have an account on the fate suite server If you upload new please make sure they are as small as space on each network bandwidth and so on benefit from smaller test cases Also keep in mind older checkouts use existing sample that means in practice generally do not remove or overwrite files as it likely would break older checkouts or releases Also all needed samples for a commit should be ideally before the push If you need an account for frequently uploading samples or you wish to help others by doing that send a mail to ffmpeg devel rsync vauL Duo x
Definition: fate.txt:150
avpriv_tempfile
int avpriv_tempfile(const char *prefix, char **filename, int log_offset, void *log_ctx)
Wrapper to work around the lack of mkstemp() on mingw.
Definition: file_open.c:110
limits.h
pix_fmt
static enum AVPixelFormat pix_fmt
Definition: demuxing_decoding.c:40
avpriv_request_sample
void void avpriv_request_sample(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
key
const char * key
Definition: hwcontext_opencl.c:168
av_printf_format
#define av_printf_format(fmtpos, attrpos)
Definition: attributes.h:161
timer.h
avpriv_mirror
static av_always_inline av_const int avpriv_mirror(int x, int w)
Definition: internal.h:338
cpu.h
avpriv_report_missing_feature
void avpriv_report_missing_feature(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
avpriv_dict_set_timestamp
int avpriv_dict_set_timestamp(AVDictionary **dict, const char *key, int64_t timestamp)
Set a dictionary value to an ISO-8601 compliant timestamp string.
Definition: dict.c:258
attributes.h
ff_check_pixfmt_descriptors
void ff_check_pixfmt_descriptors(void)
Definition: pixdesc.c:2604
av_warn_unused_result
#define av_warn_unused_result
Definition: attributes.h:64
emms.h
av_always_inline
#define av_always_inline
Definition: attributes.h:49
version.h
pixfmt.h
w
FFmpeg Automated Testing Environment ************************************Introduction Using FATE from your FFmpeg source directory Submitting the results to the FFmpeg result aggregation server Uploading new samples to the fate suite FATE makefile targets and variables Makefile targets Makefile variables Examples Introduction **************FATE is an extended regression suite on the client side and a means for results aggregation and presentation on the server side The first part of this document explains how you can use FATE from your FFmpeg source directory to test your ffmpeg binary The second part describes how you can run FATE to submit the results to FFmpeg’s FATE server In any way you can have a look at the publicly viewable FATE results by visiting this as it can be seen if some test on some platform broke with their recent contribution This usually happens on the platforms the developers could not test on The second part of this document describes how you can run FATE to submit your results to FFmpeg’s FATE server If you want to submit your results be sure to check that your combination of OS and compiler is not already listed on the above mentioned website In the third part you can find a comprehensive listing of FATE makefile targets and variables Using FATE from your FFmpeg source directory **********************************************If you want to run FATE on your machine you need to have the samples in place You can get the samples via the build target fate rsync Use this command from the top level source this will cause FATE to fail NOTE To use a custom wrapper to run the pass ‘ target exec’ to ‘configure’ or set the TARGET_EXEC Make variable Submitting the results to the FFmpeg result aggregation server ****************************************************************To submit your results to the server you should run fate through the shell script ‘tests fate sh’ from the FFmpeg sources This script needs to be invoked with a configuration file as its first argument tests fate sh path to fate_config A configuration file template with comments describing the individual configuration variables can be found at ‘doc fate_config sh template’ Create a configuration that suits your based on the configuration template The ‘slot’ configuration variable can be any string that is not yet but it is suggested that you name it adhering to the following pattern ‘ARCH OS COMPILER COMPILER VERSION’ The configuration file itself will be sourced in a shell therefore all shell features may be used This enables you to setup the environment as you need it for your build For your first test runs the ‘fate_recv’ variable should be empty or commented out This will run everything as normal except that it will omit the submission of the results to the server The following files should be present in $workdir as specified in the configuration it may help to try out the ‘ssh’ command with one or more ‘ v’ options You should get detailed output concerning your SSH configuration and the authentication process The only thing left is to automate the execution of the fate sh script and the synchronisation of the samples directory Uploading new samples to the fate suite *****************************************If you need a sample uploaded send a mail to samples request This is for developers who have an account on the fate suite server If you upload new please make sure they are as small as space on each network bandwidth and so on benefit from smaller test cases Also keep in mind older checkouts use existing sample that means in practice generally do not remove or overwrite files as it likely would break older checkouts or releases Also all needed samples for a commit should be ideally before the push If you need an account for frequently uploading samples or you wish to help others by doing that send a mail to ffmpeg devel rsync vauL Duo ug o o w
Definition: fate.txt:150
dict.h
config.h
mem.h
llrint
#define llrint(x)
Definition: libm.h:394
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:564
ff_rint64_clip
static av_always_inline av_const int64_t ff_rint64_clip(double a, int64_t amin, int64_t amax)
Clip and convert a double value into the long long amin-amax range.
Definition: internal.h:295
avpriv_open
av_warn_unused_result int avpriv_open(const char *filename, int flags,...)
A wrapper for open() setting O_CLOEXEC.
Definition: file_open.c:66