FFmpeg
h264_loopfilter.c
Go to the documentation of this file.
1 /*
2  * H.26L/H.264/AVC/JVT/14496-10/... loop filter
3  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 /**
23  * @file
24  * H.264 / AVC / MPEG-4 part10 loop filter.
25  * @author Michael Niedermayer <michaelni@gmx.at>
26  */
27 
28 #include "libavutil/internal.h"
29 #include "libavutil/intreadwrite.h"
30 #include "internal.h"
31 #include "avcodec.h"
32 #include "h264dec.h"
33 #include "h264_ps.h"
34 #include "mathops.h"
35 #include "mpegutils.h"
36 #include "rectangle.h"
37 
38 /* Deblocking filter (p153) */
39 static const uint8_t alpha_table[52*3] = {
40  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
41  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
42  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
43  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
44  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
45  0, 0, 0, 0, 0, 0, 4, 4, 5, 6,
46  7, 8, 9, 10, 12, 13, 15, 17, 20, 22,
47  25, 28, 32, 36, 40, 45, 50, 56, 63, 71,
48  80, 90,101,113,127,144,162,182,203,226,
49  255,255,
50  255,255,255,255,255,255,255,255,255,255,255,255,255,
51  255,255,255,255,255,255,255,255,255,255,255,255,255,
52  255,255,255,255,255,255,255,255,255,255,255,255,255,
53  255,255,255,255,255,255,255,255,255,255,255,255,255,
54 };
55 static const uint8_t beta_table[52*3] = {
56  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
57  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
58  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
59  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
60  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
61  0, 0, 0, 0, 0, 0, 2, 2, 2, 3,
62  3, 3, 3, 4, 4, 4, 6, 6, 7, 7,
63  8, 8, 9, 9, 10, 10, 11, 11, 12, 12,
64  13, 13, 14, 14, 15, 15, 16, 16, 17, 17,
65  18, 18,
66  18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
67  18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
68  18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
69  18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
70 };
71 static const uint8_t tc0_table[52*3][4] = {
72  {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
73  {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
74  {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
75  {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
76  {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
77  {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
78  {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
79  {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
80  {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
81  {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
82  {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
83  {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 1 },
84  {-1, 0, 0, 1 }, {-1, 0, 0, 1 }, {-1, 0, 0, 1 }, {-1, 0, 1, 1 }, {-1, 0, 1, 1 }, {-1, 1, 1, 1 },
85  {-1, 1, 1, 1 }, {-1, 1, 1, 1 }, {-1, 1, 1, 1 }, {-1, 1, 1, 2 }, {-1, 1, 1, 2 }, {-1, 1, 1, 2 },
86  {-1, 1, 1, 2 }, {-1, 1, 2, 3 }, {-1, 1, 2, 3 }, {-1, 2, 2, 3 }, {-1, 2, 2, 4 }, {-1, 2, 3, 4 },
87  {-1, 2, 3, 4 }, {-1, 3, 3, 5 }, {-1, 3, 4, 6 }, {-1, 3, 4, 6 }, {-1, 4, 5, 7 }, {-1, 4, 5, 8 },
88  {-1, 4, 6, 9 }, {-1, 5, 7,10 }, {-1, 6, 8,11 }, {-1, 6, 8,13 }, {-1, 7,10,14 }, {-1, 8,11,16 },
89  {-1, 9,12,18 }, {-1,10,13,20 }, {-1,11,15,23 }, {-1,13,17,25 },
90  {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 },
91  {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 },
92  {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 },
93  {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 },
94  {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 },
95  {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 },
96  {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 },
97  {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 },
98  {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 },
99 };
100 
101 /* intra: 0 if this loopfilter call is guaranteed to be inter (bS < 4), 1 if it might be intra (bS == 4) */
103  const int16_t bS[4],
104  unsigned int qp, int a, int b,
105  const H264Context *h, int intra)
106 {
107  const unsigned int index_a = qp + a;
108  const int alpha = alpha_table[index_a];
109  const int beta = beta_table[qp + b];
110  if (alpha ==0 || beta == 0) return;
111 
112  if( bS[0] < 4 || !intra ) {
113  int8_t tc[4];
114  tc[0] = tc0_table[index_a][bS[0]];
115  tc[1] = tc0_table[index_a][bS[1]];
116  tc[2] = tc0_table[index_a][bS[2]];
117  tc[3] = tc0_table[index_a][bS[3]];
118  h->h264dsp.h264_h_loop_filter_luma(pix, stride, alpha, beta, tc);
119  } else {
120  h->h264dsp.h264_h_loop_filter_luma_intra(pix, stride, alpha, beta);
121  }
122 }
123 
125  const int16_t bS[4],
126  unsigned int qp, int a, int b,
127  const H264Context *h, int intra)
128 {
129  const unsigned int index_a = qp + a;
130  const int alpha = alpha_table[index_a];
131  const int beta = beta_table[qp + b];
132  if (alpha ==0 || beta == 0) return;
133 
134  if( bS[0] < 4 || !intra ) {
135  int8_t tc[4];
136  tc[0] = tc0_table[index_a][bS[0]]+1;
137  tc[1] = tc0_table[index_a][bS[1]]+1;
138  tc[2] = tc0_table[index_a][bS[2]]+1;
139  tc[3] = tc0_table[index_a][bS[3]]+1;
140  h->h264dsp.h264_h_loop_filter_chroma(pix, stride, alpha, beta, tc);
141  } else {
142  h->h264dsp.h264_h_loop_filter_chroma_intra(pix, stride, alpha, beta);
143  }
144 }
145 
147  int stride,
148  const int16_t bS[7], int bsi,
149  int qp, int a, int b,
150  int intra)
151 {
152  const unsigned int index_a = qp + a;
153  const int alpha = alpha_table[index_a];
154  const int beta = beta_table[qp + b];
155  if (alpha ==0 || beta == 0) return;
156 
157  if( bS[0] < 4 || !intra ) {
158  int8_t tc[4];
159  tc[0] = tc0_table[index_a][bS[0*bsi]];
160  tc[1] = tc0_table[index_a][bS[1*bsi]];
161  tc[2] = tc0_table[index_a][bS[2*bsi]];
162  tc[3] = tc0_table[index_a][bS[3*bsi]];
163  h->h264dsp.h264_h_loop_filter_luma_mbaff(pix, stride, alpha, beta, tc);
164  } else {
165  h->h264dsp.h264_h_loop_filter_luma_mbaff_intra(pix, stride, alpha, beta);
166  }
167 }
168 
170  uint8_t *pix, int stride,
171  const int16_t bS[7],
172  int bsi, int qp, int a,
173  int b, int intra)
174 {
175  const unsigned int index_a = qp + a;
176  const int alpha = alpha_table[index_a];
177  const int beta = beta_table[qp + b];
178  if (alpha ==0 || beta == 0) return;
179 
180  if( bS[0] < 4 || !intra ) {
181  int8_t tc[4];
182  tc[0] = tc0_table[index_a][bS[0*bsi]] + 1;
183  tc[1] = tc0_table[index_a][bS[1*bsi]] + 1;
184  tc[2] = tc0_table[index_a][bS[2*bsi]] + 1;
185  tc[3] = tc0_table[index_a][bS[3*bsi]] + 1;
186  h->h264dsp.h264_h_loop_filter_chroma_mbaff(pix, stride, alpha, beta, tc);
187  } else {
188  h->h264dsp.h264_h_loop_filter_chroma_mbaff_intra(pix, stride, alpha, beta);
189  }
190 }
191 
193  const int16_t bS[4],
194  unsigned int qp, int a, int b,
195  const H264Context *h, int intra)
196 {
197  const unsigned int index_a = qp + a;
198  const int alpha = alpha_table[index_a];
199  const int beta = beta_table[qp + b];
200  if (alpha ==0 || beta == 0) return;
201 
202  if( bS[0] < 4 || !intra ) {
203  int8_t tc[4];
204  tc[0] = tc0_table[index_a][bS[0]];
205  tc[1] = tc0_table[index_a][bS[1]];
206  tc[2] = tc0_table[index_a][bS[2]];
207  tc[3] = tc0_table[index_a][bS[3]];
208  h->h264dsp.h264_v_loop_filter_luma(pix, stride, alpha, beta, tc);
209  } else {
210  h->h264dsp.h264_v_loop_filter_luma_intra(pix, stride, alpha, beta);
211  }
212 }
213 
215  const int16_t bS[4],
216  unsigned int qp, int a, int b,
217  const H264Context *h, int intra)
218 {
219  const unsigned int index_a = qp + a;
220  const int alpha = alpha_table[index_a];
221  const int beta = beta_table[qp + b];
222  if (alpha ==0 || beta == 0) return;
223 
224  if( bS[0] < 4 || !intra ) {
225  int8_t tc[4];
226  tc[0] = tc0_table[index_a][bS[0]]+1;
227  tc[1] = tc0_table[index_a][bS[1]]+1;
228  tc[2] = tc0_table[index_a][bS[2]]+1;
229  tc[3] = tc0_table[index_a][bS[3]]+1;
230  h->h264dsp.h264_v_loop_filter_chroma(pix, stride, alpha, beta, tc);
231  } else {
232  h->h264dsp.h264_v_loop_filter_chroma_intra(pix, stride, alpha, beta);
233  }
234 }
235 
237  H264SliceContext *sl,
238  int mb_x, int mb_y,
239  uint8_t *img_y,
240  uint8_t *img_cb,
241  uint8_t *img_cr,
242  unsigned int linesize,
243  unsigned int uvlinesize,
244  int pixel_shift)
245 {
246  int chroma = CHROMA(h) && !(CONFIG_GRAY && (h->flags & AV_CODEC_FLAG_GRAY));
247  int chroma444 = CHROMA444(h);
248  int chroma422 = CHROMA422(h);
249 
250  int mb_xy = sl->mb_xy;
251  int left_type = sl->left_type[LTOP];
252  int top_type = sl->top_type;
253 
254  int qp_bd_offset = 6 * (h->ps.sps->bit_depth_luma - 8);
255  int a = 52 + sl->slice_alpha_c0_offset - qp_bd_offset;
256  int b = 52 + sl->slice_beta_offset - qp_bd_offset;
257 
258  int mb_type = h->cur_pic.mb_type[mb_xy];
259  int qp = h->cur_pic.qscale_table[mb_xy];
260  int qp0 = h->cur_pic.qscale_table[mb_xy - 1];
261  int qp1 = h->cur_pic.qscale_table[sl->top_mb_xy];
262  int qpc = get_chroma_qp(h->ps.pps, 0, qp);
263  int qpc0 = get_chroma_qp(h->ps.pps, 0, qp0);
264  int qpc1 = get_chroma_qp(h->ps.pps, 0, qp1);
265  qp0 = (qp + qp0 + 1) >> 1;
266  qp1 = (qp + qp1 + 1) >> 1;
267  qpc0 = (qpc + qpc0 + 1) >> 1;
268  qpc1 = (qpc + qpc1 + 1) >> 1;
269 
270  if( IS_INTRA(mb_type) ) {
271  static const int16_t bS4[4] = {4,4,4,4};
272  static const int16_t bS3[4] = {3,3,3,3};
273  const int16_t *bSH = FIELD_PICTURE(h) ? bS3 : bS4;
274  if(left_type)
275  filter_mb_edgev( &img_y[4*0<<pixel_shift], linesize, bS4, qp0, a, b, h, 1);
276  if( IS_8x8DCT(mb_type) ) {
277  filter_mb_edgev( &img_y[4*2<<pixel_shift], linesize, bS3, qp, a, b, h, 0);
278  if(top_type){
279  filter_mb_edgeh( &img_y[4*0*linesize], linesize, bSH, qp1, a, b, h, 1);
280  }
281  filter_mb_edgeh( &img_y[4*2*linesize], linesize, bS3, qp, a, b, h, 0);
282  } else {
283  filter_mb_edgev( &img_y[4*1<<pixel_shift], linesize, bS3, qp, a, b, h, 0);
284  filter_mb_edgev( &img_y[4*2<<pixel_shift], linesize, bS3, qp, a, b, h, 0);
285  filter_mb_edgev( &img_y[4*3<<pixel_shift], linesize, bS3, qp, a, b, h, 0);
286  if(top_type){
287  filter_mb_edgeh( &img_y[4*0*linesize], linesize, bSH, qp1, a, b, h, 1);
288  }
289  filter_mb_edgeh( &img_y[4*1*linesize], linesize, bS3, qp, a, b, h, 0);
290  filter_mb_edgeh( &img_y[4*2*linesize], linesize, bS3, qp, a, b, h, 0);
291  filter_mb_edgeh( &img_y[4*3*linesize], linesize, bS3, qp, a, b, h, 0);
292  }
293  if(chroma){
294  if(chroma444){
295  if(left_type){
296  filter_mb_edgev( &img_cb[4*0<<pixel_shift], linesize, bS4, qpc0, a, b, h, 1);
297  filter_mb_edgev( &img_cr[4*0<<pixel_shift], linesize, bS4, qpc0, a, b, h, 1);
298  }
299  if( IS_8x8DCT(mb_type) ) {
300  filter_mb_edgev( &img_cb[4*2<<pixel_shift], linesize, bS3, qpc, a, b, h, 0);
301  filter_mb_edgev( &img_cr[4*2<<pixel_shift], linesize, bS3, qpc, a, b, h, 0);
302  if(top_type){
303  filter_mb_edgeh( &img_cb[4*0*linesize], linesize, bSH, qpc1, a, b, h, 1 );
304  filter_mb_edgeh( &img_cr[4*0*linesize], linesize, bSH, qpc1, a, b, h, 1 );
305  }
306  filter_mb_edgeh( &img_cb[4*2*linesize], linesize, bS3, qpc, a, b, h, 0);
307  filter_mb_edgeh( &img_cr[4*2*linesize], linesize, bS3, qpc, a, b, h, 0);
308  } else {
309  filter_mb_edgev( &img_cb[4*1<<pixel_shift], linesize, bS3, qpc, a, b, h, 0);
310  filter_mb_edgev( &img_cr[4*1<<pixel_shift], linesize, bS3, qpc, a, b, h, 0);
311  filter_mb_edgev( &img_cb[4*2<<pixel_shift], linesize, bS3, qpc, a, b, h, 0);
312  filter_mb_edgev( &img_cr[4*2<<pixel_shift], linesize, bS3, qpc, a, b, h, 0);
313  filter_mb_edgev( &img_cb[4*3<<pixel_shift], linesize, bS3, qpc, a, b, h, 0);
314  filter_mb_edgev( &img_cr[4*3<<pixel_shift], linesize, bS3, qpc, a, b, h, 0);
315  if(top_type){
316  filter_mb_edgeh( &img_cb[4*0*linesize], linesize, bSH, qpc1, a, b, h, 1);
317  filter_mb_edgeh( &img_cr[4*0*linesize], linesize, bSH, qpc1, a, b, h, 1);
318  }
319  filter_mb_edgeh( &img_cb[4*1*linesize], linesize, bS3, qpc, a, b, h, 0);
320  filter_mb_edgeh( &img_cr[4*1*linesize], linesize, bS3, qpc, a, b, h, 0);
321  filter_mb_edgeh( &img_cb[4*2*linesize], linesize, bS3, qpc, a, b, h, 0);
322  filter_mb_edgeh( &img_cr[4*2*linesize], linesize, bS3, qpc, a, b, h, 0);
323  filter_mb_edgeh( &img_cb[4*3*linesize], linesize, bS3, qpc, a, b, h, 0);
324  filter_mb_edgeh( &img_cr[4*3*linesize], linesize, bS3, qpc, a, b, h, 0);
325  }
326  }else if(chroma422){
327  if(left_type){
328  filter_mb_edgecv(&img_cb[2*0<<pixel_shift], uvlinesize, bS4, qpc0, a, b, h, 1);
329  filter_mb_edgecv(&img_cr[2*0<<pixel_shift], uvlinesize, bS4, qpc0, a, b, h, 1);
330  }
331  filter_mb_edgecv(&img_cb[2*2<<pixel_shift], uvlinesize, bS3, qpc, a, b, h, 0);
332  filter_mb_edgecv(&img_cr[2*2<<pixel_shift], uvlinesize, bS3, qpc, a, b, h, 0);
333  if(top_type){
334  filter_mb_edgech(&img_cb[4*0*uvlinesize], uvlinesize, bSH, qpc1, a, b, h, 1);
335  filter_mb_edgech(&img_cr[4*0*uvlinesize], uvlinesize, bSH, qpc1, a, b, h, 1);
336  }
337  filter_mb_edgech(&img_cb[4*1*uvlinesize], uvlinesize, bS3, qpc, a, b, h, 0);
338  filter_mb_edgech(&img_cr[4*1*uvlinesize], uvlinesize, bS3, qpc, a, b, h, 0);
339  filter_mb_edgech(&img_cb[4*2*uvlinesize], uvlinesize, bS3, qpc, a, b, h, 0);
340  filter_mb_edgech(&img_cr[4*2*uvlinesize], uvlinesize, bS3, qpc, a, b, h, 0);
341  filter_mb_edgech(&img_cb[4*3*uvlinesize], uvlinesize, bS3, qpc, a, b, h, 0);
342  filter_mb_edgech(&img_cr[4*3*uvlinesize], uvlinesize, bS3, qpc, a, b, h, 0);
343  }else{
344  if(left_type){
345  filter_mb_edgecv( &img_cb[2*0<<pixel_shift], uvlinesize, bS4, qpc0, a, b, h, 1);
346  filter_mb_edgecv( &img_cr[2*0<<pixel_shift], uvlinesize, bS4, qpc0, a, b, h, 1);
347  }
348  filter_mb_edgecv( &img_cb[2*2<<pixel_shift], uvlinesize, bS3, qpc, a, b, h, 0);
349  filter_mb_edgecv( &img_cr[2*2<<pixel_shift], uvlinesize, bS3, qpc, a, b, h, 0);
350  if(top_type){
351  filter_mb_edgech( &img_cb[2*0*uvlinesize], uvlinesize, bSH, qpc1, a, b, h, 1);
352  filter_mb_edgech( &img_cr[2*0*uvlinesize], uvlinesize, bSH, qpc1, a, b, h, 1);
353  }
354  filter_mb_edgech( &img_cb[2*2*uvlinesize], uvlinesize, bS3, qpc, a, b, h, 0);
355  filter_mb_edgech( &img_cr[2*2*uvlinesize], uvlinesize, bS3, qpc, a, b, h, 0);
356  }
357  }
358  return;
359  } else {
360  LOCAL_ALIGNED(8, int16_t, bS, [2], [4][4]);
361  int edges;
362  if( IS_8x8DCT(mb_type) && (sl->cbp&7) == 7 && !chroma444 ) {
363  edges = 4;
364  AV_WN64A(bS[0][0], 0x0002000200020002ULL);
365  AV_WN64A(bS[0][2], 0x0002000200020002ULL);
366  AV_WN64A(bS[1][0], 0x0002000200020002ULL);
367  AV_WN64A(bS[1][2], 0x0002000200020002ULL);
368  } else {
369  int mask_edge1 = (3*(((5*mb_type)>>5)&1)) | (mb_type>>4); //(mb_type & (MB_TYPE_16x16 | MB_TYPE_8x16)) ? 3 : (mb_type & MB_TYPE_16x8) ? 1 : 0;
370  int mask_edge0 = 3*((mask_edge1>>1) & ((5*left_type)>>5)&1); // (mb_type & (MB_TYPE_16x16 | MB_TYPE_8x16)) && (h->left_type[LTOP] & (MB_TYPE_16x16 | MB_TYPE_8x16)) ? 3 : 0;
371  int step = 1+(mb_type>>24); //IS_8x8DCT(mb_type) ? 2 : 1;
372  edges = 4 - 3*((mb_type>>3) & !(sl->cbp & 15)); //(mb_type & MB_TYPE_16x16) && !(h->cbp & 15) ? 1 : 4;
373  h->h264dsp.h264_loop_filter_strength(bS, sl->non_zero_count_cache, sl->ref_cache, sl->mv_cache,
374  sl->list_count==2, edges, step, mask_edge0, mask_edge1, FIELD_PICTURE(h));
375  }
376  if( IS_INTRA(left_type) )
377  AV_WN64A(bS[0][0], 0x0004000400040004ULL);
378  if( IS_INTRA(top_type) )
379  AV_WN64A(bS[1][0], FIELD_PICTURE(h) ? 0x0003000300030003ULL : 0x0004000400040004ULL);
380 
381 #define FILTER(hv,dir,edge,intra)\
382  if(AV_RN64A(bS[dir][edge])) { \
383  filter_mb_edge##hv( &img_y[4*edge*(dir?linesize:1<<pixel_shift)], linesize, bS[dir][edge], edge ? qp : qp##dir, a, b, h, intra );\
384  if(chroma){\
385  if(chroma444){\
386  filter_mb_edge##hv( &img_cb[4*edge*(dir?linesize:1<<pixel_shift)], linesize, bS[dir][edge], edge ? qpc : qpc##dir, a, b, h, intra );\
387  filter_mb_edge##hv( &img_cr[4*edge*(dir?linesize:1<<pixel_shift)], linesize, bS[dir][edge], edge ? qpc : qpc##dir, a, b, h, intra );\
388  } else if(!(edge&1)) {\
389  filter_mb_edgec##hv( &img_cb[2*edge*(dir?uvlinesize:1<<pixel_shift)], uvlinesize, bS[dir][edge], edge ? qpc : qpc##dir, a, b, h, intra );\
390  filter_mb_edgec##hv( &img_cr[2*edge*(dir?uvlinesize:1<<pixel_shift)], uvlinesize, bS[dir][edge], edge ? qpc : qpc##dir, a, b, h, intra );\
391  }\
392  }\
393  }
394  if(left_type)
395  FILTER(v,0,0,1);
396  if( edges == 1 ) {
397  if(top_type)
398  FILTER(h,1,0,1);
399  } else if( IS_8x8DCT(mb_type) ) {
400  FILTER(v,0,2,0);
401  if(top_type)
402  FILTER(h,1,0,1);
403  FILTER(h,1,2,0);
404  } else {
405  FILTER(v,0,1,0);
406  FILTER(v,0,2,0);
407  FILTER(v,0,3,0);
408  if(top_type)
409  FILTER(h,1,0,1);
410  FILTER(h,1,1,0);
411  FILTER(h,1,2,0);
412  FILTER(h,1,3,0);
413  }
414 #undef FILTER
415  }
416 }
417 
419  int mb_x, int mb_y, uint8_t *img_y,
420  uint8_t *img_cb, uint8_t *img_cr,
421  unsigned int linesize, unsigned int uvlinesize)
422 {
424  if(!h->h264dsp.h264_loop_filter_strength || h->ps.pps->chroma_qp_diff) {
425  ff_h264_filter_mb(h, sl, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize);
426  return;
427  }
428 
429 #if CONFIG_SMALL
430  h264_filter_mb_fast_internal(h, sl, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, h->pixel_shift);
431 #else
432  if(h->pixel_shift){
433  h264_filter_mb_fast_internal(h, sl, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, 1);
434  }else{
435  h264_filter_mb_fast_internal(h, sl, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, 0);
436  }
437 #endif
438 }
439 
440 static int check_mv(H264SliceContext *sl, long b_idx, long bn_idx, int mvy_limit)
441 {
442  int v;
443 
444  v = sl->ref_cache[0][b_idx] != sl->ref_cache[0][bn_idx];
445  if (!v && sl->ref_cache[0][b_idx] != -1)
446  v = sl->mv_cache[0][b_idx][0] - sl->mv_cache[0][bn_idx][0] + 3 >= 7U |
447  FFABS(sl->mv_cache[0][b_idx][1] - sl->mv_cache[0][bn_idx][1]) >= mvy_limit;
448 
449  if (sl->list_count == 2) {
450  if(!v)
451  v = sl->ref_cache[1][b_idx] != sl->ref_cache[1][bn_idx] |
452  sl->mv_cache[1][b_idx][0] - sl->mv_cache[1][bn_idx][0] + 3 >= 7U |
453  FFABS(sl->mv_cache[1][b_idx][1] - sl->mv_cache[1][bn_idx][1]) >= mvy_limit;
454 
455  if(v){
456  if (sl->ref_cache[0][b_idx] != sl->ref_cache[1][bn_idx] |
457  sl->ref_cache[1][b_idx] != sl->ref_cache[0][bn_idx])
458  return 1;
459  return
460  sl->mv_cache[0][b_idx][0] - sl->mv_cache[1][bn_idx][0] + 3 >= 7U |
461  FFABS(sl->mv_cache[0][b_idx][1] - sl->mv_cache[1][bn_idx][1]) >= mvy_limit |
462  sl->mv_cache[1][b_idx][0] - sl->mv_cache[0][bn_idx][0] + 3 >= 7U |
463  FFABS(sl->mv_cache[1][b_idx][1] - sl->mv_cache[0][bn_idx][1]) >= mvy_limit;
464  }
465  }
466 
467  return v;
468 }
469 
471  int mb_x, int mb_y,
472  uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr,
473  unsigned int linesize, unsigned int uvlinesize,
474  int mb_xy, int mb_type, int mvy_limit,
475  int first_vertical_edge_done, int a, int b,
476  int chroma, int dir)
477 {
478  int edge;
479  int chroma_qp_avg[2];
480  int chroma444 = CHROMA444(h);
481  int chroma422 = CHROMA422(h);
482  const int mbm_xy = dir == 0 ? mb_xy -1 : sl->top_mb_xy;
483  const int mbm_type = dir == 0 ? sl->left_type[LTOP] : sl->top_type;
484 
485  // how often to recheck mv-based bS when iterating between edges
486  static const uint8_t mask_edge_tab[2][8]={{0,3,3,3,1,1,1,1},
487  {0,3,1,1,3,3,3,3}};
488  const int mask_edge = mask_edge_tab[dir][(mb_type>>3)&7];
489  const int edges = mask_edge== 3 && !(sl->cbp&15) ? 1 : 4;
490 
491  // how often to recheck mv-based bS when iterating along each edge
492  const int mask_par0 = mb_type & (MB_TYPE_16x16 | (MB_TYPE_8x16 >> dir));
493 
494  if(mbm_type && !first_vertical_edge_done){
495 
496  if (FRAME_MBAFF(h) && (dir == 1) && ((mb_y&1) == 0)
497  && IS_INTERLACED(mbm_type&~mb_type)
498  ) {
499  // This is a special case in the norm where the filtering must
500  // be done twice (one each of the field) even if we are in a
501  // frame macroblock.
502  //
503  unsigned int tmp_linesize = 2 * linesize;
504  unsigned int tmp_uvlinesize = 2 * uvlinesize;
505  int mbn_xy = mb_xy - 2 * h->mb_stride;
506  int j;
507 
508  for(j=0; j<2; j++, mbn_xy += h->mb_stride){
509  LOCAL_ALIGNED(8, int16_t, bS, [4]);
510  int qp;
511  if (IS_INTRA(mb_type | h->cur_pic.mb_type[mbn_xy])) {
512  AV_WN64A(bS, 0x0003000300030003ULL);
513  } else {
514  if (!CABAC(h) && IS_8x8DCT(h->cur_pic.mb_type[mbn_xy])) {
515  bS[0]= 1+((h->cbp_table[mbn_xy] & 0x4000) || sl->non_zero_count_cache[scan8[0]+0]);
516  bS[1]= 1+((h->cbp_table[mbn_xy] & 0x4000) || sl->non_zero_count_cache[scan8[0]+1]);
517  bS[2]= 1+((h->cbp_table[mbn_xy] & 0x8000) || sl->non_zero_count_cache[scan8[0]+2]);
518  bS[3]= 1+((h->cbp_table[mbn_xy] & 0x8000) || sl->non_zero_count_cache[scan8[0]+3]);
519  }else{
520  const uint8_t *mbn_nnz = h->non_zero_count[mbn_xy] + 3*4;
521  int i;
522  for( i = 0; i < 4; i++ ) {
523  bS[i] = 1 + !!(sl->non_zero_count_cache[scan8[0]+i] | mbn_nnz[i]);
524  }
525  }
526  }
527  // Do not use s->qscale as luma quantizer because it has not the same
528  // value in IPCM macroblocks.
529  qp = (h->cur_pic.qscale_table[mb_xy] + h->cur_pic.qscale_table[mbn_xy] + 1) >> 1;
530  ff_tlog(h->avctx, "filter mb:%d/%d dir:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, qp, tmp_linesize, tmp_uvlinesize);
531  { int i; for (i = 0; i < 4; i++) ff_tlog(h->avctx, " bS[%d]:%d", i, bS[i]); ff_tlog(h->avctx, "\n"); }
532  filter_mb_edgeh( &img_y[j*linesize], tmp_linesize, bS, qp, a, b, h, 0 );
533  chroma_qp_avg[0] = (sl->chroma_qp[0] + get_chroma_qp(h->ps.pps, 0, h->cur_pic.qscale_table[mbn_xy]) + 1) >> 1;
534  chroma_qp_avg[1] = (sl->chroma_qp[1] + get_chroma_qp(h->ps.pps, 1, h->cur_pic.qscale_table[mbn_xy]) + 1) >> 1;
535  if (chroma) {
536  if (chroma444) {
537  filter_mb_edgeh (&img_cb[j*uvlinesize], tmp_uvlinesize, bS, chroma_qp_avg[0], a, b, h, 0);
538  filter_mb_edgeh (&img_cr[j*uvlinesize], tmp_uvlinesize, bS, chroma_qp_avg[1], a, b, h, 0);
539  } else {
540  filter_mb_edgech(&img_cb[j*uvlinesize], tmp_uvlinesize, bS, chroma_qp_avg[0], a, b, h, 0);
541  filter_mb_edgech(&img_cr[j*uvlinesize], tmp_uvlinesize, bS, chroma_qp_avg[1], a, b, h, 0);
542  }
543  }
544  }
545  }else{
546  LOCAL_ALIGNED(8, int16_t, bS, [4]);
547  int qp;
548 
549  if( IS_INTRA(mb_type|mbm_type)) {
550  AV_WN64A(bS, 0x0003000300030003ULL);
551  if ( (!IS_INTERLACED(mb_type|mbm_type))
552  || ((FRAME_MBAFF(h) || (h->picture_structure != PICT_FRAME)) && (dir == 0))
553  )
554  AV_WN64A(bS, 0x0004000400040004ULL);
555  } else {
556  int i;
557  int mv_done;
558 
559  if( dir && FRAME_MBAFF(h) && IS_INTERLACED(mb_type ^ mbm_type)) {
560  AV_WN64A(bS, 0x0001000100010001ULL);
561  mv_done = 1;
562  }
563  else if( mask_par0 && ((mbm_type & (MB_TYPE_16x16 | (MB_TYPE_8x16 >> dir)))) ) {
564  int b_idx= 8 + 4;
565  int bn_idx= b_idx - (dir ? 8:1);
566 
567  bS[0] = bS[1] = bS[2] = bS[3] = check_mv(sl, 8 + 4, bn_idx, mvy_limit);
568  mv_done = 1;
569  }
570  else
571  mv_done = 0;
572 
573  for( i = 0; i < 4; i++ ) {
574  int x = dir == 0 ? 0 : i;
575  int y = dir == 0 ? i : 0;
576  int b_idx= 8 + 4 + x + 8*y;
577  int bn_idx= b_idx - (dir ? 8:1);
578 
579  if (sl->non_zero_count_cache[b_idx] |
580  sl->non_zero_count_cache[bn_idx]) {
581  bS[i] = 2;
582  }
583  else if(!mv_done)
584  {
585  bS[i] = check_mv(sl, b_idx, bn_idx, mvy_limit);
586  }
587  }
588  }
589 
590  /* Filter edge */
591  // Do not use s->qscale as luma quantizer because it has not the same
592  // value in IPCM macroblocks.
593  if(bS[0]+bS[1]+bS[2]+bS[3]){
594  qp = (h->cur_pic.qscale_table[mb_xy] + h->cur_pic.qscale_table[mbm_xy] + 1) >> 1;
595  //ff_tlog(h->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d, QPc:%d, QPcn:%d\n", mb_x, mb_y, dir, edge, qp, h->chroma_qp[0], h->cur_pic.qscale_table[mbn_xy]);
596  ff_tlog(h->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, linesize, uvlinesize);
597  //{ int i; for (i = 0; i < 4; i++) ff_tlog(h->avctx, " bS[%d]:%d", i, bS[i]); ff_tlog(h->avctx, "\n"); }
598  chroma_qp_avg[0] = (sl->chroma_qp[0] + get_chroma_qp(h->ps.pps, 0, h->cur_pic.qscale_table[mbm_xy]) + 1) >> 1;
599  chroma_qp_avg[1] = (sl->chroma_qp[1] + get_chroma_qp(h->ps.pps, 1, h->cur_pic.qscale_table[mbm_xy]) + 1) >> 1;
600  if( dir == 0 ) {
601  filter_mb_edgev( &img_y[0], linesize, bS, qp, a, b, h, 1 );
602  if (chroma) {
603  if (chroma444) {
604  filter_mb_edgev ( &img_cb[0], uvlinesize, bS, chroma_qp_avg[0], a, b, h, 1);
605  filter_mb_edgev ( &img_cr[0], uvlinesize, bS, chroma_qp_avg[1], a, b, h, 1);
606  } else {
607  filter_mb_edgecv( &img_cb[0], uvlinesize, bS, chroma_qp_avg[0], a, b, h, 1);
608  filter_mb_edgecv( &img_cr[0], uvlinesize, bS, chroma_qp_avg[1], a, b, h, 1);
609  }
610  }
611  } else {
612  filter_mb_edgeh( &img_y[0], linesize, bS, qp, a, b, h, 1 );
613  if (chroma) {
614  if (chroma444) {
615  filter_mb_edgeh ( &img_cb[0], uvlinesize, bS, chroma_qp_avg[0], a, b, h, 1);
616  filter_mb_edgeh ( &img_cr[0], uvlinesize, bS, chroma_qp_avg[1], a, b, h, 1);
617  } else {
618  filter_mb_edgech( &img_cb[0], uvlinesize, bS, chroma_qp_avg[0], a, b, h, 1);
619  filter_mb_edgech( &img_cr[0], uvlinesize, bS, chroma_qp_avg[1], a, b, h, 1);
620  }
621  }
622  }
623  }
624  }
625  }
626 
627  /* Calculate bS */
628  for( edge = 1; edge < edges; edge++ ) {
629  LOCAL_ALIGNED(8, int16_t, bS, [4]);
630  int qp;
631  const int deblock_edge = !IS_8x8DCT(mb_type & (edge<<24)); // (edge&1) && IS_8x8DCT(mb_type)
632 
633  if (!deblock_edge && (!chroma422 || dir == 0))
634  continue;
635 
636  if( IS_INTRA(mb_type)) {
637  AV_WN64A(bS, 0x0003000300030003ULL);
638  } else {
639  int i;
640  int mv_done;
641 
642  if( edge & mask_edge ) {
643  AV_ZERO64(bS);
644  mv_done = 1;
645  }
646  else if( mask_par0 ) {
647  int b_idx= 8 + 4 + edge * (dir ? 8:1);
648  int bn_idx= b_idx - (dir ? 8:1);
649 
650  bS[0] = bS[1] = bS[2] = bS[3] = check_mv(sl, b_idx, bn_idx, mvy_limit);
651  mv_done = 1;
652  }
653  else
654  mv_done = 0;
655 
656  for( i = 0; i < 4; i++ ) {
657  int x = dir == 0 ? edge : i;
658  int y = dir == 0 ? i : edge;
659  int b_idx= 8 + 4 + x + 8*y;
660  int bn_idx= b_idx - (dir ? 8:1);
661 
662  if (sl->non_zero_count_cache[b_idx] |
663  sl->non_zero_count_cache[bn_idx]) {
664  bS[i] = 2;
665  }
666  else if(!mv_done)
667  {
668  bS[i] = check_mv(sl, b_idx, bn_idx, mvy_limit);
669  }
670  }
671 
672  if(bS[0]+bS[1]+bS[2]+bS[3] == 0)
673  continue;
674  }
675 
676  /* Filter edge */
677  // Do not use s->qscale as luma quantizer because it has not the same
678  // value in IPCM macroblocks.
679  qp = h->cur_pic.qscale_table[mb_xy];
680  //ff_tlog(h->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d, QPc:%d, QPcn:%d\n", mb_x, mb_y, dir, edge, qp, h->chroma_qp[0], h->cur_pic.qscale_table[mbn_xy]);
681  ff_tlog(h->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, linesize, uvlinesize);
682  //{ int i; for (i = 0; i < 4; i++) ff_tlog(h->avctx, " bS[%d]:%d", i, bS[i]); ff_tlog(h->avctx, "\n"); }
683  if( dir == 0 ) {
684  filter_mb_edgev( &img_y[4*edge << h->pixel_shift], linesize, bS, qp, a, b, h, 0 );
685  if (chroma) {
686  if (chroma444) {
687  filter_mb_edgev ( &img_cb[4*edge << h->pixel_shift], uvlinesize, bS, sl->chroma_qp[0], a, b, h, 0);
688  filter_mb_edgev ( &img_cr[4*edge << h->pixel_shift], uvlinesize, bS, sl->chroma_qp[1], a, b, h, 0);
689  } else if( (edge&1) == 0 ) {
690  filter_mb_edgecv( &img_cb[2*edge << h->pixel_shift], uvlinesize, bS, sl->chroma_qp[0], a, b, h, 0);
691  filter_mb_edgecv( &img_cr[2*edge << h->pixel_shift], uvlinesize, bS, sl->chroma_qp[1], a, b, h, 0);
692  }
693  }
694  } else {
695  if (chroma422) {
696  if (deblock_edge)
697  filter_mb_edgeh(&img_y[4*edge*linesize], linesize, bS, qp, a, b, h, 0);
698  if (chroma) {
699  filter_mb_edgech(&img_cb[4*edge*uvlinesize], uvlinesize, bS, sl->chroma_qp[0], a, b, h, 0);
700  filter_mb_edgech(&img_cr[4*edge*uvlinesize], uvlinesize, bS, sl->chroma_qp[1], a, b, h, 0);
701  }
702  } else {
703  filter_mb_edgeh(&img_y[4*edge*linesize], linesize, bS, qp, a, b, h, 0);
704  if (chroma) {
705  if (chroma444) {
706  filter_mb_edgeh (&img_cb[4*edge*uvlinesize], uvlinesize, bS, sl->chroma_qp[0], a, b, h, 0);
707  filter_mb_edgeh (&img_cr[4*edge*uvlinesize], uvlinesize, bS, sl->chroma_qp[1], a, b, h, 0);
708  } else if ((edge&1) == 0) {
709  filter_mb_edgech(&img_cb[2*edge*uvlinesize], uvlinesize, bS, sl->chroma_qp[0], a, b, h, 0);
710  filter_mb_edgech(&img_cr[2*edge*uvlinesize], uvlinesize, bS, sl->chroma_qp[1], a, b, h, 0);
711  }
712  }
713  }
714  }
715  }
716 }
717 
719  int mb_x, int mb_y,
720  uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr,
721  unsigned int linesize, unsigned int uvlinesize)
722 {
723  const int mb_xy= mb_x + mb_y*h->mb_stride;
724  const int mb_type = h->cur_pic.mb_type[mb_xy];
725  const int mvy_limit = IS_INTERLACED(mb_type) ? 2 : 4;
726  int first_vertical_edge_done = 0;
727  int chroma = CHROMA(h) && !(CONFIG_GRAY && (h->flags & AV_CODEC_FLAG_GRAY));
728  int qp_bd_offset = 6 * (h->ps.sps->bit_depth_luma - 8);
729  int a = 52 + sl->slice_alpha_c0_offset - qp_bd_offset;
730  int b = 52 + sl->slice_beta_offset - qp_bd_offset;
731 
732  if (FRAME_MBAFF(h)
733  // and current and left pair do not have the same interlaced type
734  && IS_INTERLACED(mb_type ^ sl->left_type[LTOP])
735  // and left mb is in available to us
736  && sl->left_type[LTOP]) {
737  /* First vertical edge is different in MBAFF frames
738  * There are 8 different bS to compute and 2 different Qp
739  */
740  LOCAL_ALIGNED(8, int16_t, bS, [8]);
741  int qp[2];
742  int bqp[2];
743  int rqp[2];
744  int mb_qp, mbn0_qp, mbn1_qp;
745  int i;
746  first_vertical_edge_done = 1;
747 
748  if( IS_INTRA(mb_type) ) {
749  AV_WN64A(&bS[0], 0x0004000400040004ULL);
750  AV_WN64A(&bS[4], 0x0004000400040004ULL);
751  } else {
752  static const uint8_t offset[2][2][8]={
753  {
754  {3+4*0, 3+4*0, 3+4*0, 3+4*0, 3+4*1, 3+4*1, 3+4*1, 3+4*1},
755  {3+4*2, 3+4*2, 3+4*2, 3+4*2, 3+4*3, 3+4*3, 3+4*3, 3+4*3},
756  },{
757  {3+4*0, 3+4*1, 3+4*2, 3+4*3, 3+4*0, 3+4*1, 3+4*2, 3+4*3},
758  {3+4*0, 3+4*1, 3+4*2, 3+4*3, 3+4*0, 3+4*1, 3+4*2, 3+4*3},
759  }
760  };
761  const uint8_t *off= offset[MB_FIELD(sl)][mb_y&1];
762  for( i = 0; i < 8; i++ ) {
763  int j= MB_FIELD(sl) ? i>>2 : i&1;
764  int mbn_xy = sl->left_mb_xy[LEFT(j)];
765  int mbn_type = sl->left_type[LEFT(j)];
766 
767  if( IS_INTRA( mbn_type ) )
768  bS[i] = 4;
769  else{
770  bS[i] = 1 + !!(sl->non_zero_count_cache[12+8*(i>>1)] |
771  ((!h->ps.pps->cabac && IS_8x8DCT(mbn_type)) ?
772  (h->cbp_table[mbn_xy] & (((MB_FIELD(sl) ? (i&2) : (mb_y&1)) ? 8 : 2) << 12))
773  :
774  h->non_zero_count[mbn_xy][ off[i] ]));
775  }
776  }
777  }
778 
779  mb_qp = h->cur_pic.qscale_table[mb_xy];
780  mbn0_qp = h->cur_pic.qscale_table[sl->left_mb_xy[0]];
781  mbn1_qp = h->cur_pic.qscale_table[sl->left_mb_xy[1]];
782  qp[0] = ( mb_qp + mbn0_qp + 1 ) >> 1;
783  bqp[0] = (get_chroma_qp(h->ps.pps, 0, mb_qp) +
784  get_chroma_qp(h->ps.pps, 0, mbn0_qp) + 1) >> 1;
785  rqp[0] = (get_chroma_qp(h->ps.pps, 1, mb_qp) +
786  get_chroma_qp(h->ps.pps, 1, mbn0_qp) + 1) >> 1;
787  qp[1] = ( mb_qp + mbn1_qp + 1 ) >> 1;
788  bqp[1] = (get_chroma_qp(h->ps.pps, 0, mb_qp) +
789  get_chroma_qp(h->ps.pps, 0, mbn1_qp) + 1 ) >> 1;
790  rqp[1] = (get_chroma_qp(h->ps.pps, 1, mb_qp) +
791  get_chroma_qp(h->ps.pps, 1, mbn1_qp) + 1 ) >> 1;
792 
793  /* Filter edge */
794  ff_tlog(h->avctx, "filter mb:%d/%d MBAFF, QPy:%d/%d, QPb:%d/%d QPr:%d/%d ls:%d uvls:%d", mb_x, mb_y, qp[0], qp[1], bqp[0], bqp[1], rqp[0], rqp[1], linesize, uvlinesize);
795  { int i; for (i = 0; i < 8; i++) ff_tlog(h->avctx, " bS[%d]:%d", i, bS[i]); ff_tlog(h->avctx, "\n"); }
796  if (MB_FIELD(sl)) {
797  filter_mb_mbaff_edgev ( h, img_y , linesize, bS , 1, qp [0], a, b, 1 );
798  filter_mb_mbaff_edgev ( h, img_y + 8* linesize, linesize, bS+4, 1, qp [1], a, b, 1 );
799  if (chroma){
800  if (CHROMA444(h)) {
801  filter_mb_mbaff_edgev ( h, img_cb, uvlinesize, bS , 1, bqp[0], a, b, 1 );
802  filter_mb_mbaff_edgev ( h, img_cb + 8*uvlinesize, uvlinesize, bS+4, 1, bqp[1], a, b, 1 );
803  filter_mb_mbaff_edgev ( h, img_cr, uvlinesize, bS , 1, rqp[0], a, b, 1 );
804  filter_mb_mbaff_edgev ( h, img_cr + 8*uvlinesize, uvlinesize, bS+4, 1, rqp[1], a, b, 1 );
805  } else if (CHROMA422(h)) {
806  filter_mb_mbaff_edgecv(h, img_cb, uvlinesize, bS , 1, bqp[0], a, b, 1);
807  filter_mb_mbaff_edgecv(h, img_cb + 8*uvlinesize, uvlinesize, bS+4, 1, bqp[1], a, b, 1);
808  filter_mb_mbaff_edgecv(h, img_cr, uvlinesize, bS , 1, rqp[0], a, b, 1);
809  filter_mb_mbaff_edgecv(h, img_cr + 8*uvlinesize, uvlinesize, bS+4, 1, rqp[1], a, b, 1);
810  }else{
811  filter_mb_mbaff_edgecv( h, img_cb, uvlinesize, bS , 1, bqp[0], a, b, 1 );
812  filter_mb_mbaff_edgecv( h, img_cb + 4*uvlinesize, uvlinesize, bS+4, 1, bqp[1], a, b, 1 );
813  filter_mb_mbaff_edgecv( h, img_cr, uvlinesize, bS , 1, rqp[0], a, b, 1 );
814  filter_mb_mbaff_edgecv( h, img_cr + 4*uvlinesize, uvlinesize, bS+4, 1, rqp[1], a, b, 1 );
815  }
816  }
817  }else{
818  filter_mb_mbaff_edgev ( h, img_y , 2* linesize, bS , 2, qp [0], a, b, 1 );
819  filter_mb_mbaff_edgev ( h, img_y + linesize, 2* linesize, bS+1, 2, qp [1], a, b, 1 );
820  if (chroma){
821  if (CHROMA444(h)) {
822  filter_mb_mbaff_edgev ( h, img_cb, 2*uvlinesize, bS , 2, bqp[0], a, b, 1 );
823  filter_mb_mbaff_edgev ( h, img_cb + uvlinesize, 2*uvlinesize, bS+1, 2, bqp[1], a, b, 1 );
824  filter_mb_mbaff_edgev ( h, img_cr, 2*uvlinesize, bS , 2, rqp[0], a, b, 1 );
825  filter_mb_mbaff_edgev ( h, img_cr + uvlinesize, 2*uvlinesize, bS+1, 2, rqp[1], a, b, 1 );
826  }else{
827  filter_mb_mbaff_edgecv( h, img_cb, 2*uvlinesize, bS , 2, bqp[0], a, b, 1 );
828  filter_mb_mbaff_edgecv( h, img_cb + uvlinesize, 2*uvlinesize, bS+1, 2, bqp[1], a, b, 1 );
829  filter_mb_mbaff_edgecv( h, img_cr, 2*uvlinesize, bS , 2, rqp[0], a, b, 1 );
830  filter_mb_mbaff_edgecv( h, img_cr + uvlinesize, 2*uvlinesize, bS+1, 2, rqp[1], a, b, 1 );
831  }
832  }
833  }
834  }
835 
836 #if CONFIG_SMALL
837  {
838  int dir;
839  for (dir = 0; dir < 2; dir++)
840  filter_mb_dir(h, sl, mb_x, mb_y, img_y, img_cb, img_cr, linesize,
841  uvlinesize, mb_xy, mb_type, mvy_limit,
842  dir ? 0 : first_vertical_edge_done, a, b,
843  chroma, dir);
844  }
845 #else
846  filter_mb_dir(h, sl, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, first_vertical_edge_done, a, b, chroma, 0);
847  filter_mb_dir(h, sl, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, 0, a, b, chroma, 1);
848 #endif
849 }
PICT_FRAME
#define PICT_FRAME
Definition: mpegutils.h:39
ff_h264_filter_mb_fast
void ff_h264_filter_mb_fast(const H264Context *h, H264SliceContext *sl, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize)
Definition: h264_loopfilter.c:418
stride
int stride
Definition: mace.c:144
H264SliceContext::mb_xy
int mb_xy
Definition: h264dec.h:231
H264SliceContext::ref_cache
int8_t ref_cache[2][5 *8]
Definition: h264dec.h:300
CHROMA422
#define CHROMA422(h)
Definition: h264dec.h:98
check_mv
static int check_mv(H264SliceContext *sl, long b_idx, long bn_idx, int mvy_limit)
Definition: h264_loopfilter.c:440
step
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But a word about which is also called distortion Distortion can be quantified by almost any quality measurement one chooses the sum of squared differences is used but more complex methods that consider psychovisual effects can be used as well It makes no difference in this discussion First step
Definition: rate_distortion.txt:58
internal.h
b
#define b
Definition: input.c:41
chroma
static av_always_inline void chroma(WaveformContext *s, AVFrame *in, AVFrame *out, int component, int intensity, int offset_y, int offset_x, int column, int mirror, int jobnr, int nb_jobs)
Definition: vf_waveform.c:1511
MB_TYPE_16x16
#define MB_TYPE_16x16
Definition: mpegutils.h:54
H264SliceContext::left_mb_xy
int left_mb_xy[LEFT_MBS]
Definition: h264dec.h:211
ff_tlog
#define ff_tlog(ctx,...)
Definition: internal.h:75
mpegutils.h
H264SliceContext
Definition: h264dec.h:177
MB_FIELD
#define MB_FIELD(sl)
Definition: h264dec.h:72
ff_h264_filter_mb
void ff_h264_filter_mb(const H264Context *h, H264SliceContext *sl, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize)
Definition: h264_loopfilter.c:718
H264SliceContext::mv_cache
int16_t mv_cache[2][5 *8][2]
Motion vector cache.
Definition: h264dec.h:299
alpha_table
static const uint8_t alpha_table[52 *3]
Definition: h264_loopfilter.c:39
FILTER
#define FILTER(hv, dir, edge, intra)
get_chroma_qp
static av_always_inline int get_chroma_qp(const PPS *pps, int t, int qscale)
Get the chroma qp.
Definition: h264dec.h:681
U
#define U(x)
Definition: vp56_arith.h:37
filter_mb_edgech
static av_always_inline void filter_mb_edgech(uint8_t *pix, int stride, const int16_t bS[4], unsigned int qp, int a, int b, const H264Context *h, int intra)
Definition: h264_loopfilter.c:214
intreadwrite.h
AV_ZERO64
#define AV_ZERO64(d)
Definition: intreadwrite.h:633
FIELD_PICTURE
#define FIELD_PICTURE(h)
Definition: h264dec.h:74
H264SliceContext::slice_alpha_c0_offset
int slice_alpha_c0_offset
Definition: h264dec.h:194
IS_INTRA
#define IS_INTRA(x, y)
MB_TYPE_8x16
#define MB_TYPE_8x16
Definition: mpegutils.h:56
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:72
H264SliceContext::chroma_qp
int chroma_qp[2]
Definition: h264dec.h:188
mathops.h
IS_INTERLACED
#define IS_INTERLACED(a)
Definition: mpegutils.h:83
h264_ps.h
H264SliceContext::top_type
int top_type
Definition: h264dec.h:214
AV_CODEC_FLAG_GRAY
#define AV_CODEC_FLAG_GRAY
Only decode/encode grayscale.
Definition: avcodec.h:883
CABAC
#define CABAC(h)
Definition: h264_cabac.c:28
rectangle.h
H264SliceContext::top_mb_xy
int top_mb_xy
Definition: h264dec.h:209
filter_mb_edgev
static av_always_inline void filter_mb_edgev(uint8_t *pix, int stride, const int16_t bS[4], unsigned int qp, int a, int b, const H264Context *h, int intra)
Definition: h264_loopfilter.c:102
H264SliceContext::cbp
int cbp
Definition: h264dec.h:255
LEFT
#define LEFT
Definition: cdgraphics.c:166
H264SliceContext::left_type
int left_type[LEFT_MBS]
Definition: h264dec.h:216
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
filter_mb_edgecv
static av_always_inline void filter_mb_edgecv(uint8_t *pix, int stride, const int16_t bS[4], unsigned int qp, int a, int b, const H264Context *h, int intra)
Definition: h264_loopfilter.c:124
FRAME_MBAFF
#define FRAME_MBAFF(h)
Definition: h264dec.h:73
h264dec.h
av_assert2
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:64
H264Context
H264Context.
Definition: h264dec.h:337
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
h264_filter_mb_fast_internal
static av_always_inline void h264_filter_mb_fast_internal(const H264Context *h, H264SliceContext *sl, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize, int pixel_shift)
Definition: h264_loopfilter.c:236
internal.h
av_always_inline
#define av_always_inline
Definition: attributes.h:43
uint8_t
uint8_t
Definition: audio_convert.c:194
filter_mb_mbaff_edgev
static av_always_inline void filter_mb_mbaff_edgev(const H264Context *h, uint8_t *pix, int stride, const int16_t bS[7], int bsi, int qp, int a, int b, int intra)
Definition: h264_loopfilter.c:146
H264SliceContext::list_count
unsigned int list_count
Definition: h264dec.h:268
avcodec.h
CHROMA
@ CHROMA
Definition: vf_waveform.c:44
AV_WN64A
#define AV_WN64A(p, v)
Definition: intreadwrite.h:542
H264SliceContext::slice_beta_offset
int slice_beta_offset
Definition: h264dec.h:195
scan8
static const uint8_t scan8[16 *3+3]
Definition: h264dec.h:644
filter_mb_edgeh
static av_always_inline void filter_mb_edgeh(uint8_t *pix, int stride, const int16_t bS[4], unsigned int qp, int a, int b, const H264Context *h, int intra)
Definition: h264_loopfilter.c:192
H264SliceContext::non_zero_count_cache
uint8_t non_zero_count_cache[15 *8]
non zero coeff count cache.
Definition: h264dec.h:294
tc
#define tc
Definition: regdef.h:69
LOCAL_ALIGNED
#define LOCAL_ALIGNED(a, t, v,...)
Definition: internal.h:114
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
beta_table
static const uint8_t beta_table[52 *3]
Definition: h264_loopfilter.c:55
tc0_table
static const uint8_t tc0_table[52 *3][4]
Definition: h264_loopfilter.c:71
LTOP
#define LTOP
Definition: h264dec.h:76
CHROMA444
#define CHROMA444(h)
Definition: h264dec.h:99
h
h
Definition: vp9dsp_template.c:2038
filter_mb_dir
static av_always_inline void filter_mb_dir(const H264Context *h, H264SliceContext *sl, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize, int mb_xy, int mb_type, int mvy_limit, int first_vertical_edge_done, int a, int b, int chroma, int dir)
Definition: h264_loopfilter.c:470
IS_8x8DCT
#define IS_8x8DCT(a)
Definition: h264dec.h:104
filter_mb_mbaff_edgecv
static av_always_inline void filter_mb_mbaff_edgecv(const H264Context *h, uint8_t *pix, int stride, const int16_t bS[7], int bsi, int qp, int a, int b, int intra)
Definition: h264_loopfilter.c:169