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