1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
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 ****************************************************************************/
26 /* Miscellaneous helpers */
28 #define ALIGNED_ATTR(x) __attribute__((aligned(x)))
33 /* Generic states for when things are too simple to care about naming them */
48 /* Macros for comparing memory bytes to a series of constant bytes in an
49 efficient manner - evaluate to true if corresponding bytes match */
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) \
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" \
64 [b0]"i"(((_b) >> 24) & 0xff), \
65 [b1]"i"(((_b) >> 16) & 0xff), \
66 [b2]"i"(((_b) >> 8) & 0xff) \
70 #define CMP_4_CONST(_a, _b) \
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" \
83 [b0]"i"(((_b) >> 24) & 0xff), \
84 [b1]"i"(((_b) >> 16) & 0xff), \
85 [b2]"i"(((_b) >> 8) & 0xff), \
86 [b3]"i"(((_b) ) & 0xff) \
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)))
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)
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
131 * initialize to search start position (S)
134 * initialize to = ABS(S-E)
135 * scanning = remaining bytes in scan direction
138 * scan direction; >= 0 == forward, < 0 == reverse
141 * amount of data to right of cursor - initialize by stream_scan_normalize
144 * Extra data used/returned by the function implemented
148 * | *<-margin->| dir->
153 * |<-len->*<-margin->| <-dir
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 */
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
);
188 void ts_to_hms(uint32_t ts
, struct hms
*hms
);
189 void hms_format(char *buf
, size_t bufsize
, struct hms
*hms
);
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
,
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
,
231 #endif /* MPEG_MISC_H */