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 97token_zero_while_loop 98 mov r9, #0 99 strb r9, [r7, r4] ; w->buffer[x] =(unsigned char)0 100 sub r4, r4, #1 ; x-- 101token_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 112token_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 128token_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 147stop_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 173token_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-- 177token_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 188token_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 204token_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 234encode_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 267token_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-- 271token_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 282token_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 298token_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 311