summaryrefslogtreecommitdiff
path: root/apps/plugins/mpegplayer/mpeg_misc.h
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2007-12-29 19:46:35 +0000
committerMichael Sevakis <jethead71@rockbox.org>2007-12-29 19:46:35 +0000
commita222f27c4a17ed8f9809cda7861fe5f23d4cc0c1 (patch)
treed393a23d83549f99772bb156e59ffb88725148b6 /apps/plugins/mpegplayer/mpeg_misc.h
parent1d0f6b90ff43776e55b4b9f062c9bea3f99aa768 (diff)
downloadrockbox-a222f27c4a17ed8f9809cda7861fe5f23d4cc0c1.tar.gz
rockbox-a222f27c4a17ed8f9809cda7861fe5f23d4cc0c1.zip
mpegplayer: Make playback engine fully seekable and frame-accurate and split into logical parts. Be sure to have all current features work. Actual UI for seeking will be added soon. Recommended GOP size is about 15-30 frames depending on target or seeking can be slow with really long GOPs (nature of MPEG video). More refined encoding recommendations for a particular player should be posted soon.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15977 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/mpegplayer/mpeg_misc.h')
-rw-r--r--apps/plugins/mpegplayer/mpeg_misc.h206
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 */
30enum 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 */
152struct 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 */
165void 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 */
169void stream_scan_offset(struct stream_scan *sk, off_t by);
170
171/** Audio helpers **/
172static 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 **/
181struct hms
182{
183 unsigned int hrs;
184 unsigned int min;
185 unsigned int sec;
186 unsigned int frac;
187};
188
189void ts_to_hms(uint32_t ts, struct hms *hms);
190void 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. */
202uint32_t muldiv_uint32(uint32_t multiplicand,
203 uint32_t multiplier,
204 uint32_t divisor);
205
206#endif /* MPEG_MISC_H */