loopfilter.c 20 KB
Newer Older
John Koleszar's avatar
John Koleszar committed
1
/*
2
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
John Koleszar's avatar
John Koleszar committed
3
 *
4
 *  Use of this source code is governed by a BSD-style license
5
6
 *  that can be found in the LICENSE file in the root of the source
 *  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.
John Koleszar's avatar
John Koleszar committed
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 */


#include "vpx_ports/config.h"
#include "loopfilter.h"
#include "onyxc_int.h"

typedef unsigned char uc;


prototype_loopfilter(vp8_loop_filter_horizontal_edge_c);
prototype_loopfilter(vp8_loop_filter_vertical_edge_c);
prototype_loopfilter(vp8_mbloop_filter_horizontal_edge_c);
prototype_loopfilter(vp8_mbloop_filter_vertical_edge_c);
prototype_loopfilter(vp8_loop_filter_simple_horizontal_edge_c);
prototype_loopfilter(vp8_loop_filter_simple_vertical_edge_c);

26
/* Horizontal MB filtering */
John Koleszar's avatar
John Koleszar committed
27
void vp8_loop_filter_mbh_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
Johann's avatar
Johann committed
28
                           int y_stride, int uv_stride, loop_filter_info *lfi)
John Koleszar's avatar
John Koleszar committed
29
{
30
    vp8_mbloop_filter_horizontal_edge_c(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->thr, 2);
John Koleszar's avatar
John Koleszar committed
31
32

    if (u_ptr)
33
        vp8_mbloop_filter_horizontal_edge_c(u_ptr, uv_stride, lfi->mbflim, lfi->lim, lfi->thr, 1);
John Koleszar's avatar
John Koleszar committed
34
35

    if (v_ptr)
36
        vp8_mbloop_filter_horizontal_edge_c(v_ptr, uv_stride, lfi->mbflim, lfi->lim, lfi->thr, 1);
John Koleszar's avatar
John Koleszar committed
37
38
39
}

void vp8_loop_filter_mbhs_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
Johann's avatar
Johann committed
40
                            int y_stride, int uv_stride, loop_filter_info *lfi)
John Koleszar's avatar
John Koleszar committed
41
42
43
44
{
    (void) u_ptr;
    (void) v_ptr;
    (void) uv_stride;
45
    vp8_loop_filter_simple_horizontal_edge_c(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->thr, 2);
John Koleszar's avatar
John Koleszar committed
46
47
}

48
/* Vertical MB Filtering */
John Koleszar's avatar
John Koleszar committed
49
void vp8_loop_filter_mbv_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
Johann's avatar
Johann committed
50
                           int y_stride, int uv_stride, loop_filter_info *lfi)
John Koleszar's avatar
John Koleszar committed
51
{
52
    vp8_mbloop_filter_vertical_edge_c(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->thr, 2);
John Koleszar's avatar
John Koleszar committed
53
54

    if (u_ptr)
55
        vp8_mbloop_filter_vertical_edge_c(u_ptr, uv_stride, lfi->mbflim, lfi->lim, lfi->thr, 1);
John Koleszar's avatar
John Koleszar committed
56
57

    if (v_ptr)
58
        vp8_mbloop_filter_vertical_edge_c(v_ptr, uv_stride, lfi->mbflim, lfi->lim, lfi->thr, 1);
John Koleszar's avatar
John Koleszar committed
59
60
61
}

void vp8_loop_filter_mbvs_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
Johann's avatar
Johann committed
62
                            int y_stride, int uv_stride, loop_filter_info *lfi)
John Koleszar's avatar
John Koleszar committed
63
64
65
66
{
    (void) u_ptr;
    (void) v_ptr;
    (void) uv_stride;
67
    vp8_loop_filter_simple_vertical_edge_c(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->thr, 2);
John Koleszar's avatar
John Koleszar committed
68
69
}

70
/* Horizontal B Filtering */
John Koleszar's avatar
John Koleszar committed
71
void vp8_loop_filter_bh_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
Johann's avatar
Johann committed
72
                          int y_stride, int uv_stride, loop_filter_info *lfi)
John Koleszar's avatar
John Koleszar committed
73
74
75
76
77
78
{
    vp8_loop_filter_horizontal_edge_c(y_ptr + 4 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
    vp8_loop_filter_horizontal_edge_c(y_ptr + 8 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
    vp8_loop_filter_horizontal_edge_c(y_ptr + 12 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);

    if (u_ptr)
79
        vp8_loop_filter_horizontal_edge_c(u_ptr + 4 * uv_stride, uv_stride, lfi->flim, lfi->lim, lfi->thr, 1);
John Koleszar's avatar
John Koleszar committed
80
81

    if (v_ptr)
82
        vp8_loop_filter_horizontal_edge_c(v_ptr + 4 * uv_stride, uv_stride, lfi->flim, lfi->lim, lfi->thr, 1);
John Koleszar's avatar
John Koleszar committed
83
84
85
}

void vp8_loop_filter_bhs_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
Johann's avatar
Johann committed
86
                           int y_stride, int uv_stride, loop_filter_info *lfi)
John Koleszar's avatar
John Koleszar committed
87
88
89
90
91
92
93
94
95
{
    (void) u_ptr;
    (void) v_ptr;
    (void) uv_stride;
    vp8_loop_filter_simple_horizontal_edge_c(y_ptr + 4 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
    vp8_loop_filter_simple_horizontal_edge_c(y_ptr + 8 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
    vp8_loop_filter_simple_horizontal_edge_c(y_ptr + 12 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
}

96
/* Vertical B Filtering */
John Koleszar's avatar
John Koleszar committed
97
void vp8_loop_filter_bv_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
Johann's avatar
Johann committed
98
                          int y_stride, int uv_stride, loop_filter_info *lfi)
John Koleszar's avatar
John Koleszar committed
99
100
101
102
103
104
{
    vp8_loop_filter_vertical_edge_c(y_ptr + 4, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
    vp8_loop_filter_vertical_edge_c(y_ptr + 8, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
    vp8_loop_filter_vertical_edge_c(y_ptr + 12, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);

    if (u_ptr)
105
        vp8_loop_filter_vertical_edge_c(u_ptr + 4, uv_stride, lfi->flim, lfi->lim, lfi->thr, 1);
John Koleszar's avatar
John Koleszar committed
106
107

    if (v_ptr)
108
        vp8_loop_filter_vertical_edge_c(v_ptr + 4, uv_stride, lfi->flim, lfi->lim, lfi->thr, 1);
John Koleszar's avatar
John Koleszar committed
109
110
111
}

void vp8_loop_filter_bvs_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
Johann's avatar
Johann committed
112
                           int y_stride, int uv_stride, loop_filter_info *lfi)
John Koleszar's avatar
John Koleszar committed
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
{
    (void) u_ptr;
    (void) v_ptr;
    (void) uv_stride;
    vp8_loop_filter_simple_vertical_edge_c(y_ptr + 4, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
    vp8_loop_filter_simple_vertical_edge_c(y_ptr + 8, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
    vp8_loop_filter_simple_vertical_edge_c(y_ptr + 12, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
}

void vp8_init_loop_filter(VP8_COMMON *cm)
{
    loop_filter_info *lfi = cm->lf_info;
    LOOPFILTERTYPE lft = cm->filter_type;
    int sharpness_lvl = cm->sharpness_level;
    int frame_type = cm->frame_type;
    int i, j;

    int block_inside_limit = 0;
    int HEVThresh;

133
    /* For each possible value for the loop filter fill out a "loop_filter_info" entry. */
John Koleszar's avatar
John Koleszar committed
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
    for (i = 0; i <= MAX_LOOP_FILTER; i++)
    {
        int filt_lvl = i;

        if (frame_type == KEY_FRAME)
        {
            if (filt_lvl >= 40)
                HEVThresh = 2;
            else if (filt_lvl >= 15)
                HEVThresh = 1;
            else
                HEVThresh = 0;
        }
        else
        {
            if (filt_lvl >= 40)
                HEVThresh = 3;
            else if (filt_lvl >= 20)
                HEVThresh = 2;
            else if (filt_lvl >= 15)
                HEVThresh = 1;
            else
                HEVThresh = 0;
        }

159
        /* Set loop filter paramaeters that control sharpness. */
John Koleszar's avatar
John Koleszar committed
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
        block_inside_limit = filt_lvl >> (sharpness_lvl > 0);
        block_inside_limit = block_inside_limit >> (sharpness_lvl > 4);

        if (sharpness_lvl > 0)
        {
            if (block_inside_limit > (9 - sharpness_lvl))
                block_inside_limit = (9 - sharpness_lvl);
        }

        if (block_inside_limit < 1)
            block_inside_limit = 1;

        for (j = 0; j < 16; j++)
        {
            lfi[i].lim[j] = block_inside_limit;
175
            lfi[i].mbflim[j] = filt_lvl + 2;
John Koleszar's avatar
John Koleszar committed
176
177
178
179
180
181
            lfi[i].flim[j] = filt_lvl;
            lfi[i].thr[j] = HEVThresh;
        }

    }

182
    /* Set up the function pointers depending on the type of loop filtering selected */
John Koleszar's avatar
John Koleszar committed
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
    if (lft == NORMAL_LOOPFILTER)
    {
        cm->lf_mbv = LF_INVOKE(&cm->rtcd.loopfilter, normal_mb_v);
        cm->lf_bv  = LF_INVOKE(&cm->rtcd.loopfilter, normal_b_v);
        cm->lf_mbh = LF_INVOKE(&cm->rtcd.loopfilter, normal_mb_h);
        cm->lf_bh  = LF_INVOKE(&cm->rtcd.loopfilter, normal_b_h);
    }
    else
    {
        cm->lf_mbv = LF_INVOKE(&cm->rtcd.loopfilter, simple_mb_v);
        cm->lf_bv  = LF_INVOKE(&cm->rtcd.loopfilter, simple_b_v);
        cm->lf_mbh = LF_INVOKE(&cm->rtcd.loopfilter, simple_mb_h);
        cm->lf_bh  = LF_INVOKE(&cm->rtcd.loopfilter, simple_b_h);
    }
}

199
200
201
/* Put vp8_init_loop_filter() in vp8dx_create_decompressor(). Only call vp8_frame_init_loop_filter() while decoding
 * each frame. Check last_frame_type to skip the function most of times.
 */
John Koleszar's avatar
John Koleszar committed
202
203
204
205
206
void vp8_frame_init_loop_filter(loop_filter_info *lfi, int frame_type)
{
    int HEVThresh;
    int i, j;

207
    /* For each possible value for the loop filter fill out a "loop_filter_info" entry. */
John Koleszar's avatar
John Koleszar committed
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
    for (i = 0; i <= MAX_LOOP_FILTER; i++)
    {
        int filt_lvl = i;

        if (frame_type == KEY_FRAME)
        {
            if (filt_lvl >= 40)
                HEVThresh = 2;
            else if (filt_lvl >= 15)
                HEVThresh = 1;
            else
                HEVThresh = 0;
        }
        else
        {
            if (filt_lvl >= 40)
                HEVThresh = 3;
            else if (filt_lvl >= 20)
                HEVThresh = 2;
            else if (filt_lvl >= 15)
                HEVThresh = 1;
            else
                HEVThresh = 0;
        }

        for (j = 0; j < 16; j++)
        {
235
            /*lfi[i].lim[j] = block_inside_limit;
236
            lfi[i].mbflim[j] = filt_lvl+2;*/
237
            /*lfi[i].flim[j] = filt_lvl;*/
John Koleszar's avatar
John Koleszar committed
238
239
240
241
242
243
            lfi[i].thr[j] = HEVThresh;
        }
    }
}


244
int vp8_adjust_mb_lf_value(MACROBLOCKD *mbd, int filter_level)
John Koleszar's avatar
John Koleszar committed
245
246
247
248
249
{
    MB_MODE_INFO *mbmi = &mbd->mode_info_context->mbmi;

    if (mbd->mode_ref_lf_delta_enabled)
    {
250
        /* Apply delta for reference frame */
251
        filter_level += mbd->ref_lf_deltas[mbmi->ref_frame];
John Koleszar's avatar
John Koleszar committed
252

253
        /* Apply delta for mode */
John Koleszar's avatar
John Koleszar committed
254
255
        if (mbmi->ref_frame == INTRA_FRAME)
        {
256
            /* Only the split mode BPRED has a further special case */
John Koleszar's avatar
John Koleszar committed
257
            if (mbmi->mode == B_PRED)
258
                filter_level +=  mbd->mode_lf_deltas[0];
John Koleszar's avatar
John Koleszar committed
259
260
261
        }
        else
        {
262
            /* Zero motion mode */
John Koleszar's avatar
John Koleszar committed
263
            if (mbmi->mode == ZEROMV)
264
                filter_level +=  mbd->mode_lf_deltas[1];
John Koleszar's avatar
John Koleszar committed
265

266
            /* Split MB motion mode */
John Koleszar's avatar
John Koleszar committed
267
            else if (mbmi->mode == SPLITMV)
268
                filter_level +=  mbd->mode_lf_deltas[3];
John Koleszar's avatar
John Koleszar committed
269

270
            /* All other inter motion modes (Nearest, Near, New) */
John Koleszar's avatar
John Koleszar committed
271
            else
272
                filter_level +=  mbd->mode_lf_deltas[2];
John Koleszar's avatar
John Koleszar committed
273
274
        }

275
        /* Range check */
276
277
278
279
        if (filter_level > MAX_LOOP_FILTER)
            filter_level = MAX_LOOP_FILTER;
        else if (filter_level < 0)
            filter_level = 0;
John Koleszar's avatar
John Koleszar committed
280
    }
281
    return filter_level;
John Koleszar's avatar
John Koleszar committed
282
283
284
285
286
287
288
289
290
291
292
293
}


void vp8_loop_filter_frame
(
    VP8_COMMON *cm,
    MACROBLOCKD *mbd,
    int default_filt_lvl
)
{
    YV12_BUFFER_CONFIG *post = cm->frame_to_show;
    loop_filter_info *lfi = cm->lf_info;
294
    FRAME_TYPE frame_type = cm->frame_type;
John Koleszar's avatar
John Koleszar committed
295
296
297
298
299
300
301
302
303
304
305
306

    int mb_row;
    int mb_col;


    int baseline_filter_level[MAX_MB_SEGMENTS];
    int filter_level;
    int alt_flt_enabled = mbd->segmentation_enabled;

    int i;
    unsigned char *y_ptr, *u_ptr, *v_ptr;

307
    mbd->mode_info_context = cm->mi;          /* Point at base of Mb MODE_INFO list */
John Koleszar's avatar
John Koleszar committed
308

309
    /* Note the baseline filter values for each segment */
John Koleszar's avatar
John Koleszar committed
310
311
312
313
    if (alt_flt_enabled)
    {
        for (i = 0; i < MAX_MB_SEGMENTS; i++)
        {
314
            /* Abs value */
John Koleszar's avatar
John Koleszar committed
315
316
            if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA)
                baseline_filter_level[i] = mbd->segment_feature_data[MB_LVL_ALT_LF][i];
317
            /* Delta Value */
John Koleszar's avatar
John Koleszar committed
318
319
320
            else
            {
                baseline_filter_level[i] = default_filt_lvl + mbd->segment_feature_data[MB_LVL_ALT_LF][i];
321
                baseline_filter_level[i] = (baseline_filter_level[i] >= 0) ? ((baseline_filter_level[i] <= MAX_LOOP_FILTER) ? baseline_filter_level[i] : MAX_LOOP_FILTER) : 0;  /* Clamp to valid range */
John Koleszar's avatar
John Koleszar committed
322
323
324
325
326
327
328
329
330
            }
        }
    }
    else
    {
        for (i = 0; i < MAX_MB_SEGMENTS; i++)
            baseline_filter_level[i] = default_filt_lvl;
    }

331
    /* Initialize the loop filter for this frame. */
John Koleszar's avatar
John Koleszar committed
332
333
334
335
336
    if ((cm->last_filter_type != cm->filter_type) || (cm->last_sharpness_level != cm->sharpness_level))
        vp8_init_loop_filter(cm);
    else if (frame_type != cm->last_frame_type)
        vp8_frame_init_loop_filter(lfi, frame_type);

337
    /* Set up the buffer pointers */
John Koleszar's avatar
John Koleszar committed
338
339
340
341
    y_ptr = post->y_buffer;
    u_ptr = post->u_buffer;
    v_ptr = post->v_buffer;

342
    /* vp8_filter each macro block */
John Koleszar's avatar
John Koleszar committed
343
344
345
346
347
    for (mb_row = 0; mb_row < cm->mb_rows; mb_row++)
    {
        for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
        {
            int Segment = (alt_flt_enabled) ? mbd->mode_info_context->mbmi.segment_id : 0;
348
349
350
            int skip_lf = (mbd->mode_info_context->mbmi.mode != B_PRED &&
                            mbd->mode_info_context->mbmi.mode != SPLITMV &&
                            mbd->mode_info_context->mbmi.mb_skip_coeff);
John Koleszar's avatar
John Koleszar committed
351
352
353

            filter_level = baseline_filter_level[Segment];

354
355
356
357
            /* Distance of Mb to the various image edges.
             * These specified to 8th pel as they are always compared to values that are in 1/8th pel units
             * Apply any context driven MB level adjustment
             */
358
            filter_level = vp8_adjust_mb_lf_value(mbd, filter_level);
John Koleszar's avatar
John Koleszar committed
359
360
361
362

            if (filter_level)
            {
                if (mb_col > 0)
Johann's avatar
Johann committed
363
                    cm->lf_mbv(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level]);
John Koleszar's avatar
John Koleszar committed
364

365
                if (!skip_lf)
Johann's avatar
Johann committed
366
                    cm->lf_bv(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level]);
John Koleszar's avatar
John Koleszar committed
367

368
                /* don't apply across umv border */
John Koleszar's avatar
John Koleszar committed
369
                if (mb_row > 0)
Johann's avatar
Johann committed
370
                    cm->lf_mbh(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level]);
John Koleszar's avatar
John Koleszar committed
371

372
                if (!skip_lf)
Johann's avatar
Johann committed
373
                    cm->lf_bh(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level]);
John Koleszar's avatar
John Koleszar committed
374
375
376
377
378
379
            }

            y_ptr += 16;
            u_ptr += 8;
            v_ptr += 8;

380
            mbd->mode_info_context++;     /* step to next MB */
John Koleszar's avatar
John Koleszar committed
381
382
383
384
385
386
        }

        y_ptr += post->y_stride  * 16 - post->y_width;
        u_ptr += post->uv_stride *  8 - post->uv_width;
        v_ptr += post->uv_stride *  8 - post->uv_width;

387
        mbd->mode_info_context++;         /* Skip border mb */
John Koleszar's avatar
John Koleszar committed
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
    }
}


void vp8_loop_filter_frame_yonly
(
    VP8_COMMON *cm,
    MACROBLOCKD *mbd,
    int default_filt_lvl,
    int sharpness_lvl
)
{
    YV12_BUFFER_CONFIG *post = cm->frame_to_show;

    int i;
    unsigned char *y_ptr;
    int mb_row;
    int mb_col;

    loop_filter_info *lfi = cm->lf_info;
    int baseline_filter_level[MAX_MB_SEGMENTS];
    int filter_level;
    int alt_flt_enabled = mbd->segmentation_enabled;
411
    FRAME_TYPE frame_type = cm->frame_type;
John Koleszar's avatar
John Koleszar committed
412
413
414

    (void) sharpness_lvl;

415
416
    /*MODE_INFO * this_mb_mode_info = cm->mi;*/ /* Point at base of Mb MODE_INFO list */
    mbd->mode_info_context = cm->mi;          /* Point at base of Mb MODE_INFO list */
John Koleszar's avatar
John Koleszar committed
417

418
    /* Note the baseline filter values for each segment */
John Koleszar's avatar
John Koleszar committed
419
420
421
422
    if (alt_flt_enabled)
    {
        for (i = 0; i < MAX_MB_SEGMENTS; i++)
        {
423
            /* Abs value */
John Koleszar's avatar
John Koleszar committed
424
425
            if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA)
                baseline_filter_level[i] = mbd->segment_feature_data[MB_LVL_ALT_LF][i];
426
            /* Delta Value */
John Koleszar's avatar
John Koleszar committed
427
428
429
            else
            {
                baseline_filter_level[i] = default_filt_lvl + mbd->segment_feature_data[MB_LVL_ALT_LF][i];
430
                baseline_filter_level[i] = (baseline_filter_level[i] >= 0) ? ((baseline_filter_level[i] <= MAX_LOOP_FILTER) ? baseline_filter_level[i] : MAX_LOOP_FILTER) : 0;  /* Clamp to valid range */
John Koleszar's avatar
John Koleszar committed
431
432
433
434
435
436
437
438
439
            }
        }
    }
    else
    {
        for (i = 0; i < MAX_MB_SEGMENTS; i++)
            baseline_filter_level[i] = default_filt_lvl;
    }

440
    /* Initialize the loop filter for this frame. */
John Koleszar's avatar
John Koleszar committed
441
442
443
444
445
    if ((cm->last_filter_type != cm->filter_type) || (cm->last_sharpness_level != cm->sharpness_level))
        vp8_init_loop_filter(cm);
    else if (frame_type != cm->last_frame_type)
        vp8_frame_init_loop_filter(lfi, frame_type);

446
    /* Set up the buffer pointers */
John Koleszar's avatar
John Koleszar committed
447
448
    y_ptr = post->y_buffer;

449
    /* vp8_filter each macro block */
John Koleszar's avatar
John Koleszar committed
450
451
452
453
454
    for (mb_row = 0; mb_row < cm->mb_rows; mb_row++)
    {
        for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
        {
            int Segment = (alt_flt_enabled) ? mbd->mode_info_context->mbmi.segment_id : 0;
455
456
457
458
            int skip_lf = (mbd->mode_info_context->mbmi.mode != B_PRED &&
                            mbd->mode_info_context->mbmi.mode != SPLITMV &&
                            mbd->mode_info_context->mbmi.mb_skip_coeff);

John Koleszar's avatar
John Koleszar committed
459
460
            filter_level = baseline_filter_level[Segment];

461
            /* Apply any context driven MB level adjustment */
462
            filter_level = vp8_adjust_mb_lf_value(mbd, filter_level);
John Koleszar's avatar
John Koleszar committed
463
464
465
466

            if (filter_level)
            {
                if (mb_col > 0)
Johann's avatar
Johann committed
467
                    cm->lf_mbv(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level]);
John Koleszar's avatar
John Koleszar committed
468

469
                if (!skip_lf)
Johann's avatar
Johann committed
470
                    cm->lf_bv(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level]);
John Koleszar's avatar
John Koleszar committed
471

472
                /* don't apply across umv border */
John Koleszar's avatar
John Koleszar committed
473
                if (mb_row > 0)
Johann's avatar
Johann committed
474
                    cm->lf_mbh(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level]);
John Koleszar's avatar
John Koleszar committed
475

476
                if (!skip_lf)
Johann's avatar
Johann committed
477
                    cm->lf_bh(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level]);
John Koleszar's avatar
John Koleszar committed
478
479
480
            }

            y_ptr += 16;
481
            mbd->mode_info_context ++;        /* step to next MB */
John Koleszar's avatar
John Koleszar committed
482
483
484
485

        }

        y_ptr += post->y_stride  * 16 - post->y_width;
486
        mbd->mode_info_context ++;            /* Skip border mb */
John Koleszar's avatar
John Koleszar committed
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
    }

}


void vp8_loop_filter_partial_frame
(
    VP8_COMMON *cm,
    MACROBLOCKD *mbd,
    int default_filt_lvl,
    int sharpness_lvl,
    int Fraction
)
{
    YV12_BUFFER_CONFIG *post = cm->frame_to_show;

    int i;
    unsigned char *y_ptr;
    int mb_row;
    int mb_col;
507
    /*int mb_rows = post->y_height >> 4;*/
John Koleszar's avatar
John Koleszar committed
508
509
510
511
512
513
514
515
    int mb_cols = post->y_width  >> 4;

    int linestocopy;

    loop_filter_info *lfi = cm->lf_info;
    int baseline_filter_level[MAX_MB_SEGMENTS];
    int filter_level;
    int alt_flt_enabled = mbd->segmentation_enabled;
516
    FRAME_TYPE frame_type = cm->frame_type;
John Koleszar's avatar
John Koleszar committed
517
518
519

    (void) sharpness_lvl;

520
521
    /*MODE_INFO * this_mb_mode_info = cm->mi + (post->y_height>>5) * (mb_cols + 1);*/ /* Point at base of Mb MODE_INFO list */
    mbd->mode_info_context = cm->mi + (post->y_height >> 5) * (mb_cols + 1);        /* Point at base of Mb MODE_INFO list */
John Koleszar's avatar
John Koleszar committed
522
523
524
525
526
527
528
529

    linestocopy = (post->y_height >> (4 + Fraction));

    if (linestocopy < 1)
        linestocopy = 1;

    linestocopy <<= 4;

530
    /* Note the baseline filter values for each segment */
John Koleszar's avatar
John Koleszar committed
531
532
533
534
    if (alt_flt_enabled)
    {
        for (i = 0; i < MAX_MB_SEGMENTS; i++)
        {
535
            /* Abs value */
John Koleszar's avatar
John Koleszar committed
536
537
            if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA)
                baseline_filter_level[i] = mbd->segment_feature_data[MB_LVL_ALT_LF][i];
538
            /* Delta Value */
John Koleszar's avatar
John Koleszar committed
539
540
541
            else
            {
                baseline_filter_level[i] = default_filt_lvl + mbd->segment_feature_data[MB_LVL_ALT_LF][i];
542
                baseline_filter_level[i] = (baseline_filter_level[i] >= 0) ? ((baseline_filter_level[i] <= MAX_LOOP_FILTER) ? baseline_filter_level[i] : MAX_LOOP_FILTER) : 0;  /* Clamp to valid range */
John Koleszar's avatar
John Koleszar committed
543
544
545
546
547
548
549
550
551
            }
        }
    }
    else
    {
        for (i = 0; i < MAX_MB_SEGMENTS; i++)
            baseline_filter_level[i] = default_filt_lvl;
    }

552
    /* Initialize the loop filter for this frame. */
John Koleszar's avatar
John Koleszar committed
553
554
555
556
557
    if ((cm->last_filter_type != cm->filter_type) || (cm->last_sharpness_level != cm->sharpness_level))
        vp8_init_loop_filter(cm);
    else if (frame_type != cm->last_frame_type)
        vp8_frame_init_loop_filter(lfi, frame_type);

558
    /* Set up the buffer pointers */
John Koleszar's avatar
John Koleszar committed
559
560
    y_ptr = post->y_buffer + (post->y_height >> 5) * 16 * post->y_stride;

561
    /* vp8_filter each macro block */
John Koleszar's avatar
John Koleszar committed
562
563
564
565
566
    for (mb_row = 0; mb_row<(linestocopy >> 4); mb_row++)
    {
        for (mb_col = 0; mb_col < mb_cols; mb_col++)
        {
            int Segment = (alt_flt_enabled) ? mbd->mode_info_context->mbmi.segment_id : 0;
567
568
569
570
            int skip_lf = (mbd->mode_info_context->mbmi.mode != B_PRED &&
                            mbd->mode_info_context->mbmi.mode != SPLITMV &&
                            mbd->mode_info_context->mbmi.mb_skip_coeff);

John Koleszar's avatar
John Koleszar committed
571
572
573
574
575
            filter_level = baseline_filter_level[Segment];

            if (filter_level)
            {
                if (mb_col > 0)
Johann's avatar
Johann committed
576
                    cm->lf_mbv(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level]);
John Koleszar's avatar
John Koleszar committed
577

578
                if (!skip_lf)
Johann's avatar
Johann committed
579
                    cm->lf_bv(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level]);
John Koleszar's avatar
John Koleszar committed
580

Johann's avatar
Johann committed
581
                cm->lf_mbh(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level]);
John Koleszar's avatar
John Koleszar committed
582

583
                if (!skip_lf)
Johann's avatar
Johann committed
584
                    cm->lf_bh(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level]);
John Koleszar's avatar
John Koleszar committed
585
586
587
            }

            y_ptr += 16;
588
            mbd->mode_info_context += 1;      /* step to next MB */
John Koleszar's avatar
John Koleszar committed
589
590
591
        }

        y_ptr += post->y_stride  * 16 - post->y_width;
592
        mbd->mode_info_context += 1;          /* Skip border mb */
John Koleszar's avatar
John Koleszar committed
593
594
    }
}