vp9_pred_common.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. /*
  2. * Copyright (c) 2012 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 "vp9/common/vp9_common.h"
  11. #include "vp9/common/vp9_pred_common.h"
  12. #include "vp9/common/vp9_seg_common.h"
  13. int vp9_get_reference_mode_context(const VP9_COMMON *cm,
  14. const MACROBLOCKD *xd) {
  15. int ctx;
  16. const MODE_INFO *const above_mi = xd->above_mi;
  17. const MODE_INFO *const left_mi = xd->left_mi;
  18. const int has_above = !!above_mi;
  19. const int has_left = !!left_mi;
  20. // Note:
  21. // The mode info data structure has a one element border above and to the
  22. // left of the entries corresponding to real macroblocks.
  23. // The prediction flags in these dummy entries are initialized to 0.
  24. if (has_above && has_left) { // both edges available
  25. if (!has_second_ref(above_mi) && !has_second_ref(left_mi))
  26. // neither edge uses comp pred (0/1)
  27. ctx = (above_mi->ref_frame[0] == cm->comp_fixed_ref) ^
  28. (left_mi->ref_frame[0] == cm->comp_fixed_ref);
  29. else if (!has_second_ref(above_mi))
  30. // one of two edges uses comp pred (2/3)
  31. ctx = 2 + (above_mi->ref_frame[0] == cm->comp_fixed_ref ||
  32. !is_inter_block(above_mi));
  33. else if (!has_second_ref(left_mi))
  34. // one of two edges uses comp pred (2/3)
  35. ctx = 2 + (left_mi->ref_frame[0] == cm->comp_fixed_ref ||
  36. !is_inter_block(left_mi));
  37. else // both edges use comp pred (4)
  38. ctx = 4;
  39. } else if (has_above || has_left) { // one edge available
  40. const MODE_INFO *edge_mi = has_above ? above_mi : left_mi;
  41. if (!has_second_ref(edge_mi))
  42. // edge does not use comp pred (0/1)
  43. ctx = edge_mi->ref_frame[0] == cm->comp_fixed_ref;
  44. else
  45. // edge uses comp pred (3)
  46. ctx = 3;
  47. } else { // no edges available (1)
  48. ctx = 1;
  49. }
  50. assert(ctx >= 0 && ctx < COMP_INTER_CONTEXTS);
  51. return ctx;
  52. }
  53. // Returns a context number for the given MB prediction signal
  54. int vp9_get_pred_context_comp_ref_p(const VP9_COMMON *cm,
  55. const MACROBLOCKD *xd) {
  56. int pred_context;
  57. const MODE_INFO *const above_mi = xd->above_mi;
  58. const MODE_INFO *const left_mi = xd->left_mi;
  59. const int above_in_image = !!above_mi;
  60. const int left_in_image = !!left_mi;
  61. // Note:
  62. // The mode info data structure has a one element border above and to the
  63. // left of the entries corresponding to real macroblocks.
  64. // The prediction flags in these dummy entries are initialized to 0.
  65. const int fix_ref_idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref];
  66. const int var_ref_idx = !fix_ref_idx;
  67. if (above_in_image && left_in_image) { // both edges available
  68. const int above_intra = !is_inter_block(above_mi);
  69. const int left_intra = !is_inter_block(left_mi);
  70. if (above_intra && left_intra) { // intra/intra (2)
  71. pred_context = 2;
  72. } else if (above_intra || left_intra) { // intra/inter
  73. const MODE_INFO *edge_mi = above_intra ? left_mi : above_mi;
  74. if (!has_second_ref(edge_mi)) // single pred (1/3)
  75. pred_context = 1 + 2 * (edge_mi->ref_frame[0] != cm->comp_var_ref[1]);
  76. else // comp pred (1/3)
  77. pred_context =
  78. 1 + 2 * (edge_mi->ref_frame[var_ref_idx] != cm->comp_var_ref[1]);
  79. } else { // inter/inter
  80. const int l_sg = !has_second_ref(left_mi);
  81. const int a_sg = !has_second_ref(above_mi);
  82. const MV_REFERENCE_FRAME vrfa =
  83. a_sg ? above_mi->ref_frame[0] : above_mi->ref_frame[var_ref_idx];
  84. const MV_REFERENCE_FRAME vrfl =
  85. l_sg ? left_mi->ref_frame[0] : left_mi->ref_frame[var_ref_idx];
  86. if (vrfa == vrfl && cm->comp_var_ref[1] == vrfa) {
  87. pred_context = 0;
  88. } else if (l_sg && a_sg) { // single/single
  89. if ((vrfa == cm->comp_fixed_ref && vrfl == cm->comp_var_ref[0]) ||
  90. (vrfl == cm->comp_fixed_ref && vrfa == cm->comp_var_ref[0]))
  91. pred_context = 4;
  92. else if (vrfa == vrfl)
  93. pred_context = 3;
  94. else
  95. pred_context = 1;
  96. } else if (l_sg || a_sg) { // single/comp
  97. const MV_REFERENCE_FRAME vrfc = l_sg ? vrfa : vrfl;
  98. const MV_REFERENCE_FRAME rfs = a_sg ? vrfa : vrfl;
  99. if (vrfc == cm->comp_var_ref[1] && rfs != cm->comp_var_ref[1])
  100. pred_context = 1;
  101. else if (rfs == cm->comp_var_ref[1] && vrfc != cm->comp_var_ref[1])
  102. pred_context = 2;
  103. else
  104. pred_context = 4;
  105. } else if (vrfa == vrfl) { // comp/comp
  106. pred_context = 4;
  107. } else {
  108. pred_context = 2;
  109. }
  110. }
  111. } else if (above_in_image || left_in_image) { // one edge available
  112. const MODE_INFO *edge_mi = above_in_image ? above_mi : left_mi;
  113. if (!is_inter_block(edge_mi)) {
  114. pred_context = 2;
  115. } else {
  116. if (has_second_ref(edge_mi))
  117. pred_context =
  118. 4 * (edge_mi->ref_frame[var_ref_idx] != cm->comp_var_ref[1]);
  119. else
  120. pred_context = 3 * (edge_mi->ref_frame[0] != cm->comp_var_ref[1]);
  121. }
  122. } else { // no edges available (2)
  123. pred_context = 2;
  124. }
  125. assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
  126. return pred_context;
  127. }
  128. int vp9_get_pred_context_single_ref_p1(const MACROBLOCKD *xd) {
  129. int pred_context;
  130. const MODE_INFO *const above_mi = xd->above_mi;
  131. const MODE_INFO *const left_mi = xd->left_mi;
  132. const int has_above = !!above_mi;
  133. const int has_left = !!left_mi;
  134. // Note:
  135. // The mode info data structure has a one element border above and to the
  136. // left of the entries corresponding to real macroblocks.
  137. // The prediction flags in these dummy entries are initialized to 0.
  138. if (has_above && has_left) { // both edges available
  139. const int above_intra = !is_inter_block(above_mi);
  140. const int left_intra = !is_inter_block(left_mi);
  141. if (above_intra && left_intra) { // intra/intra
  142. pred_context = 2;
  143. } else if (above_intra || left_intra) { // intra/inter or inter/intra
  144. const MODE_INFO *edge_mi = above_intra ? left_mi : above_mi;
  145. if (!has_second_ref(edge_mi))
  146. pred_context = 4 * (edge_mi->ref_frame[0] == LAST_FRAME);
  147. else
  148. pred_context = 1 + (edge_mi->ref_frame[0] == LAST_FRAME ||
  149. edge_mi->ref_frame[1] == LAST_FRAME);
  150. } else { // inter/inter
  151. const int above_has_second = has_second_ref(above_mi);
  152. const int left_has_second = has_second_ref(left_mi);
  153. const MV_REFERENCE_FRAME above0 = above_mi->ref_frame[0];
  154. const MV_REFERENCE_FRAME above1 = above_mi->ref_frame[1];
  155. const MV_REFERENCE_FRAME left0 = left_mi->ref_frame[0];
  156. const MV_REFERENCE_FRAME left1 = left_mi->ref_frame[1];
  157. if (above_has_second && left_has_second) {
  158. pred_context = 1 + (above0 == LAST_FRAME || above1 == LAST_FRAME ||
  159. left0 == LAST_FRAME || left1 == LAST_FRAME);
  160. } else if (above_has_second || left_has_second) {
  161. const MV_REFERENCE_FRAME rfs = !above_has_second ? above0 : left0;
  162. const MV_REFERENCE_FRAME crf1 = above_has_second ? above0 : left0;
  163. const MV_REFERENCE_FRAME crf2 = above_has_second ? above1 : left1;
  164. if (rfs == LAST_FRAME)
  165. pred_context = 3 + (crf1 == LAST_FRAME || crf2 == LAST_FRAME);
  166. else
  167. pred_context = (crf1 == LAST_FRAME || crf2 == LAST_FRAME);
  168. } else {
  169. pred_context = 2 * (above0 == LAST_FRAME) + 2 * (left0 == LAST_FRAME);
  170. }
  171. }
  172. } else if (has_above || has_left) { // one edge available
  173. const MODE_INFO *edge_mi = has_above ? above_mi : left_mi;
  174. if (!is_inter_block(edge_mi)) { // intra
  175. pred_context = 2;
  176. } else { // inter
  177. if (!has_second_ref(edge_mi))
  178. pred_context = 4 * (edge_mi->ref_frame[0] == LAST_FRAME);
  179. else
  180. pred_context = 1 + (edge_mi->ref_frame[0] == LAST_FRAME ||
  181. edge_mi->ref_frame[1] == LAST_FRAME);
  182. }
  183. } else { // no edges available
  184. pred_context = 2;
  185. }
  186. assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
  187. return pred_context;
  188. }
  189. int vp9_get_pred_context_single_ref_p2(const MACROBLOCKD *xd) {
  190. int pred_context;
  191. const MODE_INFO *const above_mi = xd->above_mi;
  192. const MODE_INFO *const left_mi = xd->left_mi;
  193. const int has_above = !!above_mi;
  194. const int has_left = !!left_mi;
  195. // Note:
  196. // The mode info data structure has a one element border above and to the
  197. // left of the entries corresponding to real macroblocks.
  198. // The prediction flags in these dummy entries are initialized to 0.
  199. if (has_above && has_left) { // both edges available
  200. const int above_intra = !is_inter_block(above_mi);
  201. const int left_intra = !is_inter_block(left_mi);
  202. if (above_intra && left_intra) { // intra/intra
  203. pred_context = 2;
  204. } else if (above_intra || left_intra) { // intra/inter or inter/intra
  205. const MODE_INFO *edge_mi = above_intra ? left_mi : above_mi;
  206. if (!has_second_ref(edge_mi)) {
  207. if (edge_mi->ref_frame[0] == LAST_FRAME)
  208. pred_context = 3;
  209. else
  210. pred_context = 4 * (edge_mi->ref_frame[0] == GOLDEN_FRAME);
  211. } else {
  212. pred_context = 1 +
  213. 2 * (edge_mi->ref_frame[0] == GOLDEN_FRAME ||
  214. edge_mi->ref_frame[1] == GOLDEN_FRAME);
  215. }
  216. } else { // inter/inter
  217. const int above_has_second = has_second_ref(above_mi);
  218. const int left_has_second = has_second_ref(left_mi);
  219. const MV_REFERENCE_FRAME above0 = above_mi->ref_frame[0];
  220. const MV_REFERENCE_FRAME above1 = above_mi->ref_frame[1];
  221. const MV_REFERENCE_FRAME left0 = left_mi->ref_frame[0];
  222. const MV_REFERENCE_FRAME left1 = left_mi->ref_frame[1];
  223. if (above_has_second && left_has_second) {
  224. if (above0 == left0 && above1 == left1)
  225. pred_context =
  226. 3 * (above0 == GOLDEN_FRAME || above1 == GOLDEN_FRAME ||
  227. left0 == GOLDEN_FRAME || left1 == GOLDEN_FRAME);
  228. else
  229. pred_context = 2;
  230. } else if (above_has_second || left_has_second) {
  231. const MV_REFERENCE_FRAME rfs = !above_has_second ? above0 : left0;
  232. const MV_REFERENCE_FRAME crf1 = above_has_second ? above0 : left0;
  233. const MV_REFERENCE_FRAME crf2 = above_has_second ? above1 : left1;
  234. if (rfs == GOLDEN_FRAME)
  235. pred_context = 3 + (crf1 == GOLDEN_FRAME || crf2 == GOLDEN_FRAME);
  236. else if (rfs == ALTREF_FRAME)
  237. pred_context = crf1 == GOLDEN_FRAME || crf2 == GOLDEN_FRAME;
  238. else
  239. pred_context = 1 + 2 * (crf1 == GOLDEN_FRAME || crf2 == GOLDEN_FRAME);
  240. } else {
  241. if (above0 == LAST_FRAME && left0 == LAST_FRAME) {
  242. pred_context = 3;
  243. } else if (above0 == LAST_FRAME || left0 == LAST_FRAME) {
  244. const MV_REFERENCE_FRAME edge0 =
  245. (above0 == LAST_FRAME) ? left0 : above0;
  246. pred_context = 4 * (edge0 == GOLDEN_FRAME);
  247. } else {
  248. pred_context =
  249. 2 * (above0 == GOLDEN_FRAME) + 2 * (left0 == GOLDEN_FRAME);
  250. }
  251. }
  252. }
  253. } else if (has_above || has_left) { // one edge available
  254. const MODE_INFO *edge_mi = has_above ? above_mi : left_mi;
  255. if (!is_inter_block(edge_mi) ||
  256. (edge_mi->ref_frame[0] == LAST_FRAME && !has_second_ref(edge_mi)))
  257. pred_context = 2;
  258. else if (!has_second_ref(edge_mi))
  259. pred_context = 4 * (edge_mi->ref_frame[0] == GOLDEN_FRAME);
  260. else
  261. pred_context = 3 * (edge_mi->ref_frame[0] == GOLDEN_FRAME ||
  262. edge_mi->ref_frame[1] == GOLDEN_FRAME);
  263. } else { // no edges available (2)
  264. pred_context = 2;
  265. }
  266. assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
  267. return pred_context;
  268. }