Mercurial > libavcodec.hg
annotate h264_loopfilter.c @ 10936:b2ea6b0d17bf libavcodec
Update libx264.c to use new libx264 features
With b_keyframe instead of IDR for detecting keyframes, ffmpeg should now
support periodic encoding with periodic intra refresh (although there is no
interface option for it yet).
Set the new timebase values for full VFR input support.
Bump configure to check for API version 83.
| author | darkshikari |
|---|---|
| date | Tue, 19 Jan 2010 04:00:08 +0000 |
| parents | b847f02d5b03 |
| children | 5660eac25fb4 |
| rev | line source |
|---|---|
| 10854 | 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 libavcodec/h264_loopfilter.c | |
| 24 * H.264 / AVC / MPEG4 part10 loop filter. | |
| 25 * @author Michael Niedermayer <michaelni@gmx.at> | |
| 26 */ | |
| 27 | |
| 28 #include "internal.h" | |
| 29 #include "dsputil.h" | |
| 30 #include "avcodec.h" | |
| 31 #include "mpegvideo.h" | |
| 32 #include "h264.h" | |
| 33 #include "mathops.h" | |
| 34 #include "rectangle.h" | |
| 35 | |
| 36 //#undef NDEBUG | |
| 37 #include <assert.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 | |
|
10903
8c8321b94c35
Mark a few functions as noinline, this makes ff_h264_filter_mb() a bit smaller
michael
parents:
10902
diff
changeset
|
102 static void av_noinline filter_mb_edgev( H264Context *h, uint8_t *pix, int stride, int16_t bS[4], int qp ) { |
| 10854 | 103 const int index_a = qp + h->slice_alpha_c0_offset; |
| 104 const int alpha = (alpha_table+52)[index_a]; | |
| 105 const int beta = (beta_table+52)[qp + h->slice_beta_offset]; | |
| 106 if (alpha ==0 || beta == 0) return; | |
| 107 | |
| 108 if( bS[0] < 4 ) { | |
| 109 int8_t tc[4]; | |
| 110 tc[0] = (tc0_table+52)[index_a][bS[0]]; | |
| 111 tc[1] = (tc0_table+52)[index_a][bS[1]]; | |
| 112 tc[2] = (tc0_table+52)[index_a][bS[2]]; | |
| 113 tc[3] = (tc0_table+52)[index_a][bS[3]]; | |
| 114 h->s.dsp.h264_h_loop_filter_luma(pix, stride, alpha, beta, tc); | |
| 115 } else { | |
| 116 h->s.dsp.h264_h_loop_filter_luma_intra(pix, stride, alpha, beta); | |
| 117 } | |
| 118 } | |
|
10903
8c8321b94c35
Mark a few functions as noinline, this makes ff_h264_filter_mb() a bit smaller
michael
parents:
10902
diff
changeset
|
119 static void av_noinline filter_mb_edgecv( H264Context *h, uint8_t *pix, int stride, int16_t bS[4], int qp ) { |
| 10854 | 120 const int index_a = qp + h->slice_alpha_c0_offset; |
| 121 const int alpha = (alpha_table+52)[index_a]; | |
| 122 const int beta = (beta_table+52)[qp + h->slice_beta_offset]; | |
| 123 if (alpha ==0 || beta == 0) return; | |
| 124 | |
| 125 if( bS[0] < 4 ) { | |
| 126 int8_t tc[4]; | |
| 127 tc[0] = (tc0_table+52)[index_a][bS[0]]+1; | |
| 128 tc[1] = (tc0_table+52)[index_a][bS[1]]+1; | |
| 129 tc[2] = (tc0_table+52)[index_a][bS[2]]+1; | |
| 130 tc[3] = (tc0_table+52)[index_a][bS[3]]+1; | |
| 131 h->s.dsp.h264_h_loop_filter_chroma(pix, stride, alpha, beta, tc); | |
| 132 } else { | |
| 133 h->s.dsp.h264_h_loop_filter_chroma_intra(pix, stride, alpha, beta); | |
| 134 } | |
| 135 } | |
| 136 | |
|
10924
fb0307a3355e
Rather call filter_mb_mbaff_edge*v() more often than do extra calculations
michael
parents:
10922
diff
changeset
|
137 static void filter_mb_mbaff_edgev( H264Context *h, uint8_t *pix, int stride, int16_t bS[4], int bsi, int qp ) { |
| 10854 | 138 int i; |
|
10924
fb0307a3355e
Rather call filter_mb_mbaff_edge*v() more often than do extra calculations
michael
parents:
10922
diff
changeset
|
139 for( i = 0; i < 8; i++, pix += stride) { |
| 10854 | 140 int index_a; |
| 141 int alpha; | |
| 142 int beta; | |
|
10924
fb0307a3355e
Rather call filter_mb_mbaff_edge*v() more often than do extra calculations
michael
parents:
10922
diff
changeset
|
143 const int bS_index = (i >> 1) * bsi; |
| 10854 | 144 |
| 145 if( bS[bS_index] == 0 ) { | |
| 146 continue; | |
| 147 } | |
| 148 | |
|
10924
fb0307a3355e
Rather call filter_mb_mbaff_edge*v() more often than do extra calculations
michael
parents:
10922
diff
changeset
|
149 index_a = qp + h->slice_alpha_c0_offset; |
| 10854 | 150 alpha = (alpha_table+52)[index_a]; |
|
10924
fb0307a3355e
Rather call filter_mb_mbaff_edge*v() more often than do extra calculations
michael
parents:
10922
diff
changeset
|
151 beta = (beta_table+52)[qp + h->slice_beta_offset]; |
| 10854 | 152 |
| 153 if( bS[bS_index] < 4 ) { | |
| 154 const int tc0 = (tc0_table+52)[index_a][bS[bS_index]]; | |
| 155 const int p0 = pix[-1]; | |
| 156 const int p1 = pix[-2]; | |
| 157 const int p2 = pix[-3]; | |
| 158 const int q0 = pix[0]; | |
| 159 const int q1 = pix[1]; | |
| 160 const int q2 = pix[2]; | |
| 161 | |
| 162 if( FFABS( p0 - q0 ) < alpha && | |
| 163 FFABS( p1 - p0 ) < beta && | |
| 164 FFABS( q1 - q0 ) < beta ) { | |
| 165 int tc = tc0; | |
| 166 int i_delta; | |
| 167 | |
| 168 if( FFABS( p2 - p0 ) < beta ) { | |
| 169 pix[-2] = p1 + av_clip( ( p2 + ( ( p0 + q0 + 1 ) >> 1 ) - ( p1 << 1 ) ) >> 1, -tc0, tc0 ); | |
| 170 tc++; | |
| 171 } | |
| 172 if( FFABS( q2 - q0 ) < beta ) { | |
| 173 pix[1] = q1 + av_clip( ( q2 + ( ( p0 + q0 + 1 ) >> 1 ) - ( q1 << 1 ) ) >> 1, -tc0, tc0 ); | |
| 174 tc++; | |
| 175 } | |
| 176 | |
| 177 i_delta = av_clip( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc ); | |
| 178 pix[-1] = av_clip_uint8( p0 + i_delta ); /* p0' */ | |
| 179 pix[0] = av_clip_uint8( q0 - i_delta ); /* q0' */ | |
| 180 tprintf(h->s.avctx, "filter_mb_mbaff_edgev i:%d, qp:%d, indexA:%d, alpha:%d, beta:%d, tc:%d\n# bS:%d -> [%02x, %02x, %02x, %02x, %02x, %02x] =>[%02x, %02x, %02x, %02x]\n", i, qp[qp_index], index_a, alpha, beta, tc, bS[bS_index], pix[-3], p1, p0, q0, q1, pix[2], p1, pix[-1], pix[0], q1); | |
| 181 } | |
| 182 }else{ | |
| 183 const int p0 = pix[-1]; | |
| 184 const int p1 = pix[-2]; | |
| 185 const int p2 = pix[-3]; | |
| 186 | |
| 187 const int q0 = pix[0]; | |
| 188 const int q1 = pix[1]; | |
| 189 const int q2 = pix[2]; | |
| 190 | |
| 191 if( FFABS( p0 - q0 ) < alpha && | |
| 192 FFABS( p1 - p0 ) < beta && | |
| 193 FFABS( q1 - q0 ) < beta ) { | |
| 194 | |
| 195 if(FFABS( p0 - q0 ) < (( alpha >> 2 ) + 2 )){ | |
| 196 if( FFABS( p2 - p0 ) < beta) | |
| 197 { | |
| 198 const int p3 = pix[-4]; | |
| 199 /* p0', p1', p2' */ | |
| 200 pix[-1] = ( p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4 ) >> 3; | |
| 201 pix[-2] = ( p2 + p1 + p0 + q0 + 2 ) >> 2; | |
| 202 pix[-3] = ( 2*p3 + 3*p2 + p1 + p0 + q0 + 4 ) >> 3; | |
| 203 } else { | |
| 204 /* p0' */ | |
| 205 pix[-1] = ( 2*p1 + p0 + q1 + 2 ) >> 2; | |
| 206 } | |
| 207 if( FFABS( q2 - q0 ) < beta) | |
| 208 { | |
| 209 const int q3 = pix[3]; | |
| 210 /* q0', q1', q2' */ | |
| 211 pix[0] = ( p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4 ) >> 3; | |
| 212 pix[1] = ( p0 + q0 + q1 + q2 + 2 ) >> 2; | |
| 213 pix[2] = ( 2*q3 + 3*q2 + q1 + q0 + p0 + 4 ) >> 3; | |
| 214 } else { | |
| 215 /* q0' */ | |
| 216 pix[0] = ( 2*q1 + q0 + p1 + 2 ) >> 2; | |
| 217 } | |
| 218 }else{ | |
| 219 /* p0', q0' */ | |
| 220 pix[-1] = ( 2*p1 + p0 + q1 + 2 ) >> 2; | |
| 221 pix[ 0] = ( 2*q1 + q0 + p1 + 2 ) >> 2; | |
| 222 } | |
| 223 tprintf(h->s.avctx, "filter_mb_mbaff_edgev i:%d, qp:%d, indexA:%d, alpha:%d, beta:%d\n# bS:4 -> [%02x, %02x, %02x, %02x, %02x, %02x] =>[%02x, %02x, %02x, %02x, %02x, %02x]\n", i, qp[qp_index], index_a, alpha, beta, p2, p1, p0, q0, q1, q2, pix[-3], pix[-2], pix[-1], pix[0], pix[1], pix[2]); | |
| 224 } | |
| 225 } | |
| 226 } | |
| 227 } | |
|
10924
fb0307a3355e
Rather call filter_mb_mbaff_edge*v() more often than do extra calculations
michael
parents:
10922
diff
changeset
|
228 static void filter_mb_mbaff_edgecv( H264Context *h, uint8_t *pix, int stride, int16_t bS[4], int bsi, int qp ) { |
| 10854 | 229 int i; |
|
10924
fb0307a3355e
Rather call filter_mb_mbaff_edge*v() more often than do extra calculations
michael
parents:
10922
diff
changeset
|
230 for( i = 0; i < 4; i++, pix += stride) { |
| 10854 | 231 int index_a; |
| 232 int alpha; | |
| 233 int beta; | |
|
10924
fb0307a3355e
Rather call filter_mb_mbaff_edge*v() more often than do extra calculations
michael
parents:
10922
diff
changeset
|
234 const int bS_index = i*bsi; |
| 10854 | 235 |
| 236 if( bS[bS_index] == 0 ) { | |
| 237 continue; | |
| 238 } | |
| 239 | |
|
10924
fb0307a3355e
Rather call filter_mb_mbaff_edge*v() more often than do extra calculations
michael
parents:
10922
diff
changeset
|
240 index_a = qp + h->slice_alpha_c0_offset; |
| 10854 | 241 alpha = (alpha_table+52)[index_a]; |
|
10924
fb0307a3355e
Rather call filter_mb_mbaff_edge*v() more often than do extra calculations
michael
parents:
10922
diff
changeset
|
242 beta = (beta_table+52)[qp + h->slice_beta_offset]; |
| 10854 | 243 |
| 244 if( bS[bS_index] < 4 ) { | |
| 245 const int tc = (tc0_table+52)[index_a][bS[bS_index]] + 1; | |
| 246 const int p0 = pix[-1]; | |
| 247 const int p1 = pix[-2]; | |
| 248 const int q0 = pix[0]; | |
| 249 const int q1 = pix[1]; | |
| 250 | |
| 251 if( FFABS( p0 - q0 ) < alpha && | |
| 252 FFABS( p1 - p0 ) < beta && | |
| 253 FFABS( q1 - q0 ) < beta ) { | |
| 254 const int i_delta = av_clip( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc ); | |
| 255 | |
| 256 pix[-1] = av_clip_uint8( p0 + i_delta ); /* p0' */ | |
| 257 pix[0] = av_clip_uint8( q0 - i_delta ); /* q0' */ | |
| 258 tprintf(h->s.avctx, "filter_mb_mbaff_edgecv i:%d, qp:%d, indexA:%d, alpha:%d, beta:%d, tc:%d\n# bS:%d -> [%02x, %02x, %02x, %02x, %02x, %02x] =>[%02x, %02x, %02x, %02x]\n", i, qp[qp_index], index_a, alpha, beta, tc, bS[bS_index], pix[-3], p1, p0, q0, q1, pix[2], p1, pix[-1], pix[0], q1); | |
| 259 } | |
| 260 }else{ | |
| 261 const int p0 = pix[-1]; | |
| 262 const int p1 = pix[-2]; | |
| 263 const int q0 = pix[0]; | |
| 264 const int q1 = pix[1]; | |
| 265 | |
| 266 if( FFABS( p0 - q0 ) < alpha && | |
| 267 FFABS( p1 - p0 ) < beta && | |
| 268 FFABS( q1 - q0 ) < beta ) { | |
| 269 | |
| 270 pix[-1] = ( 2*p1 + p0 + q1 + 2 ) >> 2; /* p0' */ | |
| 271 pix[0] = ( 2*q1 + q0 + p1 + 2 ) >> 2; /* q0' */ | |
| 272 tprintf(h->s.avctx, "filter_mb_mbaff_edgecv i:%d\n# bS:4 -> [%02x, %02x, %02x, %02x, %02x, %02x] =>[%02x, %02x, %02x, %02x, %02x, %02x]\n", i, pix[-3], p1, p0, q0, q1, pix[2], pix[-3], pix[-2], pix[-1], pix[0], pix[1], pix[2]); | |
| 273 } | |
| 274 } | |
| 275 } | |
| 276 } | |
| 277 | |
|
10903
8c8321b94c35
Mark a few functions as noinline, this makes ff_h264_filter_mb() a bit smaller
michael
parents:
10902
diff
changeset
|
278 static void av_noinline filter_mb_edgeh( H264Context *h, uint8_t *pix, int stride, int16_t bS[4], int qp ) { |
| 10854 | 279 const int index_a = qp + h->slice_alpha_c0_offset; |
| 280 const int alpha = (alpha_table+52)[index_a]; | |
| 281 const int beta = (beta_table+52)[qp + h->slice_beta_offset]; | |
| 282 if (alpha ==0 || beta == 0) return; | |
| 283 | |
| 284 if( bS[0] < 4 ) { | |
| 285 int8_t tc[4]; | |
| 286 tc[0] = (tc0_table+52)[index_a][bS[0]]; | |
| 287 tc[1] = (tc0_table+52)[index_a][bS[1]]; | |
| 288 tc[2] = (tc0_table+52)[index_a][bS[2]]; | |
| 289 tc[3] = (tc0_table+52)[index_a][bS[3]]; | |
| 290 h->s.dsp.h264_v_loop_filter_luma(pix, stride, alpha, beta, tc); | |
| 291 } else { | |
| 292 h->s.dsp.h264_v_loop_filter_luma_intra(pix, stride, alpha, beta); | |
| 293 } | |
| 294 } | |
| 295 | |
|
10903
8c8321b94c35
Mark a few functions as noinline, this makes ff_h264_filter_mb() a bit smaller
michael
parents:
10902
diff
changeset
|
296 static void av_noinline filter_mb_edgech( H264Context *h, uint8_t *pix, int stride, int16_t bS[4], int qp ) { |
| 10854 | 297 const int index_a = qp + h->slice_alpha_c0_offset; |
| 298 const int alpha = (alpha_table+52)[index_a]; | |
| 299 const int beta = (beta_table+52)[qp + h->slice_beta_offset]; | |
| 300 if (alpha ==0 || beta == 0) return; | |
| 301 | |
| 302 if( bS[0] < 4 ) { | |
| 303 int8_t tc[4]; | |
| 304 tc[0] = (tc0_table+52)[index_a][bS[0]]+1; | |
| 305 tc[1] = (tc0_table+52)[index_a][bS[1]]+1; | |
| 306 tc[2] = (tc0_table+52)[index_a][bS[2]]+1; | |
| 307 tc[3] = (tc0_table+52)[index_a][bS[3]]+1; | |
| 308 h->s.dsp.h264_v_loop_filter_chroma(pix, stride, alpha, beta, tc); | |
| 309 } else { | |
| 310 h->s.dsp.h264_v_loop_filter_chroma_intra(pix, stride, alpha, beta); | |
| 311 } | |
| 312 } | |
| 313 | |
| 314 void ff_h264_filter_mb_fast( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize) { | |
| 315 MpegEncContext * const s = &h->s; | |
| 316 int mb_y_firstrow = s->picture_structure == PICT_BOTTOM_FIELD; | |
| 317 int mb_xy, mb_type; | |
| 318 int qp, qp0, qp1, qpc, qpc0, qpc1, qp_thresh; | |
| 319 | |
| 320 mb_xy = h->mb_xy; | |
| 321 | |
| 322 if(mb_x==0 || mb_y==mb_y_firstrow || !s->dsp.h264_loop_filter_strength || h->pps.chroma_qp_diff || | |
|
10918
f36f33e673b4
Reenable filter_mb_fast for I slices and progressive CABAC P slices.
michael
parents:
10914
diff
changeset
|
323 !(h->slice_type_nos == FF_I_TYPE || |
| 10921 | 324 h->slice_type_nos == FF_P_TYPE || |
|
10918
f36f33e673b4
Reenable filter_mb_fast for I slices and progressive CABAC P slices.
michael
parents:
10914
diff
changeset
|
325 (s->flags2 & CODEC_FLAG2_FAST)) || |
| 10922 | 326 (h->deblocking_filter == 2 && (h->slice_num != h->slice_table[h->top_mb_xy] || |
| 327 h->slice_num != h->slice_table[mb_xy - 1]))) { | |
| 10854 | 328 ff_h264_filter_mb(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize); |
| 329 return; | |
| 330 } | |
| 331 assert(!FRAME_MBAFF); | |
| 332 | |
| 333 mb_type = s->current_picture.mb_type[mb_xy]; | |
| 334 qp = s->current_picture.qscale_table[mb_xy]; | |
| 335 qp0 = s->current_picture.qscale_table[mb_xy-1]; | |
| 336 qp1 = s->current_picture.qscale_table[h->top_mb_xy]; | |
| 337 qpc = get_chroma_qp( h, 0, qp ); | |
| 338 qpc0 = get_chroma_qp( h, 0, qp0 ); | |
| 339 qpc1 = get_chroma_qp( h, 0, qp1 ); | |
| 340 qp0 = (qp + qp0 + 1) >> 1; | |
| 341 qp1 = (qp + qp1 + 1) >> 1; | |
| 342 qpc0 = (qpc + qpc0 + 1) >> 1; | |
| 343 qpc1 = (qpc + qpc1 + 1) >> 1; | |
| 344 qp_thresh = 15 - h->slice_alpha_c0_offset; | |
| 345 if(qp <= qp_thresh && qp0 <= qp_thresh && qp1 <= qp_thresh && | |
| 346 qpc <= qp_thresh && qpc0 <= qp_thresh && qpc1 <= qp_thresh) | |
| 347 return; | |
| 348 | |
| 349 if( IS_INTRA(mb_type) ) { | |
| 350 int16_t bS4[4] = {4,4,4,4}; | |
| 351 int16_t bS3[4] = {3,3,3,3}; | |
| 352 int16_t *bSH = FIELD_PICTURE ? bS3 : bS4; | |
| 353 if( IS_8x8DCT(mb_type) ) { | |
| 354 filter_mb_edgev( h, &img_y[4*0], linesize, bS4, qp0 ); | |
| 355 filter_mb_edgev( h, &img_y[4*2], linesize, bS3, qp ); | |
| 356 filter_mb_edgeh( h, &img_y[4*0*linesize], linesize, bSH, qp1 ); | |
| 357 filter_mb_edgeh( h, &img_y[4*2*linesize], linesize, bS3, qp ); | |
| 358 } else { | |
| 359 filter_mb_edgev( h, &img_y[4*0], linesize, bS4, qp0 ); | |
| 360 filter_mb_edgev( h, &img_y[4*1], linesize, bS3, qp ); | |
| 361 filter_mb_edgev( h, &img_y[4*2], linesize, bS3, qp ); | |
| 362 filter_mb_edgev( h, &img_y[4*3], linesize, bS3, qp ); | |
| 363 filter_mb_edgeh( h, &img_y[4*0*linesize], linesize, bSH, qp1 ); | |
| 364 filter_mb_edgeh( h, &img_y[4*1*linesize], linesize, bS3, qp ); | |
| 365 filter_mb_edgeh( h, &img_y[4*2*linesize], linesize, bS3, qp ); | |
| 366 filter_mb_edgeh( h, &img_y[4*3*linesize], linesize, bS3, qp ); | |
| 367 } | |
| 368 filter_mb_edgecv( h, &img_cb[2*0], uvlinesize, bS4, qpc0 ); | |
| 369 filter_mb_edgecv( h, &img_cb[2*2], uvlinesize, bS3, qpc ); | |
| 370 filter_mb_edgecv( h, &img_cr[2*0], uvlinesize, bS4, qpc0 ); | |
| 371 filter_mb_edgecv( h, &img_cr[2*2], uvlinesize, bS3, qpc ); | |
| 372 filter_mb_edgech( h, &img_cb[2*0*uvlinesize], uvlinesize, bSH, qpc1 ); | |
| 373 filter_mb_edgech( h, &img_cb[2*2*uvlinesize], uvlinesize, bS3, qpc ); | |
| 374 filter_mb_edgech( h, &img_cr[2*0*uvlinesize], uvlinesize, bSH, qpc1 ); | |
| 375 filter_mb_edgech( h, &img_cr[2*2*uvlinesize], uvlinesize, bS3, qpc ); | |
| 376 return; | |
| 377 } else { | |
| 378 DECLARE_ALIGNED_8(int16_t, bS[2][4][4]); | |
| 379 uint64_t (*bSv)[4] = (uint64_t(*)[4])bS; | |
| 380 int edges; | |
| 381 if( IS_8x8DCT(mb_type) && (h->cbp&7) == 7 ) { | |
| 382 edges = 4; | |
| 383 bSv[0][0] = bSv[0][2] = bSv[1][0] = bSv[1][2] = 0x0002000200020002ULL; | |
| 384 } else { | |
| 385 int mask_edge1 = (mb_type & (MB_TYPE_16x16 | MB_TYPE_8x16)) ? 3 : | |
| 386 (mb_type & MB_TYPE_16x8) ? 1 : 0; | |
| 387 int mask_edge0 = (mb_type & (MB_TYPE_16x16 | MB_TYPE_8x16)) | |
| 388 && (s->current_picture.mb_type[mb_xy-1] & (MB_TYPE_16x16 | MB_TYPE_8x16)) | |
| 389 ? 3 : 0; | |
| 390 int step = IS_8x8DCT(mb_type) ? 2 : 1; | |
| 391 edges = (mb_type & MB_TYPE_16x16) && !(h->cbp & 15) ? 1 : 4; | |
| 392 s->dsp.h264_loop_filter_strength( bS, h->non_zero_count_cache, h->ref_cache, h->mv_cache, | |
| 393 (h->slice_type_nos == FF_B_TYPE), edges, step, mask_edge0, mask_edge1, FIELD_PICTURE); | |
| 394 } | |
| 395 if( IS_INTRA(s->current_picture.mb_type[mb_xy-1]) ) | |
| 396 bSv[0][0] = 0x0004000400040004ULL; | |
| 397 if( IS_INTRA(s->current_picture.mb_type[h->top_mb_xy]) ) | |
| 398 bSv[1][0] = FIELD_PICTURE ? 0x0003000300030003ULL : 0x0004000400040004ULL; | |
| 399 | |
| 400 #define FILTER(hv,dir,edge)\ | |
| 401 if(bSv[dir][edge]) {\ | |
| 402 filter_mb_edge##hv( h, &img_y[4*edge*(dir?linesize:1)], linesize, bS[dir][edge], edge ? qp : qp##dir );\ | |
| 403 if(!(edge&1)) {\ | |
| 404 filter_mb_edgec##hv( h, &img_cb[2*edge*(dir?uvlinesize:1)], uvlinesize, bS[dir][edge], edge ? qpc : qpc##dir );\ | |
| 405 filter_mb_edgec##hv( h, &img_cr[2*edge*(dir?uvlinesize:1)], uvlinesize, bS[dir][edge], edge ? qpc : qpc##dir );\ | |
| 406 }\ | |
| 407 } | |
| 408 if( edges == 1 ) { | |
| 409 FILTER(v,0,0); | |
| 410 FILTER(h,1,0); | |
| 411 } else if( IS_8x8DCT(mb_type) ) { | |
| 412 FILTER(v,0,0); | |
| 413 FILTER(v,0,2); | |
| 414 FILTER(h,1,0); | |
| 415 FILTER(h,1,2); | |
| 416 } else { | |
| 417 FILTER(v,0,0); | |
| 418 FILTER(v,0,1); | |
| 419 FILTER(v,0,2); | |
| 420 FILTER(v,0,3); | |
| 421 FILTER(h,1,0); | |
| 422 FILTER(h,1,1); | |
| 423 FILTER(h,1,2); | |
| 424 FILTER(h,1,3); | |
| 425 } | |
| 426 #undef FILTER | |
| 427 } | |
| 428 } | |
| 429 | |
| 430 | |
| 431 static av_always_inline void filter_mb_dir(H264Context *h, 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 dir) { | |
| 432 MpegEncContext * const s = &h->s; | |
| 433 int edge; | |
| 434 const int mbm_xy = dir == 0 ? mb_xy -1 : h->top_mb_xy; | |
| 435 const int mbm_type = s->current_picture.mb_type[mbm_xy]; | |
| 436 int start = h->slice_table[mbm_xy] == 0xFFFF ? 1 : 0; | |
| 437 | |
| 438 const int edges = (mb_type & (MB_TYPE_16x16|MB_TYPE_SKIP)) | |
| 439 == (MB_TYPE_16x16|MB_TYPE_SKIP) ? 1 : 4; | |
| 440 // how often to recheck mv-based bS when iterating between edges | |
| 441 const int mask_edge = (mb_type & (MB_TYPE_16x16 | (MB_TYPE_16x8 << dir))) ? 3 : | |
| 442 (mb_type & (MB_TYPE_8x16 >> dir)) ? 1 : 0; | |
| 443 // how often to recheck mv-based bS when iterating along each edge | |
| 444 const int mask_par0 = mb_type & (MB_TYPE_16x16 | (MB_TYPE_8x16 >> dir)); | |
| 445 | |
| 446 if (first_vertical_edge_done) { | |
| 447 start = 1; | |
| 448 } | |
| 449 | |
| 10922 | 450 if (h->deblocking_filter==2 && h->slice_table[mbm_xy] != h->slice_num) |
| 10854 | 451 start = 1; |
| 452 | |
| 453 if (FRAME_MBAFF && (dir == 1) && ((mb_y&1) == 0) && start == 0 | |
| 454 && !IS_INTERLACED(mb_type) | |
| 455 && IS_INTERLACED(mbm_type) | |
| 456 ) { | |
| 457 // This is a special case in the norm where the filtering must | |
| 458 // be done twice (one each of the field) even if we are in a | |
| 459 // frame macroblock. | |
| 460 // | |
| 461 unsigned int tmp_linesize = 2 * linesize; | |
| 462 unsigned int tmp_uvlinesize = 2 * uvlinesize; | |
| 463 int mbn_xy = mb_xy - 2 * s->mb_stride; | |
| 464 int qp; | |
| 465 int i, j; | |
| 466 int16_t bS[4]; | |
| 467 | |
| 468 for(j=0; j<2; j++, mbn_xy += s->mb_stride){ | |
| 469 if( IS_INTRA(mb_type) || | |
| 470 IS_INTRA(s->current_picture.mb_type[mbn_xy]) ) { | |
| 471 bS[0] = bS[1] = bS[2] = bS[3] = 3; | |
| 472 } else { | |
| 473 const uint8_t *mbn_nnz = h->non_zero_count[mbn_xy]; | |
| 474 for( i = 0; i < 4; i++ ) { | |
| 475 if( h->non_zero_count_cache[scan8[0]+i] != 0 || | |
|
10909
f4cf3960b8c6
Reorganize how values are stored in h->non_zero_count.
michael
parents:
10906
diff
changeset
|
476 mbn_nnz[i+4+3*8] != 0 ) |
| 10854 | 477 bS[i] = 2; |
| 478 else | |
| 479 bS[i] = 1; | |
| 480 } | |
| 481 } | |
| 482 // Do not use s->qscale as luma quantizer because it has not the same | |
| 483 // value in IPCM macroblocks. | |
| 484 qp = ( s->current_picture.qscale_table[mb_xy] + s->current_picture.qscale_table[mbn_xy] + 1 ) >> 1; | |
| 485 tprintf(s->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, tmp_linesize, tmp_uvlinesize); | |
| 486 { int i; for (i = 0; i < 4; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); } | |
| 487 filter_mb_edgeh( h, &img_y[j*linesize], tmp_linesize, bS, qp ); | |
| 488 filter_mb_edgech( h, &img_cb[j*uvlinesize], tmp_uvlinesize, bS, | |
| 489 ( h->chroma_qp[0] + get_chroma_qp( h, 0, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1); | |
| 490 filter_mb_edgech( h, &img_cr[j*uvlinesize], tmp_uvlinesize, bS, | |
| 491 ( h->chroma_qp[1] + get_chroma_qp( h, 1, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1); | |
| 492 } | |
| 493 | |
| 494 start = 1; | |
| 495 } | |
| 496 | |
| 497 /* Calculate bS */ | |
| 498 for( edge = start; edge < edges; edge++ ) { | |
| 499 /* mbn_xy: neighbor macroblock */ | |
| 500 const int mbn_xy = edge > 0 ? mb_xy : mbm_xy; | |
| 501 const int mbn_type = s->current_picture.mb_type[mbn_xy]; | |
| 502 int16_t bS[4]; | |
| 503 int qp; | |
| 504 | |
| 505 if( (edge&1) && IS_8x8DCT(mb_type) ) | |
| 506 continue; | |
| 507 | |
| 508 if( IS_INTRA(mb_type) || | |
| 509 IS_INTRA(mbn_type) ) { | |
| 510 int value; | |
| 511 if (edge == 0) { | |
| 512 if ( (!IS_INTERLACED(mb_type) && !IS_INTERLACED(mbm_type)) | |
| 513 || ((FRAME_MBAFF || (s->picture_structure != PICT_FRAME)) && (dir == 0)) | |
| 514 ) { | |
| 515 value = 4; | |
| 516 } else { | |
| 517 value = 3; | |
| 518 } | |
| 519 } else { | |
| 520 value = 3; | |
| 521 } | |
| 522 bS[0] = bS[1] = bS[2] = bS[3] = value; | |
| 523 } else { | |
| 524 int i, l; | |
| 525 int mv_done; | |
| 526 | |
| 527 if( edge & mask_edge ) { | |
| 528 bS[0] = bS[1] = bS[2] = bS[3] = 0; | |
| 529 mv_done = 1; | |
| 530 } | |
| 531 else if( FRAME_MBAFF && IS_INTERLACED(mb_type ^ mbn_type)) { | |
| 532 bS[0] = bS[1] = bS[2] = bS[3] = 1; | |
| 533 mv_done = 1; | |
| 534 } | |
| 535 else if( mask_par0 && (edge || (mbn_type & (MB_TYPE_16x16 | (MB_TYPE_8x16 >> dir)))) ) { | |
| 536 int b_idx= 8 + 4 + edge * (dir ? 8:1); | |
| 537 int bn_idx= b_idx - (dir ? 8:1); | |
| 538 int v = 0; | |
| 539 | |
| 540 for( l = 0; !v && l < 1 + (h->slice_type_nos == FF_B_TYPE); l++ ) { | |
|
10913
497929e9d912
Perform reference remapping at fill_cache() time instead of in the
michael
parents:
10910
diff
changeset
|
541 v |= h->ref_cache[l][b_idx] != h->ref_cache[l][bn_idx] | |
|
10901
2a5c3d89201d
Another microopt, 4 cpu cycles for avoidance of FFABS().
michael
parents:
10899
diff
changeset
|
542 h->mv_cache[l][b_idx][0] - h->mv_cache[l][bn_idx][0] + 3 >= 7U | |
| 10854 | 543 FFABS( h->mv_cache[l][b_idx][1] - h->mv_cache[l][bn_idx][1] ) >= mvy_limit; |
| 544 } | |
| 545 | |
| 546 if(h->slice_type_nos == FF_B_TYPE && v){ | |
| 547 v=0; | |
| 548 for( l = 0; !v && l < 2; l++ ) { | |
| 549 int ln= 1-l; | |
|
10913
497929e9d912
Perform reference remapping at fill_cache() time instead of in the
michael
parents:
10910
diff
changeset
|
550 v |= h->ref_cache[l][b_idx] != h->ref_cache[ln][bn_idx] | |
|
10901
2a5c3d89201d
Another microopt, 4 cpu cycles for avoidance of FFABS().
michael
parents:
10899
diff
changeset
|
551 h->mv_cache[l][b_idx][0] - h->mv_cache[ln][bn_idx][0] + 3 >= 7U | |
| 10854 | 552 FFABS( h->mv_cache[l][b_idx][1] - h->mv_cache[ln][bn_idx][1] ) >= mvy_limit; |
| 553 } | |
| 554 } | |
| 555 | |
| 556 bS[0] = bS[1] = bS[2] = bS[3] = v; | |
| 557 mv_done = 1; | |
| 558 } | |
| 559 else | |
| 560 mv_done = 0; | |
| 561 | |
| 562 for( i = 0; i < 4; i++ ) { | |
| 563 int x = dir == 0 ? edge : i; | |
| 564 int y = dir == 0 ? i : edge; | |
| 565 int b_idx= 8 + 4 + x + 8*y; | |
| 566 int bn_idx= b_idx - (dir ? 8:1); | |
| 567 | |
| 568 if( h->non_zero_count_cache[b_idx] | | |
| 569 h->non_zero_count_cache[bn_idx] ) { | |
| 570 bS[i] = 2; | |
| 571 } | |
| 572 else if(!mv_done) | |
| 573 { | |
| 574 bS[i] = 0; | |
| 575 for( l = 0; l < 1 + (h->slice_type_nos == FF_B_TYPE); l++ ) { | |
|
10913
497929e9d912
Perform reference remapping at fill_cache() time instead of in the
michael
parents:
10910
diff
changeset
|
576 if( h->ref_cache[l][b_idx] != h->ref_cache[l][bn_idx] | |
|
10902
1e41e6ab9a18
Apply last 2 optimizations to similar code i forgot.
michael
parents:
10901
diff
changeset
|
577 h->mv_cache[l][b_idx][0] - h->mv_cache[l][bn_idx][0] + 3 >= 7U | |
| 10854 | 578 FFABS( h->mv_cache[l][b_idx][1] - h->mv_cache[l][bn_idx][1] ) >= mvy_limit ) { |
| 579 bS[i] = 1; | |
| 580 break; | |
| 581 } | |
| 582 } | |
| 583 | |
| 584 if(h->slice_type_nos == FF_B_TYPE && bS[i]){ | |
| 585 bS[i] = 0; | |
| 586 for( l = 0; l < 2; l++ ) { | |
| 587 int ln= 1-l; | |
|
10913
497929e9d912
Perform reference remapping at fill_cache() time instead of in the
michael
parents:
10910
diff
changeset
|
588 if( h->ref_cache[l][b_idx] != h->ref_cache[ln][bn_idx] | |
|
10902
1e41e6ab9a18
Apply last 2 optimizations to similar code i forgot.
michael
parents:
10901
diff
changeset
|
589 h->mv_cache[l][b_idx][0] - h->mv_cache[ln][bn_idx][0] + 3 >= 7U | |
| 10854 | 590 FFABS( h->mv_cache[l][b_idx][1] - h->mv_cache[ln][bn_idx][1] ) >= mvy_limit ) { |
| 591 bS[i] = 1; | |
| 592 break; | |
| 593 } | |
| 594 } | |
| 595 } | |
| 596 } | |
| 597 } | |
| 598 | |
| 599 if(bS[0]+bS[1]+bS[2]+bS[3] == 0) | |
| 600 continue; | |
| 601 } | |
| 602 | |
| 603 /* Filter edge */ | |
| 604 // Do not use s->qscale as luma quantizer because it has not the same | |
| 605 // value in IPCM macroblocks. | |
| 606 qp = ( s->current_picture.qscale_table[mb_xy] + s->current_picture.qscale_table[mbn_xy] + 1 ) >> 1; | |
| 10906 | 607 //tprintf(s->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], s->current_picture.qscale_table[mbn_xy]); |
| 10854 | 608 tprintf(s->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, linesize, uvlinesize); |
| 10904 | 609 //{ int i; for (i = 0; i < 4; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); } |
| 10854 | 610 if( dir == 0 ) { |
| 611 filter_mb_edgev( h, &img_y[4*edge], linesize, bS, qp ); | |
| 612 if( (edge&1) == 0 ) { | |
| 613 filter_mb_edgecv( h, &img_cb[2*edge], uvlinesize, bS, | |
| 614 ( h->chroma_qp[0] + get_chroma_qp( h, 0, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1); | |
| 615 filter_mb_edgecv( h, &img_cr[2*edge], uvlinesize, bS, | |
| 616 ( h->chroma_qp[1] + get_chroma_qp( h, 1, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1); | |
| 617 } | |
| 618 } else { | |
| 619 filter_mb_edgeh( h, &img_y[4*edge*linesize], linesize, bS, qp ); | |
| 620 if( (edge&1) == 0 ) { | |
| 621 filter_mb_edgech( h, &img_cb[2*edge*uvlinesize], uvlinesize, bS, | |
| 622 ( h->chroma_qp[0] + get_chroma_qp( h, 0, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1); | |
| 623 filter_mb_edgech( h, &img_cr[2*edge*uvlinesize], uvlinesize, bS, | |
| 624 ( h->chroma_qp[1] + get_chroma_qp( h, 1, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1); | |
| 625 } | |
| 626 } | |
| 627 } | |
| 628 } | |
| 629 | |
| 630 void ff_h264_filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize) { | |
| 631 MpegEncContext * const s = &h->s; | |
| 632 const int mb_xy= mb_x + mb_y*s->mb_stride; | |
| 633 const int mb_type = s->current_picture.mb_type[mb_xy]; | |
| 634 const int mvy_limit = IS_INTERLACED(mb_type) ? 2 : 4; | |
| 635 int first_vertical_edge_done = 0; | |
| 636 av_unused int dir; | |
| 10906 | 637 int list; |
| 10854 | 638 |
| 639 if (FRAME_MBAFF | |
| 640 // left mb is in picture | |
| 641 && h->slice_table[mb_xy-1] != 0xFFFF | |
| 642 // and current and left pair do not have the same interlaced type | |
| 643 && (IS_INTERLACED(mb_type) != IS_INTERLACED(s->current_picture.mb_type[mb_xy-1])) | |
| 644 // and left mb is in the same slice if deblocking_filter == 2 | |
| 10922 | 645 && (h->deblocking_filter!=2 || h->slice_table[mb_xy-1] == h->slice_num)) { |
| 10854 | 646 /* First vertical edge is different in MBAFF frames |
| 647 * There are 8 different bS to compute and 2 different Qp | |
| 648 */ | |
| 649 const int pair_xy = mb_x + (mb_y&~1)*s->mb_stride; | |
| 650 const int left_mb_xy[2] = { pair_xy-1, pair_xy-1+s->mb_stride }; | |
| 651 int16_t bS[8]; | |
| 652 int qp[2]; | |
| 653 int bqp[2]; | |
| 654 int rqp[2]; | |
| 655 int mb_qp, mbn0_qp, mbn1_qp; | |
| 656 int i; | |
| 657 first_vertical_edge_done = 1; | |
| 658 | |
| 659 if( IS_INTRA(mb_type) ) | |
| 660 bS[0] = bS[1] = bS[2] = bS[3] = bS[4] = bS[5] = bS[6] = bS[7] = 4; | |
| 661 else { | |
| 662 for( i = 0; i < 8; i++ ) { | |
| 663 int mbn_xy = MB_FIELD ? left_mb_xy[i>>2] : left_mb_xy[i&1]; | |
| 664 | |
| 665 if( IS_INTRA( s->current_picture.mb_type[mbn_xy] ) ) | |
| 666 bS[i] = 4; | |
| 667 else if( h->non_zero_count_cache[12+8*(i>>1)] != 0 || | |
| 668 ((!h->pps.cabac && IS_8x8DCT(s->current_picture.mb_type[mbn_xy])) ? | |
| 669 (h->cbp_table[mbn_xy] & ((MB_FIELD ? (i&2) : (mb_y&1)) ? 8 : 2)) | |
| 670 : | |
|
10909
f4cf3960b8c6
Reorganize how values are stored in h->non_zero_count.
michael
parents:
10906
diff
changeset
|
671 h->non_zero_count[mbn_xy][7+(MB_FIELD ? (i&3) : (i>>2)+(mb_y&1)*2)*8])) |
| 10854 | 672 bS[i] = 2; |
| 673 else | |
| 674 bS[i] = 1; | |
| 675 } | |
| 676 } | |
| 677 | |
| 678 mb_qp = s->current_picture.qscale_table[mb_xy]; | |
| 679 mbn0_qp = s->current_picture.qscale_table[left_mb_xy[0]]; | |
| 680 mbn1_qp = s->current_picture.qscale_table[left_mb_xy[1]]; | |
| 681 qp[0] = ( mb_qp + mbn0_qp + 1 ) >> 1; | |
| 682 bqp[0] = ( get_chroma_qp( h, 0, mb_qp ) + | |
| 683 get_chroma_qp( h, 0, mbn0_qp ) + 1 ) >> 1; | |
| 684 rqp[0] = ( get_chroma_qp( h, 1, mb_qp ) + | |
| 685 get_chroma_qp( h, 1, mbn0_qp ) + 1 ) >> 1; | |
| 686 qp[1] = ( mb_qp + mbn1_qp + 1 ) >> 1; | |
| 687 bqp[1] = ( get_chroma_qp( h, 0, mb_qp ) + | |
| 688 get_chroma_qp( h, 0, mbn1_qp ) + 1 ) >> 1; | |
| 689 rqp[1] = ( get_chroma_qp( h, 1, mb_qp ) + | |
| 690 get_chroma_qp( h, 1, mbn1_qp ) + 1 ) >> 1; | |
| 691 | |
| 692 /* Filter edge */ | |
| 693 tprintf(s->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); | |
| 694 { int i; for (i = 0; i < 8; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); } | |
|
10924
fb0307a3355e
Rather call filter_mb_mbaff_edge*v() more often than do extra calculations
michael
parents:
10922
diff
changeset
|
695 if(MB_FIELD){ |
|
fb0307a3355e
Rather call filter_mb_mbaff_edge*v() more often than do extra calculations
michael
parents:
10922
diff
changeset
|
696 filter_mb_mbaff_edgev ( h, img_y , linesize, bS , 1, qp [0] ); |
|
fb0307a3355e
Rather call filter_mb_mbaff_edge*v() more often than do extra calculations
michael
parents:
10922
diff
changeset
|
697 filter_mb_mbaff_edgev ( h, img_y + 8* linesize, linesize, bS+4, 1, qp [1] ); |
|
fb0307a3355e
Rather call filter_mb_mbaff_edge*v() more often than do extra calculations
michael
parents:
10922
diff
changeset
|
698 filter_mb_mbaff_edgecv( h, img_cb, uvlinesize, bS , 1, bqp[0] ); |
|
fb0307a3355e
Rather call filter_mb_mbaff_edge*v() more often than do extra calculations
michael
parents:
10922
diff
changeset
|
699 filter_mb_mbaff_edgecv( h, img_cb + 4*uvlinesize, uvlinesize, bS+4, 1, bqp[1] ); |
|
fb0307a3355e
Rather call filter_mb_mbaff_edge*v() more often than do extra calculations
michael
parents:
10922
diff
changeset
|
700 filter_mb_mbaff_edgecv( h, img_cr, uvlinesize, bS , 1, rqp[0] ); |
|
fb0307a3355e
Rather call filter_mb_mbaff_edge*v() more often than do extra calculations
michael
parents:
10922
diff
changeset
|
701 filter_mb_mbaff_edgecv( h, img_cr + 4*uvlinesize, uvlinesize, bS+4, 1, rqp[1] ); |
|
fb0307a3355e
Rather call filter_mb_mbaff_edge*v() more often than do extra calculations
michael
parents:
10922
diff
changeset
|
702 }else{ |
|
fb0307a3355e
Rather call filter_mb_mbaff_edge*v() more often than do extra calculations
michael
parents:
10922
diff
changeset
|
703 filter_mb_mbaff_edgev ( h, img_y , 2* linesize, bS , 2, qp [0] ); |
|
fb0307a3355e
Rather call filter_mb_mbaff_edge*v() more often than do extra calculations
michael
parents:
10922
diff
changeset
|
704 filter_mb_mbaff_edgev ( h, img_y + linesize, 2* linesize, bS+1, 2, qp [1] ); |
|
fb0307a3355e
Rather call filter_mb_mbaff_edge*v() more often than do extra calculations
michael
parents:
10922
diff
changeset
|
705 filter_mb_mbaff_edgecv( h, img_cb, 2*uvlinesize, bS , 2, bqp[0] ); |
|
fb0307a3355e
Rather call filter_mb_mbaff_edge*v() more often than do extra calculations
michael
parents:
10922
diff
changeset
|
706 filter_mb_mbaff_edgecv( h, img_cb + uvlinesize, 2*uvlinesize, bS+1, 2, bqp[1] ); |
|
fb0307a3355e
Rather call filter_mb_mbaff_edge*v() more often than do extra calculations
michael
parents:
10922
diff
changeset
|
707 filter_mb_mbaff_edgecv( h, img_cr, 2*uvlinesize, bS , 2, rqp[0] ); |
|
fb0307a3355e
Rather call filter_mb_mbaff_edge*v() more often than do extra calculations
michael
parents:
10922
diff
changeset
|
708 filter_mb_mbaff_edgecv( h, img_cr + uvlinesize, 2*uvlinesize, bS+1, 2, rqp[1] ); |
|
fb0307a3355e
Rather call filter_mb_mbaff_edge*v() more often than do extra calculations
michael
parents:
10922
diff
changeset
|
709 } |
| 10854 | 710 } |
| 711 | |
| 712 #if CONFIG_SMALL | |
| 713 for( dir = 0; dir < 2; dir++ ) | |
| 714 filter_mb_dir(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, dir ? 0 : first_vertical_edge_done, dir); | |
| 715 #else | |
| 716 filter_mb_dir(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, first_vertical_edge_done, 0); | |
| 717 filter_mb_dir(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, 0, 1); | |
| 718 #endif | |
| 719 } |
