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