2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
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.
18 #include "vpx_mem/vpx_mem.h"
20 /* Global event counters used for accumulating statistics across several
21 compressions, then generating context.c = initial stats. */
24 _int64 context_counters
[BLOCK_TYPES
] [COEF_BANDS
] [PREV_COEF_CONTEXTS
] [vp8_coef_tokens
];
26 void vp8_stuff_mb(VP8_COMP
*cpi
, MACROBLOCKD
*x
, TOKENEXTRA
**t
) ;
27 void vp8_fix_contexts(MACROBLOCKD
*x
);
29 TOKENVALUE vp8_dct_value_tokens
[DCT_MAX_VALUE
*2];
30 const TOKENVALUE
*vp8_dct_value_tokens_ptr
;
31 int vp8_dct_value_cost
[DCT_MAX_VALUE
*2];
32 const int *vp8_dct_value_cost_ptr
;
34 int skip_true_count
= 0;
35 int skip_false_count
= 0;
37 static void fill_value_tokens()
40 TOKENVALUE
*const t
= vp8_dct_value_tokens
+ DCT_MAX_VALUE
;
41 vp8_extra_bit_struct
*const e
= vp8_extra_bits
;
43 int i
= -DCT_MAX_VALUE
;
52 const int a
= sign
? -i
: i
;
59 while (++j
< 11 && e
[j
].base_val
<= a
) {}
62 eb
|= (a
- e
[j
].base_val
) << 1;
70 // initialize the cost for extra bits for all possible coefficient value.
73 vp8_extra_bit_struct
*p
= vp8_extra_bits
+ t
[i
].Token
;
77 const int extra
= t
[i
].Extra
;
78 const int Length
= p
->Len
;
81 cost
+= vp8_treed_cost(p
->tree
, p
->prob
, extra
>> 1, Length
);
83 cost
+= vp8_cost_bit(vp8_prob_half
, extra
& 1); /* sign */
84 vp8_dct_value_cost
[i
+ DCT_MAX_VALUE
] = cost
;
90 while (++i
< DCT_MAX_VALUE
);
92 vp8_dct_value_tokens_ptr
= vp8_dct_value_tokens
+ DCT_MAX_VALUE
;
93 vp8_dct_value_cost_ptr
= vp8_dct_value_cost
+ DCT_MAX_VALUE
;
96 static void tokenize2nd_order_b
98 const BLOCKD
*const b
,
100 const int type
, /* which plane: 0=Y no DC, 1=Y2, 2=UV, 3=Y with DC */
101 const FRAME_TYPE frametype
,
107 int pt
; /* near block/prev token context index */
108 int c
= 0; /* start at DC */
109 const int eob
= b
->eob
; /* one beyond last nonzero coeff */
110 TOKENEXTRA
*t
= *tp
; /* store tokens starting here */
112 const short *qcoeff_ptr
= b
->qcoeff
;
113 VP8_COMBINEENTROPYCONTEXTS(pt
, *a
, *l
);
117 const int band
= vp8_coef_bands
[c
];
121 int rc
= vp8_default_zig_zag1d
[c
];
122 const int v
= qcoeff_ptr
[rc
];
124 assert(-DCT_MAX_VALUE
<= v
&& v
< (DCT_MAX_VALUE
));
126 t
->Extra
= vp8_dct_value_tokens_ptr
[v
].Extra
;
127 x
= vp8_dct_value_tokens_ptr
[v
].Token
;
133 t
->context_tree
= cpi
->common
.fc
.coef_probs
[type
] [band
] [pt
];
135 t
->skip_eob_node
= pt
== 0 && ((band
> 0 && type
> 0) || (band
> 1 && type
== 0));
137 ++cpi
->coef_counts
[type
] [band
] [pt
] [x
];
139 while (pt
= vp8_prev_token_class
[x
], ++t
, c
< eob
&& ++c
< 16);
142 pt
= (c
!= !type
); /* 0 <-> all coeff data is zero */
147 static void tokenize1st_order_b
149 const BLOCKD
*const b
,
151 const int type
, /* which plane: 0=Y no DC, 1=Y2, 2=UV, 3=Y with DC */
152 const FRAME_TYPE frametype
,
158 int pt
; /* near block/prev token context index */
159 int c
= type
? 0 : 1; /* start at DC unless type 0 */
160 const int eob
= b
->eob
; /* one beyond last nonzero coeff */
161 TOKENEXTRA
*t
= *tp
; /* store tokens starting here */
163 const short *qcoeff_ptr
= b
->qcoeff
;
164 VP8_COMBINEENTROPYCONTEXTS(pt
, *a
, *l
);
168 const int band
= vp8_coef_bands
[c
];
174 int rc
= vp8_default_zig_zag1d
[c
];
175 const int v
= qcoeff_ptr
[rc
];
177 assert(-DCT_MAX_VALUE
<= v
&& v
< (DCT_MAX_VALUE
));
179 t
->Extra
= vp8_dct_value_tokens_ptr
[v
].Extra
;
180 x
= vp8_dct_value_tokens_ptr
[v
].Token
;
184 t
->context_tree
= cpi
->common
.fc
.coef_probs
[type
] [band
] [pt
];
186 t
->skip_eob_node
= pt
== 0 && ((band
> 0 && type
> 0) || (band
> 1 && type
== 0));
188 ++cpi
->coef_counts
[type
] [band
] [pt
] [x
];
190 while (pt
= vp8_prev_token_class
[x
], ++t
, c
< eob
&& ++c
< 16);
193 pt
= (c
!= !type
); /* 0 <-> all coeff data is zero */
199 static int mb_is_skippable(MACROBLOCKD
*x
)
205 has_y2_block
= (x
->mode_info_context
->mbmi
.mode
!= B_PRED
206 && x
->mode_info_context
->mbmi
.mode
!= SPLITMV
);
209 for (i
= 0; i
< 16; i
++)
210 skip
&= (x
->block
[i
].eob
< 2);
213 for (; i
< 24 + has_y2_block
; i
++)
214 skip
&= (!x
->block
[i
].eob
);
220 void vp8_tokenize_mb(VP8_COMP
*cpi
, MACROBLOCKD
*x
, TOKENEXTRA
**t
)
222 ENTROPY_CONTEXT
* A
= (ENTROPY_CONTEXT
*)x
->above_context
;
223 ENTROPY_CONTEXT
* L
= (ENTROPY_CONTEXT
*)x
->left_context
;
227 TOKENEXTRA
*start
= *t
;
230 x
->mode_info_context
->mbmi
.dc_diff
= 1;
234 if (x
->mbmi
.force_no_skip
)
236 x
->mbmi
.mb_skip_coeff
= 1;
238 x
->mbmi
.force_no_skip
= 0;
245 x
->mode_info_context
->mbmi
.mb_skip_coeff
= mb_is_skippable(x
);
246 if (x
->mode_info_context
->mbmi
.mb_skip_coeff
)
249 cpi
->skip_true_count
++;
251 if (!cpi
->common
.mb_no_coeff_skip
)
252 vp8_stuff_mb(cpi
, x
, t
) ;
258 if (x
->mode_info_context
->mbmi
.mode
!= B_PRED
&& x
->mode_info_context
->mbmi
.mode
!= SPLITMV
)
259 x
->mode_info_context
->mbmi
.dc_diff
= 0;
261 x
->mode_info_context
->mbmi
.dc_diff
= 1;
267 cpi
->skip_false_count
++;
270 vpx_memcpy(cpi
->coef_counts_backup
, cpi
->coef_counts
, sizeof(cpi
->coef_counts
));
273 if (x
->mode_info_context
->mbmi
.mode
== B_PRED
|| x
->mode_info_context
->mbmi
.mode
== SPLITMV
)
279 tokenize2nd_order_b(x
->block
+ 24, t
, 1, x
->frame_type
,
280 A
+ vp8_block2above
[24], L
+ vp8_block2left
[24], cpi
);
285 for (b
= 0; b
< 16; b
++)
286 tokenize1st_order_b(x
->block
+ b
, t
, plane_type
, x
->frame_type
,
287 A
+ vp8_block2above
[b
],
288 L
+ vp8_block2left
[b
], cpi
);
290 for (b
= 16; b
< 24; b
++)
291 tokenize1st_order_b(x
->block
+ b
, t
, 2, x
->frame_type
,
292 A
+ vp8_block2above
[b
],
293 L
+ vp8_block2left
[b
], cpi
);
297 if (cpi
->common
.mb_no_coeff_skip
)
301 while ((tp
!= *t
) && skip
)
303 skip
= (skip
&& (tp
->Token
== DCT_EOB_TOKEN
));
307 if (skip
!= x
->mbmi
.mb_skip_coeff
)
310 x
->mbmi
.mb_skip_coeff
= skip
;
312 if (x
->mbmi
.mb_skip_coeff
== 1)
316 vpx_memcpy(cpi
->coef_counts
, cpi
->coef_counts_backup
, sizeof(cpi
->coef_counts
));
319 cpi
->skip_true_count
++;
325 cpi
->skip_false_count
++;
326 //skip_false_count++;
336 void init_context_counters(void)
338 vpx_memset(context_counters
, 0, sizeof(context_counters
));
341 void print_context_counters()
344 int type
, band
, pt
, t
;
346 FILE *const f
= fopen("context.c", "w");
348 fprintf(f
, "#include \"entropy.h\"\n");
350 fprintf(f
, "\n/* *** GENERATED FILE: DO NOT EDIT *** */\n\n");
352 fprintf(f
, "int Contexts[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens];\n\n");
354 fprintf(f
, "const int default_contexts[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens] = {");
356 # define Comma( X) (X? ",":"")
362 fprintf(f
, "%s\n { /* block Type %d */", Comma(type
), type
);
368 fprintf(f
, "%s\n { /* Coeff Band %d */", Comma(band
), band
);
374 fprintf(f
, "%s\n {", Comma(pt
));
380 const _int64 x
= context_counters
[type
] [band
] [pt
] [t
];
381 const int y
= (int) x
;
383 assert(x
== (_int64
) y
); /* no overflow handling yet */
384 fprintf(f
, "%s %d", Comma(t
), y
);
387 while (++t
< vp8_coef_tokens
);
391 while (++pt
< PREV_COEF_CONTEXTS
);
396 while (++band
< COEF_BANDS
);
400 while (++type
< BLOCK_TYPES
);
402 fprintf(f
, "\n};\n");
408 void vp8_tokenize_initialize()
414 static __inline
void stuff2nd_order_b
416 const BLOCKD
*const b
,
418 const int type
, /* which plane: 0=Y no DC, 1=Y2, 2=UV, 3=Y with DC */
419 const FRAME_TYPE frametype
,
425 int pt
; /* near block/prev token context index */
426 TOKENEXTRA
*t
= *tp
; /* store tokens starting here */
427 VP8_COMBINEENTROPYCONTEXTS(pt
, *a
, *l
);
432 t
->Token
= DCT_EOB_TOKEN
;
433 t
->context_tree
= cpi
->common
.fc
.coef_probs
[1] [0] [pt
];
434 t
->skip_eob_node
= 0;
435 ++cpi
->coef_counts
[1] [0] [pt
] [DCT_EOB_TOKEN
];
444 static __inline
void stuff1st_order_b
446 const BLOCKD
*const b
,
448 const int type
, /* which plane: 0=Y no DC, 1=Y2, 2=UV, 3=Y with DC */
449 const FRAME_TYPE frametype
,
455 int pt
; /* near block/prev token context index */
456 TOKENEXTRA
*t
= *tp
; /* store tokens starting here */
457 VP8_COMBINEENTROPYCONTEXTS(pt
, *a
, *l
);
462 t
->Token
= DCT_EOB_TOKEN
;
463 t
->context_tree
= cpi
->common
.fc
.coef_probs
[0] [1] [pt
];
464 t
->skip_eob_node
= 0;
465 ++cpi
->coef_counts
[0] [1] [pt
] [DCT_EOB_TOKEN
];
468 pt
= 0; /* 0 <-> all coeff data is zero */
473 void stuff1st_order_buv
475 const BLOCKD
*const b
,
477 const int type
, /* which plane: 0=Y no DC, 1=Y2, 2=UV, 3=Y with DC */
478 const FRAME_TYPE frametype
,
484 int pt
; /* near block/prev token context index */
485 TOKENEXTRA
*t
= *tp
; /* store tokens starting here */
486 VP8_COMBINEENTROPYCONTEXTS(pt
, *a
, *l
);
491 t
->Token
= DCT_EOB_TOKEN
;
492 t
->context_tree
= cpi
->common
.fc
.coef_probs
[2] [0] [pt
];
493 t
->skip_eob_node
= 0;
494 ++cpi
->coef_counts
[2] [0] [pt
] [DCT_EOB_TOKEN
];
497 pt
= 0; /* 0 <-> all coeff data is zero */
502 void vp8_stuff_mb(VP8_COMP
*cpi
, MACROBLOCKD
*x
, TOKENEXTRA
**t
)
504 ENTROPY_CONTEXT
* A
= (ENTROPY_CONTEXT
*)x
->above_context
;
505 ENTROPY_CONTEXT
* L
= (ENTROPY_CONTEXT
*)x
->left_context
;
509 stuff2nd_order_b(x
->block
+ 24, t
, 1, x
->frame_type
,
510 A
+ vp8_block2above
[24], L
+ vp8_block2left
[24], cpi
);
514 if (x
->mode_info_context
->mbmi
.mode
!= B_PRED
&& x
->mode_info_context
->mbmi
.mode
!= SPLITMV
)
515 x
->mode_info_context
->mbmi
.dc_diff
= 0;
517 x
->mode_info_context
->mbmi
.dc_diff
= 1;
520 for (b
= 0; b
< 16; b
++)
521 stuff1st_order_b(x
->block
+ b
, t
, plane_type
, x
->frame_type
,
522 A
+ vp8_block2above
[b
],
523 L
+ vp8_block2left
[b
], cpi
);
525 for (b
= 16; b
< 24; b
++)
526 stuff1st_order_buv(x
->block
+ b
, t
, 2, x
->frame_type
,
527 A
+ vp8_block2above
[b
],
528 L
+ vp8_block2left
[b
], cpi
);
531 void vp8_fix_contexts(MACROBLOCKD
*x
)
533 /* Clear entropy contexts for Y2 blocks */
534 if (x
->mode_info_context
->mbmi
.mode
!= B_PRED
&& x
->mode_info_context
->mbmi
.mode
!= SPLITMV
)
536 vpx_memset(x
->above_context
, 0, sizeof(ENTROPY_CONTEXT_PLANES
));
537 vpx_memset(x
->left_context
, 0, sizeof(ENTROPY_CONTEXT_PLANES
));
541 vpx_memset(x
->above_context
, 0, sizeof(ENTROPY_CONTEXT_PLANES
)-1);
542 vpx_memset(x
->left_context
, 0, sizeof(ENTROPY_CONTEXT_PLANES
)-1);