• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_ports/config.h"
13 #include "loopfilter.h"
14 #include "onyxc_int.h"
15 
16 typedef unsigned char uc;
17 
18 
19 prototype_loopfilter(vp8_loop_filter_horizontal_edge_c);
20 prototype_loopfilter(vp8_loop_filter_vertical_edge_c);
21 prototype_loopfilter(vp8_mbloop_filter_horizontal_edge_c);
22 prototype_loopfilter(vp8_mbloop_filter_vertical_edge_c);
23 prototype_loopfilter(vp8_loop_filter_simple_horizontal_edge_c);
24 prototype_loopfilter(vp8_loop_filter_simple_vertical_edge_c);
25 
26 /* Horizontal MB filtering */
vp8_loop_filter_mbh_c(unsigned char * y_ptr,unsigned char * u_ptr,unsigned char * v_ptr,int y_stride,int uv_stride,loop_filter_info * lfi,int simpler_lpf)27 void vp8_loop_filter_mbh_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
28                            int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
29 {
30     (void) simpler_lpf;
31     vp8_mbloop_filter_horizontal_edge_c(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->mbthr, 2);
32 
33     if (u_ptr)
34         vp8_mbloop_filter_horizontal_edge_c(u_ptr, uv_stride, lfi->uvmbflim, lfi->uvlim, lfi->uvmbthr, 1);
35 
36     if (v_ptr)
37         vp8_mbloop_filter_horizontal_edge_c(v_ptr, uv_stride, lfi->uvmbflim, lfi->uvlim, lfi->uvmbthr, 1);
38 }
39 
vp8_loop_filter_mbhs_c(unsigned char * y_ptr,unsigned char * u_ptr,unsigned char * v_ptr,int y_stride,int uv_stride,loop_filter_info * lfi,int simpler_lpf)40 void vp8_loop_filter_mbhs_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
41                             int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
42 {
43     (void) u_ptr;
44     (void) v_ptr;
45     (void) uv_stride;
46     (void) simpler_lpf;
47     vp8_loop_filter_simple_horizontal_edge_c(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->mbthr, 2);
48 }
49 
50 /* Vertical MB Filtering */
vp8_loop_filter_mbv_c(unsigned char * y_ptr,unsigned char * u_ptr,unsigned char * v_ptr,int y_stride,int uv_stride,loop_filter_info * lfi,int simpler_lpf)51 void vp8_loop_filter_mbv_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
52                            int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
53 {
54     (void) simpler_lpf;
55     vp8_mbloop_filter_vertical_edge_c(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->mbthr, 2);
56 
57     if (u_ptr)
58         vp8_mbloop_filter_vertical_edge_c(u_ptr, uv_stride, lfi->uvmbflim, lfi->uvlim, lfi->uvmbthr, 1);
59 
60     if (v_ptr)
61         vp8_mbloop_filter_vertical_edge_c(v_ptr, uv_stride, lfi->uvmbflim, lfi->uvlim, lfi->uvmbthr, 1);
62 }
63 
vp8_loop_filter_mbvs_c(unsigned char * y_ptr,unsigned char * u_ptr,unsigned char * v_ptr,int y_stride,int uv_stride,loop_filter_info * lfi,int simpler_lpf)64 void vp8_loop_filter_mbvs_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
65                             int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
66 {
67     (void) u_ptr;
68     (void) v_ptr;
69     (void) uv_stride;
70     (void) simpler_lpf;
71     vp8_loop_filter_simple_vertical_edge_c(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->mbthr, 2);
72 }
73 
74 /* Horizontal B Filtering */
vp8_loop_filter_bh_c(unsigned char * y_ptr,unsigned char * u_ptr,unsigned char * v_ptr,int y_stride,int uv_stride,loop_filter_info * lfi,int simpler_lpf)75 void vp8_loop_filter_bh_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
76                           int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
77 {
78     (void) simpler_lpf;
79     vp8_loop_filter_horizontal_edge_c(y_ptr + 4 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
80     vp8_loop_filter_horizontal_edge_c(y_ptr + 8 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
81     vp8_loop_filter_horizontal_edge_c(y_ptr + 12 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
82 
83     if (u_ptr)
84         vp8_loop_filter_horizontal_edge_c(u_ptr + 4 * uv_stride, uv_stride, lfi->uvflim, lfi->uvlim, lfi->uvthr, 1);
85 
86     if (v_ptr)
87         vp8_loop_filter_horizontal_edge_c(v_ptr + 4 * uv_stride, uv_stride, lfi->uvflim, lfi->uvlim, lfi->uvthr, 1);
88 }
89 
vp8_loop_filter_bhs_c(unsigned char * y_ptr,unsigned char * u_ptr,unsigned char * v_ptr,int y_stride,int uv_stride,loop_filter_info * lfi,int simpler_lpf)90 void vp8_loop_filter_bhs_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
91                            int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
92 {
93     (void) u_ptr;
94     (void) v_ptr;
95     (void) uv_stride;
96     (void) simpler_lpf;
97     vp8_loop_filter_simple_horizontal_edge_c(y_ptr + 4 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
98     vp8_loop_filter_simple_horizontal_edge_c(y_ptr + 8 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
99     vp8_loop_filter_simple_horizontal_edge_c(y_ptr + 12 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
100 }
101 
102 /* Vertical B Filtering */
vp8_loop_filter_bv_c(unsigned char * y_ptr,unsigned char * u_ptr,unsigned char * v_ptr,int y_stride,int uv_stride,loop_filter_info * lfi,int simpler_lpf)103 void vp8_loop_filter_bv_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
104                           int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
105 {
106     (void) simpler_lpf;
107     vp8_loop_filter_vertical_edge_c(y_ptr + 4, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
108     vp8_loop_filter_vertical_edge_c(y_ptr + 8, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
109     vp8_loop_filter_vertical_edge_c(y_ptr + 12, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
110 
111     if (u_ptr)
112         vp8_loop_filter_vertical_edge_c(u_ptr + 4, uv_stride, lfi->uvflim, lfi->uvlim, lfi->uvthr, 1);
113 
114     if (v_ptr)
115         vp8_loop_filter_vertical_edge_c(v_ptr + 4, uv_stride, lfi->uvflim, lfi->uvlim, lfi->uvthr, 1);
116 }
117 
vp8_loop_filter_bvs_c(unsigned char * y_ptr,unsigned char * u_ptr,unsigned char * v_ptr,int y_stride,int uv_stride,loop_filter_info * lfi,int simpler_lpf)118 void vp8_loop_filter_bvs_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
119                            int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
120 {
121     (void) u_ptr;
122     (void) v_ptr;
123     (void) uv_stride;
124     (void) simpler_lpf;
125     vp8_loop_filter_simple_vertical_edge_c(y_ptr + 4, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
126     vp8_loop_filter_simple_vertical_edge_c(y_ptr + 8, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
127     vp8_loop_filter_simple_vertical_edge_c(y_ptr + 12, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
128 }
129 
vp8_init_loop_filter(VP8_COMMON * cm)130 void vp8_init_loop_filter(VP8_COMMON *cm)
131 {
132     loop_filter_info *lfi = cm->lf_info;
133     LOOPFILTERTYPE lft = cm->filter_type;
134     int sharpness_lvl = cm->sharpness_level;
135     int frame_type = cm->frame_type;
136     int i, j;
137 
138     int block_inside_limit = 0;
139     int HEVThresh;
140     const int yhedge_boost  = 2;
141     const int uvhedge_boost = 2;
142 
143     /* For each possible value for the loop filter fill out a "loop_filter_info" entry. */
144     for (i = 0; i <= MAX_LOOP_FILTER; i++)
145     {
146         int filt_lvl = i;
147 
148         if (frame_type == KEY_FRAME)
149         {
150             if (filt_lvl >= 40)
151                 HEVThresh = 2;
152             else if (filt_lvl >= 15)
153                 HEVThresh = 1;
154             else
155                 HEVThresh = 0;
156         }
157         else
158         {
159             if (filt_lvl >= 40)
160                 HEVThresh = 3;
161             else if (filt_lvl >= 20)
162                 HEVThresh = 2;
163             else if (filt_lvl >= 15)
164                 HEVThresh = 1;
165             else
166                 HEVThresh = 0;
167         }
168 
169         /* Set loop filter paramaeters that control sharpness. */
170         block_inside_limit = filt_lvl >> (sharpness_lvl > 0);
171         block_inside_limit = block_inside_limit >> (sharpness_lvl > 4);
172 
173         if (sharpness_lvl > 0)
174         {
175             if (block_inside_limit > (9 - sharpness_lvl))
176                 block_inside_limit = (9 - sharpness_lvl);
177         }
178 
179         if (block_inside_limit < 1)
180             block_inside_limit = 1;
181 
182         for (j = 0; j < 16; j++)
183         {
184             lfi[i].lim[j] = block_inside_limit;
185             lfi[i].mbflim[j] = filt_lvl + yhedge_boost;
186             lfi[i].mbthr[j] = HEVThresh;
187             lfi[i].flim[j] = filt_lvl;
188             lfi[i].thr[j] = HEVThresh;
189             lfi[i].uvlim[j] = block_inside_limit;
190             lfi[i].uvmbflim[j] = filt_lvl + uvhedge_boost;
191             lfi[i].uvmbthr[j] = HEVThresh;
192             lfi[i].uvflim[j] = filt_lvl;
193             lfi[i].uvthr[j] = HEVThresh;
194         }
195 
196     }
197 
198     /* Set up the function pointers depending on the type of loop filtering selected */
199     if (lft == NORMAL_LOOPFILTER)
200     {
201         cm->lf_mbv = LF_INVOKE(&cm->rtcd.loopfilter, normal_mb_v);
202         cm->lf_bv  = LF_INVOKE(&cm->rtcd.loopfilter, normal_b_v);
203         cm->lf_mbh = LF_INVOKE(&cm->rtcd.loopfilter, normal_mb_h);
204         cm->lf_bh  = LF_INVOKE(&cm->rtcd.loopfilter, normal_b_h);
205     }
206     else
207     {
208         cm->lf_mbv = LF_INVOKE(&cm->rtcd.loopfilter, simple_mb_v);
209         cm->lf_bv  = LF_INVOKE(&cm->rtcd.loopfilter, simple_b_v);
210         cm->lf_mbh = LF_INVOKE(&cm->rtcd.loopfilter, simple_mb_h);
211         cm->lf_bh  = LF_INVOKE(&cm->rtcd.loopfilter, simple_b_h);
212     }
213 }
214 
215 /* Put vp8_init_loop_filter() in vp8dx_create_decompressor(). Only call vp8_frame_init_loop_filter() while decoding
216  * each frame. Check last_frame_type to skip the function most of times.
217  */
vp8_frame_init_loop_filter(loop_filter_info * lfi,int frame_type)218 void vp8_frame_init_loop_filter(loop_filter_info *lfi, int frame_type)
219 {
220     int HEVThresh;
221     int i, j;
222 
223     /* For each possible value for the loop filter fill out a "loop_filter_info" entry. */
224     for (i = 0; i <= MAX_LOOP_FILTER; i++)
225     {
226         int filt_lvl = i;
227 
228         if (frame_type == KEY_FRAME)
229         {
230             if (filt_lvl >= 40)
231                 HEVThresh = 2;
232             else if (filt_lvl >= 15)
233                 HEVThresh = 1;
234             else
235                 HEVThresh = 0;
236         }
237         else
238         {
239             if (filt_lvl >= 40)
240                 HEVThresh = 3;
241             else if (filt_lvl >= 20)
242                 HEVThresh = 2;
243             else if (filt_lvl >= 15)
244                 HEVThresh = 1;
245             else
246                 HEVThresh = 0;
247         }
248 
249         for (j = 0; j < 16; j++)
250         {
251             /*lfi[i].lim[j] = block_inside_limit;
252             lfi[i].mbflim[j] = filt_lvl+yhedge_boost;*/
253             lfi[i].mbthr[j] = HEVThresh;
254             /*lfi[i].flim[j] = filt_lvl;*/
255             lfi[i].thr[j] = HEVThresh;
256             /*lfi[i].uvlim[j] = block_inside_limit;
257             lfi[i].uvmbflim[j] = filt_lvl+uvhedge_boost;*/
258             lfi[i].uvmbthr[j] = HEVThresh;
259             /*lfi[i].uvflim[j] = filt_lvl;*/
260             lfi[i].uvthr[j] = HEVThresh;
261         }
262     }
263 }
264 
265 
vp8_adjust_mb_lf_value(MACROBLOCKD * mbd,int * filter_level)266 void vp8_adjust_mb_lf_value(MACROBLOCKD *mbd, int *filter_level)
267 {
268     MB_MODE_INFO *mbmi = &mbd->mode_info_context->mbmi;
269 
270     if (mbd->mode_ref_lf_delta_enabled)
271     {
272         /* Apply delta for reference frame */
273         *filter_level += mbd->ref_lf_deltas[mbmi->ref_frame];
274 
275         /* Apply delta for mode */
276         if (mbmi->ref_frame == INTRA_FRAME)
277         {
278             /* Only the split mode BPRED has a further special case */
279             if (mbmi->mode == B_PRED)
280                 *filter_level +=  mbd->mode_lf_deltas[0];
281         }
282         else
283         {
284             /* Zero motion mode */
285             if (mbmi->mode == ZEROMV)
286                 *filter_level +=  mbd->mode_lf_deltas[1];
287 
288             /* Split MB motion mode */
289             else if (mbmi->mode == SPLITMV)
290                 *filter_level +=  mbd->mode_lf_deltas[3];
291 
292             /* All other inter motion modes (Nearest, Near, New) */
293             else
294                 *filter_level +=  mbd->mode_lf_deltas[2];
295         }
296 
297         /* Range check */
298         if (*filter_level > MAX_LOOP_FILTER)
299             *filter_level = MAX_LOOP_FILTER;
300         else if (*filter_level < 0)
301             *filter_level = 0;
302     }
303 }
304 
305 
vp8_loop_filter_frame(VP8_COMMON * cm,MACROBLOCKD * mbd,int default_filt_lvl)306 void vp8_loop_filter_frame
307 (
308     VP8_COMMON *cm,
309     MACROBLOCKD *mbd,
310     int default_filt_lvl
311 )
312 {
313     YV12_BUFFER_CONFIG *post = cm->frame_to_show;
314     loop_filter_info *lfi = cm->lf_info;
315     FRAME_TYPE frame_type = cm->frame_type;
316 
317     int mb_row;
318     int mb_col;
319 
320 
321     int baseline_filter_level[MAX_MB_SEGMENTS];
322     int filter_level;
323     int alt_flt_enabled = mbd->segmentation_enabled;
324 
325     int i;
326     unsigned char *y_ptr, *u_ptr, *v_ptr;
327 
328     mbd->mode_info_context = cm->mi;          /* Point at base of Mb MODE_INFO list */
329 
330     /* Note the baseline filter values for each segment */
331     if (alt_flt_enabled)
332     {
333         for (i = 0; i < MAX_MB_SEGMENTS; i++)
334         {
335             /* Abs value */
336             if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA)
337                 baseline_filter_level[i] = mbd->segment_feature_data[MB_LVL_ALT_LF][i];
338             /* Delta Value */
339             else
340             {
341                 baseline_filter_level[i] = default_filt_lvl + mbd->segment_feature_data[MB_LVL_ALT_LF][i];
342                 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 */
343             }
344         }
345     }
346     else
347     {
348         for (i = 0; i < MAX_MB_SEGMENTS; i++)
349             baseline_filter_level[i] = default_filt_lvl;
350     }
351 
352     /* Initialize the loop filter for this frame. */
353     if ((cm->last_filter_type != cm->filter_type) || (cm->last_sharpness_level != cm->sharpness_level))
354         vp8_init_loop_filter(cm);
355     else if (frame_type != cm->last_frame_type)
356         vp8_frame_init_loop_filter(lfi, frame_type);
357 
358     /* Set up the buffer pointers */
359     y_ptr = post->y_buffer;
360     u_ptr = post->u_buffer;
361     v_ptr = post->v_buffer;
362 
363     /* vp8_filter each macro block */
364     for (mb_row = 0; mb_row < cm->mb_rows; mb_row++)
365     {
366         for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
367         {
368             int Segment = (alt_flt_enabled) ? mbd->mode_info_context->mbmi.segment_id : 0;
369 
370             filter_level = baseline_filter_level[Segment];
371 
372             /* Distance of Mb to the various image edges.
373              * These specified to 8th pel as they are always compared to values that are in 1/8th pel units
374              * Apply any context driven MB level adjustment
375              */
376             vp8_adjust_mb_lf_value(mbd, &filter_level);
377 
378             if (filter_level)
379             {
380                 if (mb_col > 0)
381                     cm->lf_mbv(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level], cm->simpler_lpf);
382 
383                 if (mbd->mode_info_context->mbmi.dc_diff > 0)
384                     cm->lf_bv(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level], cm->simpler_lpf);
385 
386                 /* don't apply across umv border */
387                 if (mb_row > 0)
388                     cm->lf_mbh(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level], cm->simpler_lpf);
389 
390                 if (mbd->mode_info_context->mbmi.dc_diff > 0)
391                     cm->lf_bh(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level], cm->simpler_lpf);
392             }
393 
394             y_ptr += 16;
395             u_ptr += 8;
396             v_ptr += 8;
397 
398             mbd->mode_info_context++;     /* step to next MB */
399         }
400 
401         y_ptr += post->y_stride  * 16 - post->y_width;
402         u_ptr += post->uv_stride *  8 - post->uv_width;
403         v_ptr += post->uv_stride *  8 - post->uv_width;
404 
405         mbd->mode_info_context++;         /* Skip border mb */
406     }
407 }
408 
409 
vp8_loop_filter_frame_yonly(VP8_COMMON * cm,MACROBLOCKD * mbd,int default_filt_lvl,int sharpness_lvl)410 void vp8_loop_filter_frame_yonly
411 (
412     VP8_COMMON *cm,
413     MACROBLOCKD *mbd,
414     int default_filt_lvl,
415     int sharpness_lvl
416 )
417 {
418     YV12_BUFFER_CONFIG *post = cm->frame_to_show;
419 
420     int i;
421     unsigned char *y_ptr;
422     int mb_row;
423     int mb_col;
424 
425     loop_filter_info *lfi = cm->lf_info;
426     int baseline_filter_level[MAX_MB_SEGMENTS];
427     int filter_level;
428     int alt_flt_enabled = mbd->segmentation_enabled;
429     FRAME_TYPE frame_type = cm->frame_type;
430 
431     (void) sharpness_lvl;
432 
433     /*MODE_INFO * this_mb_mode_info = cm->mi;*/ /* Point at base of Mb MODE_INFO list */
434     mbd->mode_info_context = cm->mi;          /* Point at base of Mb MODE_INFO list */
435 
436     /* Note the baseline filter values for each segment */
437     if (alt_flt_enabled)
438     {
439         for (i = 0; i < MAX_MB_SEGMENTS; i++)
440         {
441             /* Abs value */
442             if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA)
443                 baseline_filter_level[i] = mbd->segment_feature_data[MB_LVL_ALT_LF][i];
444             /* Delta Value */
445             else
446             {
447                 baseline_filter_level[i] = default_filt_lvl + mbd->segment_feature_data[MB_LVL_ALT_LF][i];
448                 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 */
449             }
450         }
451     }
452     else
453     {
454         for (i = 0; i < MAX_MB_SEGMENTS; i++)
455             baseline_filter_level[i] = default_filt_lvl;
456     }
457 
458     /* Initialize the loop filter for this frame. */
459     if ((cm->last_filter_type != cm->filter_type) || (cm->last_sharpness_level != cm->sharpness_level))
460         vp8_init_loop_filter(cm);
461     else if (frame_type != cm->last_frame_type)
462         vp8_frame_init_loop_filter(lfi, frame_type);
463 
464     /* Set up the buffer pointers */
465     y_ptr = post->y_buffer;
466 
467     /* vp8_filter each macro block */
468     for (mb_row = 0; mb_row < cm->mb_rows; mb_row++)
469     {
470         for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
471         {
472             int Segment = (alt_flt_enabled) ? mbd->mode_info_context->mbmi.segment_id : 0;
473             filter_level = baseline_filter_level[Segment];
474 
475             /* Apply any context driven MB level adjustment */
476             vp8_adjust_mb_lf_value(mbd, &filter_level);
477 
478             if (filter_level)
479             {
480                 if (mb_col > 0)
481                     cm->lf_mbv(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
482 
483                 if (mbd->mode_info_context->mbmi.dc_diff > 0)
484                     cm->lf_bv(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
485 
486                 /* don't apply across umv border */
487                 if (mb_row > 0)
488                     cm->lf_mbh(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
489 
490                 if (mbd->mode_info_context->mbmi.dc_diff > 0)
491                     cm->lf_bh(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
492             }
493 
494             y_ptr += 16;
495             mbd->mode_info_context ++;        /* step to next MB */
496 
497         }
498 
499         y_ptr += post->y_stride  * 16 - post->y_width;
500         mbd->mode_info_context ++;            /* Skip border mb */
501     }
502 
503 }
504 
505 
vp8_loop_filter_partial_frame(VP8_COMMON * cm,MACROBLOCKD * mbd,int default_filt_lvl,int sharpness_lvl,int Fraction)506 void vp8_loop_filter_partial_frame
507 (
508     VP8_COMMON *cm,
509     MACROBLOCKD *mbd,
510     int default_filt_lvl,
511     int sharpness_lvl,
512     int Fraction
513 )
514 {
515     YV12_BUFFER_CONFIG *post = cm->frame_to_show;
516 
517     int i;
518     unsigned char *y_ptr;
519     int mb_row;
520     int mb_col;
521     /*int mb_rows = post->y_height >> 4;*/
522     int mb_cols = post->y_width  >> 4;
523 
524     int linestocopy;
525 
526     loop_filter_info *lfi = cm->lf_info;
527     int baseline_filter_level[MAX_MB_SEGMENTS];
528     int filter_level;
529     int alt_flt_enabled = mbd->segmentation_enabled;
530     FRAME_TYPE frame_type = cm->frame_type;
531 
532     (void) sharpness_lvl;
533 
534     /*MODE_INFO * this_mb_mode_info = cm->mi + (post->y_height>>5) * (mb_cols + 1);*/ /* Point at base of Mb MODE_INFO list */
535     mbd->mode_info_context = cm->mi + (post->y_height >> 5) * (mb_cols + 1);        /* Point at base of Mb MODE_INFO list */
536 
537     linestocopy = (post->y_height >> (4 + Fraction));
538 
539     if (linestocopy < 1)
540         linestocopy = 1;
541 
542     linestocopy <<= 4;
543 
544     /* Note the baseline filter values for each segment */
545     if (alt_flt_enabled)
546     {
547         for (i = 0; i < MAX_MB_SEGMENTS; i++)
548         {
549             /* Abs value */
550             if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA)
551                 baseline_filter_level[i] = mbd->segment_feature_data[MB_LVL_ALT_LF][i];
552             /* Delta Value */
553             else
554             {
555                 baseline_filter_level[i] = default_filt_lvl + mbd->segment_feature_data[MB_LVL_ALT_LF][i];
556                 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 */
557             }
558         }
559     }
560     else
561     {
562         for (i = 0; i < MAX_MB_SEGMENTS; i++)
563             baseline_filter_level[i] = default_filt_lvl;
564     }
565 
566     /* Initialize the loop filter for this frame. */
567     if ((cm->last_filter_type != cm->filter_type) || (cm->last_sharpness_level != cm->sharpness_level))
568         vp8_init_loop_filter(cm);
569     else if (frame_type != cm->last_frame_type)
570         vp8_frame_init_loop_filter(lfi, frame_type);
571 
572     /* Set up the buffer pointers */
573     y_ptr = post->y_buffer + (post->y_height >> 5) * 16 * post->y_stride;
574 
575     /* vp8_filter each macro block */
576     for (mb_row = 0; mb_row<(linestocopy >> 4); mb_row++)
577     {
578         for (mb_col = 0; mb_col < mb_cols; mb_col++)
579         {
580             int Segment = (alt_flt_enabled) ? mbd->mode_info_context->mbmi.segment_id : 0;
581             filter_level = baseline_filter_level[Segment];
582 
583             if (filter_level)
584             {
585                 if (mb_col > 0)
586                     cm->lf_mbv(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
587 
588                 if (mbd->mode_info_context->mbmi.dc_diff > 0)
589                     cm->lf_bv(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
590 
591                 cm->lf_mbh(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
592 
593                 if (mbd->mode_info_context->mbmi.dc_diff > 0)
594                     cm->lf_bh(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
595             }
596 
597             y_ptr += 16;
598             mbd->mode_info_context += 1;      /* step to next MB */
599         }
600 
601         y_ptr += post->y_stride  * 16 - post->y_width;
602         mbd->mode_info_context += 1;          /* Skip border mb */
603     }
604 }
605