Mercurial > libavcodec.hg
annotate rangecoder.c @ 3990:746a60ba3177 libavcodec
enable CMOV_IS_FAST as its faster or equal speed on every cpu (duron, athlon, PM, P3) from which ive seen benchmarks, it might be slower on P4 but noone has posted benchmarks ...
author | michael |
---|---|
date | Wed, 11 Oct 2006 12:23:40 +0000 |
parents | c8c591fe26f8 |
children | b1314834b3a7 |
rev | line source |
---|---|
2334 | 1 /* |
2 * Range coder | |
3 * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at> | |
4 * | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3184
diff
changeset
|
5 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3184
diff
changeset
|
6 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3184
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
2334 | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3184
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
2334 | 11 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3184
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
2334 | 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Lesser General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Lesser General Public | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3184
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
2967
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
2334 | 20 * |
21 */ | |
2967 | 22 |
2334 | 23 /** |
24 * @file rangecoder.c | |
25 * Range coder. | |
26 * based upon | |
27 * "Range encoding: an algorithm for removing redundancy from a digitised | |
28 * message. | |
29 * G. N. N. Martin Presented in March 1979 to the Video & | |
30 * Data Recording Conference, | |
31 * IBM UK Scientific Center held in Southampton July 24-27 1979." | |
32 * | |
33 */ | |
34 | |
35 #include <string.h> | |
36 | |
37 #include "avcodec.h" | |
38 #include "common.h" | |
39 #include "rangecoder.h" | |
40 | |
41 | |
42 void ff_init_range_encoder(RangeCoder *c, uint8_t *buf, int buf_size){ | |
2967 | 43 c->bytestream_start= |
2334 | 44 c->bytestream= buf; |
45 c->bytestream_end= buf + buf_size; | |
46 | |
47 c->low= 0; | |
48 c->range= 0xFF00; | |
49 c->outstanding_count= 0; | |
50 c->outstanding_byte= -1; | |
51 } | |
52 | |
53 void ff_init_range_decoder(RangeCoder *c, const uint8_t *buf, int buf_size){ | |
2864
95bac7109ff0
Kill some compiler warnings. Compiled code verified identical after changes.
mru
parents:
2522
diff
changeset
|
54 /* cast to avoid compiler warning */ |
95bac7109ff0
Kill some compiler warnings. Compiled code verified identical after changes.
mru
parents:
2522
diff
changeset
|
55 ff_init_range_encoder(c, (uint8_t *) buf, buf_size); |
2334 | 56 |
57 c->low =(*c->bytestream++)<<8; | |
58 c->low+= *c->bytestream++; | |
59 } | |
60 | |
61 void ff_build_rac_states(RangeCoder *c, int factor, int max_p){ | |
62 const int64_t one= 1LL<<32; | |
63 int64_t p; | |
2522
e25782262d7d
kill warnings patch by (Mns Rullgrd <mru inprovide com>)
michael
parents:
2334
diff
changeset
|
64 int last_p8, p8, i; |
2334 | 65 |
66 memset(c->zero_state, 0, sizeof(c->zero_state)); | |
67 memset(c-> one_state, 0, sizeof(c-> one_state)); | |
68 | |
69 #if 0 | |
70 for(i=1; i<256; i++){ | |
2967 | 71 if(c->one_state[i]) |
2334 | 72 continue; |
2967 | 73 |
2334 | 74 p= (i*one + 128) >> 8; |
75 last_p8= i; | |
76 for(;;){ | |
77 p+= ((one-p)*factor + one/2) >> 32; | |
78 p8= (256*p + one/2) >> 32; //FIXME try without the one | |
79 if(p8 <= last_p8) p8= last_p8+1; | |
80 if(p8 > max_p) p8= max_p; | |
81 if(p8 < last_p8) | |
82 break; | |
83 c->one_state[last_p8]= p8; | |
84 if(p8 == last_p8) | |
85 break; | |
86 last_p8= p8; | |
87 } | |
88 } | |
89 #endif | |
90 #if 1 | |
91 last_p8= 0; | |
92 p= one/2; | |
93 for(i=0; i<128; i++){ | |
94 p8= (256*p + one/2) >> 32; //FIXME try without the one | |
95 if(p8 <= last_p8) p8= last_p8+1; | |
96 if(last_p8 && last_p8<256 && p8<=max_p) | |
97 c->one_state[last_p8]= p8; | |
2967 | 98 |
2334 | 99 p+= ((one-p)*factor + one/2) >> 32; |
100 last_p8= p8; | |
101 } | |
102 #endif | |
103 for(i=256-max_p; i<=max_p; i++){ | |
2967 | 104 if(c->one_state[i]) |
2334 | 105 continue; |
106 | |
107 p= (i*one + 128) >> 8; | |
108 p+= ((one-p)*factor + one/2) >> 32; | |
109 p8= (256*p + one/2) >> 32; //FIXME try without the one | |
110 if(p8 <= i) p8= i+1; | |
111 if(p8 > max_p) p8= max_p; | |
112 c->one_state[ i]= p8; | |
113 } | |
2967 | 114 |
3184
68d7896a08e4
fixing out of array access (only cosmetic, this should never have had a end user vissible effect)
michael
parents:
3036
diff
changeset
|
115 for(i=1; i<255; i++) |
2334 | 116 c->zero_state[i]= 256-c->one_state[256-i]; |
117 #if 0 | |
118 for(i=0; i<256; i++) | |
119 av_log(NULL, AV_LOG_DEBUG, "%3d %3d\n", i, c->one_state[i]); | |
120 #endif | |
121 } | |
122 | |
123 /** | |
124 * | |
125 * @return the number of bytes written | |
126 */ | |
127 int ff_rac_terminate(RangeCoder *c){ | |
128 c->range=0xFF; | |
129 c->low +=0xFF; | |
130 renorm_encoder(c); | |
131 c->range=0xFF; | |
132 renorm_encoder(c); | |
133 | |
134 assert(c->low == 0); | |
135 assert(c->range >= 0x100); | |
136 | |
137 return c->bytestream - c->bytestream_start; | |
138 } | |
139 | |
140 #if 0 //selftest | |
141 #define SIZE 10240 | |
142 int main(){ | |
143 RangeCoder c; | |
144 uint8_t b[9*SIZE]; | |
145 uint8_t r[9*SIZE]; | |
146 int i; | |
147 uint8_t state[10]= {0}; | |
2967 | 148 |
2334 | 149 ff_init_range_encoder(&c, b, SIZE); |
150 ff_build_rac_states(&c, 0.05*(1LL<<32), 128+64+32+16); | |
2967 | 151 |
2334 | 152 memset(state, 128, sizeof(state)); |
153 | |
154 for(i=0; i<SIZE; i++){ | |
155 r[i]= random()%7; | |
156 } | |
2967 | 157 |
158 | |
2334 | 159 for(i=0; i<SIZE; i++){ |
160 START_TIMER | |
161 put_rac(&c, state, r[i]&1); | |
162 STOP_TIMER("put_rac") | |
163 } | |
164 | |
165 ff_put_rac_terminate(&c); | |
2967 | 166 |
2334 | 167 ff_init_range_decoder(&c, b, SIZE); |
2967 | 168 |
2334 | 169 memset(state, 128, sizeof(state)); |
2967 | 170 |
2334 | 171 for(i=0; i<SIZE; i++){ |
172 START_TIMER | |
173 if( (r[i]&1) != get_rac(&c, state) ) | |
174 av_log(NULL, AV_LOG_DEBUG, "rac failure at %d\n", i); | |
175 STOP_TIMER("get_rac") | |
176 } | |
2967 | 177 |
2334 | 178 return 0; |
179 } | |
180 | |
181 #endif |