Originally committed as revision 25594 to svn://svn.ffmpeg.org/ffmpeg/trunk
| ... | ... |
@@ -302,6 +302,48 @@ static inline int get_context(PlaneContext *p, int_fast16_t *src, int_fast16_t * |
| 302 | 302 |
return p->quant_table[0][(L-LT) & 0xFF] + p->quant_table[1][(LT-T) & 0xFF] + p->quant_table[2][(T-RT) & 0xFF]; |
| 303 | 303 |
} |
| 304 | 304 |
|
| 305 |
+static void find_best_state(uint8_t best_state[256][256], const uint8_t one_state[256]){
|
|
| 306 |
+ int i,j,k,m; |
|
| 307 |
+ double l2tab[256]; |
|
| 308 |
+ |
|
| 309 |
+ for(i=1; i<256; i++) |
|
| 310 |
+ l2tab[i]= log2(i/256.0); |
|
| 311 |
+ |
|
| 312 |
+ for(i=0; i<256; i++){
|
|
| 313 |
+ double best_len[256]; |
|
| 314 |
+ double p= i/256.0; |
|
| 315 |
+ |
|
| 316 |
+ for(j=0; j<256; j++) |
|
| 317 |
+ best_len[j]= 1<<30; |
|
| 318 |
+ |
|
| 319 |
+ for(j=FFMAX(i-10,1); j<FFMIN(i+11,256); j++){
|
|
| 320 |
+ double occ[256]={0};
|
|
| 321 |
+ double len=0; |
|
| 322 |
+ occ[j]=1.0; |
|
| 323 |
+ for(k=0; k<256; k++){
|
|
| 324 |
+ double newocc[256]={0};
|
|
| 325 |
+ for(m=0; m<256; m++){
|
|
| 326 |
+ if(occ[m]){
|
|
| 327 |
+ len -=occ[m]*( p *l2tab[ m] |
|
| 328 |
+ + (1-p)*l2tab[256-m]); |
|
| 329 |
+ } |
|
| 330 |
+ } |
|
| 331 |
+ if(len < best_len[k]){
|
|
| 332 |
+ best_len[k]= len; |
|
| 333 |
+ best_state[i][k]= j; |
|
| 334 |
+ } |
|
| 335 |
+ for(m=0; m<256; m++){
|
|
| 336 |
+ if(occ[m]){
|
|
| 337 |
+ newocc[ one_state[ m]] += occ[m]* p ; |
|
| 338 |
+ newocc[256-one_state[256-m]] += occ[m]*(1-p); |
|
| 339 |
+ } |
|
| 340 |
+ } |
|
| 341 |
+ memcpy(occ, newocc, sizeof(occ)); |
|
| 342 |
+ } |
|
| 343 |
+ } |
|
| 344 |
+ } |
|
| 345 |
+} |
|
| 346 |
+ |
|
| 305 | 347 |
static av_always_inline av_flatten void put_symbol_inline(RangeCoder *c, uint8_t *state, int v, int is_signed, uint64_t rc_stat[256][2], uint64_t rc_stat2[32][2]){
|
| 306 | 348 |
int i; |
| 307 | 349 |
|
| ... | ... |
@@ -961,6 +1003,7 @@ static av_cold int encode_init(AVCodecContext *avctx) |
| 961 | 961 |
} |
| 962 | 962 |
if(avctx->stats_in){
|
| 963 | 963 |
char *p= avctx->stats_in; |
| 964 |
+ uint8_t best_state[256][256]; |
|
| 964 | 965 |
int gob_count=0; |
| 965 | 966 |
char *next; |
| 966 | 967 |
|
| ... | ... |
@@ -1002,15 +1045,16 @@ static av_cold int encode_init(AVCodecContext *avctx) |
| 1002 | 1002 |
} |
| 1003 | 1003 |
sort_stt(s, s->state_transition); |
| 1004 | 1004 |
|
| 1005 |
+ find_best_state(best_state, s->state_transition); |
|
| 1006 |
+ |
|
| 1005 | 1007 |
for(i=0; i<s->quant_table_count; i++){
|
| 1006 | 1008 |
for(j=0; j<s->context_count[i]; j++){
|
| 1007 | 1009 |
for(k=0; k<32; k++){
|
| 1008 |
- int p= 128; |
|
| 1010 |
+ double p= 128; |
|
| 1009 | 1011 |
if(s->rc_stat2[i][j][k][0]+s->rc_stat2[i][j][k][1]){
|
| 1010 |
- p=256*s->rc_stat2[i][j][k][1] / (s->rc_stat2[i][j][k][0]+s->rc_stat2[i][j][k][1]); |
|
| 1012 |
+ p=256.0*s->rc_stat2[i][j][k][1] / (s->rc_stat2[i][j][k][0]+s->rc_stat2[i][j][k][1]); |
|
| 1011 | 1013 |
} |
| 1012 |
- p= av_clip(p, 1, 254); |
|
| 1013 |
- s->initial_states[i][j][k]= p; |
|
| 1014 |
+ s->initial_states[i][j][k]= best_state[av_clip(round(p), 1, 255)][av_clip((s->rc_stat2[i][j][k][0]+s->rc_stat2[i][j][k][1])/gob_count, 0, 255)]; |
|
| 1014 | 1015 |
} |
| 1015 | 1016 |
} |
| 1016 | 1017 |
} |