Merge "asm_*_offsets to define variables as constants"
[profile/ivi/libvpx.git] / vp8 / common / loopfilter.c
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
12 #include "vpx_config.h"
13 #include "vpx_rtcd.h"
14 #include "loopfilter.h"
15 #include "onyxc_int.h"
16 #include "vpx_mem/vpx_mem.h"
17
18 typedef unsigned char uc;
19
20 static void lf_init_lut(loop_filter_info_n *lfi)
21 {
22     int filt_lvl;
23
24     for (filt_lvl = 0; filt_lvl <= MAX_LOOP_FILTER; filt_lvl++)
25     {
26         if (filt_lvl >= 40)
27         {
28             lfi->hev_thr_lut[KEY_FRAME][filt_lvl] = 2;
29             lfi->hev_thr_lut[INTER_FRAME][filt_lvl] = 3;
30         }
31         else if (filt_lvl >= 20)
32         {
33             lfi->hev_thr_lut[KEY_FRAME][filt_lvl] = 1;
34             lfi->hev_thr_lut[INTER_FRAME][filt_lvl] = 2;
35         }
36         else if (filt_lvl >= 15)
37         {
38             lfi->hev_thr_lut[KEY_FRAME][filt_lvl] = 1;
39             lfi->hev_thr_lut[INTER_FRAME][filt_lvl] = 1;
40         }
41         else
42         {
43             lfi->hev_thr_lut[KEY_FRAME][filt_lvl] = 0;
44             lfi->hev_thr_lut[INTER_FRAME][filt_lvl] = 0;
45         }
46     }
47
48     lfi->mode_lf_lut[DC_PRED] = 1;
49     lfi->mode_lf_lut[V_PRED] = 1;
50     lfi->mode_lf_lut[H_PRED] = 1;
51     lfi->mode_lf_lut[TM_PRED] = 1;
52     lfi->mode_lf_lut[B_PRED]  = 0;
53
54     lfi->mode_lf_lut[ZEROMV]  = 1;
55     lfi->mode_lf_lut[NEARESTMV] = 2;
56     lfi->mode_lf_lut[NEARMV] = 2;
57     lfi->mode_lf_lut[NEWMV] = 2;
58     lfi->mode_lf_lut[SPLITMV] = 3;
59
60 }
61
62 void vp8_loop_filter_update_sharpness(loop_filter_info_n *lfi,
63                                       int sharpness_lvl)
64 {
65     int i;
66
67     /* For each possible value for the loop filter fill out limits */
68     for (i = 0; i <= MAX_LOOP_FILTER; i++)
69     {
70         int filt_lvl = i;
71         int block_inside_limit = 0;
72
73         /* Set loop filter paramaeters that control sharpness. */
74         block_inside_limit = filt_lvl >> (sharpness_lvl > 0);
75         block_inside_limit = block_inside_limit >> (sharpness_lvl > 4);
76
77         if (sharpness_lvl > 0)
78         {
79             if (block_inside_limit > (9 - sharpness_lvl))
80                 block_inside_limit = (9 - sharpness_lvl);
81         }
82
83         if (block_inside_limit < 1)
84             block_inside_limit = 1;
85
86         vpx_memset(lfi->lim[i], block_inside_limit, SIMD_WIDTH);
87         vpx_memset(lfi->blim[i], (2 * filt_lvl + block_inside_limit),
88                 SIMD_WIDTH);
89         vpx_memset(lfi->mblim[i], (2 * (filt_lvl + 2) + block_inside_limit),
90                 SIMD_WIDTH);
91     }
92 }
93
94 void vp8_loop_filter_init(VP8_COMMON *cm)
95 {
96     loop_filter_info_n *lfi = &cm->lf_info;
97     int i;
98
99     /* init limits for given sharpness*/
100     vp8_loop_filter_update_sharpness(lfi, cm->sharpness_level);
101     cm->last_sharpness_level = cm->sharpness_level;
102
103     /* init LUT for lvl  and hev thr picking */
104     lf_init_lut(lfi);
105
106     /* init hev threshold const vectors */
107     for(i = 0; i < 4 ; i++)
108     {
109         vpx_memset(lfi->hev_thr[i], i, SIMD_WIDTH);
110     }
111 }
112
113 void vp8_loop_filter_frame_init(VP8_COMMON *cm,
114                                 MACROBLOCKD *mbd,
115                                 int default_filt_lvl)
116 {
117     int seg,  /* segment number */
118         ref,  /* index in ref_lf_deltas */
119         mode; /* index in mode_lf_deltas */
120
121     loop_filter_info_n *lfi = &cm->lf_info;
122
123     /* update limits if sharpness has changed */
124     if(cm->last_sharpness_level != cm->sharpness_level)
125     {
126         vp8_loop_filter_update_sharpness(lfi, cm->sharpness_level);
127         cm->last_sharpness_level = cm->sharpness_level;
128     }
129
130     for(seg = 0; seg < MAX_MB_SEGMENTS; seg++)
131     {
132         int lvl_seg = default_filt_lvl;
133         int lvl_ref, lvl_mode;
134
135         /* Note the baseline filter values for each segment */
136         if (mbd->segmentation_enabled)
137         {
138             /* Abs value */
139             if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA)
140             {
141                 lvl_seg = mbd->segment_feature_data[MB_LVL_ALT_LF][seg];
142             }
143             else  /* Delta Value */
144             {
145                 lvl_seg += mbd->segment_feature_data[MB_LVL_ALT_LF][seg];
146                 lvl_seg = (lvl_seg > 0) ? ((lvl_seg > 63) ? 63: lvl_seg) : 0;
147             }
148         }
149
150         if (!mbd->mode_ref_lf_delta_enabled)
151         {
152             /* we could get rid of this if we assume that deltas are set to
153              * zero when not in use; encoder always uses deltas
154              */
155             vpx_memset(lfi->lvl[seg][0], lvl_seg, 4 * 4 );
156             continue;
157         }
158
159         lvl_ref = lvl_seg;
160
161         /* INTRA_FRAME */
162         ref = INTRA_FRAME;
163
164         /* Apply delta for reference frame */
165         lvl_ref += mbd->ref_lf_deltas[ref];
166
167         /* Apply delta for Intra modes */
168         mode = 0; /* B_PRED */
169         /* Only the split mode BPRED has a further special case */
170         lvl_mode = lvl_ref +  mbd->mode_lf_deltas[mode];
171         lvl_mode = (lvl_mode > 0) ? (lvl_mode > 63 ? 63 : lvl_mode) : 0; /* clamp */
172
173         lfi->lvl[seg][ref][mode] = lvl_mode;
174
175         mode = 1; /* all the rest of Intra modes */
176         lvl_mode = (lvl_ref > 0) ? (lvl_ref > 63 ? 63 : lvl_ref)  : 0; /* clamp */
177         lfi->lvl[seg][ref][mode] = lvl_mode;
178
179         /* LAST, GOLDEN, ALT */
180         for(ref = 1; ref < MAX_REF_FRAMES; ref++)
181         {
182             int lvl_ref = lvl_seg;
183
184             /* Apply delta for reference frame */
185             lvl_ref += mbd->ref_lf_deltas[ref];
186
187             /* Apply delta for Inter modes */
188             for (mode = 1; mode < 4; mode++)
189             {
190                 lvl_mode = lvl_ref + mbd->mode_lf_deltas[mode];
191                 lvl_mode = (lvl_mode > 0) ? (lvl_mode > 63 ? 63 : lvl_mode) : 0; /* clamp */
192
193                 lfi->lvl[seg][ref][mode] = lvl_mode;
194             }
195         }
196     }
197 }
198
199 void vp8_loop_filter_frame
200 (
201     VP8_COMMON *cm,
202     MACROBLOCKD *mbd
203 )
204 {
205     YV12_BUFFER_CONFIG *post = cm->frame_to_show;
206     loop_filter_info_n *lfi_n = &cm->lf_info;
207     loop_filter_info lfi;
208
209     FRAME_TYPE frame_type = cm->frame_type;
210
211     int mb_row;
212     int mb_col;
213     int mb_rows = cm->mb_rows;
214     int mb_cols = cm->mb_cols;
215
216     int filter_level;
217
218     unsigned char *y_ptr, *u_ptr, *v_ptr;
219
220     /* Point at base of Mb MODE_INFO list */
221     const MODE_INFO *mode_info_context = cm->mi;
222     int post_y_stride = post->y_stride;
223     int post_uv_stride = post->uv_stride;
224
225     /* Initialize the loop filter for this frame. */
226     vp8_loop_filter_frame_init(cm, mbd, cm->filter_level);
227
228     /* Set up the buffer pointers */
229     y_ptr = post->y_buffer;
230     u_ptr = post->u_buffer;
231     v_ptr = post->v_buffer;
232
233     /* vp8_filter each macro block */
234     if (cm->filter_type == NORMAL_LOOPFILTER)
235     {
236         for (mb_row = 0; mb_row < mb_rows; mb_row++)
237         {
238             for (mb_col = 0; mb_col < mb_cols; mb_col++)
239             {
240                 int skip_lf = (mode_info_context->mbmi.mode != B_PRED &&
241                                 mode_info_context->mbmi.mode != SPLITMV &&
242                                 mode_info_context->mbmi.mb_skip_coeff);
243
244                 const int mode_index = lfi_n->mode_lf_lut[mode_info_context->mbmi.mode];
245                 const int seg = mode_info_context->mbmi.segment_id;
246                 const int ref_frame = mode_info_context->mbmi.ref_frame;
247
248                 filter_level = lfi_n->lvl[seg][ref_frame][mode_index];
249
250                 if (filter_level)
251                 {
252                     const int hev_index = lfi_n->hev_thr_lut[frame_type][filter_level];
253                     lfi.mblim = lfi_n->mblim[filter_level];
254                     lfi.blim = lfi_n->blim[filter_level];
255                     lfi.lim = lfi_n->lim[filter_level];
256                     lfi.hev_thr = lfi_n->hev_thr[hev_index];
257
258                     if (mb_col > 0)
259                         vp8_loop_filter_mbv
260                         (y_ptr, u_ptr, v_ptr, post_y_stride, post_uv_stride, &lfi);
261
262                     if (!skip_lf)
263                         vp8_loop_filter_bv
264                         (y_ptr, u_ptr, v_ptr, post_y_stride, post_uv_stride, &lfi);
265
266                     /* don't apply across umv border */
267                     if (mb_row > 0)
268                         vp8_loop_filter_mbh
269                         (y_ptr, u_ptr, v_ptr, post_y_stride, post_uv_stride, &lfi);
270
271                     if (!skip_lf)
272                         vp8_loop_filter_bh
273                         (y_ptr, u_ptr, v_ptr, post_y_stride, post_uv_stride, &lfi);
274                 }
275
276                 y_ptr += 16;
277                 u_ptr += 8;
278                 v_ptr += 8;
279
280                 mode_info_context++;     /* step to next MB */
281             }
282             y_ptr += post_y_stride  * 16 - post->y_width;
283             u_ptr += post_uv_stride *  8 - post->uv_width;
284             v_ptr += post_uv_stride *  8 - post->uv_width;
285
286             mode_info_context++;         /* Skip border mb */
287
288         }
289     }
290     else /* SIMPLE_LOOPFILTER */
291     {
292         for (mb_row = 0; mb_row < mb_rows; mb_row++)
293         {
294             for (mb_col = 0; mb_col < mb_cols; mb_col++)
295             {
296                 int skip_lf = (mode_info_context->mbmi.mode != B_PRED &&
297                                 mode_info_context->mbmi.mode != SPLITMV &&
298                                 mode_info_context->mbmi.mb_skip_coeff);
299
300                 const int mode_index = lfi_n->mode_lf_lut[mode_info_context->mbmi.mode];
301                 const int seg = mode_info_context->mbmi.segment_id;
302                 const int ref_frame = mode_info_context->mbmi.ref_frame;
303
304                 filter_level = lfi_n->lvl[seg][ref_frame][mode_index];
305                 if (filter_level)
306                 {
307                     const unsigned char * mblim = lfi_n->mblim[filter_level];
308                     const unsigned char * blim = lfi_n->blim[filter_level];
309
310                     if (mb_col > 0)
311                         vp8_loop_filter_simple_mbv
312                         (y_ptr, post_y_stride, mblim);
313
314                     if (!skip_lf)
315                         vp8_loop_filter_simple_bv
316                         (y_ptr, post_y_stride, blim);
317
318                     /* don't apply across umv border */
319                     if (mb_row > 0)
320                         vp8_loop_filter_simple_mbh
321                         (y_ptr, post_y_stride, mblim);
322
323                     if (!skip_lf)
324                         vp8_loop_filter_simple_bh
325                         (y_ptr, post_y_stride, blim);
326                 }
327
328                 y_ptr += 16;
329                 u_ptr += 8;
330                 v_ptr += 8;
331
332                 mode_info_context++;     /* step to next MB */
333             }
334             y_ptr += post_y_stride  * 16 - post->y_width;
335             u_ptr += post_uv_stride *  8 - post->uv_width;
336             v_ptr += post_uv_stride *  8 - post->uv_width;
337
338             mode_info_context++;         /* Skip border mb */
339
340         }
341     }
342 }
343
344 void vp8_loop_filter_frame_yonly
345 (
346     VP8_COMMON *cm,
347     MACROBLOCKD *mbd,
348     int default_filt_lvl
349 )
350 {
351     YV12_BUFFER_CONFIG *post = cm->frame_to_show;
352
353     unsigned char *y_ptr;
354     int mb_row;
355     int mb_col;
356
357     loop_filter_info_n *lfi_n = &cm->lf_info;
358     loop_filter_info lfi;
359
360     int filter_level;
361     FRAME_TYPE frame_type = cm->frame_type;
362
363     /* Point at base of Mb MODE_INFO list */
364     const MODE_INFO *mode_info_context = cm->mi;
365
366 #if 0
367     if(default_filt_lvl == 0) /* no filter applied */
368         return;
369 #endif
370
371     /* Initialize the loop filter for this frame. */
372     vp8_loop_filter_frame_init( cm, mbd, default_filt_lvl);
373
374     /* Set up the buffer pointers */
375     y_ptr = post->y_buffer;
376
377     /* vp8_filter each macro block */
378     for (mb_row = 0; mb_row < cm->mb_rows; mb_row++)
379     {
380         for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
381         {
382             int skip_lf = (mode_info_context->mbmi.mode != B_PRED &&
383                             mode_info_context->mbmi.mode != SPLITMV &&
384                             mode_info_context->mbmi.mb_skip_coeff);
385
386             const int mode_index = lfi_n->mode_lf_lut[mode_info_context->mbmi.mode];
387             const int seg = mode_info_context->mbmi.segment_id;
388             const int ref_frame = mode_info_context->mbmi.ref_frame;
389
390             filter_level = lfi_n->lvl[seg][ref_frame][mode_index];
391
392             if (filter_level)
393             {
394                 if (cm->filter_type == NORMAL_LOOPFILTER)
395                 {
396                     const int hev_index = lfi_n->hev_thr_lut[frame_type][filter_level];
397                     lfi.mblim = lfi_n->mblim[filter_level];
398                     lfi.blim = lfi_n->blim[filter_level];
399                     lfi.lim = lfi_n->lim[filter_level];
400                     lfi.hev_thr = lfi_n->hev_thr[hev_index];
401
402                     if (mb_col > 0)
403                         vp8_loop_filter_mbv
404                         (y_ptr, 0, 0, post->y_stride, 0, &lfi);
405
406                     if (!skip_lf)
407                         vp8_loop_filter_bv
408                         (y_ptr, 0, 0, post->y_stride, 0, &lfi);
409
410                     /* don't apply across umv border */
411                     if (mb_row > 0)
412                         vp8_loop_filter_mbh
413                         (y_ptr, 0, 0, post->y_stride, 0, &lfi);
414
415                     if (!skip_lf)
416                         vp8_loop_filter_bh
417                         (y_ptr, 0, 0, post->y_stride, 0, &lfi);
418                 }
419                 else
420                 {
421                     if (mb_col > 0)
422                         vp8_loop_filter_simple_mbv
423                         (y_ptr, post->y_stride, lfi_n->mblim[filter_level]);
424
425                     if (!skip_lf)
426                         vp8_loop_filter_simple_bv
427                         (y_ptr, post->y_stride, lfi_n->blim[filter_level]);
428
429                     /* don't apply across umv border */
430                     if (mb_row > 0)
431                         vp8_loop_filter_simple_mbh
432                         (y_ptr, post->y_stride, lfi_n->mblim[filter_level]);
433
434                     if (!skip_lf)
435                         vp8_loop_filter_simple_bh
436                         (y_ptr, post->y_stride, lfi_n->blim[filter_level]);
437                 }
438             }
439
440             y_ptr += 16;
441             mode_info_context ++;        /* step to next MB */
442
443         }
444
445         y_ptr += post->y_stride  * 16 - post->y_width;
446         mode_info_context ++;            /* Skip border mb */
447     }
448
449 }
450
451 void vp8_loop_filter_partial_frame
452 (
453     VP8_COMMON *cm,
454     MACROBLOCKD *mbd,
455     int default_filt_lvl
456 )
457 {
458     YV12_BUFFER_CONFIG *post = cm->frame_to_show;
459
460     unsigned char *y_ptr;
461     int mb_row;
462     int mb_col;
463     int mb_cols = post->y_width >> 4;
464     int mb_rows = post->y_height >> 4;
465
466     int linestocopy, i;
467
468     loop_filter_info_n *lfi_n = &cm->lf_info;
469     loop_filter_info lfi;
470
471     int filter_level;
472     int alt_flt_enabled = mbd->segmentation_enabled;
473     FRAME_TYPE frame_type = cm->frame_type;
474
475     const MODE_INFO *mode_info_context;
476
477     int lvl_seg[MAX_MB_SEGMENTS];
478
479     /* number of MB rows to use in partial filtering */
480     linestocopy = mb_rows / PARTIAL_FRAME_FRACTION;
481     linestocopy = linestocopy ? linestocopy << 4 : 16;     /* 16 lines per MB */
482
483     /* Note the baseline filter values for each segment */
484     /* See vp8_loop_filter_frame_init. Rather than call that for each change
485      * to default_filt_lvl, copy the relevant calculation here.
486      */
487     if (alt_flt_enabled)
488     {
489         for (i = 0; i < MAX_MB_SEGMENTS; i++)
490         {    /* Abs value */
491             if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA)
492             {
493                 lvl_seg[i] = mbd->segment_feature_data[MB_LVL_ALT_LF][i];
494             }
495             /* Delta Value */
496             else
497             {
498                 lvl_seg[i] = default_filt_lvl
499                         + mbd->segment_feature_data[MB_LVL_ALT_LF][i];
500                 lvl_seg[i] = (lvl_seg[i] > 0) ?
501                         ((lvl_seg[i] > 63) ? 63: lvl_seg[i]) : 0;
502             }
503         }
504     }
505
506     /* Set up the buffer pointers; partial image starts at ~middle of frame */
507     y_ptr = post->y_buffer + ((post->y_height >> 5) * 16) * post->y_stride;
508     mode_info_context = cm->mi + (post->y_height >> 5) * (mb_cols + 1);
509
510     /* vp8_filter each macro block */
511     for (mb_row = 0; mb_row<(linestocopy >> 4); mb_row++)
512     {
513         for (mb_col = 0; mb_col < mb_cols; mb_col++)
514         {
515             int skip_lf = (mode_info_context->mbmi.mode != B_PRED &&
516                            mode_info_context->mbmi.mode != SPLITMV &&
517                            mode_info_context->mbmi.mb_skip_coeff);
518
519             if (alt_flt_enabled)
520                 filter_level = lvl_seg[mode_info_context->mbmi.segment_id];
521             else
522                 filter_level = default_filt_lvl;
523
524             if (filter_level)
525             {
526                 if (cm->filter_type == NORMAL_LOOPFILTER)
527                 {
528                     const int hev_index = lfi_n->hev_thr_lut[frame_type][filter_level];
529                     lfi.mblim = lfi_n->mblim[filter_level];
530                     lfi.blim = lfi_n->blim[filter_level];
531                     lfi.lim = lfi_n->lim[filter_level];
532                     lfi.hev_thr = lfi_n->hev_thr[hev_index];
533
534                     if (mb_col > 0)
535                         vp8_loop_filter_mbv
536                         (y_ptr, 0, 0, post->y_stride, 0, &lfi);
537
538                     if (!skip_lf)
539                         vp8_loop_filter_bv
540                         (y_ptr, 0, 0, post->y_stride, 0, &lfi);
541
542                     vp8_loop_filter_mbh
543                         (y_ptr, 0, 0, post->y_stride, 0, &lfi);
544
545                     if (!skip_lf)
546                         vp8_loop_filter_bh
547                         (y_ptr, 0, 0, post->y_stride, 0, &lfi);
548                 }
549                 else
550                 {
551                     if (mb_col > 0)
552                         vp8_loop_filter_simple_mbv
553                         (y_ptr, post->y_stride, lfi_n->mblim[filter_level]);
554
555                     if (!skip_lf)
556                         vp8_loop_filter_simple_bv
557                         (y_ptr, post->y_stride, lfi_n->blim[filter_level]);
558
559                     vp8_loop_filter_simple_mbh
560                         (y_ptr, post->y_stride, lfi_n->mblim[filter_level]);
561
562                     if (!skip_lf)
563                         vp8_loop_filter_simple_bh
564                         (y_ptr, post->y_stride, lfi_n->blim[filter_level]);
565                 }
566             }
567
568             y_ptr += 16;
569             mode_info_context += 1;      /* step to next MB */
570         }
571
572         y_ptr += post->y_stride  * 16 - post->y_width;
573         mode_info_context += 1;          /* Skip border mb */
574     }
575 }