tokenize.c 14 KB

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