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