1 | /*
|
---|
2 | * copyright (c) 2006 Michael Niedermayer <[email protected]>
|
---|
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 common.h
|
---|
23 | * common internal and external api header.
|
---|
24 | */
|
---|
25 |
|
---|
26 | #ifndef COMMON_H
|
---|
27 | #define COMMON_H
|
---|
28 |
|
---|
29 | #include <inttypes.h>
|
---|
30 |
|
---|
31 | #ifdef HAVE_AV_CONFIG_H
|
---|
32 | /* only include the following when compiling package */
|
---|
33 | # include "config.h"
|
---|
34 |
|
---|
35 | # include <stdlib.h>
|
---|
36 | # include <stdio.h>
|
---|
37 | # include <string.h>
|
---|
38 | # include <ctype.h>
|
---|
39 | # include <limits.h>
|
---|
40 | # include <errno.h>
|
---|
41 | # include <math.h>
|
---|
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 | # define av_noinline __attribute__((noinline))
|
---|
48 | #else
|
---|
49 | # define av_always_inline inline
|
---|
50 | # define av_noinline
|
---|
51 | #endif
|
---|
52 | #endif
|
---|
53 |
|
---|
54 | #ifdef HAVE_AV_CONFIG_H
|
---|
55 | # include "internal.h"
|
---|
56 | #endif /* HAVE_AV_CONFIG_H */
|
---|
57 |
|
---|
58 | #ifndef attribute_deprecated
|
---|
59 | #if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0)
|
---|
60 | # define attribute_deprecated __attribute__((deprecated))
|
---|
61 | #else
|
---|
62 | # define attribute_deprecated
|
---|
63 | #endif
|
---|
64 | #endif
|
---|
65 |
|
---|
66 | #ifndef av_unused
|
---|
67 | #if defined(__GNUC__)
|
---|
68 | # define av_unused __attribute__((unused))
|
---|
69 | #else
|
---|
70 | # define av_unused
|
---|
71 | #endif
|
---|
72 | #endif
|
---|
73 |
|
---|
74 | #include "mem.h"
|
---|
75 |
|
---|
76 | //rounded divison & shift
|
---|
77 | #define RSHIFT(a,b) ((a) > 0 ? ((a) + ((1<<(b))>>1))>>(b) : ((a) + ((1<<(b))>>1)-1)>>(b))
|
---|
78 | /* assume b>0 */
|
---|
79 | #define ROUNDED_DIV(a,b) (((a)>0 ? (a) + ((b)>>1) : (a) - ((b)>>1))/(b))
|
---|
80 | #define FFABS(a) ((a) >= 0 ? (a) : (-(a)))
|
---|
81 | #define FFSIGN(a) ((a) > 0 ? 1 : -1)
|
---|
82 |
|
---|
83 | #define FFMAX(a,b) ((a) > (b) ? (a) : (b))
|
---|
84 | #define FFMIN(a,b) ((a) > (b) ? (b) : (a))
|
---|
85 |
|
---|
86 | #define FFSWAP(type,a,b) do{type SWAP_tmp= b; b= a; a= SWAP_tmp;}while(0)
|
---|
87 |
|
---|
88 | /* misc math functions */
|
---|
89 | extern const uint8_t ff_log2_tab[256];
|
---|
90 |
|
---|
91 | static inline int av_log2(unsigned int v)
|
---|
92 | {
|
---|
93 | int n;
|
---|
94 |
|
---|
95 | n = 0;
|
---|
96 | if (v & 0xffff0000) {
|
---|
97 | v >>= 16;
|
---|
98 | n += 16;
|
---|
99 | }
|
---|
100 | if (v & 0xff00) {
|
---|
101 | v >>= 8;
|
---|
102 | n += 8;
|
---|
103 | }
|
---|
104 | n += ff_log2_tab[v];
|
---|
105 |
|
---|
106 | return n;
|
---|
107 | }
|
---|
108 |
|
---|
109 | static inline int av_log2_16bit(unsigned int v)
|
---|
110 | {
|
---|
111 | int n;
|
---|
112 |
|
---|
113 | n = 0;
|
---|
114 | if (v & 0xff00) {
|
---|
115 | v >>= 8;
|
---|
116 | n += 8;
|
---|
117 | }
|
---|
118 | n += ff_log2_tab[v];
|
---|
119 |
|
---|
120 | return n;
|
---|
121 | }
|
---|
122 |
|
---|
123 | /* median of 3 */
|
---|
124 | static inline int mid_pred(int a, int b, int c)
|
---|
125 | {
|
---|
126 | #ifdef HAVE_CMOV
|
---|
127 | int i=b;
|
---|
128 | asm volatile(
|
---|
129 | "cmp %2, %1 \n\t"
|
---|
130 | "cmovg %1, %0 \n\t"
|
---|
131 | "cmovg %2, %1 \n\t"
|
---|
132 | "cmp %3, %1 \n\t"
|
---|
133 | "cmovl %3, %1 \n\t"
|
---|
134 | "cmp %1, %0 \n\t"
|
---|
135 | "cmovg %1, %0 \n\t"
|
---|
136 | :"+&r"(i), "+&r"(a)
|
---|
137 | :"r"(b), "r"(c)
|
---|
138 | );
|
---|
139 | return i;
|
---|
140 | #elif 0
|
---|
141 | int t= (a-b)&((a-b)>>31);
|
---|
142 | a-=t;
|
---|
143 | b+=t;
|
---|
144 | b-= (b-c)&((b-c)>>31);
|
---|
145 | b+= (a-b)&((a-b)>>31);
|
---|
146 |
|
---|
147 | return b;
|
---|
148 | #else
|
---|
149 | if(a>b){
|
---|
150 | if(c>b){
|
---|
151 | if(c>a) b=a;
|
---|
152 | else b=c;
|
---|
153 | }
|
---|
154 | }else{
|
---|
155 | if(b>c){
|
---|
156 | if(c>a) b=c;
|
---|
157 | else b=a;
|
---|
158 | }
|
---|
159 | }
|
---|
160 | return b;
|
---|
161 | #endif
|
---|
162 | }
|
---|
163 |
|
---|
164 | /**
|
---|
165 | * clip a signed integer value into the amin-amax range
|
---|
166 | * @param a value to clip
|
---|
167 | * @param amin minimum value of the clip range
|
---|
168 | * @param amax maximum value of the clip range
|
---|
169 | * @return clipped value
|
---|
170 | */
|
---|
171 | static inline int av_clip(int a, int amin, int amax)
|
---|
172 | {
|
---|
173 | if (a < amin) return amin;
|
---|
174 | else if (a > amax) return amax;
|
---|
175 | else return a;
|
---|
176 | }
|
---|
177 |
|
---|
178 | /**
|
---|
179 | * clip a signed integer value into the 0-255 range
|
---|
180 | * @param a value to clip
|
---|
181 | * @return clipped value
|
---|
182 | */
|
---|
183 | static inline uint8_t av_clip_uint8(int a)
|
---|
184 | {
|
---|
185 | if (a&(~255)) return (-a)>>31;
|
---|
186 | else return a;
|
---|
187 | }
|
---|
188 |
|
---|
189 | /* math */
|
---|
190 | int64_t ff_gcd(int64_t a, int64_t b);
|
---|
191 |
|
---|
192 | /**
|
---|
193 | * converts fourcc string to int
|
---|
194 | */
|
---|
195 | static inline int ff_get_fourcc(const char *s){
|
---|
196 | #ifdef HAVE_AV_CONFIG_H
|
---|
197 | assert( strlen(s)==4 );
|
---|
198 | #endif
|
---|
199 |
|
---|
200 | return (s[0]) + (s[1]<<8) + (s[2]<<16) + (s[3]<<24);
|
---|
201 | }
|
---|
202 |
|
---|
203 | #define MKTAG(a,b,c,d) (a | (b << 8) | (c << 16) | (d << 24))
|
---|
204 | #define MKBETAG(a,b,c,d) (d | (c << 8) | (b << 16) | (a << 24))
|
---|
205 |
|
---|
206 | /*!
|
---|
207 | * \def GET_UTF8(val, GET_BYTE, ERROR)
|
---|
208 | * converts a UTF-8 character (up to 4 bytes long) to its 32-bit UCS-4 encoded form
|
---|
209 | * \param val is the output and should be of type uint32_t. It holds the converted
|
---|
210 | * UCS-4 character and should be a left value.
|
---|
211 | * \param GET_BYTE gets UTF-8 encoded bytes from any proper source. It can be
|
---|
212 | * a function or a statement whose return value or evaluated value is of type
|
---|
213 | * uint8_t. It will be executed up to 4 times for values in the valid UTF-8 range,
|
---|
214 | * and up to 7 times in the general case.
|
---|
215 | * \param ERROR action that should be taken when an invalid UTF-8 byte is returned
|
---|
216 | * from GET_BYTE. It should be a statement that jumps out of the macro,
|
---|
217 | * like exit(), goto, return, break, or continue.
|
---|
218 | */
|
---|
219 | #define GET_UTF8(val, GET_BYTE, ERROR)\
|
---|
220 | val= GET_BYTE;\
|
---|
221 | {\
|
---|
222 | int ones= 7 - av_log2(val ^ 255);\
|
---|
223 | if(ones==1)\
|
---|
224 | ERROR\
|
---|
225 | val&= 127>>ones;\
|
---|
226 | while(--ones > 0){\
|
---|
227 | int tmp= GET_BYTE - 128;\
|
---|
228 | if(tmp>>6)\
|
---|
229 | ERROR\
|
---|
230 | val= (val<<6) + tmp;\
|
---|
231 | }\
|
---|
232 | }
|
---|
233 |
|
---|
234 | /*!
|
---|
235 | * \def PUT_UTF8(val, tmp, PUT_BYTE)
|
---|
236 | * converts a 32-bit unicode character to its UTF-8 encoded form (up to 4 bytes long).
|
---|
237 | * \param val is an input only argument and should be of type uint32_t. It holds
|
---|
238 | * a ucs4 encoded unicode character that is to be converted to UTF-8. If
|
---|
239 | * val is given as a function it's executed only once.
|
---|
240 | * \param tmp is a temporary variable and should be of type uint8_t. It
|
---|
241 | * represents an intermediate value during conversion that is to be
|
---|
242 | * outputted by PUT_BYTE.
|
---|
243 | * \param PUT_BYTE writes the converted UTF-8 bytes to any proper destination.
|
---|
244 | * It could be a function or a statement, and uses tmp as the input byte.
|
---|
245 | * For example, PUT_BYTE could be "*output++ = tmp;" PUT_BYTE will be
|
---|
246 | * executed up to 4 times for values in the valid UTF-8 range and up to
|
---|
247 | * 7 times in the general case, depending on the length of the converted
|
---|
248 | * unicode character.
|
---|
249 | */
|
---|
250 | #define PUT_UTF8(val, tmp, PUT_BYTE)\
|
---|
251 | {\
|
---|
252 | int bytes, shift;\
|
---|
253 | uint32_t in = val;\
|
---|
254 | if (in < 0x80) {\
|
---|
255 | tmp = in;\
|
---|
256 | PUT_BYTE\
|
---|
257 | } else {\
|
---|
258 | bytes = (av_log2(in) + 4) / 5;\
|
---|
259 | shift = (bytes - 1) * 6;\
|
---|
260 | tmp = (256 - (256 >> bytes)) | (in >> shift);\
|
---|
261 | PUT_BYTE\
|
---|
262 | while (shift >= 6) {\
|
---|
263 | shift -= 6;\
|
---|
264 | tmp = 0x80 | ((in >> shift) & 0x3f);\
|
---|
265 | PUT_BYTE\
|
---|
266 | }\
|
---|
267 | }\
|
---|
268 | }
|
---|
269 |
|
---|
270 | #if defined(ARCH_X86) || defined(ARCH_POWERPC) || defined(ARCH_BFIN)
|
---|
271 | #if defined(ARCH_X86_64)
|
---|
272 | static inline uint64_t read_time(void)
|
---|
273 | {
|
---|
274 | uint64_t a, d;
|
---|
275 | asm volatile( "rdtsc\n\t"
|
---|
276 | : "=a" (a), "=d" (d)
|
---|
277 | );
|
---|
278 | return (d << 32) | (a & 0xffffffff);
|
---|
279 | }
|
---|
280 | #elif defined(ARCH_X86_32)
|
---|
281 | static inline long long read_time(void)
|
---|
282 | {
|
---|
283 | long long l;
|
---|
284 | asm volatile( "rdtsc\n\t"
|
---|
285 | : "=A" (l)
|
---|
286 | );
|
---|
287 | return l;
|
---|
288 | }
|
---|
289 | #elif ARCH_BFIN
|
---|
290 | static inline uint64_t read_time(void)
|
---|
291 | {
|
---|
292 | union {
|
---|
293 | struct {
|
---|
294 | unsigned lo;
|
---|
295 | unsigned hi;
|
---|
296 | } p;
|
---|
297 | unsigned long long c;
|
---|
298 | } t;
|
---|
299 | asm volatile ("%0=cycles; %1=cycles2;" : "=d" (t.p.lo), "=d" (t.p.hi));
|
---|
300 | return t.c;
|
---|
301 | }
|
---|
302 | #else //FIXME check ppc64
|
---|
303 | static inline uint64_t read_time(void)
|
---|
304 | {
|
---|
305 | uint32_t tbu, tbl, temp;
|
---|
306 |
|
---|
307 | /* from section 2.2.1 of the 32-bit PowerPC PEM */
|
---|
308 | __asm__ __volatile__(
|
---|
309 | "1:\n"
|
---|
310 | "mftbu %2\n"
|
---|
311 | "mftb %0\n"
|
---|
312 | "mftbu %1\n"
|
---|
313 | "cmpw %2,%1\n"
|
---|
314 | "bne 1b\n"
|
---|
315 | : "=r"(tbl), "=r"(tbu), "=r"(temp)
|
---|
316 | :
|
---|
317 | : "cc");
|
---|
318 |
|
---|
319 | return (((uint64_t)tbu)<<32) | (uint64_t)tbl;
|
---|
320 | }
|
---|
321 | #endif
|
---|
322 |
|
---|
323 | #define START_TIMER \
|
---|
324 | uint64_t tend;\
|
---|
325 | uint64_t tstart= read_time();\
|
---|
326 |
|
---|
327 | #define STOP_TIMER(id) \
|
---|
328 | tend= read_time();\
|
---|
329 | {\
|
---|
330 | static uint64_t tsum=0;\
|
---|
331 | static int tcount=0;\
|
---|
332 | static int tskip_count=0;\
|
---|
333 | if(tcount<2 || tend - tstart < FFMAX(8*tsum/tcount, 2000)){\
|
---|
334 | tsum+= tend - tstart;\
|
---|
335 | tcount++;\
|
---|
336 | }else\
|
---|
337 | tskip_count++;\
|
---|
338 | if(((tcount+tskip_count)&(tcount+tskip_count-1))==0){\
|
---|
339 | av_log(NULL, AV_LOG_DEBUG, "%"PRIu64" dezicycles in %s, %d runs, %d skips\n", tsum*10/tcount, id, tcount, tskip_count);\
|
---|
340 | }\
|
---|
341 | }
|
---|
342 | #else
|
---|
343 | #define START_TIMER
|
---|
344 | #define STOP_TIMER(id) {}
|
---|
345 | #endif
|
---|
346 |
|
---|
347 | #endif /* COMMON_H */
|
---|