temporal_filter.c 15.9 KB
Newer Older
Johann's avatar
Johann committed
1 2 3 4 5 6 7 8 9 10 11
/*
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */


John Koleszar's avatar
John Koleszar committed
12
#include "vp8/common/onyxc_int.h"
Johann's avatar
Johann committed
13
#include "onyx_int.h"
John Koleszar's avatar
John Koleszar committed
14
#include "vp8/common/systemdependent.h"
Johann's avatar
Johann committed
15
#include "quantize.h"
John Koleszar's avatar
John Koleszar committed
16
#include "vp8/common/alloccommon.h"
Johann's avatar
Johann committed
17 18 19 20
#include "mcomp.h"
#include "firstpass.h"
#include "psnr.h"
#include "vpx_scale/vpxscale.h"
John Koleszar's avatar
John Koleszar committed
21
#include "vp8/common/extend.h"
Johann's avatar
Johann committed
22
#include "ratectrl.h"
John Koleszar's avatar
John Koleszar committed
23
#include "vp8/common/quant_common.h"
Johann's avatar
Johann committed
24 25 26
#include "segmentation.h"
#include "vpx_scale/yv12extend.h"
#include "vpx_mem/vpx_mem.h"
John Koleszar's avatar
John Koleszar committed
27 28
#include "vp8/common/swapyv12buffer.h"
#include "vp8/common/threading.h"
Johann's avatar
Johann committed
29 30 31 32 33 34 35 36 37 38
#include "vpx_ports/vpx_timer.h"

#include <math.h>
#include <limits.h>

#define ALT_REF_MC_ENABLED 1    // dis/enable MC in AltRef filtering
#define ALT_REF_SUBPEL_ENABLED 1 // dis/enable subpel in MC AltRef filtering

#if VP8_TEMPORAL_ALT_REF

Johann's avatar
Johann committed
39
static void vp8_temporal_filter_predictors_mb_c
Johann's avatar
Johann committed
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
(
    MACROBLOCKD *x,
    unsigned char *y_mb_ptr,
    unsigned char *u_mb_ptr,
    unsigned char *v_mb_ptr,
    int stride,
    int mv_row,
    int mv_col,
    unsigned char *pred
)
{
    int offset;
    unsigned char *yptr, *uptr, *vptr;

    // Y
    yptr = y_mb_ptr + (mv_row >> 3) * stride + (mv_col >> 3);

    if ((mv_row | mv_col) & 7)
    {
        x->subpixel_predict16x16(yptr, stride,
                                    mv_col & 7, mv_row & 7, &pred[0], 16);
    }
    else
    {
John Koleszar's avatar
John Koleszar committed
64
        vp8_copy_mem16x16(yptr, stride, &pred[0], 16);
Johann's avatar
Johann committed
65 66 67 68 69
    }

    // U & V
    mv_row >>= 1;
    mv_col >>= 1;
70
    stride = (stride + 1) >> 1;
Johann's avatar
Johann committed
71 72 73 74 75 76 77 78 79 80 81 82 83
    offset = (mv_row >> 3) * stride + (mv_col >> 3);
    uptr = u_mb_ptr + offset;
    vptr = v_mb_ptr + offset;

    if ((mv_row | mv_col) & 7)
    {
        x->subpixel_predict8x8(uptr, stride,
                            mv_col & 7, mv_row & 7, &pred[256], 8);
        x->subpixel_predict8x8(vptr, stride,
                            mv_col & 7, mv_row & 7, &pred[320], 8);
    }
    else
    {
John Koleszar's avatar
John Koleszar committed
84 85
        vp8_copy_mem8x8(uptr, stride, &pred[256], 8);
        vp8_copy_mem8x8(vptr, stride, &pred[320], 8);
Johann's avatar
Johann committed
86 87
    }
}
Johann's avatar
Johann committed
88
void vp8_temporal_filter_apply_c
Johann's avatar
Johann committed
89 90 91 92 93 94 95
(
    unsigned char *frame1,
    unsigned int stride,
    unsigned char *frame2,
    unsigned int block_size,
    int strength,
    int filter_weight,
Johann's avatar
Johann committed
96
    unsigned int *accumulator,
Johann's avatar
Johann committed
97
    unsigned short *count
Johann's avatar
Johann committed
98 99
)
{
100
    unsigned int i, j, k;
Johann's avatar
Johann committed
101 102 103 104 105 106 107 108 109 110 111
    int modifier;
    int byte = 0;

    for (i = 0,k = 0; i < block_size; i++)
    {
        for (j = 0; j < block_size; j++, k++)
        {

            int src_byte = frame1[byte];
            int pixel_value = *frame2++;

Johann's avatar
Johann committed
112
            modifier   = src_byte - pixel_value;
Johann's avatar
Johann committed
113 114 115
            // This is an integer approximation of:
            // float coeff = (3.0 * modifer * modifier) / pow(2, strength);
            // modifier =  (int)roundf(coeff > 16 ? 0 : 16-coeff);
Johann's avatar
Johann committed
116 117
            modifier  *= modifier;
            modifier  *= 3;
Johann's avatar
Johann committed
118 119
            modifier  += 1 << (strength - 1);
            modifier >>= strength;
Johann's avatar
Johann committed
120 121 122 123 124 125

            if (modifier > 16)
                modifier = 16;

            modifier = 16 - modifier;
            modifier *= filter_weight;
Johann's avatar
Johann committed
126

Johann's avatar
Johann committed
127 128 129 130 131 132 133 134 135 136 137 138 139
            count[k] += modifier;
            accumulator[k] += modifier * pixel_value;

            byte++;
        }

        byte += stride - block_size;
    }
}

#if ALT_REF_MC_ENABLED
static int dummy_cost[2*mv_max+1];

Johann's avatar
Johann committed
140
static int vp8_temporal_filter_find_matching_mb_c
Johann's avatar
Johann committed
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
(
    VP8_COMP *cpi,
    YV12_BUFFER_CONFIG *arf_frame,
    YV12_BUFFER_CONFIG *frame_ptr,
    int mb_offset,
    int error_thresh
)
{
    MACROBLOCK *x = &cpi->mb;
    int step_param;
    int further_steps;
    int sadpb = x->sadperbit16;
    int bestsme = INT_MAX;

    BLOCK *b = &x->block[0];
    BLOCKD *d = &x->e_mbd.block[0];
Scott LaVarnway's avatar
Scott LaVarnway committed
157
    int_mv best_ref_mv1;
158
    int_mv best_ref_mv1_full; /* full-pixel value of best_ref_mv1 */
Johann's avatar
Johann committed
159 160 161 162 163 164 165 166 167 168 169 170

    int *mvcost[2]    = { &dummy_cost[mv_max+1], &dummy_cost[mv_max+1] };
    int *mvsadcost[2] = { &dummy_cost[mv_max+1], &dummy_cost[mv_max+1] };

    // Save input state
    unsigned char **base_src = b->base_src;
    int src = b->src;
    int src_stride = b->src_stride;
    unsigned char **base_pre = d->base_pre;
    int pre = d->pre;
    int pre_stride = d->pre_stride;

Scott LaVarnway's avatar
Scott LaVarnway committed
171
    best_ref_mv1.as_int = 0;
172 173
    best_ref_mv1_full.as_mv.col = best_ref_mv1.as_mv.col >>3;
    best_ref_mv1_full.as_mv.row = best_ref_mv1.as_mv.row >>3;
Scott LaVarnway's avatar
Scott LaVarnway committed
174

Johann's avatar
Johann committed
175 176 177 178 179 180 181 182 183 184 185 186 187
    // Setup frame pointers
    b->base_src = &arf_frame->y_buffer;
    b->src_stride = arf_frame->y_stride;
    b->src = mb_offset;

    d->base_pre = &frame_ptr->y_buffer;
    d->pre_stride = frame_ptr->y_stride;
    d->pre = mb_offset;

    // Further step/diamond searches as necessary
    if (cpi->Speed < 8)
    {
        step_param = cpi->sf.first_step +
188
                    (cpi->Speed > 5);
Johann's avatar
Johann committed
189 190 191 192 193 194 195 196 197
        further_steps =
            (cpi->sf.max_step_search_steps - 1)-step_param;
    }
    else
    {
        step_param = cpi->sf.first_step + 2;
        further_steps = 0;
    }

198 199 200
    /*cpi->sf.search_method == HEX*/
    // TODO Check that the 16x16 vf & sdf are selected here
    bestsme = vp8_hex_search(x, b, d,
201
        &best_ref_mv1_full, &d->bmi.mv,
202
        step_param,
203
        sadpb,
204
        &cpi->fn_ptr[BLOCK_16X16],
205
        mvsadcost, mvcost, &best_ref_mv1);
Johann's avatar
Johann committed
206 207 208 209 210

#if ALT_REF_SUBPEL_ENABLED
    // Try sub-pixel MC?
    //if (bestsme > error_thresh && bestsme < INT_MAX)
    {
211
        int distortion;
212
        unsigned int sse;
Johann's avatar
Johann committed
213
        bestsme = cpi->find_fractional_mv_step(x, b, d,
Scott LaVarnway's avatar
Scott LaVarnway committed
214
                    &d->bmi.mv, &best_ref_mv1,
215
                    x->errorperbit, &cpi->fn_ptr[BLOCK_16X16],
216
                    mvcost, &distortion, &sse);
Johann's avatar
Johann committed
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
    }
#endif

    // Save input state
    b->base_src = base_src;
    b->src = src;
    b->src_stride = src_stride;
    d->base_pre = base_pre;
    d->pre = pre;
    d->pre_stride = pre_stride;

    return bestsme;
}
#endif

Johann's avatar
Johann committed
232
static void vp8_temporal_filter_iterate_c
Johann's avatar
Johann committed
233 234 235 236 237 238 239 240 241 242
(
    VP8_COMP *cpi,
    int frame_count,
    int alt_ref_index,
    int strength
)
{
    int byte;
    int frame;
    int mb_col, mb_row;
Adrian Grange's avatar
Adrian Grange committed
243
    unsigned int filter_weight;
244 245
    int mb_cols = cpi->common.mb_cols;
    int mb_rows = cpi->common.mb_rows;
Johann's avatar
Johann committed
246 247
    int mb_y_offset = 0;
    int mb_uv_offset = 0;
Johann's avatar
Johann committed
248 249
    DECLARE_ALIGNED_ARRAY(16, unsigned int, accumulator, 16*16 + 8*8 + 8*8);
    DECLARE_ALIGNED_ARRAY(16, unsigned short, count, 16*16 + 8*8 + 8*8);
Johann's avatar
Johann committed
250 251 252
    MACROBLOCKD *mbd = &cpi->mb.e_mbd;
    YV12_BUFFER_CONFIG *f = cpi->frames[alt_ref_index];
    unsigned char *dst1, *dst2;
Johann's avatar
Johann committed
253
    DECLARE_ALIGNED_ARRAY(16, unsigned char,  predictor, 16*16 + 8*8 + 8*8);
Johann's avatar
Johann committed
254

Johann's avatar
Johann committed
255 256 257 258 259
    // Save input state
    unsigned char *y_buffer = mbd->pre.y_buffer;
    unsigned char *u_buffer = mbd->pre.u_buffer;
    unsigned char *v_buffer = mbd->pre.v_buffer;

260
    for (mb_row = 0; mb_row < mb_rows; mb_row++)
Johann's avatar
Johann committed
261 262
    {
#if ALT_REF_MC_ENABLED
263 264 265 266 267 268 269 270 271 272 273
        // Source frames are extended to 16 pixels.  This is different than
        //  L/A/G reference frames that have a border of 32 (VP8BORDERINPIXELS)
        // A 6 tap filter is used for motion search.  This requires 2 pixels
        //  before and 3 pixels after.  So the largest Y mv on a border would
        //  then be 16 - 3.  The UV blocks are half the size of the Y and
        //  therefore only extended by 8.  The largest mv that a UV block
        //  can support is 8 - 3.  A UV mv is half of a Y mv.
        //  (16 - 3) >> 1 == 6 which is greater than 8 - 3.
        // To keep the mv in play for both Y and UV planes the max that it
        //  can be on a border is therefore 16 - 5.
        cpi->mb.mv_row_min = -((mb_row * 16) + (16 - 5));
Johann's avatar
Johann committed
274
        cpi->mb.mv_row_max = ((cpi->common.mb_rows - 1 - mb_row) * 16)
275
                                + (16 - 5);
Johann's avatar
Johann committed
276 277
#endif

278
        for (mb_col = 0; mb_col < mb_cols; mb_col++)
Johann's avatar
Johann committed
279
        {
Johann's avatar
Johann committed
280
            int i, j, k;
Johann's avatar
Johann committed
281 282 283
            int stride;

            vpx_memset(accumulator, 0, 384*sizeof(unsigned int));
Johann's avatar
Johann committed
284
            vpx_memset(count, 0, 384*sizeof(unsigned short));
Johann's avatar
Johann committed
285 286

#if ALT_REF_MC_ENABLED
287
            cpi->mb.mv_col_min = -((mb_col * 16) + (16 - 5));
Johann's avatar
Johann committed
288
            cpi->mb.mv_col_max = ((cpi->common.mb_cols - 1 - mb_col) * 16)
289
                                    + (16 - 5);
Johann's avatar
Johann committed
290 291 292 293
#endif

            for (frame = 0; frame < frame_count; frame++)
            {
Adrian Grange's avatar
Adrian Grange committed
294
                int err = 0;
Johann's avatar
Johann committed
295 296 297 298 299 300 301 302 303 304 305

                if (cpi->frames[frame] == NULL)
                    continue;

                mbd->block[0].bmi.mv.as_mv.row = 0;
                mbd->block[0].bmi.mv.as_mv.col = 0;

#if ALT_REF_MC_ENABLED
#define THRESH_LOW   10000
#define THRESH_HIGH  20000

Adrian Grange's avatar
Adrian Grange committed
306 307 308 309 310 311 312 313
                // Find best match in this frame by MC
                err = vp8_temporal_filter_find_matching_mb_c
                      (cpi,
                       cpi->frames[alt_ref_index],
                       cpi->frames[frame],
                       mb_y_offset,
                       THRESH_LOW);

Johann's avatar
Johann committed
314
#endif
Adrian Grange's avatar
Adrian Grange committed
315 316 317 318 319 320 321
                // Assign higher weight to matching MB if it's error
                // score is lower. If not applying MC default behavior
                // is to weight all MBs equal.
                filter_weight = err<THRESH_LOW
                                  ? 2 : err<THRESH_HIGH ? 1 : 0;

                if (filter_weight != 0)
Johann's avatar
Johann committed
322 323
                {
                    // Construct the predictors
Johann's avatar
Johann committed
324 325 326 327 328 329 330 331 332
                    vp8_temporal_filter_predictors_mb_c
                        (mbd,
                         cpi->frames[frame]->y_buffer + mb_y_offset,
                         cpi->frames[frame]->u_buffer + mb_uv_offset,
                         cpi->frames[frame]->v_buffer + mb_uv_offset,
                         cpi->frames[frame]->y_stride,
                         mbd->block[0].bmi.mv.as_mv.row,
                         mbd->block[0].bmi.mv.as_mv.col,
                         predictor);
Johann's avatar
Johann committed
333 334

                    // Apply the filter (YUV)
John Koleszar's avatar
John Koleszar committed
335
                    vp8_temporal_filter_apply
Johann's avatar
Johann committed
336 337 338 339 340
                        (f->y_buffer + mb_y_offset,
                         f->y_stride,
                         predictor,
                         16,
                         strength,
Adrian Grange's avatar
Adrian Grange committed
341
                         filter_weight,
Johann's avatar
Johann committed
342 343 344
                         accumulator,
                         count);

John Koleszar's avatar
John Koleszar committed
345
                    vp8_temporal_filter_apply
Johann's avatar
Johann committed
346 347 348 349 350
                        (f->u_buffer + mb_uv_offset,
                         f->uv_stride,
                         predictor + 256,
                         8,
                         strength,
Adrian Grange's avatar
Adrian Grange committed
351
                         filter_weight,
Johann's avatar
Johann committed
352 353 354
                         accumulator + 256,
                         count + 256);

John Koleszar's avatar
John Koleszar committed
355
                    vp8_temporal_filter_apply
Johann's avatar
Johann committed
356 357 358 359 360
                        (f->v_buffer + mb_uv_offset,
                         f->uv_stride,
                         predictor + 320,
                         8,
                         strength,
Adrian Grange's avatar
Adrian Grange committed
361
                         filter_weight,
Johann's avatar
Johann committed
362 363
                         accumulator + 320,
                         count + 320);
Johann's avatar
Johann committed
364 365 366 367
                }
            }

            // Normalize filter output to produce AltRef frame
John Koleszar's avatar
John Koleszar committed
368 369
            dst1 = cpi->alt_ref_buffer.y_buffer;
            stride = cpi->alt_ref_buffer.y_stride;
Johann's avatar
Johann committed
370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387
            byte = mb_y_offset;
            for (i = 0,k = 0; i < 16; i++)
            {
                for (j = 0; j < 16; j++, k++)
                {
                    unsigned int pval = accumulator[k] + (count[k] >> 1);
                    pval *= cpi->fixed_divide[count[k]];
                    pval >>= 19;

                    dst1[byte] = (unsigned char)pval;

                    // move to next pixel
                    byte++;
                }

                byte += stride - 16;
            }

John Koleszar's avatar
John Koleszar committed
388 389 390
            dst1 = cpi->alt_ref_buffer.u_buffer;
            dst2 = cpi->alt_ref_buffer.v_buffer;
            stride = cpi->alt_ref_buffer.uv_stride;
Johann's avatar
Johann committed
391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420
            byte = mb_uv_offset;
            for (i = 0,k = 256; i < 8; i++)
            {
                for (j = 0; j < 8; j++, k++)
                {
                    int m=k+64;

                    // U
                    unsigned int pval = accumulator[k] + (count[k] >> 1);
                    pval *= cpi->fixed_divide[count[k]];
                    pval >>= 19;
                    dst1[byte] = (unsigned char)pval;

                    // V
                    pval = accumulator[m] + (count[m] >> 1);
                    pval *= cpi->fixed_divide[count[m]];
                    pval >>= 19;
                    dst2[byte] = (unsigned char)pval;

                    // move to next pixel
                    byte++;
                }

                byte += stride - 8;
            }

            mb_y_offset += 16;
            mb_uv_offset += 8;
        }

421 422
        mb_y_offset += 16*(f->y_stride-mb_cols);
        mb_uv_offset += 8*(f->uv_stride-mb_cols);
Johann's avatar
Johann committed
423 424 425 426 427 428 429 430
    }

    // Restore input state
    mbd->pre.y_buffer = y_buffer;
    mbd->pre.u_buffer = u_buffer;
    mbd->pre.v_buffer = v_buffer;
}

Johann's avatar
Johann committed
431
void vp8_temporal_filter_prepare_c
Johann's avatar
Johann committed
432
(
John Koleszar's avatar
John Koleszar committed
433 434
    VP8_COMP *cpi,
    int distance
Johann's avatar
Johann committed
435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451
)
{
    int frame = 0;

    int num_frames_backward = 0;
    int num_frames_forward = 0;
    int frames_to_blur_backward = 0;
    int frames_to_blur_forward = 0;
    int frames_to_blur = 0;
    int start_frame = 0;

    int strength = cpi->oxcf.arnr_strength;

    int blur_type = cpi->oxcf.arnr_type;

    int max_frames = cpi->active_arnr_frames;

John Koleszar's avatar
John Koleszar committed
452 453 454
    num_frames_backward = distance;
    num_frames_forward = vp8_lookahead_depth(cpi->lookahead)
                         - (num_frames_backward + 1);
Johann's avatar
Johann committed
455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505

    switch (blur_type)
    {
    case 1:
        /////////////////////////////////////////
        // Backward Blur

        frames_to_blur_backward = num_frames_backward;

        if (frames_to_blur_backward >= max_frames)
            frames_to_blur_backward = max_frames - 1;

        frames_to_blur = frames_to_blur_backward + 1;
        break;

    case 2:
        /////////////////////////////////////////
        // Forward Blur

        frames_to_blur_forward = num_frames_forward;

        if (frames_to_blur_forward >= max_frames)
            frames_to_blur_forward = max_frames - 1;

        frames_to_blur = frames_to_blur_forward + 1;
        break;

    case 3:
    default:
        /////////////////////////////////////////
        // Center Blur
        frames_to_blur_forward = num_frames_forward;
        frames_to_blur_backward = num_frames_backward;

        if (frames_to_blur_forward > frames_to_blur_backward)
            frames_to_blur_forward = frames_to_blur_backward;

        if (frames_to_blur_backward > frames_to_blur_forward)
            frames_to_blur_backward = frames_to_blur_forward;

        // When max_frames is even we have 1 more frame backward than forward
        if (frames_to_blur_forward > (max_frames - 1) / 2)
            frames_to_blur_forward = ((max_frames - 1) / 2);

        if (frames_to_blur_backward > (max_frames / 2))
            frames_to_blur_backward = (max_frames / 2);

        frames_to_blur = frames_to_blur_backward + frames_to_blur_forward + 1;
        break;
    }

John Koleszar's avatar
John Koleszar committed
506
    start_frame = distance + frames_to_blur_forward;
Johann's avatar
Johann committed
507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526

#ifdef DEBUGFWG
    // DEBUG FWG
    printf("max:%d FBCK:%d FFWD:%d ftb:%d ftbbck:%d ftbfwd:%d sei:%d lasei:%d start:%d"
           , max_frames
           , num_frames_backward
           , num_frames_forward
           , frames_to_blur
           , frames_to_blur_backward
           , frames_to_blur_forward
           , cpi->source_encode_index
           , cpi->last_alt_ref_sei
           , start_frame);
#endif

    // Setup frame pointers, NULL indicates frame not included in filter
    vpx_memset(cpi->frames, 0, max_frames*sizeof(YV12_BUFFER_CONFIG *));
    for (frame = 0; frame < frames_to_blur; frame++)
    {
        int which_buffer =  start_frame - frame;
John Koleszar's avatar
John Koleszar committed
527 528 529
        struct lookahead_entry* buf = vp8_lookahead_peek(cpi->lookahead,
                                                         which_buffer);
        cpi->frames[frames_to_blur-1-frame] = &buf->img;
Johann's avatar
Johann committed
530 531
    }

Johann's avatar
Johann committed
532
    vp8_temporal_filter_iterate_c (
Johann's avatar
Johann committed
533 534 535 536 537 538
        cpi,
        frames_to_blur,
        frames_to_blur_backward,
        strength );
}
#endif