temporal_filter.c 16 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
#include "segmentation.h"
John Koleszar's avatar
John Koleszar committed
25
#include "vp8/common/g_common.h"
Johann's avatar
Johann committed
26
27
#include "vpx_scale/yv12extend.h"
#include "vpx_mem/vpx_mem.h"
John Koleszar's avatar
John Koleszar committed
28
29
#include "vp8/common/swapyv12buffer.h"
#include "vp8/common/threading.h"
Johann's avatar
Johann committed
30
31
32
33
34
35
36
37
38
39
#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
40
static void vp8_temporal_filter_predictors_mb_c
Johann's avatar
Johann committed
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
(
    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
    {
        RECON_INVOKE(&x->rtcd->recon, copy16x16)(yptr, stride, &pred[0], 16);
    }

    // U & V
    mv_row >>= 1;
    mv_col >>= 1;
71
    stride = (stride + 1) >> 1;
Johann's avatar
Johann committed
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
    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
    {
        RECON_INVOKE(&x->rtcd->recon, copy8x8)(uptr, stride, &pred[256], 8);
        RECON_INVOKE(&x->rtcd->recon, copy8x8)(vptr, stride, &pred[320], 8);
    }
}
Johann's avatar
Johann committed
89
void vp8_temporal_filter_apply_c
Johann's avatar
Johann committed
90
91
92
93
94
95
96
(
    unsigned char *frame1,
    unsigned int stride,
    unsigned char *frame2,
    unsigned int block_size,
    int strength,
    int filter_weight,
Johann's avatar
Johann committed
97
    unsigned int *accumulator,
Johann's avatar
Johann committed
98
    unsigned short *count
Johann's avatar
Johann committed
99
100
101
102
103
104
105
106
107
108
109
110
111
112
)
{
    int i, j, k;
    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
113
            modifier   = src_byte - pixel_value;
Johann's avatar
Johann committed
114
115
116
            // 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
117
118
            modifier  *= modifier;
            modifier  *= 3;
Johann's avatar
Johann committed
119
120
            modifier  += 1 << (strength - 1);
            modifier >>= strength;
Johann's avatar
Johann committed
121
122
123
124
125
126

            if (modifier > 16)
                modifier = 16;

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

Johann's avatar
Johann committed
128
129
130
131
132
133
134
135
136
137
138
139
140
            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
141
static int vp8_temporal_filter_find_matching_mb_c
Johann's avatar
Johann committed
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
(
    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
158
    int_mv best_ref_mv1;
159
    int_mv best_ref_mv1_full; /* full-pixel value of best_ref_mv1 */
Johann's avatar
Johann committed
160
161
162
163
164
165
166
167
168
169
170
171

    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
172
    best_ref_mv1.as_int = 0;
173
174
    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
175

Johann's avatar
Johann committed
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
    // 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 +
                    ((cpi->Speed > 5) ? 1 : 0);
        further_steps =
            (cpi->sf.max_step_search_steps - 1)-step_param;
    }
    else
    {
        step_param = cpi->sf.first_step + 2;
        further_steps = 0;
    }

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

#if ALT_REF_SUBPEL_ENABLED
    // Try sub-pixel MC?
    //if (bestsme > error_thresh && bestsme < INT_MAX)
    {
212
        int distortion;
213
        unsigned int sse;
Johann's avatar
Johann committed
214
        bestsme = cpi->find_fractional_mv_step(x, b, d,
Scott LaVarnway's avatar
Scott LaVarnway committed
215
                    &d->bmi.mv, &best_ref_mv1,
216
                    x->errorperbit, &cpi->fn_ptr[BLOCK_16X16],
217
                    mvcost, &distortion, &sse);
Johann's avatar
Johann committed
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
    }
#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
233
static void vp8_temporal_filter_iterate_c
Johann's avatar
Johann committed
234
235
236
237
238
239
240
241
242
243
(
    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
244
    unsigned int filter_weight;
245
246
    int mb_cols = cpi->common.mb_cols;
    int mb_rows = cpi->common.mb_rows;
Johann's avatar
Johann committed
247
248
    int mb_y_offset = 0;
    int mb_uv_offset = 0;
Johann's avatar
Johann committed
249
250
    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
251
252
253
    MACROBLOCKD *mbd = &cpi->mb.e_mbd;
    YV12_BUFFER_CONFIG *f = cpi->frames[alt_ref_index];
    unsigned char *dst1, *dst2;
Johann's avatar
Johann committed
254
    DECLARE_ALIGNED_ARRAY(16, unsigned char,  predictor, 16*16 + 8*8 + 8*8);
Johann's avatar
Johann committed
255

Johann's avatar
Johann committed
256
257
258
259
260
    // 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;

261
    for (mb_row = 0; mb_row < mb_rows; mb_row++)
Johann's avatar
Johann committed
262
263
    {
#if ALT_REF_MC_ENABLED
264
265
266
267
268
269
270
271
272
273
274
        // 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
275
        cpi->mb.mv_row_max = ((cpi->common.mb_rows - 1 - mb_row) * 16)
276
                                + (16 - 5);
Johann's avatar
Johann committed
277
278
#endif

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

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

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

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

                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
307
308
309
310
311
312
313
314
                // 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
315
#endif
Adrian Grange's avatar
Adrian Grange committed
316
317
318
319
320
321
322
                // 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
323
324
                {
                    // Construct the predictors
Johann's avatar
Johann committed
325
326
327
328
329
330
331
332
333
                    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
334
335

                    // Apply the filter (YUV)
Johann's avatar
Johann committed
336
                    TEMPORAL_INVOKE(&cpi->rtcd.temporal, apply)
Johann's avatar
Johann committed
337
338
339
340
341
                        (f->y_buffer + mb_y_offset,
                         f->y_stride,
                         predictor,
                         16,
                         strength,
Adrian Grange's avatar
Adrian Grange committed
342
                         filter_weight,
Johann's avatar
Johann committed
343
344
345
                         accumulator,
                         count);

Johann's avatar
Johann committed
346
                    TEMPORAL_INVOKE(&cpi->rtcd.temporal, apply)
Johann's avatar
Johann committed
347
348
349
350
351
                        (f->u_buffer + mb_uv_offset,
                         f->uv_stride,
                         predictor + 256,
                         8,
                         strength,
Adrian Grange's avatar
Adrian Grange committed
352
                         filter_weight,
Johann's avatar
Johann committed
353
354
355
                         accumulator + 256,
                         count + 256);

Johann's avatar
Johann committed
356
                    TEMPORAL_INVOKE(&cpi->rtcd.temporal, apply)
Johann's avatar
Johann committed
357
358
359
360
361
                        (f->v_buffer + mb_uv_offset,
                         f->uv_stride,
                         predictor + 320,
                         8,
                         strength,
Adrian Grange's avatar
Adrian Grange committed
362
                         filter_weight,
Johann's avatar
Johann committed
363
364
                         accumulator + 320,
                         count + 320);
Johann's avatar
Johann committed
365
366
367
368
                }
            }

            // Normalize filter output to produce AltRef frame
John Koleszar's avatar
John Koleszar committed
369
370
            dst1 = cpi->alt_ref_buffer.y_buffer;
            stride = cpi->alt_ref_buffer.y_stride;
Johann's avatar
Johann committed
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
            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
389
390
391
            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
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
421
            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;
        }

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

    // 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
432
void vp8_temporal_filter_prepare_c
Johann's avatar
Johann committed
433
(
John Koleszar's avatar
John Koleszar committed
434
435
    VP8_COMP *cpi,
    int distance
Johann's avatar
Johann committed
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
)
{
    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
453
454
455
    num_frames_backward = distance;
    num_frames_forward = vp8_lookahead_depth(cpi->lookahead)
                         - (num_frames_backward + 1);
Johann's avatar
Johann committed
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
506

    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
507
    start_frame = distance + frames_to_blur_forward;
Johann's avatar
Johann committed
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527

#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
528
529
530
        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
531
532
    }

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