OLD | NEW |
| (Empty) |
1 ; | |
2 ; Copyright (c) 2010 The WebM project authors. All Rights Reserved. | |
3 ; | |
4 ; Use of this source code is governed by a BSD-style license | |
5 ; that can be found in the LICENSE file in the root of the source | |
6 ; tree. An additional intellectual property rights grant can be found | |
7 ; in the file PATENTS. All contributing project authors may | |
8 ; be found in the AUTHORS file in the root of the source tree. | |
9 ; | |
10 | |
11 | |
12 EXPORT |vp8_start_encode| | |
13 EXPORT |vp8_encode_bool| | |
14 EXPORT |vp8_stop_encode| | |
15 EXPORT |vp8_encode_value| | |
16 IMPORT |vp8_validate_buffer_arm| | |
17 | |
18 INCLUDE vp8_asm_enc_offsets.asm | |
19 | |
20 ARM | |
21 REQUIRE8 | |
22 PRESERVE8 | |
23 | |
24 AREA |.text|, CODE, READONLY | |
25 | |
26 ; macro for validating write buffer position | |
27 ; needs vp8_writer in r0 | |
28 ; start shall not be in r1 | |
29 MACRO | |
30 VALIDATE_POS $start, $pos | |
31 push {r0-r3, r12, lr} ; rest of regs are preserved by subroutine call | |
32 ldr r2, [r0, #vp8_writer_buffer_end] | |
33 ldr r3, [r0, #vp8_writer_error] | |
34 mov r1, $pos | |
35 mov r0, $start | |
36 bl vp8_validate_buffer_arm | |
37 pop {r0-r3, r12, lr} | |
38 MEND | |
39 | |
40 ; r0 BOOL_CODER *br | |
41 ; r1 unsigned char *source | |
42 ; r2 unsigned char *source_end | |
43 |vp8_start_encode| PROC | |
44 str r2, [r0, #vp8_writer_buffer_end] | |
45 mov r12, #0 | |
46 mov r3, #255 | |
47 mvn r2, #23 | |
48 str r12, [r0, #vp8_writer_lowvalue] | |
49 str r3, [r0, #vp8_writer_range] | |
50 str r2, [r0, #vp8_writer_count] | |
51 str r12, [r0, #vp8_writer_pos] | |
52 str r1, [r0, #vp8_writer_buffer] | |
53 bx lr | |
54 ENDP | |
55 | |
56 ; r0 BOOL_CODER *br | |
57 ; r1 int bit | |
58 ; r2 int probability | |
59 |vp8_encode_bool| PROC | |
60 push {r4-r10, lr} | |
61 | |
62 mov r4, r2 | |
63 | |
64 ldr r2, [r0, #vp8_writer_lowvalue] | |
65 ldr r5, [r0, #vp8_writer_range] | |
66 ldr r3, [r0, #vp8_writer_count] | |
67 | |
68 sub r7, r5, #1 ; range-1 | |
69 | |
70 cmp r1, #0 | |
71 mul r6, r4, r7 ; ((range-1) * probability) | |
72 | |
73 mov r7, #1 | |
74 add r4, r7, r6, lsr #8 ; 1 + (((range-1) * probability) >> 8) | |
75 | |
76 addne r2, r2, r4 ; if (bit) lowvalue += split | |
77 subne r4, r5, r4 ; if (bit) range = range-split | |
78 | |
79 ; Counting the leading zeros is used to normalize range. | |
80 clz r6, r4 | |
81 sub r6, r6, #24 ; shift | |
82 | |
83 ; Flag is set on the sum of count. This flag is used later | |
84 ; to determine if count >= 0 | |
85 adds r3, r3, r6 ; count += shift | |
86 lsl r5, r4, r6 ; range <<= shift | |
87 bmi token_count_lt_zero ; if(count >= 0) | |
88 | |
89 sub r6, r6, r3 ; offset = shift - count | |
90 sub r4, r6, #1 ; offset-1 | |
91 lsls r4, r2, r4 ; if((lowvalue<<(offset-1)) & 0x80000000
) | |
92 bpl token_high_bit_not_set | |
93 | |
94 ldr r4, [r0, #vp8_writer_pos] ; x | |
95 sub r4, r4, #1 ; x = w->pos-1 | |
96 b token_zero_while_start | |
97 token_zero_while_loop | |
98 mov r9, #0 | |
99 strb r9, [r7, r4] ; w->buffer[x] =(unsigned char)0 | |
100 sub r4, r4, #1 ; x-- | |
101 token_zero_while_start | |
102 cmp r4, #0 | |
103 ldrge r7, [r0, #vp8_writer_buffer] | |
104 ldrb r1, [r7, r4] | |
105 cmpge r1, #0xff | |
106 beq token_zero_while_loop | |
107 | |
108 ldr r7, [r0, #vp8_writer_buffer] | |
109 ldrb r9, [r7, r4] ; w->buffer[x] | |
110 add r9, r9, #1 | |
111 strb r9, [r7, r4] ; w->buffer[x] + 1 | |
112 token_high_bit_not_set | |
113 rsb r4, r6, #24 ; 24-offset | |
114 ldr r9, [r0, #vp8_writer_buffer] | |
115 lsr r7, r2, r4 ; lowvalue >> (24-offset) | |
116 ldr r4, [r0, #vp8_writer_pos] ; w->pos | |
117 lsl r2, r2, r6 ; lowvalue <<= offset | |
118 mov r6, r3 ; shift = count | |
119 add r1, r4, #1 ; w->pos++ | |
120 bic r2, r2, #0xff000000 ; lowvalue &= 0xffffff | |
121 str r1, [r0, #vp8_writer_pos] | |
122 sub r3, r3, #8 ; count -= 8 | |
123 | |
124 VALIDATE_POS r9, r1 ; validate_buffer at pos | |
125 | |
126 strb r7, [r9, r4] ; w->buffer[w->pos++] | |
127 | |
128 token_count_lt_zero | |
129 lsl r2, r2, r6 ; lowvalue <<= shift | |
130 | |
131 str r2, [r0, #vp8_writer_lowvalue] | |
132 str r5, [r0, #vp8_writer_range] | |
133 str r3, [r0, #vp8_writer_count] | |
134 pop {r4-r10, pc} | |
135 ENDP | |
136 | |
137 ; r0 BOOL_CODER *br | |
138 |vp8_stop_encode| PROC | |
139 push {r4-r10, lr} | |
140 | |
141 ldr r2, [r0, #vp8_writer_lowvalue] | |
142 ldr r5, [r0, #vp8_writer_range] | |
143 ldr r3, [r0, #vp8_writer_count] | |
144 | |
145 mov r10, #32 | |
146 | |
147 stop_encode_loop | |
148 sub r7, r5, #1 ; range-1 | |
149 | |
150 mov r4, r7, lsl #7 ; ((range-1) * 128) | |
151 | |
152 mov r7, #1 | |
153 add r4, r7, r4, lsr #8 ; 1 + (((range-1) * 128) >> 8) | |
154 | |
155 ; Counting the leading zeros is used to normalize range. | |
156 clz r6, r4 | |
157 sub r6, r6, #24 ; shift | |
158 | |
159 ; Flag is set on the sum of count. This flag is used later | |
160 ; to determine if count >= 0 | |
161 adds r3, r3, r6 ; count += shift | |
162 lsl r5, r4, r6 ; range <<= shift | |
163 bmi token_count_lt_zero_se ; if(count >= 0) | |
164 | |
165 sub r6, r6, r3 ; offset = shift - count | |
166 sub r4, r6, #1 ; offset-1 | |
167 lsls r4, r2, r4 ; if((lowvalue<<(offset-1)) & 0x80000000
) | |
168 bpl token_high_bit_not_set_se | |
169 | |
170 ldr r4, [r0, #vp8_writer_pos] ; x | |
171 sub r4, r4, #1 ; x = w->pos-1 | |
172 b token_zero_while_start_se | |
173 token_zero_while_loop_se | |
174 mov r9, #0 | |
175 strb r9, [r7, r4] ; w->buffer[x] =(unsigned char)0 | |
176 sub r4, r4, #1 ; x-- | |
177 token_zero_while_start_se | |
178 cmp r4, #0 | |
179 ldrge r7, [r0, #vp8_writer_buffer] | |
180 ldrb r1, [r7, r4] | |
181 cmpge r1, #0xff | |
182 beq token_zero_while_loop_se | |
183 | |
184 ldr r7, [r0, #vp8_writer_buffer] | |
185 ldrb r9, [r7, r4] ; w->buffer[x] | |
186 add r9, r9, #1 | |
187 strb r9, [r7, r4] ; w->buffer[x] + 1 | |
188 token_high_bit_not_set_se | |
189 rsb r4, r6, #24 ; 24-offset | |
190 ldr r9, [r0, #vp8_writer_buffer] | |
191 lsr r7, r2, r4 ; lowvalue >> (24-offset) | |
192 ldr r4, [r0, #vp8_writer_pos] ; w->pos | |
193 lsl r2, r2, r6 ; lowvalue <<= offset | |
194 mov r6, r3 ; shift = count | |
195 add r1, r4, #1 ; w->pos++ | |
196 bic r2, r2, #0xff000000 ; lowvalue &= 0xffffff | |
197 str r1, [r0, #vp8_writer_pos] | |
198 sub r3, r3, #8 ; count -= 8 | |
199 | |
200 VALIDATE_POS r9, r1 ; validate_buffer at pos | |
201 | |
202 strb r7, [r9, r4] ; w->buffer[w->pos++] | |
203 | |
204 token_count_lt_zero_se | |
205 lsl r2, r2, r6 ; lowvalue <<= shift | |
206 | |
207 subs r10, r10, #1 | |
208 bne stop_encode_loop | |
209 | |
210 str r2, [r0, #vp8_writer_lowvalue] | |
211 str r5, [r0, #vp8_writer_range] | |
212 str r3, [r0, #vp8_writer_count] | |
213 pop {r4-r10, pc} | |
214 | |
215 ENDP | |
216 | |
217 ; r0 BOOL_CODER *br | |
218 ; r1 int data | |
219 ; r2 int bits | |
220 |vp8_encode_value| PROC | |
221 push {r4-r12, lr} | |
222 | |
223 mov r10, r2 | |
224 | |
225 ldr r2, [r0, #vp8_writer_lowvalue] | |
226 ldr r5, [r0, #vp8_writer_range] | |
227 ldr r3, [r0, #vp8_writer_count] | |
228 | |
229 rsb r4, r10, #32 ; 32-n | |
230 | |
231 ; v is kept in r1 during the token pack loop | |
232 lsl r1, r1, r4 ; r1 = v << 32 - n | |
233 | |
234 encode_value_loop | |
235 sub r7, r5, #1 ; range-1 | |
236 | |
237 ; Decisions are made based on the bit value shifted | |
238 ; off of v, so set a flag here based on this. | |
239 ; This value is refered to as "bb" | |
240 lsls r1, r1, #1 ; bit = v >> n | |
241 mov r4, r7, lsl #7 ; ((range-1) * 128) | |
242 | |
243 mov r7, #1 | |
244 add r4, r7, r4, lsr #8 ; 1 + (((range-1) * 128) >> 8) | |
245 | |
246 addcs r2, r2, r4 ; if (bit) lowvalue += split | |
247 subcs r4, r5, r4 ; if (bit) range = range-split | |
248 | |
249 ; Counting the leading zeros is used to normalize range. | |
250 clz r6, r4 | |
251 sub r6, r6, #24 ; shift | |
252 | |
253 ; Flag is set on the sum of count. This flag is used later | |
254 ; to determine if count >= 0 | |
255 adds r3, r3, r6 ; count += shift | |
256 lsl r5, r4, r6 ; range <<= shift | |
257 bmi token_count_lt_zero_ev ; if(count >= 0) | |
258 | |
259 sub r6, r6, r3 ; offset = shift - count | |
260 sub r4, r6, #1 ; offset-1 | |
261 lsls r4, r2, r4 ; if((lowvalue<<(offset-1)) & 0x80000000
) | |
262 bpl token_high_bit_not_set_ev | |
263 | |
264 ldr r4, [r0, #vp8_writer_pos] ; x | |
265 sub r4, r4, #1 ; x = w->pos-1 | |
266 b token_zero_while_start_ev | |
267 token_zero_while_loop_ev | |
268 mov r9, #0 | |
269 strb r9, [r7, r4] ; w->buffer[x] =(unsigned char)0 | |
270 sub r4, r4, #1 ; x-- | |
271 token_zero_while_start_ev | |
272 cmp r4, #0 | |
273 ldrge r7, [r0, #vp8_writer_buffer] | |
274 ldrb r11, [r7, r4] | |
275 cmpge r11, #0xff | |
276 beq token_zero_while_loop_ev | |
277 | |
278 ldr r7, [r0, #vp8_writer_buffer] | |
279 ldrb r9, [r7, r4] ; w->buffer[x] | |
280 add r9, r9, #1 | |
281 strb r9, [r7, r4] ; w->buffer[x] + 1 | |
282 token_high_bit_not_set_ev | |
283 rsb r4, r6, #24 ; 24-offset | |
284 ldr r9, [r0, #vp8_writer_buffer] | |
285 lsr r7, r2, r4 ; lowvalue >> (24-offset) | |
286 ldr r4, [r0, #vp8_writer_pos] ; w->pos | |
287 lsl r2, r2, r6 ; lowvalue <<= offset | |
288 mov r6, r3 ; shift = count | |
289 add r11, r4, #1 ; w->pos++ | |
290 bic r2, r2, #0xff000000 ; lowvalue &= 0xffffff | |
291 str r11, [r0, #vp8_writer_pos] | |
292 sub r3, r3, #8 ; count -= 8 | |
293 | |
294 VALIDATE_POS r9, r11 ; validate_buffer at pos | |
295 | |
296 strb r7, [r9, r4] ; w->buffer[w->pos++] | |
297 | |
298 token_count_lt_zero_ev | |
299 lsl r2, r2, r6 ; lowvalue <<= shift | |
300 | |
301 subs r10, r10, #1 | |
302 bne encode_value_loop | |
303 | |
304 str r2, [r0, #vp8_writer_lowvalue] | |
305 str r5, [r0, #vp8_writer_range] | |
306 str r3, [r0, #vp8_writer_count] | |
307 pop {r4-r12, pc} | |
308 ENDP | |
309 | |
310 END | |
OLD | NEW |