2
0

mr_dissim.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  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 <limits.h>
  11. #include "vpx_config.h"
  12. #include "onyx_int.h"
  13. #include "mr_dissim.h"
  14. #include "vpx_dsp/vpx_dsp_common.h"
  15. #include "vpx_mem/vpx_mem.h"
  16. #include "rdopt.h"
  17. #include "vp8/common/common.h"
  18. void vp8_cal_low_res_mb_cols(VP8_COMP *cpi) {
  19. int low_res_w;
  20. /* Support arbitrary down-sampling factor */
  21. unsigned int iw = cpi->oxcf.Width * cpi->oxcf.mr_down_sampling_factor.den +
  22. cpi->oxcf.mr_down_sampling_factor.num - 1;
  23. low_res_w = iw / cpi->oxcf.mr_down_sampling_factor.num;
  24. cpi->mr_low_res_mb_cols = ((low_res_w + 15) >> 4);
  25. }
  26. #define GET_MV(x) \
  27. if (x->mbmi.ref_frame != INTRA_FRAME) { \
  28. mvx[cnt] = x->mbmi.mv.as_mv.row; \
  29. mvy[cnt] = x->mbmi.mv.as_mv.col; \
  30. cnt++; \
  31. }
  32. #define GET_MV_SIGN(x) \
  33. if (x->mbmi.ref_frame != INTRA_FRAME) { \
  34. mvx[cnt] = x->mbmi.mv.as_mv.row; \
  35. mvy[cnt] = x->mbmi.mv.as_mv.col; \
  36. if (cm->ref_frame_sign_bias[x->mbmi.ref_frame] != \
  37. cm->ref_frame_sign_bias[tmp->mbmi.ref_frame]) { \
  38. mvx[cnt] *= -1; \
  39. mvy[cnt] *= -1; \
  40. } \
  41. cnt++; \
  42. }
  43. void vp8_cal_dissimilarity(VP8_COMP *cpi) {
  44. VP8_COMMON *cm = &cpi->common;
  45. int i;
  46. /* Note: The first row & first column in mip are outside the frame, which
  47. * were initialized to all 0.(ref_frame, mode, mv...)
  48. * Their ref_frame = 0 means they won't be counted in the following
  49. * calculation.
  50. */
  51. if (cpi->oxcf.mr_total_resolutions > 1 &&
  52. cpi->oxcf.mr_encoder_id < (cpi->oxcf.mr_total_resolutions - 1)) {
  53. /* Store info for show/no-show frames for supporting alt_ref.
  54. * If parent frame is alt_ref, child has one too.
  55. */
  56. LOWER_RES_FRAME_INFO *store_info =
  57. (LOWER_RES_FRAME_INFO *)cpi->oxcf.mr_low_res_mode_info;
  58. store_info->frame_type = cm->frame_type;
  59. if (cm->frame_type != KEY_FRAME) {
  60. store_info->is_frame_dropped = 0;
  61. for (i = 1; i < MAX_REF_FRAMES; ++i)
  62. store_info->low_res_ref_frames[i] = cpi->current_ref_frames[i];
  63. }
  64. if (cm->frame_type != KEY_FRAME) {
  65. int mb_row;
  66. int mb_col;
  67. /* Point to beginning of allocated MODE_INFO arrays. */
  68. MODE_INFO *tmp = cm->mip + cm->mode_info_stride;
  69. LOWER_RES_MB_INFO *store_mode_info = store_info->mb_info;
  70. for (mb_row = 0; mb_row < cm->mb_rows; ++mb_row) {
  71. tmp++;
  72. for (mb_col = 0; mb_col < cm->mb_cols; ++mb_col) {
  73. int dissim = INT_MAX;
  74. if (tmp->mbmi.ref_frame != INTRA_FRAME) {
  75. int mvx[8];
  76. int mvy[8];
  77. int mmvx;
  78. int mmvy;
  79. int cnt = 0;
  80. const MODE_INFO *here = tmp;
  81. const MODE_INFO *above = here - cm->mode_info_stride;
  82. const MODE_INFO *left = here - 1;
  83. const MODE_INFO *aboveleft = above - 1;
  84. const MODE_INFO *aboveright = NULL;
  85. const MODE_INFO *right = NULL;
  86. const MODE_INFO *belowleft = NULL;
  87. const MODE_INFO *below = NULL;
  88. const MODE_INFO *belowright = NULL;
  89. /* If alternate reference frame is used, we have to
  90. * check sign of MV. */
  91. if (cpi->oxcf.play_alternate) {
  92. /* Gather mv of neighboring MBs */
  93. GET_MV_SIGN(above)
  94. GET_MV_SIGN(left)
  95. GET_MV_SIGN(aboveleft)
  96. if (mb_col < (cm->mb_cols - 1)) {
  97. right = here + 1;
  98. aboveright = above + 1;
  99. GET_MV_SIGN(right)
  100. GET_MV_SIGN(aboveright)
  101. }
  102. if (mb_row < (cm->mb_rows - 1)) {
  103. below = here + cm->mode_info_stride;
  104. belowleft = below - 1;
  105. GET_MV_SIGN(below)
  106. GET_MV_SIGN(belowleft)
  107. }
  108. if (mb_col < (cm->mb_cols - 1) && mb_row < (cm->mb_rows - 1)) {
  109. belowright = below + 1;
  110. GET_MV_SIGN(belowright)
  111. }
  112. } else {
  113. /* No alt_ref and gather mv of neighboring MBs */
  114. GET_MV(above)
  115. GET_MV(left)
  116. GET_MV(aboveleft)
  117. if (mb_col < (cm->mb_cols - 1)) {
  118. right = here + 1;
  119. aboveright = above + 1;
  120. GET_MV(right)
  121. GET_MV(aboveright)
  122. }
  123. if (mb_row < (cm->mb_rows - 1)) {
  124. below = here + cm->mode_info_stride;
  125. belowleft = below - 1;
  126. GET_MV(below)
  127. GET_MV(belowleft)
  128. }
  129. if (mb_col < (cm->mb_cols - 1) && mb_row < (cm->mb_rows - 1)) {
  130. belowright = below + 1;
  131. GET_MV(belowright)
  132. }
  133. }
  134. if (cnt > 0) {
  135. int max_mvx = mvx[0];
  136. int min_mvx = mvx[0];
  137. int max_mvy = mvy[0];
  138. int min_mvy = mvy[0];
  139. int i;
  140. if (cnt > 1) {
  141. for (i = 1; i < cnt; ++i) {
  142. if (mvx[i] > max_mvx)
  143. max_mvx = mvx[i];
  144. else if (mvx[i] < min_mvx)
  145. min_mvx = mvx[i];
  146. if (mvy[i] > max_mvy)
  147. max_mvy = mvy[i];
  148. else if (mvy[i] < min_mvy)
  149. min_mvy = mvy[i];
  150. }
  151. }
  152. mmvx = VPXMAX(abs(min_mvx - here->mbmi.mv.as_mv.row),
  153. abs(max_mvx - here->mbmi.mv.as_mv.row));
  154. mmvy = VPXMAX(abs(min_mvy - here->mbmi.mv.as_mv.col),
  155. abs(max_mvy - here->mbmi.mv.as_mv.col));
  156. dissim = VPXMAX(mmvx, mmvy);
  157. }
  158. }
  159. /* Store mode info for next resolution encoding */
  160. store_mode_info->mode = tmp->mbmi.mode;
  161. store_mode_info->ref_frame = tmp->mbmi.ref_frame;
  162. store_mode_info->mv.as_int = tmp->mbmi.mv.as_int;
  163. store_mode_info->dissim = dissim;
  164. tmp++;
  165. store_mode_info++;
  166. }
  167. }
  168. }
  169. }
  170. }
  171. /* This function is called only when this frame is dropped at current
  172. resolution level. */
  173. void vp8_store_drop_frame_info(VP8_COMP *cpi) {
  174. /* If the frame is dropped in lower-resolution encoding, this information
  175. is passed to higher resolution level so that the encoder knows there
  176. is no mode & motion info available.
  177. */
  178. if (cpi->oxcf.mr_total_resolutions > 1 &&
  179. cpi->oxcf.mr_encoder_id < (cpi->oxcf.mr_total_resolutions - 1)) {
  180. /* Store info for show/no-show frames for supporting alt_ref.
  181. * If parent frame is alt_ref, child has one too.
  182. */
  183. LOWER_RES_FRAME_INFO *store_info =
  184. (LOWER_RES_FRAME_INFO *)cpi->oxcf.mr_low_res_mode_info;
  185. /* Set frame_type to be INTER_FRAME since we won't drop key frame. */
  186. store_info->frame_type = INTER_FRAME;
  187. store_info->is_frame_dropped = 1;
  188. }
  189. }