| File: | root/firefox-clang/media/libvpx/libvpx/vp9/encoder/vp9_mbgraph.c |
| Warning: | line 242, column 3 Address of stack memory associated with local variable 'mi_above' is still referred to by the caller variable 'cpi' upon returning to the caller. This will be a dangling reference |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 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 | ||||
| 11 | #include <limits.h> | |||
| 12 | ||||
| 13 | #include "./vp9_rtcd.h" | |||
| 14 | #include "./vpx_dsp_rtcd.h" | |||
| 15 | ||||
| 16 | #include "vpx_dsp/vpx_dsp_common.h" | |||
| 17 | #include "vpx_mem/vpx_mem.h" | |||
| 18 | #include "vpx_ports/system_state.h" | |||
| 19 | #include "vp9/encoder/vp9_segmentation.h" | |||
| 20 | #include "vp9/encoder/vp9_mcomp.h" | |||
| 21 | #include "vp9/common/vp9_blockd.h" | |||
| 22 | #include "vp9/common/vp9_reconinter.h" | |||
| 23 | #include "vp9/common/vp9_reconintra.h" | |||
| 24 | ||||
| 25 | static unsigned int do_16x16_motion_iteration(VP9_COMP *cpi, const MV *ref_mv, | |||
| 26 | MV *dst_mv, int mb_row, | |||
| 27 | int mb_col) { | |||
| 28 | MACROBLOCK *const x = &cpi->td.mb; | |||
| 29 | MACROBLOCKD *const xd = &x->e_mbd; | |||
| 30 | MV_SPEED_FEATURES *const mv_sf = &cpi->sf.mv; | |||
| 31 | const SEARCH_METHODS old_search_method = mv_sf->search_method; | |||
| 32 | const vp9_variance_fn_ptr_t v_fn_ptr = cpi->fn_ptr[BLOCK_16X166]; | |||
| 33 | const MvLimits tmp_mv_limits = x->mv_limits; | |||
| 34 | MV ref_full; | |||
| 35 | int cost_list[5]; | |||
| 36 | ||||
| 37 | // Further step/diamond searches as necessary | |||
| 38 | int step_param = mv_sf->reduce_first_step_size; | |||
| 39 | step_param = VPXMIN(step_param, MAX_MVSEARCH_STEPS - 2)(((step_param) < (11 - 2)) ? (step_param) : (11 - 2)); | |||
| 40 | ||||
| 41 | vp9_set_mv_search_range(&x->mv_limits, ref_mv); | |||
| 42 | ||||
| 43 | ref_full.col = ref_mv->col >> 3; | |||
| 44 | ref_full.row = ref_mv->row >> 3; | |||
| 45 | ||||
| 46 | mv_sf->search_method = HEX; | |||
| 47 | vp9_full_pixel_search(cpi, x, BLOCK_16X166, &ref_full, step_param, | |||
| 48 | cpi->sf.mv.search_method, x->errorperbit, | |||
| 49 | cond_cost_list(cpi, cost_list), ref_mv, dst_mv, 0, 0); | |||
| 50 | mv_sf->search_method = old_search_method; | |||
| 51 | ||||
| 52 | /* restore UMV window */ | |||
| 53 | x->mv_limits = tmp_mv_limits; | |||
| 54 | ||||
| 55 | // Try sub-pixel MC | |||
| 56 | // if (bestsme > error_thresh && bestsme < INT_MAX) | |||
| 57 | { | |||
| 58 | uint32_t distortion; | |||
| 59 | uint32_t sse; | |||
| 60 | // TODO(yunqing): may use higher tap interp filter than 2 taps if needed. | |||
| 61 | cpi->find_fractional_mv_step( | |||
| 62 | x, dst_mv, ref_mv, cpi->common.allow_high_precision_mv, x->errorperbit, | |||
| 63 | &v_fn_ptr, 0, mv_sf->subpel_search_level, | |||
| 64 | cond_cost_list(cpi, cost_list), NULL((void*)0), NULL((void*)0), &distortion, &sse, NULL((void*)0), 0, | |||
| 65 | 0, USE_2_TAPS); | |||
| 66 | } | |||
| 67 | ||||
| 68 | xd->mi[0]->mode = NEWMV13; | |||
| 69 | xd->mi[0]->mv[0].as_mv = *dst_mv; | |||
| 70 | ||||
| 71 | vp9_build_inter_predictors_sby(xd, mb_row, mb_col, BLOCK_16X166); | |||
| 72 | ||||
| 73 | return vpx_sad16x16vpx_sad16x16_sse2(x->plane[0].src.buf, x->plane[0].src.stride, | |||
| 74 | xd->plane[0].dst.buf, xd->plane[0].dst.stride); | |||
| 75 | } | |||
| 76 | ||||
| 77 | static int do_16x16_motion_search(VP9_COMP *cpi, const MV *ref_mv, | |||
| 78 | int_mv *dst_mv, int mb_row, int mb_col) { | |||
| 79 | MACROBLOCK *const x = &cpi->td.mb; | |||
| 80 | MACROBLOCKD *const xd = &x->e_mbd; | |||
| 81 | unsigned int err, tmp_err; | |||
| 82 | MV tmp_mv; | |||
| 83 | ||||
| 84 | // Try zero MV first | |||
| 85 | // FIXME should really use something like near/nearest MV and/or MV prediction | |||
| 86 | err = vpx_sad16x16vpx_sad16x16_sse2(x->plane[0].src.buf, x->plane[0].src.stride, | |||
| 87 | xd->plane[0].pre[0].buf, xd->plane[0].pre[0].stride); | |||
| 88 | dst_mv->as_int = 0; | |||
| 89 | ||||
| 90 | // Test last reference frame using the previous best mv as the | |||
| 91 | // starting point (best reference) for the search | |||
| 92 | tmp_err = do_16x16_motion_iteration(cpi, ref_mv, &tmp_mv, mb_row, mb_col); | |||
| 93 | if (tmp_err < err) { | |||
| 94 | err = tmp_err; | |||
| 95 | dst_mv->as_mv = tmp_mv; | |||
| 96 | } | |||
| 97 | ||||
| 98 | // If the current best reference mv is not centered on 0,0 then do a 0,0 | |||
| 99 | // based search as well. | |||
| 100 | if (ref_mv->row != 0 || ref_mv->col != 0) { | |||
| 101 | MV zero_ref_mv = { 0, 0 }; | |||
| 102 | ||||
| 103 | tmp_err = | |||
| 104 | do_16x16_motion_iteration(cpi, &zero_ref_mv, &tmp_mv, mb_row, mb_col); | |||
| 105 | if (tmp_err < err) { | |||
| 106 | dst_mv->as_mv = tmp_mv; | |||
| 107 | err = tmp_err; | |||
| 108 | } | |||
| 109 | } | |||
| 110 | ||||
| 111 | return err; | |||
| 112 | } | |||
| 113 | ||||
| 114 | static int do_16x16_zerozero_search(VP9_COMP *cpi, int_mv *dst_mv) { | |||
| 115 | MACROBLOCK *const x = &cpi->td.mb; | |||
| 116 | MACROBLOCKD *const xd = &x->e_mbd; | |||
| 117 | unsigned int err; | |||
| 118 | ||||
| 119 | // Try zero MV first | |||
| 120 | // FIXME should really use something like near/nearest MV and/or MV prediction | |||
| 121 | err = vpx_sad16x16vpx_sad16x16_sse2(x->plane[0].src.buf, x->plane[0].src.stride, | |||
| 122 | xd->plane[0].pre[0].buf, xd->plane[0].pre[0].stride); | |||
| 123 | ||||
| 124 | dst_mv->as_int = 0; | |||
| 125 | ||||
| 126 | return err; | |||
| 127 | } | |||
| 128 | static int find_best_16x16_intra(VP9_COMP *cpi, PREDICTION_MODE *pbest_mode) { | |||
| 129 | MACROBLOCK *const x = &cpi->td.mb; | |||
| 130 | MACROBLOCKD *const xd = &x->e_mbd; | |||
| 131 | PREDICTION_MODE best_mode = -1, mode; | |||
| 132 | unsigned int best_err = INT_MAX2147483647; | |||
| 133 | ||||
| 134 | // calculate SATD for each intra prediction mode; | |||
| 135 | // we're intentionally not doing 4x4, we just want a rough estimate | |||
| 136 | for (mode = DC_PRED0; mode <= TM_PRED9; mode++) { | |||
| 137 | unsigned int err; | |||
| 138 | ||||
| 139 | xd->mi[0]->mode = mode; | |||
| 140 | vp9_predict_intra_block(xd, 2, TX_16X16((TX_SIZE)2), mode, x->plane[0].src.buf, | |||
| 141 | x->plane[0].src.stride, xd->plane[0].dst.buf, | |||
| 142 | xd->plane[0].dst.stride, 0, 0, 0); | |||
| 143 | err = vpx_sad16x16vpx_sad16x16_sse2(x->plane[0].src.buf, x->plane[0].src.stride, | |||
| 144 | xd->plane[0].dst.buf, xd->plane[0].dst.stride); | |||
| 145 | ||||
| 146 | // find best | |||
| 147 | if (err < best_err) { | |||
| 148 | best_err = err; | |||
| 149 | best_mode = mode; | |||
| 150 | } | |||
| 151 | } | |||
| 152 | ||||
| 153 | if (pbest_mode) *pbest_mode = best_mode; | |||
| 154 | ||||
| 155 | return best_err; | |||
| 156 | } | |||
| 157 | ||||
| 158 | static void update_mbgraph_mb_stats(VP9_COMP *cpi, MBGRAPH_MB_STATS *stats, | |||
| 159 | YV12_BUFFER_CONFIG *buf, int mb_y_offset, | |||
| 160 | YV12_BUFFER_CONFIG *golden_ref, | |||
| 161 | const MV *prev_golden_ref_mv, | |||
| 162 | YV12_BUFFER_CONFIG *alt_ref, int mb_row, | |||
| 163 | int mb_col) { | |||
| 164 | MACROBLOCK *const x = &cpi->td.mb; | |||
| 165 | MACROBLOCKD *const xd = &x->e_mbd; | |||
| 166 | int intra_error; | |||
| 167 | VP9_COMMON *cm = &cpi->common; | |||
| 168 | ||||
| 169 | // FIXME in practice we're completely ignoring chroma here | |||
| 170 | x->plane[0].src.buf = buf->y_buffer + mb_y_offset; | |||
| 171 | x->plane[0].src.stride = buf->y_stride; | |||
| 172 | ||||
| 173 | xd->plane[0].dst.buf = get_frame_new_buffer(cm)->y_buffer + mb_y_offset; | |||
| 174 | xd->plane[0].dst.stride = get_frame_new_buffer(cm)->y_stride; | |||
| 175 | ||||
| 176 | // do intra 16x16 prediction | |||
| 177 | intra_error = find_best_16x16_intra(cpi, &stats->ref[INTRA_FRAME0].m.mode); | |||
| 178 | if (intra_error <= 0) intra_error = 1; | |||
| 179 | stats->ref[INTRA_FRAME0].err = intra_error; | |||
| 180 | ||||
| 181 | // Golden frame MV search, if it exists and is different than last frame | |||
| 182 | if (golden_ref) { | |||
| 183 | int g_motion_error; | |||
| 184 | xd->plane[0].pre[0].buf = golden_ref->y_buffer + mb_y_offset; | |||
| 185 | xd->plane[0].pre[0].stride = golden_ref->y_stride; | |||
| 186 | g_motion_error = | |||
| 187 | do_16x16_motion_search(cpi, prev_golden_ref_mv, | |||
| 188 | &stats->ref[GOLDEN_FRAME2].m.mv, mb_row, mb_col); | |||
| 189 | stats->ref[GOLDEN_FRAME2].err = g_motion_error; | |||
| 190 | } else { | |||
| 191 | stats->ref[GOLDEN_FRAME2].err = INT_MAX2147483647; | |||
| 192 | stats->ref[GOLDEN_FRAME2].m.mv.as_int = 0; | |||
| 193 | } | |||
| 194 | ||||
| 195 | // Do an Alt-ref frame MV search, if it exists and is different than | |||
| 196 | // last/golden frame. | |||
| 197 | if (alt_ref) { | |||
| 198 | int a_motion_error; | |||
| 199 | xd->plane[0].pre[0].buf = alt_ref->y_buffer + mb_y_offset; | |||
| 200 | xd->plane[0].pre[0].stride = alt_ref->y_stride; | |||
| 201 | a_motion_error = | |||
| 202 | do_16x16_zerozero_search(cpi, &stats->ref[ALTREF_FRAME3].m.mv); | |||
| 203 | ||||
| 204 | stats->ref[ALTREF_FRAME3].err = a_motion_error; | |||
| 205 | } else { | |||
| 206 | stats->ref[ALTREF_FRAME3].err = INT_MAX2147483647; | |||
| 207 | stats->ref[ALTREF_FRAME3].m.mv.as_int = 0; | |||
| 208 | } | |||
| 209 | } | |||
| 210 | ||||
| 211 | static void update_mbgraph_frame_stats(VP9_COMP *cpi, | |||
| 212 | MBGRAPH_FRAME_STATS *stats, | |||
| 213 | YV12_BUFFER_CONFIG *buf, | |||
| 214 | YV12_BUFFER_CONFIG *golden_ref, | |||
| 215 | YV12_BUFFER_CONFIG *alt_ref) { | |||
| 216 | MACROBLOCK *const x = &cpi->td.mb; | |||
| 217 | MACROBLOCKD *const xd = &x->e_mbd; | |||
| 218 | VP9_COMMON *const cm = &cpi->common; | |||
| 219 | ||||
| 220 | int mb_col, mb_row, offset = 0; | |||
| 221 | int mb_y_offset = 0; | |||
| 222 | MV gld_top_mv = { 0, 0 }; | |||
| 223 | MODE_INFO mi_local; | |||
| 224 | MODE_INFO mi_above, mi_left; | |||
| 225 | ||||
| 226 | vp9_zero(mi_local)memset(&(mi_local), 0, sizeof(mi_local)); | |||
| 227 | // Set up limit values for motion vectors to prevent them extending outside | |||
| 228 | // the UMV borders. | |||
| 229 | x->mv_limits.row_min = -BORDER_MV_PIXELS_B16(16 + 4); | |||
| 230 | x->mv_limits.row_max = (cm->mb_rows - 1) * 8 + BORDER_MV_PIXELS_B16(16 + 4); | |||
| 231 | // Signal to vp9_predict_intra_block() that above is not available | |||
| 232 | xd->above_mi = NULL((void*)0); | |||
| 233 | ||||
| 234 | xd->plane[0].dst.stride = buf->y_stride; | |||
| 235 | xd->plane[0].pre[0].stride = buf->y_stride; | |||
| 236 | xd->plane[1].dst.stride = buf->uv_stride; | |||
| 237 | xd->mi[0] = &mi_local; | |||
| 238 | mi_local.sb_type = BLOCK_16X166; | |||
| 239 | mi_local.ref_frame[0] = LAST_FRAME1; | |||
| 240 | mi_local.ref_frame[1] = NO_REF_FRAME(-1); | |||
| 241 | ||||
| 242 | for (mb_row = 0; mb_row < cm->mb_rows; mb_row++) { | |||
| ||||
| 243 | MV gld_left_mv = gld_top_mv; | |||
| 244 | int mb_y_in_offset = mb_y_offset; | |||
| 245 | ||||
| 246 | // Set up limit values for motion vectors to prevent them extending outside | |||
| 247 | // the UMV borders. | |||
| 248 | x->mv_limits.col_min = -BORDER_MV_PIXELS_B16(16 + 4); | |||
| 249 | x->mv_limits.col_max = (cm->mb_cols - 1) * 8 + BORDER_MV_PIXELS_B16(16 + 4); | |||
| 250 | // Signal to vp9_predict_intra_block() that left is not available | |||
| 251 | xd->left_mi = NULL((void*)0); | |||
| 252 | ||||
| 253 | for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) { | |||
| 254 | MBGRAPH_MB_STATS *mb_stats = &stats->mb_stats[offset + mb_col]; | |||
| 255 | ||||
| 256 | update_mbgraph_mb_stats(cpi, mb_stats, buf, mb_y_in_offset, golden_ref, | |||
| 257 | &gld_left_mv, alt_ref, mb_row, mb_col); | |||
| 258 | gld_left_mv = mb_stats->ref[GOLDEN_FRAME2].m.mv.as_mv; | |||
| 259 | if (mb_col == 0) { | |||
| 260 | gld_top_mv = gld_left_mv; | |||
| 261 | } | |||
| 262 | // Signal to vp9_predict_intra_block() that left is available | |||
| 263 | xd->left_mi = &mi_left; | |||
| 264 | ||||
| 265 | mb_y_in_offset += 16; | |||
| 266 | x->mv_limits.col_min -= 16; | |||
| 267 | x->mv_limits.col_max -= 16; | |||
| 268 | } | |||
| 269 | ||||
| 270 | // Signal to vp9_predict_intra_block() that above is available | |||
| 271 | xd->above_mi = &mi_above; | |||
| 272 | ||||
| 273 | mb_y_offset += buf->y_stride * 16; | |||
| 274 | x->mv_limits.row_min -= 16; | |||
| 275 | x->mv_limits.row_max -= 16; | |||
| 276 | offset += cm->mb_cols; | |||
| 277 | } | |||
| 278 | } | |||
| 279 | ||||
| 280 | // void separate_arf_mbs_byzz | |||
| 281 | static void separate_arf_mbs(VP9_COMP *cpi) { | |||
| 282 | VP9_COMMON *const cm = &cpi->common; | |||
| 283 | int mb_col, mb_row, offset, i; | |||
| 284 | int mi_row, mi_col; | |||
| 285 | int ncnt[4] = { 0 }; | |||
| 286 | int n_frames = cpi->mbgraph_n_frames; | |||
| 287 | ||||
| 288 | int *arf_not_zz; | |||
| 289 | ||||
| 290 | CHECK_MEM_ERROR(do { ((void) sizeof (((&cm->error)->setjmp) ? 1 : 0 ), __extension__ ({ if ((&cm->error)->setjmp) ; else __assert_fail ("(&cm->error)->setjmp", "/root/firefox-clang/media/libvpx/libvpx/vp9/encoder/vp9_mbgraph.c" , 292, __extension__ __PRETTY_FUNCTION__); })); (arf_not_zz) = (vpx_calloc(cm->mb_rows * cm->mb_cols * sizeof(*arf_not_zz ), 1)); if (!(arf_not_zz)) vpx_internal_error(&cm->error , VPX_CODEC_MEM_ERROR, "Failed to allocate " "arf_not_zz"); } while (0) | |||
| 291 | &cm->error, arf_not_zz,do { ((void) sizeof (((&cm->error)->setjmp) ? 1 : 0 ), __extension__ ({ if ((&cm->error)->setjmp) ; else __assert_fail ("(&cm->error)->setjmp", "/root/firefox-clang/media/libvpx/libvpx/vp9/encoder/vp9_mbgraph.c" , 292, __extension__ __PRETTY_FUNCTION__); })); (arf_not_zz) = (vpx_calloc(cm->mb_rows * cm->mb_cols * sizeof(*arf_not_zz ), 1)); if (!(arf_not_zz)) vpx_internal_error(&cm->error , VPX_CODEC_MEM_ERROR, "Failed to allocate " "arf_not_zz"); } while (0) | |||
| 292 | vpx_calloc(cm->mb_rows * cm->mb_cols * sizeof(*arf_not_zz), 1))do { ((void) sizeof (((&cm->error)->setjmp) ? 1 : 0 ), __extension__ ({ if ((&cm->error)->setjmp) ; else __assert_fail ("(&cm->error)->setjmp", "/root/firefox-clang/media/libvpx/libvpx/vp9/encoder/vp9_mbgraph.c" , 292, __extension__ __PRETTY_FUNCTION__); })); (arf_not_zz) = (vpx_calloc(cm->mb_rows * cm->mb_cols * sizeof(*arf_not_zz ), 1)); if (!(arf_not_zz)) vpx_internal_error(&cm->error , VPX_CODEC_MEM_ERROR, "Failed to allocate " "arf_not_zz"); } while (0); | |||
| 293 | ||||
| 294 | // We are not interested in results beyond the alt ref itself. | |||
| 295 | if (n_frames > cpi->rc.frames_till_gf_update_due) | |||
| 296 | n_frames = cpi->rc.frames_till_gf_update_due; | |||
| 297 | ||||
| 298 | // defer cost to reference frames | |||
| 299 | for (i = n_frames - 1; i >= 0; i--) { | |||
| 300 | MBGRAPH_FRAME_STATS *frame_stats = &cpi->mbgraph_stats[i]; | |||
| 301 | ||||
| 302 | for (offset = 0, mb_row = 0; mb_row < cm->mb_rows; | |||
| 303 | offset += cm->mb_cols, mb_row++) { | |||
| 304 | for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) { | |||
| 305 | MBGRAPH_MB_STATS *mb_stats = &frame_stats->mb_stats[offset + mb_col]; | |||
| 306 | ||||
| 307 | int altref_err = mb_stats->ref[ALTREF_FRAME3].err; | |||
| 308 | int intra_err = mb_stats->ref[INTRA_FRAME0].err; | |||
| 309 | int golden_err = mb_stats->ref[GOLDEN_FRAME2].err; | |||
| 310 | ||||
| 311 | // Test for altref vs intra and gf and that its mv was 0,0. | |||
| 312 | if (altref_err > 1000 || altref_err > intra_err || | |||
| 313 | altref_err > golden_err) { | |||
| 314 | arf_not_zz[offset + mb_col]++; | |||
| 315 | } | |||
| 316 | } | |||
| 317 | } | |||
| 318 | } | |||
| 319 | ||||
| 320 | // arf_not_zz is indexed by MB, but this loop is indexed by MI to avoid out | |||
| 321 | // of bound access in segmentation_map | |||
| 322 | for (mi_row = 0; mi_row < cm->mi_rows; mi_row++) { | |||
| 323 | for (mi_col = 0; mi_col < cm->mi_cols; mi_col++) { | |||
| 324 | // If any of the blocks in the sequence failed then the MB | |||
| 325 | // goes in segment 0 | |||
| 326 | if (arf_not_zz[mi_row / 2 * cm->mb_cols + mi_col / 2]) { | |||
| 327 | ncnt[0]++; | |||
| 328 | cpi->segmentation_map[mi_row * cm->mi_cols + mi_col] = 0; | |||
| 329 | } else { | |||
| 330 | cpi->segmentation_map[mi_row * cm->mi_cols + mi_col] = 1; | |||
| 331 | ncnt[1]++; | |||
| 332 | } | |||
| 333 | } | |||
| 334 | } | |||
| 335 | ||||
| 336 | // Note % of blocks that are marked as static | |||
| 337 | if (cm->MBs) | |||
| 338 | cpi->static_mb_pct = (ncnt[1] * 100) / (cm->mi_rows * cm->mi_cols); | |||
| 339 | ||||
| 340 | // This error case should not be reachable as this function should | |||
| 341 | // never be called with the common data structure uninitialized. | |||
| 342 | else | |||
| 343 | cpi->static_mb_pct = 0; | |||
| 344 | ||||
| 345 | vp9_enable_segmentation(&cm->seg); | |||
| 346 | ||||
| 347 | // Free localy allocated storage | |||
| 348 | vpx_free(arf_not_zz); | |||
| 349 | } | |||
| 350 | ||||
| 351 | void vp9_update_mbgraph_stats(VP9_COMP *cpi) { | |||
| 352 | VP9_COMMON *const cm = &cpi->common; | |||
| 353 | int i, n_frames = vp9_lookahead_depth(cpi->lookahead); | |||
| 354 | YV12_BUFFER_CONFIG *golden_ref = get_ref_frame_buffer(cpi, GOLDEN_FRAME2); | |||
| 355 | ||||
| 356 | assert(golden_ref != NULL)((void) sizeof ((golden_ref != ((void*)0)) ? 1 : 0), __extension__ ({ if (golden_ref != ((void*)0)) ; else __assert_fail ("golden_ref != NULL" , "/root/firefox-clang/media/libvpx/libvpx/vp9/encoder/vp9_mbgraph.c" , 356, __extension__ __PRETTY_FUNCTION__); })); | |||
| ||||
| 357 | ||||
| 358 | // we need to look ahead beyond where the ARF transitions into | |||
| 359 | // being a GF - so exit if we don't look ahead beyond that | |||
| 360 | if (n_frames <= cpi->rc.frames_till_gf_update_due) return; | |||
| 361 | ||||
| 362 | if (n_frames > MAX_LAG_BUFFERS25) n_frames = MAX_LAG_BUFFERS25; | |||
| 363 | ||||
| 364 | cpi->mbgraph_n_frames = n_frames; | |||
| 365 | for (i = 0; i < n_frames; i++) { | |||
| 366 | MBGRAPH_FRAME_STATS *frame_stats = &cpi->mbgraph_stats[i]; | |||
| 367 | memset(frame_stats->mb_stats, 0, | |||
| 368 | cm->mb_rows * cm->mb_cols * sizeof(*cpi->mbgraph_stats[i].mb_stats)); | |||
| 369 | } | |||
| 370 | ||||
| 371 | // do motion search to find contribution of each reference to data | |||
| 372 | // later on in this GF group | |||
| 373 | // FIXME really, the GF/last MC search should be done forward, and | |||
| 374 | // the ARF MC search backwards, to get optimal results for MV caching | |||
| 375 | for (i = 0; i < n_frames; i++) { | |||
| 376 | MBGRAPH_FRAME_STATS *frame_stats = &cpi->mbgraph_stats[i]; | |||
| 377 | struct lookahead_entry *q_cur = vp9_lookahead_peek(cpi->lookahead, i); | |||
| 378 | ||||
| 379 | assert(q_cur != NULL)((void) sizeof ((q_cur != ((void*)0)) ? 1 : 0), __extension__ ({ if (q_cur != ((void*)0)) ; else __assert_fail ("q_cur != NULL" , "/root/firefox-clang/media/libvpx/libvpx/vp9/encoder/vp9_mbgraph.c" , 379, __extension__ __PRETTY_FUNCTION__); })); | |||
| 380 | ||||
| 381 | update_mbgraph_frame_stats(cpi, frame_stats, &q_cur->img, golden_ref, | |||
| 382 | cpi->Source); | |||
| 383 | } | |||
| 384 | ||||
| 385 | vpx_clear_system_state(); | |||
| 386 | ||||
| 387 | separate_arf_mbs(cpi); | |||
| 388 | } |