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