2
0

tokenize.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  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. #include <math.h>
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <assert.h>
  14. #include "onyx_int.h"
  15. #include "tokenize.h"
  16. #include "vpx_mem/vpx_mem.h"
  17. /* Global event counters used for accumulating statistics across several
  18. compressions, then generating context.c = initial stats. */
  19. void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t);
  20. void vp8_fix_contexts(MACROBLOCKD *x);
  21. #include "dct_value_tokens.h"
  22. #include "dct_value_cost.h"
  23. const TOKENVALUE *const vp8_dct_value_tokens_ptr =
  24. dct_value_tokens + DCT_MAX_VALUE;
  25. const short *const vp8_dct_value_cost_ptr = dct_value_cost + DCT_MAX_VALUE;
  26. #if 0
  27. int skip_true_count = 0;
  28. int skip_false_count = 0;
  29. #endif
  30. /* function used to generate dct_value_tokens and dct_value_cost tables */
  31. /*
  32. static void fill_value_tokens()
  33. {
  34. TOKENVALUE *t = dct_value_tokens + DCT_MAX_VALUE;
  35. const vp8_extra_bit_struct *e = vp8_extra_bits;
  36. int i = -DCT_MAX_VALUE;
  37. int sign = 1;
  38. do
  39. {
  40. if (!i)
  41. sign = 0;
  42. {
  43. const int a = sign ? -i : i;
  44. int eb = sign;
  45. if (a > 4)
  46. {
  47. int j = 4;
  48. while (++j < 11 && e[j].base_val <= a) {}
  49. t[i].Token = --j;
  50. eb |= (a - e[j].base_val) << 1;
  51. }
  52. else
  53. t[i].Token = a;
  54. t[i].Extra = eb;
  55. }
  56. // initialize the cost for extra bits for all possible coefficient
  57. value.
  58. {
  59. int cost = 0;
  60. const vp8_extra_bit_struct *p = vp8_extra_bits + t[i].Token;
  61. if (p->base_val)
  62. {
  63. const int extra = t[i].Extra;
  64. const int Length = p->Len;
  65. if (Length)
  66. cost += vp8_treed_cost(p->tree, p->prob, extra >> 1,
  67. Length);
  68. cost += vp8_cost_bit(vp8_prob_half, extra & 1); // sign
  69. dct_value_cost[i + DCT_MAX_VALUE] = cost;
  70. }
  71. }
  72. }
  73. while (++i < DCT_MAX_VALUE);
  74. vp8_dct_value_tokens_ptr = dct_value_tokens + DCT_MAX_VALUE;
  75. vp8_dct_value_cost_ptr = dct_value_cost + DCT_MAX_VALUE;
  76. }
  77. */
  78. static void tokenize2nd_order_b(MACROBLOCK *x, TOKENEXTRA **tp, VP8_COMP *cpi) {
  79. MACROBLOCKD *xd = &x->e_mbd;
  80. int pt; /* near block/prev token context index */
  81. int c; /* start at DC */
  82. TOKENEXTRA *t = *tp; /* store tokens starting here */
  83. const BLOCKD *b;
  84. const short *qcoeff_ptr;
  85. ENTROPY_CONTEXT *a;
  86. ENTROPY_CONTEXT *l;
  87. int band, rc, v, token;
  88. int eob;
  89. b = xd->block + 24;
  90. qcoeff_ptr = b->qcoeff;
  91. a = (ENTROPY_CONTEXT *)xd->above_context + 8;
  92. l = (ENTROPY_CONTEXT *)xd->left_context + 8;
  93. eob = xd->eobs[24];
  94. VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
  95. if (!eob) {
  96. /* c = band for this case */
  97. t->Token = DCT_EOB_TOKEN;
  98. t->context_tree = cpi->common.fc.coef_probs[1][0][pt];
  99. t->skip_eob_node = 0;
  100. ++x->coef_counts[1][0][pt][DCT_EOB_TOKEN];
  101. t++;
  102. *tp = t;
  103. *a = *l = 0;
  104. return;
  105. }
  106. v = qcoeff_ptr[0];
  107. t->Extra = vp8_dct_value_tokens_ptr[v].Extra;
  108. token = vp8_dct_value_tokens_ptr[v].Token;
  109. t->Token = token;
  110. t->context_tree = cpi->common.fc.coef_probs[1][0][pt];
  111. t->skip_eob_node = 0;
  112. ++x->coef_counts[1][0][pt][token];
  113. pt = vp8_prev_token_class[token];
  114. t++;
  115. c = 1;
  116. for (; c < eob; ++c) {
  117. rc = vp8_default_zig_zag1d[c];
  118. band = vp8_coef_bands[c];
  119. v = qcoeff_ptr[rc];
  120. t->Extra = vp8_dct_value_tokens_ptr[v].Extra;
  121. token = vp8_dct_value_tokens_ptr[v].Token;
  122. t->Token = token;
  123. t->context_tree = cpi->common.fc.coef_probs[1][band][pt];
  124. t->skip_eob_node = ((pt == 0));
  125. ++x->coef_counts[1][band][pt][token];
  126. pt = vp8_prev_token_class[token];
  127. t++;
  128. }
  129. if (c < 16) {
  130. band = vp8_coef_bands[c];
  131. t->Token = DCT_EOB_TOKEN;
  132. t->context_tree = cpi->common.fc.coef_probs[1][band][pt];
  133. t->skip_eob_node = 0;
  134. ++x->coef_counts[1][band][pt][DCT_EOB_TOKEN];
  135. t++;
  136. }
  137. *tp = t;
  138. *a = *l = 1;
  139. }
  140. static void tokenize1st_order_b(
  141. MACROBLOCK *x, TOKENEXTRA **tp,
  142. int type, /* which plane: 0=Y no DC, 1=Y2, 2=UV, 3=Y with DC */
  143. VP8_COMP *cpi) {
  144. MACROBLOCKD *xd = &x->e_mbd;
  145. unsigned int block;
  146. const BLOCKD *b;
  147. int pt; /* near block/prev token context index */
  148. int c;
  149. int token;
  150. TOKENEXTRA *t = *tp; /* store tokens starting here */
  151. const short *qcoeff_ptr;
  152. ENTROPY_CONTEXT *a;
  153. ENTROPY_CONTEXT *l;
  154. int band, rc, v;
  155. int tmp1, tmp2;
  156. b = xd->block;
  157. /* Luma */
  158. for (block = 0; block < 16; block++, b++) {
  159. const int eob = *b->eob;
  160. tmp1 = vp8_block2above[block];
  161. tmp2 = vp8_block2left[block];
  162. qcoeff_ptr = b->qcoeff;
  163. a = (ENTROPY_CONTEXT *)xd->above_context + tmp1;
  164. l = (ENTROPY_CONTEXT *)xd->left_context + tmp2;
  165. VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
  166. c = type ? 0 : 1;
  167. if (c >= eob) {
  168. /* c = band for this case */
  169. t->Token = DCT_EOB_TOKEN;
  170. t->context_tree = cpi->common.fc.coef_probs[type][c][pt];
  171. t->skip_eob_node = 0;
  172. ++x->coef_counts[type][c][pt][DCT_EOB_TOKEN];
  173. t++;
  174. *tp = t;
  175. *a = *l = 0;
  176. continue;
  177. }
  178. v = qcoeff_ptr[c];
  179. t->Extra = vp8_dct_value_tokens_ptr[v].Extra;
  180. token = vp8_dct_value_tokens_ptr[v].Token;
  181. t->Token = token;
  182. t->context_tree = cpi->common.fc.coef_probs[type][c][pt];
  183. t->skip_eob_node = 0;
  184. ++x->coef_counts[type][c][pt][token];
  185. pt = vp8_prev_token_class[token];
  186. t++;
  187. c++;
  188. assert(eob <= 16);
  189. for (; c < eob; ++c) {
  190. rc = vp8_default_zig_zag1d[c];
  191. band = vp8_coef_bands[c];
  192. v = qcoeff_ptr[rc];
  193. t->Extra = vp8_dct_value_tokens_ptr[v].Extra;
  194. token = vp8_dct_value_tokens_ptr[v].Token;
  195. t->Token = token;
  196. t->context_tree = cpi->common.fc.coef_probs[type][band][pt];
  197. t->skip_eob_node = (pt == 0);
  198. ++x->coef_counts[type][band][pt][token];
  199. pt = vp8_prev_token_class[token];
  200. t++;
  201. }
  202. if (c < 16) {
  203. band = vp8_coef_bands[c];
  204. t->Token = DCT_EOB_TOKEN;
  205. t->context_tree = cpi->common.fc.coef_probs[type][band][pt];
  206. t->skip_eob_node = 0;
  207. ++x->coef_counts[type][band][pt][DCT_EOB_TOKEN];
  208. t++;
  209. }
  210. *tp = t;
  211. *a = *l = 1;
  212. }
  213. /* Chroma */
  214. for (block = 16; block < 24; block++, b++) {
  215. const int eob = *b->eob;
  216. tmp1 = vp8_block2above[block];
  217. tmp2 = vp8_block2left[block];
  218. qcoeff_ptr = b->qcoeff;
  219. a = (ENTROPY_CONTEXT *)xd->above_context + tmp1;
  220. l = (ENTROPY_CONTEXT *)xd->left_context + tmp2;
  221. VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
  222. if (!eob) {
  223. /* c = band for this case */
  224. t->Token = DCT_EOB_TOKEN;
  225. t->context_tree = cpi->common.fc.coef_probs[2][0][pt];
  226. t->skip_eob_node = 0;
  227. ++x->coef_counts[2][0][pt][DCT_EOB_TOKEN];
  228. t++;
  229. *tp = t;
  230. *a = *l = 0;
  231. continue;
  232. }
  233. v = qcoeff_ptr[0];
  234. t->Extra = vp8_dct_value_tokens_ptr[v].Extra;
  235. token = vp8_dct_value_tokens_ptr[v].Token;
  236. t->Token = token;
  237. t->context_tree = cpi->common.fc.coef_probs[2][0][pt];
  238. t->skip_eob_node = 0;
  239. ++x->coef_counts[2][0][pt][token];
  240. pt = vp8_prev_token_class[token];
  241. t++;
  242. c = 1;
  243. assert(eob <= 16);
  244. for (; c < eob; ++c) {
  245. rc = vp8_default_zig_zag1d[c];
  246. band = vp8_coef_bands[c];
  247. v = qcoeff_ptr[rc];
  248. t->Extra = vp8_dct_value_tokens_ptr[v].Extra;
  249. token = vp8_dct_value_tokens_ptr[v].Token;
  250. t->Token = token;
  251. t->context_tree = cpi->common.fc.coef_probs[2][band][pt];
  252. t->skip_eob_node = (pt == 0);
  253. ++x->coef_counts[2][band][pt][token];
  254. pt = vp8_prev_token_class[token];
  255. t++;
  256. }
  257. if (c < 16) {
  258. band = vp8_coef_bands[c];
  259. t->Token = DCT_EOB_TOKEN;
  260. t->context_tree = cpi->common.fc.coef_probs[2][band][pt];
  261. t->skip_eob_node = 0;
  262. ++x->coef_counts[2][band][pt][DCT_EOB_TOKEN];
  263. t++;
  264. }
  265. *tp = t;
  266. *a = *l = 1;
  267. }
  268. }
  269. static int mb_is_skippable(MACROBLOCKD *x, int has_y2_block) {
  270. int skip = 1;
  271. int i = 0;
  272. if (has_y2_block) {
  273. for (i = 0; i < 16; ++i) skip &= (x->eobs[i] < 2);
  274. }
  275. for (; i < 24 + has_y2_block; ++i) skip &= (!x->eobs[i]);
  276. return skip;
  277. }
  278. void vp8_tokenize_mb(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t) {
  279. MACROBLOCKD *xd = &x->e_mbd;
  280. int plane_type;
  281. int has_y2_block;
  282. has_y2_block = (xd->mode_info_context->mbmi.mode != B_PRED &&
  283. xd->mode_info_context->mbmi.mode != SPLITMV);
  284. xd->mode_info_context->mbmi.mb_skip_coeff = mb_is_skippable(xd, has_y2_block);
  285. if (xd->mode_info_context->mbmi.mb_skip_coeff) {
  286. if (!cpi->common.mb_no_coeff_skip) {
  287. vp8_stuff_mb(cpi, x, t);
  288. } else {
  289. vp8_fix_contexts(xd);
  290. x->skip_true_count++;
  291. }
  292. return;
  293. }
  294. plane_type = 3;
  295. if (has_y2_block) {
  296. tokenize2nd_order_b(x, t, cpi);
  297. plane_type = 0;
  298. }
  299. tokenize1st_order_b(x, t, plane_type, cpi);
  300. }
  301. static void stuff2nd_order_b(TOKENEXTRA **tp, ENTROPY_CONTEXT *a,
  302. ENTROPY_CONTEXT *l, VP8_COMP *cpi, MACROBLOCK *x) {
  303. int pt; /* near block/prev token context index */
  304. TOKENEXTRA *t = *tp; /* store tokens starting here */
  305. VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
  306. t->Token = DCT_EOB_TOKEN;
  307. t->context_tree = cpi->common.fc.coef_probs[1][0][pt];
  308. t->skip_eob_node = 0;
  309. ++x->coef_counts[1][0][pt][DCT_EOB_TOKEN];
  310. ++t;
  311. *tp = t;
  312. pt = 0;
  313. *a = *l = pt;
  314. }
  315. static void stuff1st_order_b(TOKENEXTRA **tp, ENTROPY_CONTEXT *a,
  316. ENTROPY_CONTEXT *l, int type, VP8_COMP *cpi,
  317. MACROBLOCK *x) {
  318. int pt; /* near block/prev token context index */
  319. int band;
  320. TOKENEXTRA *t = *tp; /* store tokens starting here */
  321. VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
  322. band = type ? 0 : 1;
  323. t->Token = DCT_EOB_TOKEN;
  324. t->context_tree = cpi->common.fc.coef_probs[type][band][pt];
  325. t->skip_eob_node = 0;
  326. ++x->coef_counts[type][band][pt][DCT_EOB_TOKEN];
  327. ++t;
  328. *tp = t;
  329. pt = 0; /* 0 <-> all coeff data is zero */
  330. *a = *l = pt;
  331. }
  332. static void stuff1st_order_buv(TOKENEXTRA **tp, ENTROPY_CONTEXT *a,
  333. ENTROPY_CONTEXT *l, VP8_COMP *cpi,
  334. MACROBLOCK *x) {
  335. int pt; /* near block/prev token context index */
  336. TOKENEXTRA *t = *tp; /* store tokens starting here */
  337. VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
  338. t->Token = DCT_EOB_TOKEN;
  339. t->context_tree = cpi->common.fc.coef_probs[2][0][pt];
  340. t->skip_eob_node = 0;
  341. ++x->coef_counts[2][0][pt][DCT_EOB_TOKEN];
  342. ++t;
  343. *tp = t;
  344. pt = 0; /* 0 <-> all coeff data is zero */
  345. *a = *l = pt;
  346. }
  347. void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t) {
  348. MACROBLOCKD *xd = &x->e_mbd;
  349. ENTROPY_CONTEXT *A = (ENTROPY_CONTEXT *)xd->above_context;
  350. ENTROPY_CONTEXT *L = (ENTROPY_CONTEXT *)xd->left_context;
  351. int plane_type;
  352. int b;
  353. plane_type = 3;
  354. if ((xd->mode_info_context->mbmi.mode != B_PRED &&
  355. xd->mode_info_context->mbmi.mode != SPLITMV)) {
  356. stuff2nd_order_b(t, A + vp8_block2above[24], L + vp8_block2left[24], cpi,
  357. x);
  358. plane_type = 0;
  359. }
  360. for (b = 0; b < 16; ++b) {
  361. stuff1st_order_b(t, A + vp8_block2above[b], L + vp8_block2left[b],
  362. plane_type, cpi, x);
  363. }
  364. for (b = 16; b < 24; ++b) {
  365. stuff1st_order_buv(t, A + vp8_block2above[b], L + vp8_block2left[b], cpi,
  366. x);
  367. }
  368. }
  369. void vp8_fix_contexts(MACROBLOCKD *x) {
  370. /* Clear entropy contexts for Y2 blocks */
  371. if (x->mode_info_context->mbmi.mode != B_PRED &&
  372. x->mode_info_context->mbmi.mode != SPLITMV) {
  373. memset(x->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES));
  374. memset(x->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES));
  375. } else {
  376. memset(x->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES) - 1);
  377. memset(x->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES) - 1);
  378. }
  379. }