Commit | Line | Data |
---|---|---|
04d7f601 DB |
1 | /* |
2 | * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> | |
3 | * | |
b78e7197 DB |
4 | * This file is part of FFmpeg. |
5 | * | |
6 | * FFmpeg is free software; you can redistribute it and/or | |
04d7f601 DB |
7 | * modify it under the terms of the GNU Lesser General Public |
8 | * License as published by the Free Software Foundation; either | |
b78e7197 | 9 | * version 2.1 of the License, or (at your option) any later version. |
04d7f601 | 10 | * |
b78e7197 | 11 | * FFmpeg is distributed in the hope that it will be useful, |
04d7f601 DB |
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 | |
b78e7197 | 17 | * License along with FFmpeg; if not, write to the Free Software |
04d7f601 DB |
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
19 | */ | |
20 | ||
983e3246 MN |
21 | /** |
22 | * @file common.h | |
7ce68923 | 23 | * common internal and external API header |
983e3246 MN |
24 | */ |
25 | ||
5b21bdab DB |
26 | #ifndef FFMPEG_COMMON_H |
27 | #define FFMPEG_COMMON_H | |
de6d9b64 | 28 | |
1845bf1f MR |
29 | #include <inttypes.h> |
30 | ||
420b073b | 31 | #ifdef HAVE_AV_CONFIG_H |
1a565432 | 32 | /* only include the following when compiling package */ |
9b59c92f MN |
33 | # include "config.h" |
34 | ||
35 | # include <stdlib.h> | |
36 | # include <stdio.h> | |
37 | # include <string.h> | |
56c4a184 | 38 | # include <ctype.h> |
9ff18a70 | 39 | # include <limits.h> |
8fa36ae0 | 40 | # include <errno.h> |
9b59c92f | 41 | # include <math.h> |
849f1035 MR |
42 | #endif /* HAVE_AV_CONFIG_H */ |
43 | ||
44 | #ifndef av_always_inline | |
45 | #if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0) | |
46 | # define av_always_inline __attribute__((always_inline)) inline | |
47 | #else | |
48 | # define av_always_inline inline | |
b9c684a2 AJ |
49 | #endif |
50 | #endif | |
51 | ||
52 | #ifndef av_noinline | |
53 | #if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0) | |
54 | # define av_noinline __attribute__((noinline)) | |
55 | #else | |
410bf273 | 56 | # define av_noinline |
849f1035 MR |
57 | #endif |
58 | #endif | |
59 | ||
85074d3c ZM |
60 | #ifndef av_pure |
61 | #if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0) | |
62 | # define av_pure __attribute__((pure)) | |
63 | #else | |
64 | # define av_pure | |
65 | #endif | |
66 | #endif | |
67 | ||
68 | #ifndef av_const | |
69 | #if defined(__GNUC__) && (__GNUC__ > 2 || __GNUC__ == 2 && __GNUC_MINOR__ > 5) | |
70 | # define av_const __attribute__((const)) | |
71 | #else | |
72 | # define av_const | |
73 | #endif | |
74 | #endif | |
75 | ||
98a6fff9 ZM |
76 | #ifndef av_cold |
77 | #if defined(__GNUC__) && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ > 2) | |
78 | # define av_cold __attribute__((cold)) | |
79 | #else | |
80 | # define av_cold | |
81 | #endif | |
82 | #endif | |
83 | ||
849f1035 | 84 | #ifdef HAVE_AV_CONFIG_H |
1845bf1f | 85 | # include "internal.h" |
44f27b3a | 86 | #endif /* HAVE_AV_CONFIG_H */ |
1a565432 | 87 | |
955ab9a4 MN |
88 | #ifndef attribute_deprecated |
89 | #if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0) | |
90 | # define attribute_deprecated __attribute__((deprecated)) | |
91 | #else | |
92 | # define attribute_deprecated | |
93 | #endif | |
94 | #endif | |
95 | ||
154e30f6 CEH |
96 | #ifndef av_unused |
97 | #if defined(__GNUC__) | |
98 | # define av_unused __attribute__((unused)) | |
99 | #else | |
100 | # define av_unused | |
101 | #endif | |
102 | #endif | |
103 | ||
792098c2 PI |
104 | #include "mem.h" |
105 | ||
073b013d | 106 | //rounded divison & shift |
10f3005f | 107 | #define RSHIFT(a,b) ((a) > 0 ? ((a) + ((1<<(b))>>1))>>(b) : ((a) + ((1<<(b))>>1)-1)>>(b)) |
d7e9533a MN |
108 | /* assume b>0 */ |
109 | #define ROUNDED_DIV(a,b) (((a)>0 ? (a) + ((b)>>1) : (a) - ((b)>>1))/(b)) | |
c26abfa5 | 110 | #define FFABS(a) ((a) >= 0 ? (a) : (-(a))) |
02305ff3 | 111 | #define FFSIGN(a) ((a) > 0 ? 1 : -1) |
75460b0c | 112 | |
b8a78f41 | 113 | #define FFMAX(a,b) ((a) > (b) ? (a) : (b)) |
159ef4b0 | 114 | #define FFMAX3(a,b,c) FFMAX(FFMAX(a,b),c) |
b8a78f41 | 115 | #define FFMIN(a,b) ((a) > (b) ? (b) : (a)) |
b842ecbe | 116 | #define FFMIN3(a,b,c) FFMIN(FFMIN(a,b),c) |
d7e9533a | 117 | |
1345f4ed | 118 | #define FFSWAP(type,a,b) do{type SWAP_tmp= b; b= a; a= SWAP_tmp;}while(0) |
67eca72d | 119 | |
de6d9b64 | 120 | /* misc math functions */ |
a77caa4d | 121 | extern const uint8_t ff_log2_tab[256]; |
de6d9b64 | 122 | |
85074d3c | 123 | static inline av_const int av_log2(unsigned int v) |
de6d9b64 | 124 | { |
89ef2c29 | 125 | int n = 0; |
de6d9b64 FB |
126 | if (v & 0xffff0000) { |
127 | v >>= 16; | |
128 | n += 16; | |
129 | } | |
130 | if (v & 0xff00) { | |
131 | v >>= 8; | |
132 | n += 8; | |
133 | } | |
c81f0349 MN |
134 | n += ff_log2_tab[v]; |
135 | ||
136 | return n; | |
137 | } | |
138 | ||
85074d3c | 139 | static inline av_const int av_log2_16bit(unsigned int v) |
c81f0349 | 140 | { |
89ef2c29 | 141 | int n = 0; |
c81f0349 MN |
142 | if (v & 0xff00) { |
143 | v >>= 8; | |
144 | n += 8; | |
de6d9b64 | 145 | } |
c81f0349 MN |
146 | n += ff_log2_tab[v]; |
147 | ||
de6d9b64 FB |
148 | return n; |
149 | } | |
150 | ||
45870f57 | 151 | /* median of 3 */ |
85074d3c | 152 | static inline av_const int mid_pred(int a, int b, int c) |
45870f57 | 153 | { |
d0b456ba | 154 | #ifdef HAVE_CMOV |
7e611a0e | 155 | int i=b; |
93a319f1 | 156 | asm volatile( |
7e611a0e LM |
157 | "cmp %2, %1 \n\t" |
158 | "cmovg %1, %0 \n\t" | |
159 | "cmovg %2, %1 \n\t" | |
160 | "cmp %3, %1 \n\t" | |
93a319f1 | 161 | "cmovl %3, %1 \n\t" |
7e611a0e LM |
162 | "cmp %1, %0 \n\t" |
163 | "cmovg %1, %0 \n\t" | |
164 | :"+&r"(i), "+&r"(a) | |
165 | :"r"(b), "r"(c) | |
93a319f1 LM |
166 | ); |
167 | return i; | |
168 | #elif 0 | |
7a62e94a MN |
169 | int t= (a-b)&((a-b)>>31); |
170 | a-=t; | |
171 | b+=t; | |
172 | b-= (b-c)&((b-c)>>31); | |
173 | b+= (a-b)&((a-b)>>31); | |
174 | ||
175 | return b; | |
176 | #else | |
177 | if(a>b){ | |
178 | if(c>b){ | |
179 | if(c>a) b=a; | |
180 | else b=c; | |
181 | } | |
182 | }else{ | |
183 | if(b>c){ | |
184 | if(c>a) b=c; | |
185 | else b=a; | |
186 | } | |
187 | } | |
188 | return b; | |
189 | #endif | |
45870f57 MN |
190 | } |
191 | ||
77177335 AJ |
192 | /** |
193 | * clip a signed integer value into the amin-amax range | |
194 | * @param a value to clip | |
195 | * @param amin minimum value of the clip range | |
196 | * @param amax maximum value of the clip range | |
c6c36725 | 197 | * @return clipped value |
77177335 | 198 | */ |
85074d3c | 199 | static inline av_const int av_clip(int a, int amin, int amax) |
91029be7 | 200 | { |
27af15dc | 201 | if (a < amin) return amin; |
18769c0a MN |
202 | else if (a > amax) return amax; |
203 | else return a; | |
91029be7 MN |
204 | } |
205 | ||
77177335 AJ |
206 | /** |
207 | * clip a signed integer value into the 0-255 range | |
208 | * @param a value to clip | |
c6c36725 | 209 | * @return clipped value |
77177335 | 210 | */ |
85074d3c | 211 | static inline av_const uint8_t av_clip_uint8(int a) |
3ebc7e04 MN |
212 | { |
213 | if (a&(~255)) return (-a)>>31; | |
214 | else return a; | |
215 | } | |
216 | ||
ddb8ebe7 AJ |
217 | /** |
218 | * clip a signed integer value into the -32768,32767 range | |
219 | * @param a value to clip | |
220 | * @return clipped value | |
221 | */ | |
85074d3c | 222 | static inline av_const int16_t av_clip_int16(int a) |
ddb8ebe7 AJ |
223 | { |
224 | if ((a+32768) & ~65535) return (a>>31) ^ 32767; | |
225 | else return a; | |
226 | } | |
227 | ||
9dbcbd92 | 228 | /* math */ |
85074d3c | 229 | int64_t av_const ff_gcd(int64_t a, int64_t b); |
9dbcbd92 | 230 | |
202ef8b8 MN |
231 | /** |
232 | * converts fourcc string to int | |
233 | */ | |
85074d3c | 234 | static inline av_pure int ff_get_fourcc(const char *s){ |
05020c89 | 235 | #ifdef HAVE_AV_CONFIG_H |
202ef8b8 | 236 | assert( strlen(s)==4 ); |
05020c89 | 237 | #endif |
966df5b6 | 238 | |
202ef8b8 MN |
239 | return (s[0]) + (s[1]<<8) + (s[2]<<16) + (s[3]<<24); |
240 | } | |
241 | ||
e8750b00 FR |
242 | #define MKTAG(a,b,c,d) (a | (b << 8) | (c << 16) | (d << 24)) |
243 | #define MKBETAG(a,b,c,d) (d | (c << 8) | (b << 16) | (a << 24)) | |
244 | ||
d73427e3 GP |
245 | /*! |
246 | * \def GET_UTF8(val, GET_BYTE, ERROR) | |
90b5b51e | 247 | * converts a UTF-8 character (up to 4 bytes long) to its 32-bit UCS-4 encoded form |
d73427e3 | 248 | * \param val is the output and should be of type uint32_t. It holds the converted |
90b5b51e DB |
249 | * UCS-4 character and should be a left value. |
250 | * \param GET_BYTE gets UTF-8 encoded bytes from any proper source. It can be | |
d73427e3 | 251 | * a function or a statement whose return value or evaluated value is of type |
90b5b51e | 252 | * uint8_t. It will be executed up to 4 times for values in the valid UTF-8 range, |
40a08c7e | 253 | * and up to 7 times in the general case. |
90b5b51e | 254 | * \param ERROR action that should be taken when an invalid UTF-8 byte is returned |
d73427e3 GP |
255 | * from GET_BYTE. It should be a statement that jumps out of the macro, |
256 | * like exit(), goto, return, break, or continue. | |
257 | */ | |
9d82b0dd MN |
258 | #define GET_UTF8(val, GET_BYTE, ERROR)\ |
259 | val= GET_BYTE;\ | |
260 | {\ | |
261 | int ones= 7 - av_log2(val ^ 255);\ | |
262 | if(ones==1)\ | |
263 | ERROR\ | |
264 | val&= 127>>ones;\ | |
265 | while(--ones > 0){\ | |
266 | int tmp= GET_BYTE - 128;\ | |
267 | if(tmp>>6)\ | |
268 | ERROR\ | |
269 | val= (val<<6) + tmp;\ | |
270 | }\ | |
271 | } | |
2ad1516a | 272 | |
0e8c148b | 273 | /*! |
34d33769 | 274 | * \def PUT_UTF8(val, tmp, PUT_BYTE) |
90b5b51e | 275 | * converts a 32-bit unicode character to its UTF-8 encoded form (up to 4 bytes long). |
0e8c148b | 276 | * \param val is an input only argument and should be of type uint32_t. It holds |
90b5b51e | 277 | * a ucs4 encoded unicode character that is to be converted to UTF-8. If |
0e8c148b GP |
278 | * val is given as a function it's executed only once. |
279 | * \param tmp is a temporary variable and should be of type uint8_t. It | |
280 | * represents an intermediate value during conversion that is to be | |
281 | * outputted by PUT_BYTE. | |
90b5b51e | 282 | * \param PUT_BYTE writes the converted UTF-8 bytes to any proper destination. |
0e8c148b GP |
283 | * It could be a function or a statement, and uses tmp as the input byte. |
284 | * For example, PUT_BYTE could be "*output++ = tmp;" PUT_BYTE will be | |
90b5b51e | 285 | * executed up to 4 times for values in the valid UTF-8 range and up to |
40a08c7e | 286 | * 7 times in the general case, depending on the length of the converted |
0e8c148b GP |
287 | * unicode character. |
288 | */ | |
360932f7 ZM |
289 | #define PUT_UTF8(val, tmp, PUT_BYTE)\ |
290 | {\ | |
291 | int bytes, shift;\ | |
292 | uint32_t in = val;\ | |
293 | if (in < 0x80) {\ | |
294 | tmp = in;\ | |
295 | PUT_BYTE\ | |
296 | } else {\ | |
297 | bytes = (av_log2(in) + 4) / 5;\ | |
298 | shift = (bytes - 1) * 6;\ | |
299 | tmp = (256 - (256 >> bytes)) | (in >> shift);\ | |
300 | PUT_BYTE\ | |
301 | while (shift >= 6) {\ | |
302 | shift -= 6;\ | |
303 | tmp = 0x80 | ((in >> shift) & 0x3f);\ | |
304 | PUT_BYTE\ | |
305 | }\ | |
306 | }\ | |
307 | } | |
308 | ||
f70c2739 | 309 | #if defined(ARCH_X86) || defined(ARCH_POWERPC) || defined(ARCH_BFIN) |
b6c748ed | 310 | #define AV_READ_TIME read_time |
8230cf02 | 311 | #if defined(ARCH_X86_64) |
0775c88f | 312 | static inline uint64_t read_time(void) |
8230cf02 | 313 | { |
27af15dc DB |
314 | uint64_t a, d; |
315 | asm volatile("rdtsc\n\t" | |
316 | : "=a" (a), "=d" (d)); | |
317 | return (d << 32) | (a & 0xffffffff); | |
8230cf02 | 318 | } |
419b8784 | 319 | #elif defined(ARCH_X86_32) |
0775c88f | 320 | static inline long long read_time(void) |
b534c7f9 | 321 | { |
27af15dc DB |
322 | long long l; |
323 | asm volatile("rdtsc\n\t" | |
324 | : "=A" (l)); | |
325 | return l; | |
b534c7f9 | 326 | } |
f70c2739 MH |
327 | #elif ARCH_BFIN |
328 | static inline uint64_t read_time(void) | |
329 | { | |
330 | union { | |
331 | struct { | |
332 | unsigned lo; | |
333 | unsigned hi; | |
334 | } p; | |
335 | unsigned long long c; | |
336 | } t; | |
337 | asm volatile ("%0=cycles; %1=cycles2;" : "=d" (t.p.lo), "=d" (t.p.hi)); | |
338 | return t.c; | |
339 | } | |
0775c88f MN |
340 | #else //FIXME check ppc64 |
341 | static inline uint64_t read_time(void) | |
342 | { | |
343 | uint32_t tbu, tbl, temp; | |
344 | ||
345 | /* from section 2.2.1 of the 32-bit PowerPC PEM */ | |
c88c253d | 346 | asm volatile( |
0775c88f MN |
347 | "1:\n" |
348 | "mftbu %2\n" | |
349 | "mftb %0\n" | |
350 | "mftbu %1\n" | |
351 | "cmpw %2,%1\n" | |
352 | "bne 1b\n" | |
353 | : "=r"(tbl), "=r"(tbu), "=r"(temp) | |
354 | : | |
355 | : "cc"); | |
356 | ||
357 | return (((uint64_t)tbu)<<32) | (uint64_t)tbl; | |
358 | } | |
8230cf02 | 359 | #endif |
b6c748ed RS |
360 | #elif defined(HAVE_GETHRTIME) |
361 | #define AV_READ_TIME gethrtime | |
362 | #endif | |
b534c7f9 | 363 | |
b6c748ed | 364 | #ifdef AV_READ_TIME |
b534c7f9 | 365 | #define START_TIMER \ |
b534c7f9 | 366 | uint64_t tend;\ |
b6c748ed | 367 | uint64_t tstart= AV_READ_TIME();\ |
b534c7f9 MN |
368 | |
369 | #define STOP_TIMER(id) \ | |
b6c748ed | 370 | tend= AV_READ_TIME();\ |
d705e4a6 | 371 | {\ |
27af15dc DB |
372 | static uint64_t tsum=0;\ |
373 | static int tcount=0;\ | |
374 | static int tskip_count=0;\ | |
375 | if(tcount<2 || tend - tstart < FFMAX(8*tsum/tcount, 2000)){\ | |
376 | tsum+= tend - tstart;\ | |
377 | tcount++;\ | |
378 | }else\ | |
379 | tskip_count++;\ | |
380 | if(((tcount+tskip_count)&(tcount+tskip_count-1))==0){\ | |
8cd8eaa5 | 381 | av_log(NULL, AV_LOG_ERROR, "%"PRIu64" dezicycles in %s, %d runs, %d skips\n",\ |
27af15dc DB |
382 | tsum*10/tcount, id, tcount, tskip_count);\ |
383 | }\ | |
b534c7f9 | 384 | } |
0187e903 | 385 | #else |
115329f1 | 386 | #define START_TIMER |
0187e903 | 387 | #define STOP_TIMER(id) {} |
b534c7f9 MN |
388 | #endif |
389 | ||
4a567b40 SS |
390 | /** |
391 | * Returns NULL if CONFIG_SMALL is defined otherwise the argument | |
392 | * without modifications, used to disable the definition of strings | |
393 | * (for example AVCodec long_names). | |
394 | */ | |
395 | #ifdef CONFIG_SMALL | |
396 | # define NULL_IF_CONFIG_SMALL(x) NULL | |
397 | #else | |
398 | # define NULL_IF_CONFIG_SMALL(x) x | |
399 | #endif | |
400 | ||
5b21bdab | 401 | #endif /* FFMPEG_COMMON_H */ |