internal.h 9.63 KB
Newer Older
1 2 3
/*
 * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
 *
4 5 6
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
7 8
 * modify it under the terms of the GNU Lesser General Public
 * 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 13 14 15 16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * 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 19 20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

21
/**
22
 * @file
23
 * common internal API header
24 25
 */

26 27
#ifndef AVUTIL_INTERNAL_H
#define AVUTIL_INTERNAL_H
28

29 30 31 32
#if !defined(DEBUG) && !defined(NDEBUG)
#    define NDEBUG
#endif

33
#include <limits.h>
34
#include <stdint.h>
35 36
#include <stddef.h>
#include <assert.h>
37
#include "config.h"
38
#include "attributes.h"
39
#include "timer.h"
40
#include "cpu.h"
41
#include "dict.h"
42
#include "pixfmt.h"
43
#include "version.h"
44

45 46 47 48
#if ARCH_X86
#   include "x86/emms.h"
#endif

49
#ifndef emms_c
50
#   define emms_c() while(0)
51 52
#endif

53
#ifndef attribute_align_arg
54
#if ARCH_X86_32 && AV_GCC_VERSION_AT_LEAST(4,2)
55 56 57 58 59 60
#    define attribute_align_arg __attribute__((force_align_arg_pointer))
#else
#    define attribute_align_arg
#endif
#endif

61 62 63 64 65 66
#if defined(_MSC_VER) && CONFIG_SHARED
#    define av_export __declspec(dllimport)
#else
#    define av_export
#endif

67
#if HAVE_PRAGMA_DEPRECATED
68
#    if defined(__ICL) || defined (__INTEL_COMPILER)
69 70 71 72 73 74 75 76 77
#        define FF_DISABLE_DEPRECATION_WARNINGS __pragma(warning(push)) __pragma(warning(disable:1478))
#        define FF_ENABLE_DEPRECATION_WARNINGS  __pragma(warning(pop))
#    elif defined(_MSC_VER)
#        define FF_DISABLE_DEPRECATION_WARNINGS __pragma(warning(push)) __pragma(warning(disable:4996))
#        define FF_ENABLE_DEPRECATION_WARNINGS  __pragma(warning(pop))
#    else
#        define FF_DISABLE_DEPRECATION_WARNINGS _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
#        define FF_ENABLE_DEPRECATION_WARNINGS  _Pragma("GCC diagnostic warning \"-Wdeprecated-declarations\"")
#    endif
78 79 80 81 82
#else
#    define FF_DISABLE_DEPRECATION_WARNINGS
#    define FF_ENABLE_DEPRECATION_WARNINGS
#endif

83

84 85
#define FF_MEMORY_POISON 0x2a

86 87 88 89
#define MAKE_ACCESSORS(str, name, type, field) \
    type av_##name##_get_##field(const str *s) { return s->field; } \
    void av_##name##_set_##field(str *s, type v) { s->field = v; }

90 91
// Some broken preprocessors need a second expansion
// to be forced to tokenize __VA_ARGS__
92
#define E1(x) x
93

94 95 96 97 98 99
/* Check if the hard coded offset of a struct member still matches reality.
 * Induce a compilation failure if not.
 */
#define AV_CHECK_OFFSET(s, m, o) struct check_##o {    \
        int x_##o[offsetof(s, m) == o? 1: -1];         \
    }
100 101 102 103 104 105 106 107 108

#define LOCAL_ALIGNED_A(a, t, v, s, o, ...)             \
    uint8_t la_##v[sizeof(t s o) + (a)];                \
    t (*v) o = (void *)FFALIGN((uintptr_t)la_##v, a)

#define LOCAL_ALIGNED_D(a, t, v, s, o, ...)             \
    DECLARE_ALIGNED(a, t, la_##v) s o;                  \
    t (*v) o = la_##v

109
#define LOCAL_ALIGNED(a, t, v, ...) E1(LOCAL_ALIGNED_A(a, t, v, __VA_ARGS__,,))
110 111

#if HAVE_LOCAL_ALIGNED_8
112
#   define LOCAL_ALIGNED_8(t, v, ...) E1(LOCAL_ALIGNED_D(8, t, v, __VA_ARGS__,,))
113 114 115 116 117
#else
#   define LOCAL_ALIGNED_8(t, v, ...) LOCAL_ALIGNED(8, t, v, __VA_ARGS__)
#endif

#if HAVE_LOCAL_ALIGNED_16
118
#   define LOCAL_ALIGNED_16(t, v, ...) E1(LOCAL_ALIGNED_D(16, t, v, __VA_ARGS__,,))
119 120 121 122
#else
#   define LOCAL_ALIGNED_16(t, v, ...) LOCAL_ALIGNED(16, t, v, __VA_ARGS__)
#endif

James Almer's avatar
James Almer committed
123 124 125 126 127 128
#if HAVE_LOCAL_ALIGNED_32
#   define LOCAL_ALIGNED_32(t, v, ...) E1(LOCAL_ALIGNED_D(32, t, v, __VA_ARGS__,,))
#else
#   define LOCAL_ALIGNED_32(t, v, ...) LOCAL_ALIGNED(32, t, v, __VA_ARGS__)
#endif

129
#define FF_ALLOC_OR_GOTO(ctx, p, size, label)\
Ramiro Polla's avatar
Ramiro Polla committed
130
{\
131
    p = av_malloc(size);\
132
    if (!(p) && (size) != 0) {\
133 134
        av_log(ctx, AV_LOG_ERROR, "Cannot allocate memory.\n");\
        goto label;\
Ramiro Polla's avatar
Ramiro Polla committed
135 136 137
    }\
}

138
#define FF_ALLOCZ_OR_GOTO(ctx, p, size, label)\
139
{\
140
    p = av_mallocz(size);\
141
    if (!(p) && (size) != 0) {\
142
        av_log(ctx, AV_LOG_ERROR, "Cannot allocate memory.\n");\
143 144 145 146 147 148 149
        goto label;\
    }\
}

#define FF_ALLOC_ARRAY_OR_GOTO(ctx, p, nelem, elsize, label)\
{\
    p = av_malloc_array(nelem, elsize);\
150
    if (!p) {\
151 152 153 154 155 156 157 158
        av_log(ctx, AV_LOG_ERROR, "Cannot allocate memory.\n");\
        goto label;\
    }\
}

#define FF_ALLOCZ_ARRAY_OR_GOTO(ctx, p, nelem, elsize, label)\
{\
    p = av_mallocz_array(nelem, elsize);\
159
    if (!p) {\
160
        av_log(ctx, AV_LOG_ERROR, "Cannot allocate memory.\n");\
161
        goto label;\
162 163 164
    }\
}

165
#include "libm.h"
166

167
/**
168
 * Return NULL if CONFIG_SMALL is true, otherwise the argument
169
 * without modification. Used to disable the definition of strings
170 171 172 173 174 175 176 177
 * (for example AVCodec long_names).
 */
#if CONFIG_SMALL
#   define NULL_IF_CONFIG_SMALL(x) NULL
#else
#   define NULL_IF_CONFIG_SMALL(x) x
#endif

178
/**
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
 * Define a function with only the non-default version specified.
 *
 * On systems with ELF shared libraries, all symbols exported from
 * FFmpeg libraries are tagged with the name and major version of the
 * library to which they belong.  If a function is moved from one
 * library to another, a wrapper must be retained in the original
 * location to preserve binary compatibility.
 *
 * Functions defined with this macro will never be used to resolve
 * symbols by the build-time linker.
 *
 * @param type return type of function
 * @param name name of function
 * @param args argument list of function
 * @param ver  version tag to assign function
194
 */
195
#if HAVE_SYMVER_ASM_LABEL
196 197
#   define FF_SYMVER(type, name, args, ver)                     \
    type ff_##name args __asm__ (EXTERN_PREFIX #name "@" ver);  \
198 199
    type ff_##name args
#elif HAVE_SYMVER_GNU_ASM
200 201 202
#   define FF_SYMVER(type, name, args, ver)                             \
    __asm__ (".symver ff_" #name "," EXTERN_PREFIX #name "@" ver);      \
    type ff_##name args;                                                \
203 204 205
    type ff_##name args
#endif

206
/**
207
 * Return NULL if a threading library has not been enabled.
208 209 210 211 212 213 214 215 216
 * Used to disable threading functions in AVCodec definitions
 * when not needed.
 */
#if HAVE_THREADS
#   define ONLY_IF_THREADS_ENABLED(x) x
#else
#   define ONLY_IF_THREADS_ENABLED(x) NULL
#endif

217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
/**
 * Log a generic warning message about a missing feature.
 *
 * @param[in] avc a pointer to an arbitrary struct of which the first
 *                field is a pointer to an AVClass struct
 * @param[in] msg string containing the name of the missing feature
 */
void avpriv_report_missing_feature(void *avc,
                                   const char *msg, ...) av_printf_format(2, 3);

/**
 * Log a generic warning message about a missing feature.
 * Additionally request that a sample showcasing the feature be uploaded.
 *
 * @param[in] avc a pointer to an arbitrary struct of which the first field is
 *                a pointer to an AVClass struct
 * @param[in] msg string containing the name of the missing feature
 */
void avpriv_request_sample(void *avc,
                           const char *msg, ...) av_printf_format(2, 3);

238
#if HAVE_LIBC_MSVCRT
239 240
#include <crtversion.h>
#if defined(_VC_CRT_MAJOR_VERSION) && _VC_CRT_MAJOR_VERSION < 14
241 242
#pragma comment(linker, "/include:" EXTERN_PREFIX "avpriv_strtod")
#pragma comment(linker, "/include:" EXTERN_PREFIX "avpriv_snprintf")
243 244
#endif

245
#define avpriv_open ff_open
246 247 248 249 250
#define PTRDIFF_SPECIFIER "Id"
#define SIZE_SPECIFIER "Iu"
#else
#define PTRDIFF_SPECIFIER "td"
#define SIZE_SPECIFIER "zu"
251 252
#endif

253 254 255 256 257 258
#ifdef DEBUG
#   define ff_dlog(ctx, ...) av_log(ctx, AV_LOG_DEBUG, __VA_ARGS__)
#else
#   define ff_dlog(ctx, ...) do { if (0) av_log(ctx, AV_LOG_DEBUG, __VA_ARGS__); } while (0)
#endif

259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295
/**
 * Clip and convert a double value into the long long amin-amax range.
 * This function is needed because conversion of floating point to integers when
 * it does not fit in the integer's representation does not necessarily saturate
 * correctly (usually converted to a cvttsd2si on x86) which saturates numbers
 * > INT64_MAX to INT64_MIN. The standard marks such conversions as undefined
 * behavior, allowing this sort of mathematically bogus conversions. This provides
 * a safe alternative that is slower obviously but assures safety and better
 * mathematical behavior.
 * @param a value to clip
 * @param amin minimum value of the clip range
 * @param amax maximum value of the clip range
 * @return clipped value
 */
static av_always_inline av_const int64_t ff_rint64_clip(double a, int64_t amin, int64_t amax)
{
    int64_t res;
#if defined(HAVE_AV_CONFIG_H) && defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2
    if (amin > amax) abort();
#endif
    // INT64_MAX+1,INT64_MIN are exactly representable as IEEE doubles
    // do range checks first
    if (a >=  9223372036854775808.0)
        return amax;
    if (a <= -9223372036854775808.0)
       return amin;

    // safe to call llrint and clip accordingly
    res = llrint(a);
    if (res > amax)
        return amax;
    if (res < amin)
        return amin;
    return res;
}


296 297 298
/**
 * A wrapper for open() setting O_CLOEXEC.
 */
299
av_warn_unused_result
300 301
int avpriv_open(const char *filename, int flags, ...);

302 303
int avpriv_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt);

304 305 306 307 308 309 310 311 312 313 314 315 316
static av_always_inline av_const int avpriv_mirror(int x, int w)
{
    if (!w)
        return 0;

    while ((unsigned)x > (unsigned)w) {
        x = -x;
        if (x < 0)
            x += 2 * w;
    }
    return x;
}

317 318
void ff_check_pixfmt_descriptors(void);

319 320
extern const uint8_t ff_reverse[256];

321
#endif /* AVUTIL_INTERNAL_H */