diff options
Diffstat (limited to 'apps/plugins/mpegplayer/mpeg_misc.h')
-rw-r--r-- | apps/plugins/mpegplayer/mpeg_misc.h | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/apps/plugins/mpegplayer/mpeg_misc.h b/apps/plugins/mpegplayer/mpeg_misc.h new file mode 100644 index 0000000000..2da9c2e313 --- /dev/null +++ b/apps/plugins/mpegplayer/mpeg_misc.h | |||
@@ -0,0 +1,206 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Miscellaneous helper API declarations | ||
11 | * | ||
12 | * Copyright (c) 2007 Michael Sevakis | ||
13 | * | ||
14 | * All files in this archive are subject to the GNU General Public License. | ||
15 | * See the file COPYING in the source tree root for full license agreement. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #ifndef MPEG_MISC_H | ||
22 | #define MPEG_MISC_H | ||
23 | |||
24 | /* Miscellaneous helpers */ | ||
25 | #ifndef ALIGNED_ATTR | ||
26 | #define ALIGNED_ATTR(x) __attribute__((aligned(x))) | ||
27 | #endif | ||
28 | |||
29 | /* Generic states for when things are too simple to care about naming them */ | ||
30 | enum state_enum | ||
31 | { | ||
32 | state0 = 0, | ||
33 | state1, | ||
34 | state2, | ||
35 | state3, | ||
36 | state4, | ||
37 | state5, | ||
38 | state6, | ||
39 | state7, | ||
40 | state8, | ||
41 | state9, | ||
42 | }; | ||
43 | |||
44 | /* Macros for comparing memory bytes to a series of constant bytes in an | ||
45 | efficient manner - evaluate to true if corresponding bytes match */ | ||
46 | #if defined (CPU_ARM) | ||
47 | /* ARM must load 32-bit values at addres % 4 == 0 offsets but this data | ||
48 | isn't aligned nescessarily, so just byte compare */ | ||
49 | #define CMP_3_CONST(_a, _b) \ | ||
50 | ({ int _x; \ | ||
51 | asm volatile ( \ | ||
52 | "ldrb %[x], [%[a], #0] \n" \ | ||
53 | "eors %[x], %[x], %[b0] \n" \ | ||
54 | "ldreqb %[x], [%[a], #1] \n" \ | ||
55 | "eoreqs %[x], %[x], %[b1] \n" \ | ||
56 | "ldreqb %[x], [%[a], #2] \n" \ | ||
57 | "eoreqs %[x], %[x], %[b2] \n" \ | ||
58 | : [x]"=&r"(_x) \ | ||
59 | : [a]"r"(_a), \ | ||
60 | [b0]"i"(((_b) >> 24) & 0xff), \ | ||
61 | [b1]"i"(((_b) >> 16) & 0xff), \ | ||
62 | [b2]"i"(((_b) >> 8) & 0xff) \ | ||
63 | ); \ | ||
64 | _x == 0; }) | ||
65 | |||
66 | #define CMP_4_CONST(_a, _b) \ | ||
67 | ({ int _x; \ | ||
68 | asm volatile ( \ | ||
69 | "ldrb %[x], [%[a], #0] \n" \ | ||
70 | "eors %[x], %[x], %[b0] \n" \ | ||
71 | "ldreqb %[x], [%[a], #1] \n" \ | ||
72 | "eoreqs %[x], %[x], %[b1] \n" \ | ||
73 | "ldreqb %[x], [%[a], #2] \n" \ | ||
74 | "eoreqs %[x], %[x], %[b2] \n" \ | ||
75 | "ldreqb %[x], [%[a], #3] \n" \ | ||
76 | "eoreqs %[x], %[x], %[b3] \n" \ | ||
77 | : [x]"=&r"(_x) \ | ||
78 | : [a]"r"(_a), \ | ||
79 | [b0]"i"(((_b) >> 24) & 0xff), \ | ||
80 | [b1]"i"(((_b) >> 16) & 0xff), \ | ||
81 | [b2]"i"(((_b) >> 8) & 0xff), \ | ||
82 | [b3]"i"(((_b) ) & 0xff) \ | ||
83 | ); \ | ||
84 | _x == 0; }) | ||
85 | |||
86 | #elif defined (CPU_COLDFIRE) | ||
87 | /* Coldfire can just load a 32 bit value at any offset but ASM is not the | ||
88 | best way to integrate this with the C code */ | ||
89 | #define CMP_3_CONST(a, b) \ | ||
90 | (((*(uint32_t *)(a) >> 8) == ((uint32_t)(b) >> 8))) | ||
91 | |||
92 | #define CMP_4_CONST(a, b) \ | ||
93 | ((*(uint32_t *)(a) == (b))) | ||
94 | |||
95 | #else | ||
96 | /* Don't know what this is - use bytewise comparisons */ | ||
97 | #define CMP_3_CONST(a, b) \ | ||
98 | (( ((a)[0] ^ (((b) >> 24) & 0xff)) | \ | ||
99 | ((a)[1] ^ (((b) >> 16) & 0xff)) | \ | ||
100 | ((a)[2] ^ (((b) >> 8) & 0xff)) ) == 0) | ||
101 | |||
102 | #define CMP_4_CONST(a, b) \ | ||
103 | (( ((a)[0] ^ (((b) >> 24) & 0xff)) | \ | ||
104 | ((a)[1] ^ (((b) >> 16) & 0xff)) | \ | ||
105 | ((a)[2] ^ (((b) >> 8) & 0xff)) | \ | ||
106 | ((a)[3] ^ (((b) ) & 0xff)) ) == 0) | ||
107 | #endif /* CPU_* */ | ||
108 | |||
109 | |||
110 | /** Streams **/ | ||
111 | |||
112 | /* Convert PTS/DTS ticks to our clock ticks */ | ||
113 | #define TS_TO_TICKS(pts) ((uint64_t)CLOCK_RATE*(pts) / TS_SECOND) | ||
114 | /* Convert our clock ticks to PTS/DTS ticks */ | ||
115 | #define TICKS_TO_TS(ts) ((uint64_t)TS_SECOND*(ts) / CLOCK_RATE) | ||
116 | /* Convert timecode ticks to our clock ticks */ | ||
117 | #define TC_TO_TICKS(stamp) ((uint64_t)CLOCK_RATE*(stamp) / TC_SECOND) | ||
118 | /* Convert our clock ticks to timecode ticks */ | ||
119 | #define TICKS_TO_TC(stamp) ((uint64_t)TC_SECOND*(stamp) / CLOCK_RATE) | ||
120 | /* Convert timecode ticks to timestamp ticks */ | ||
121 | #define TC_TO_TS(stamp) ((stamp) / 600) | ||
122 | |||
123 | /* | ||
124 | * S = start position, E = end position | ||
125 | * | ||
126 | * pos: | ||
127 | * initialize to search start position (S) | ||
128 | * | ||
129 | * len: | ||
130 | * initialize to = ABS(S-E) | ||
131 | * scanning = remaining bytes in scan direction | ||
132 | * | ||
133 | * dir: | ||
134 | * scan direction; >= 0 == forward, < 0 == reverse | ||
135 | * | ||
136 | * margin: | ||
137 | * amount of data to right of cursor - initialize by stream_scan_normalize | ||
138 | * | ||
139 | * data: | ||
140 | * Extra data used/returned by the function implemented | ||
141 | * | ||
142 | * Forward scan: | ||
143 | * S pos E | ||
144 | * | *<-margin->| dir-> | ||
145 | * | |<--len--->| | ||
146 | * | ||
147 | * Reverse scan: | ||
148 | * E pos S | ||
149 | * |<-len->*<-margin->| <-dir | ||
150 | * | | | | ||
151 | */ | ||
152 | struct stream_scan | ||
153 | { | ||
154 | off_t pos; /* Initial scan position (file offset) */ | ||
155 | ssize_t len; /* Maximum length of scan */ | ||
156 | off_t dir; /* Direction - >= 0; forward, < 0 backward */ | ||
157 | ssize_t margin; /* Used by function to track margin between position and data end */ | ||
158 | intptr_t data; /* */ | ||
159 | }; | ||
160 | |||
161 | #define SSCAN_REVERSE (-1) | ||
162 | #define SSCAN_FORWARD 1 | ||
163 | |||
164 | /* Ensures direction is -1 or 1 and margin is properly initialized */ | ||
165 | void stream_scan_normalize(struct stream_scan *sk); | ||
166 | |||
167 | /* Moves a scan cursor. If amount is positive, the increment is in the scan | ||
168 | * direction, otherwise opposite the scan direction */ | ||
169 | void stream_scan_offset(struct stream_scan *sk, off_t by); | ||
170 | |||
171 | /** Audio helpers **/ | ||
172 | static inline int32_t clip_sample(int32_t sample) | ||
173 | { | ||
174 | if ((int16_t)sample != sample) | ||
175 | sample = 0x7fff ^ (sample >> 31); | ||
176 | |||
177 | return sample; | ||
178 | } | ||
179 | |||
180 | /** Time helpers **/ | ||
181 | struct hms | ||
182 | { | ||
183 | unsigned int hrs; | ||
184 | unsigned int min; | ||
185 | unsigned int sec; | ||
186 | unsigned int frac; | ||
187 | }; | ||
188 | |||
189 | void ts_to_hms(uint32_t ts, struct hms *hms); | ||
190 | void hms_format(char *buf, size_t bufsize, struct hms *hms); | ||
191 | |||
192 | /** Maths **/ | ||
193 | |||
194 | /* Moving average */ | ||
195 | #define AVERAGE(var, x, count) \ | ||
196 | ({ typeof (count) _c = (count); \ | ||
197 | ((var) * (_c-1) + (x)) / (_c); }) | ||
198 | |||
199 | /* Multiply two unsigned 32-bit integers yielding a 64-bit result and | ||
200 | * divide by another unsigned 32-bit integer to yield a 32-bit result. | ||
201 | * Rounds to nearest with saturation. */ | ||
202 | uint32_t muldiv_uint32(uint32_t multiplicand, | ||
203 | uint32_t multiplier, | ||
204 | uint32_t divisor); | ||
205 | |||
206 | #endif /* MPEG_MISC_H */ | ||