Prepare new maemo release
[maemo-rb.git] / apps / plugins / mpegplayer / mpeg_misc.h
blob6996f2798751ff6b3717ae54e9ac5d66af6fbc47
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Miscellaneous helper API declarations
12 * Copyright (c) 2007 Michael Sevakis
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
22 ****************************************************************************/
23 #ifndef MPEG_MISC_H
24 #define MPEG_MISC_H
26 /* Miscellaneous helpers */
27 #ifndef ALIGNED_ATTR
28 #define ALIGNED_ATTR(x) __attribute__((aligned(x)))
29 #endif
31 #include "disk_buf.h"
33 /* Generic states for when things are too simple to care about naming them */
34 enum state_enum
36 STATE0 = 0,
37 STATE1,
38 STATE2,
39 STATE3,
40 STATE4,
41 STATE5,
42 STATE6,
43 STATE7,
44 STATE8,
45 STATE9,
48 /* Macros for comparing memory bytes to a series of constant bytes in an
49 efficient manner - evaluate to true if corresponding bytes match */
50 #if defined (CPU_ARM)
51 /* ARM must load 32-bit values at addres % 4 == 0 offsets but this data
52 isn't aligned nescessarily, so just byte compare */
53 #define CMP_3_CONST(_a, _b) \
54 ({ int _x; \
55 asm volatile ( \
56 "ldrb %[x], [%[a], #0] \n" \
57 "eors %[x], %[x], %[b0] \n" \
58 "ldreqb %[x], [%[a], #1] \n" \
59 "eoreqs %[x], %[x], %[b1] \n" \
60 "ldreqb %[x], [%[a], #2] \n" \
61 "eoreqs %[x], %[x], %[b2] \n" \
62 : [x]"=&r"(_x) \
63 : [a]"r"(_a), \
64 [b0]"i"(((_b) >> 24) & 0xff), \
65 [b1]"i"(((_b) >> 16) & 0xff), \
66 [b2]"i"(((_b) >> 8) & 0xff) \
67 ); \
68 _x == 0; })
70 #define CMP_4_CONST(_a, _b) \
71 ({ int _x; \
72 asm volatile ( \
73 "ldrb %[x], [%[a], #0] \n" \
74 "eors %[x], %[x], %[b0] \n" \
75 "ldreqb %[x], [%[a], #1] \n" \
76 "eoreqs %[x], %[x], %[b1] \n" \
77 "ldreqb %[x], [%[a], #2] \n" \
78 "eoreqs %[x], %[x], %[b2] \n" \
79 "ldreqb %[x], [%[a], #3] \n" \
80 "eoreqs %[x], %[x], %[b3] \n" \
81 : [x]"=&r"(_x) \
82 : [a]"r"(_a), \
83 [b0]"i"(((_b) >> 24) & 0xff), \
84 [b1]"i"(((_b) >> 16) & 0xff), \
85 [b2]"i"(((_b) >> 8) & 0xff), \
86 [b3]"i"(((_b) ) & 0xff) \
87 ); \
88 _x == 0; })
90 #elif defined (CPU_COLDFIRE)
91 /* Coldfire can just load a 32 bit value at any offset but ASM is not the
92 best way to integrate this with the C code */
93 #define CMP_3_CONST(a, b) \
94 (((*(uint32_t *)(a) >> 8) == ((uint32_t)(b) >> 8)))
96 #define CMP_4_CONST(a, b) \
97 ((*(uint32_t *)(a) == (b)))
99 #else
100 /* Don't know what this is - use bytewise comparisons */
101 #define CMP_3_CONST(a, b) \
102 (( ((a)[0] ^ (((b) >> 24) & 0xff)) | \
103 ((a)[1] ^ (((b) >> 16) & 0xff)) | \
104 ((a)[2] ^ (((b) >> 8) & 0xff)) ) == 0)
106 #define CMP_4_CONST(a, b) \
107 (( ((a)[0] ^ (((b) >> 24) & 0xff)) | \
108 ((a)[1] ^ (((b) >> 16) & 0xff)) | \
109 ((a)[2] ^ (((b) >> 8) & 0xff)) | \
110 ((a)[3] ^ (((b) ) & 0xff)) ) == 0)
111 #endif /* CPU_* */
114 /** Streams **/
116 /* Convert PTS/DTS ticks to our clock ticks */
117 #define TS_TO_TICKS(pts) ((uint64_t)CLOCK_RATE*(pts) / TS_SECOND)
118 /* Convert our clock ticks to PTS/DTS ticks */
119 #define TICKS_TO_TS(ts) ((uint64_t)TS_SECOND*(ts) / CLOCK_RATE)
120 /* Convert timecode ticks to our clock ticks */
121 #define TC_TO_TICKS(stamp) ((uint64_t)CLOCK_RATE*(stamp) / TC_SECOND)
122 /* Convert our clock ticks to timecode ticks */
123 #define TICKS_TO_TC(stamp) ((uint64_t)TC_SECOND*(stamp) / CLOCK_RATE)
124 /* Convert timecode ticks to timestamp ticks */
125 #define TC_TO_TS(stamp) ((stamp) / 600)
128 * S = start position, E = end position
130 * pos:
131 * initialize to search start position (S)
133 * len:
134 * initialize to = ABS(S-E)
135 * scanning = remaining bytes in scan direction
137 * dir:
138 * scan direction; >= 0 == forward, < 0 == reverse
140 * margin:
141 * amount of data to right of cursor - initialize by stream_scan_normalize
143 * data:
144 * Extra data used/returned by the function implemented
146 * Forward scan:
147 * S pos E
148 * | *<-margin->| dir->
149 * | |<--len--->|
151 * Reverse scan:
152 * E pos S
153 * |<-len->*<-margin->| <-dir
154 * | | |
156 struct stream_scan
158 off_t pos; /* Initial scan position (file offset) */
159 ssize_t len; /* Maximum length of scan */
160 off_t dir; /* Direction - >= 0; forward, < 0 backward */
161 ssize_t margin; /* Used by function to track margin between position and data end */
162 intptr_t data; /* */
163 struct dbuf_l2_cache l2;
166 #define SSCAN_REVERSE (-1)
167 #define SSCAN_FORWARD 1
169 /* Initializes the cursor */
170 void stream_scan_init(struct stream_scan *sk);
172 /* Ensures direction is -1 or 1 and margin is properly initialized */
173 void stream_scan_normalize(struct stream_scan *sk);
175 /* Moves a scan cursor. If amount is positive, the increment is in the scan
176 * direction, otherwise opposite the scan direction */
177 void stream_scan_offset(struct stream_scan *sk, off_t by);
179 /** Time helpers **/
180 struct hms
182 unsigned int hrs;
183 unsigned int min;
184 unsigned int sec;
185 unsigned int frac;
188 void ts_to_hms(uint32_t ts, struct hms *hms);
189 void hms_format(char *buf, size_t bufsize, struct hms *hms);
191 /** Maths **/
193 /* Moving average */
194 #define AVERAGE(var, x, count) \
195 ({ typeof (count) _c = (count); \
196 ((var) * (_c-1) + (x)) / (_c); })
198 /* Multiply two unsigned 32-bit integers yielding a 64-bit result and
199 * divide by another unsigned 32-bit integer to yield a 32-bit result.
200 * Rounds to nearest with saturation. */
201 uint32_t muldiv_uint32(uint32_t multiplicand,
202 uint32_t multiplier,
203 uint32_t divisor);
206 /** Lists **/
208 /* Does the list have any members? */
209 bool list_is_empty(void **list);
211 /* Is the item inserted into a particular list? */
212 bool list_is_member(void **list, void *item);
214 /* Removes an item from a list - returns true if item was found
215 * and thus removed. */
216 bool list_remove_item(void **list, void *item);
218 /* Adds a list item, insert last, if not already present. */
219 void list_add_item(void **list, void *item);
221 /* Clears the entire list. */
222 void list_clear_all(void **list);
224 /* Enumerate all items in the array. */
225 typedef bool (*list_enum_callback_t)(void *item, intptr_t data);
227 void list_enum_items(void **list,
228 list_enum_callback_t callback,
229 intptr_t data);
232 /** System events **/
234 /* Clear event */
235 void mpeg_sysevent_clear(void);
237 /* Set to ACTION_STD_CANCEL */
238 void mpeg_sysevent_set(void);
240 /* Get event code */
241 long mpeg_sysevent(void);
243 /* Call with a system event code and used as menu callback */
244 int mpeg_sysevent_callback(int btn, const struct menu_item_ex *menu);
246 /* Handle recorded event */
247 void mpeg_sysevent_handle(void);
250 /** Buttons **/
252 /* Get button codes while remembering important events for later
253 * processing; return of ACTION_STD_CANCEL means plugin should
254 * abort and handle the event */
255 int mpeg_button_get(int timeout);
257 #endif /* MPEG_MISC_H */