• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

libavcodec/h264_loopfilter.c

Go to the documentation of this file.
00001 /*
00002  * H.26L/H.264/AVC/JVT/14496-10/... loop filter
00003  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
00004  *
00005  * This file is part of Libav.
00006  *
00007  * Libav is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * Libav is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with Libav; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00028 #include "libavutil/intreadwrite.h"
00029 #include "internal.h"
00030 #include "dsputil.h"
00031 #include "avcodec.h"
00032 #include "mpegvideo.h"
00033 #include "h264.h"
00034 #include "mathops.h"
00035 #include "rectangle.h"
00036 
00037 //#undef NDEBUG
00038 #include <assert.h>
00039 
00040 /* Deblocking filter (p153) */
00041 static const uint8_t alpha_table[52*3] = {
00042      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
00043      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
00044      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
00045      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
00046      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
00047      0,  0,  0,  0,  0,  0,  4,  4,  5,  6,
00048      7,  8,  9, 10, 12, 13, 15, 17, 20, 22,
00049     25, 28, 32, 36, 40, 45, 50, 56, 63, 71,
00050     80, 90,101,113,127,144,162,182,203,226,
00051    255,255,
00052    255,255,255,255,255,255,255,255,255,255,255,255,255,
00053    255,255,255,255,255,255,255,255,255,255,255,255,255,
00054    255,255,255,255,255,255,255,255,255,255,255,255,255,
00055    255,255,255,255,255,255,255,255,255,255,255,255,255,
00056 };
00057 static const uint8_t beta_table[52*3] = {
00058      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
00059      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
00060      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
00061      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
00062      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
00063      0,  0,  0,  0,  0,  0,  2,  2,  2,  3,
00064      3,  3,  3,  4,  4,  4,  6,  6,  7,  7,
00065      8,  8,  9,  9, 10, 10, 11, 11, 12, 12,
00066     13, 13, 14, 14, 15, 15, 16, 16, 17, 17,
00067     18, 18,
00068     18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
00069     18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
00070     18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
00071     18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
00072 };
00073 static const uint8_t tc0_table[52*3][4] = {
00074     {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
00075     {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
00076     {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
00077     {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
00078     {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
00079     {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
00080     {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
00081     {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
00082     {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
00083     {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
00084     {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
00085     {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 1 },
00086     {-1, 0, 0, 1 }, {-1, 0, 0, 1 }, {-1, 0, 0, 1 }, {-1, 0, 1, 1 }, {-1, 0, 1, 1 }, {-1, 1, 1, 1 },
00087     {-1, 1, 1, 1 }, {-1, 1, 1, 1 }, {-1, 1, 1, 1 }, {-1, 1, 1, 2 }, {-1, 1, 1, 2 }, {-1, 1, 1, 2 },
00088     {-1, 1, 1, 2 }, {-1, 1, 2, 3 }, {-1, 1, 2, 3 }, {-1, 2, 2, 3 }, {-1, 2, 2, 4 }, {-1, 2, 3, 4 },
00089     {-1, 2, 3, 4 }, {-1, 3, 3, 5 }, {-1, 3, 4, 6 }, {-1, 3, 4, 6 }, {-1, 4, 5, 7 }, {-1, 4, 5, 8 },
00090     {-1, 4, 6, 9 }, {-1, 5, 7,10 }, {-1, 6, 8,11 }, {-1, 6, 8,13 }, {-1, 7,10,14 }, {-1, 8,11,16 },
00091     {-1, 9,12,18 }, {-1,10,13,20 }, {-1,11,15,23 }, {-1,13,17,25 },
00092     {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 },
00093     {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 },
00094     {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 },
00095     {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 },
00096     {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 },
00097     {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 },
00098     {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 },
00099     {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 },
00100     {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 },
00101 };
00102 
00103 /* intra: 0 if this loopfilter call is guaranteed to be inter (bS < 4), 1 if it might be intra (bS == 4) */
00104 static av_always_inline void filter_mb_edgev(uint8_t *pix, int stride,
00105                                              const int16_t bS[4],
00106                                              unsigned int qp, int a, int b,
00107                                              H264Context *h, int intra)
00108 {
00109     const unsigned int index_a = qp + a;
00110     const int alpha = alpha_table[index_a];
00111     const int beta  = beta_table[qp + b];
00112     if (alpha ==0 || beta == 0) return;
00113 
00114     if( bS[0] < 4 || !intra ) {
00115         int8_t tc[4];
00116         tc[0] = tc0_table[index_a][bS[0]];
00117         tc[1] = tc0_table[index_a][bS[1]];
00118         tc[2] = tc0_table[index_a][bS[2]];
00119         tc[3] = tc0_table[index_a][bS[3]];
00120         h->h264dsp.h264_h_loop_filter_luma(pix, stride, alpha, beta, tc);
00121     } else {
00122         h->h264dsp.h264_h_loop_filter_luma_intra(pix, stride, alpha, beta);
00123     }
00124 }
00125 
00126 static av_always_inline void filter_mb_edgecv(uint8_t *pix, int stride,
00127                                               const int16_t bS[4],
00128                                               unsigned int qp, int a, int b,
00129                                               H264Context *h, int intra)
00130 {
00131     const unsigned int index_a = qp + a;
00132     const int alpha = alpha_table[index_a];
00133     const int beta  = beta_table[qp + b];
00134     if (alpha ==0 || beta == 0) return;
00135 
00136     if( bS[0] < 4 || !intra ) {
00137         int8_t tc[4];
00138         tc[0] = tc0_table[index_a][bS[0]]+1;
00139         tc[1] = tc0_table[index_a][bS[1]]+1;
00140         tc[2] = tc0_table[index_a][bS[2]]+1;
00141         tc[3] = tc0_table[index_a][bS[3]]+1;
00142         h->h264dsp.h264_h_loop_filter_chroma(pix, stride, alpha, beta, tc);
00143     } else {
00144         h->h264dsp.h264_h_loop_filter_chroma_intra(pix, stride, alpha, beta);
00145     }
00146 }
00147 
00148 static av_always_inline void filter_mb_mbaff_edgev(H264Context *h, uint8_t *pix,
00149                                                    int stride,
00150                                                    const int16_t bS[7], int bsi,
00151                                                    int qp, int a, int b,
00152                                                    int intra)
00153 {
00154     const unsigned int index_a = qp + a;
00155     const int alpha = alpha_table[index_a];
00156     const int beta  = beta_table[qp + b];
00157     if (alpha ==0 || beta == 0) return;
00158 
00159     if( bS[0] < 4 || !intra ) {
00160         int8_t tc[4];
00161         tc[0] = tc0_table[index_a][bS[0*bsi]];
00162         tc[1] = tc0_table[index_a][bS[1*bsi]];
00163         tc[2] = tc0_table[index_a][bS[2*bsi]];
00164         tc[3] = tc0_table[index_a][bS[3*bsi]];
00165         h->h264dsp.h264_h_loop_filter_luma_mbaff(pix, stride, alpha, beta, tc);
00166     } else {
00167         h->h264dsp.h264_h_loop_filter_luma_mbaff_intra(pix, stride, alpha, beta);
00168     }
00169 }
00170 
00171 static av_always_inline void filter_mb_mbaff_edgecv(H264Context *h,
00172                                                     uint8_t *pix, int stride,
00173                                                     const int16_t bS[7],
00174                                                     int bsi, int qp, int a,
00175                                                     int b, int intra)
00176 {
00177     const unsigned int index_a = qp + a;
00178     const int alpha = alpha_table[index_a];
00179     const int beta  = beta_table[qp + b];
00180     if (alpha ==0 || beta == 0) return;
00181 
00182     if( bS[0] < 4 || !intra ) {
00183         int8_t tc[4];
00184         tc[0] = tc0_table[index_a][bS[0*bsi]] + 1;
00185         tc[1] = tc0_table[index_a][bS[1*bsi]] + 1;
00186         tc[2] = tc0_table[index_a][bS[2*bsi]] + 1;
00187         tc[3] = tc0_table[index_a][bS[3*bsi]] + 1;
00188         h->h264dsp.h264_h_loop_filter_chroma_mbaff(pix, stride, alpha, beta, tc);
00189     } else {
00190         h->h264dsp.h264_h_loop_filter_chroma_mbaff_intra(pix, stride, alpha, beta);
00191     }
00192 }
00193 
00194 static av_always_inline void filter_mb_edgeh(uint8_t *pix, int stride,
00195                                              const int16_t bS[4],
00196                                              unsigned int qp, int a, int b,
00197                                              H264Context *h, int intra)
00198 {
00199     const unsigned int index_a = qp + a;
00200     const int alpha = alpha_table[index_a];
00201     const int beta  = beta_table[qp + b];
00202     if (alpha ==0 || beta == 0) return;
00203 
00204     if( bS[0] < 4 || !intra ) {
00205         int8_t tc[4];
00206         tc[0] = tc0_table[index_a][bS[0]];
00207         tc[1] = tc0_table[index_a][bS[1]];
00208         tc[2] = tc0_table[index_a][bS[2]];
00209         tc[3] = tc0_table[index_a][bS[3]];
00210         h->h264dsp.h264_v_loop_filter_luma(pix, stride, alpha, beta, tc);
00211     } else {
00212         h->h264dsp.h264_v_loop_filter_luma_intra(pix, stride, alpha, beta);
00213     }
00214 }
00215 
00216 static av_always_inline void filter_mb_edgech(uint8_t *pix, int stride,
00217                                               const int16_t bS[4],
00218                                               unsigned int qp, int a, int b,
00219                                               H264Context *h, int intra)
00220 {
00221     const unsigned int index_a = qp + a;
00222     const int alpha = alpha_table[index_a];
00223     const int beta  = beta_table[qp + b];
00224     if (alpha ==0 || beta == 0) return;
00225 
00226     if( bS[0] < 4 || !intra ) {
00227         int8_t tc[4];
00228         tc[0] = tc0_table[index_a][bS[0]]+1;
00229         tc[1] = tc0_table[index_a][bS[1]]+1;
00230         tc[2] = tc0_table[index_a][bS[2]]+1;
00231         tc[3] = tc0_table[index_a][bS[3]]+1;
00232         h->h264dsp.h264_v_loop_filter_chroma(pix, stride, alpha, beta, tc);
00233     } else {
00234         h->h264dsp.h264_v_loop_filter_chroma_intra(pix, stride, alpha, beta);
00235     }
00236 }
00237 
00238 static av_always_inline void h264_filter_mb_fast_internal(H264Context *h,
00239                                                           int mb_x, int mb_y,
00240                                                           uint8_t *img_y,
00241                                                           uint8_t *img_cb,
00242                                                           uint8_t *img_cr,
00243                                                           unsigned int linesize,
00244                                                           unsigned int uvlinesize,
00245                                                           int pixel_shift)
00246 {
00247     MpegEncContext * const s = &h->s;
00248     int chroma = !(CONFIG_GRAY && (s->flags&CODEC_FLAG_GRAY));
00249     int chroma444 = CHROMA444;
00250     int chroma422 = CHROMA422;
00251 
00252     int mb_xy = h->mb_xy;
00253     int left_type= h->left_type[LTOP];
00254     int top_type= h->top_type;
00255 
00256     int qp_bd_offset = 6 * (h->sps.bit_depth_luma - 8);
00257     int a = h->slice_alpha_c0_offset - qp_bd_offset;
00258     int b = h->slice_beta_offset - qp_bd_offset;
00259 
00260     int mb_type = s->current_picture.f.mb_type[mb_xy];
00261     int qp      = s->current_picture.f.qscale_table[mb_xy];
00262     int qp0     = s->current_picture.f.qscale_table[mb_xy - 1];
00263     int qp1     = s->current_picture.f.qscale_table[h->top_mb_xy];
00264     int qpc = get_chroma_qp( h, 0, qp );
00265     int qpc0 = get_chroma_qp( h, 0, qp0 );
00266     int qpc1 = get_chroma_qp( h, 0, qp1 );
00267     qp0 = (qp + qp0 + 1) >> 1;
00268     qp1 = (qp + qp1 + 1) >> 1;
00269     qpc0 = (qpc + qpc0 + 1) >> 1;
00270     qpc1 = (qpc + qpc1 + 1) >> 1;
00271 
00272     if( IS_INTRA(mb_type) ) {
00273         static const int16_t bS4[4] = {4,4,4,4};
00274         static const int16_t bS3[4] = {3,3,3,3};
00275         const int16_t *bSH = FIELD_PICTURE ? bS3 : bS4;
00276         if(left_type)
00277             filter_mb_edgev( &img_y[4*0<<pixel_shift], linesize, bS4, qp0, a, b, h, 1);
00278         if( IS_8x8DCT(mb_type) ) {
00279             filter_mb_edgev( &img_y[4*2<<pixel_shift], linesize, bS3, qp, a, b, h, 0);
00280             if(top_type){
00281                 filter_mb_edgeh( &img_y[4*0*linesize], linesize, bSH, qp1, a, b, h, 1);
00282             }
00283             filter_mb_edgeh( &img_y[4*2*linesize], linesize, bS3, qp, a, b, h, 0);
00284         } else {
00285             filter_mb_edgev( &img_y[4*1<<pixel_shift], linesize, bS3, qp, a, b, h, 0);
00286             filter_mb_edgev( &img_y[4*2<<pixel_shift], linesize, bS3, qp, a, b, h, 0);
00287             filter_mb_edgev( &img_y[4*3<<pixel_shift], linesize, bS3, qp, a, b, h, 0);
00288             if(top_type){
00289                 filter_mb_edgeh( &img_y[4*0*linesize], linesize, bSH, qp1, a, b, h, 1);
00290             }
00291             filter_mb_edgeh( &img_y[4*1*linesize], linesize, bS3, qp, a, b, h, 0);
00292             filter_mb_edgeh( &img_y[4*2*linesize], linesize, bS3, qp, a, b, h, 0);
00293             filter_mb_edgeh( &img_y[4*3*linesize], linesize, bS3, qp, a, b, h, 0);
00294         }
00295         if(chroma){
00296             if(chroma444){
00297                 if(left_type){
00298                     filter_mb_edgev( &img_cb[4*0<<pixel_shift], linesize, bS4, qpc0, a, b, h, 1);
00299                     filter_mb_edgev( &img_cr[4*0<<pixel_shift], linesize, bS4, qpc0, a, b, h, 1);
00300                 }
00301                 if( IS_8x8DCT(mb_type) ) {
00302                     filter_mb_edgev( &img_cb[4*2<<pixel_shift], linesize, bS3, qpc, a, b, h, 0);
00303                     filter_mb_edgev( &img_cr[4*2<<pixel_shift], linesize, bS3, qpc, a, b, h, 0);
00304                     if(top_type){
00305                         filter_mb_edgeh( &img_cb[4*0*linesize], linesize, bSH, qpc1, a, b, h, 1 );
00306                         filter_mb_edgeh( &img_cr[4*0*linesize], linesize, bSH, qpc1, a, b, h, 1 );
00307                     }
00308                     filter_mb_edgeh( &img_cb[4*2*linesize], linesize, bS3, qpc, a, b, h, 0);
00309                     filter_mb_edgeh( &img_cr[4*2*linesize], linesize, bS3, qpc, a, b, h, 0);
00310                 } else {
00311                     filter_mb_edgev( &img_cb[4*1<<pixel_shift], linesize, bS3, qpc, a, b, h, 0);
00312                     filter_mb_edgev( &img_cr[4*1<<pixel_shift], linesize, bS3, qpc, a, b, h, 0);
00313                     filter_mb_edgev( &img_cb[4*2<<pixel_shift], linesize, bS3, qpc, a, b, h, 0);
00314                     filter_mb_edgev( &img_cr[4*2<<pixel_shift], linesize, bS3, qpc, a, b, h, 0);
00315                     filter_mb_edgev( &img_cb[4*3<<pixel_shift], linesize, bS3, qpc, a, b, h, 0);
00316                     filter_mb_edgev( &img_cr[4*3<<pixel_shift], linesize, bS3, qpc, a, b, h, 0);
00317                     if(top_type){
00318                         filter_mb_edgeh( &img_cb[4*0*linesize], linesize, bSH, qpc1, a, b, h, 1);
00319                         filter_mb_edgeh( &img_cr[4*0*linesize], linesize, bSH, qpc1, a, b, h, 1);
00320                     }
00321                     filter_mb_edgeh( &img_cb[4*1*linesize], linesize, bS3, qpc, a, b, h, 0);
00322                     filter_mb_edgeh( &img_cr[4*1*linesize], linesize, bS3, qpc, a, b, h, 0);
00323                     filter_mb_edgeh( &img_cb[4*2*linesize], linesize, bS3, qpc, a, b, h, 0);
00324                     filter_mb_edgeh( &img_cr[4*2*linesize], linesize, bS3, qpc, a, b, h, 0);
00325                     filter_mb_edgeh( &img_cb[4*3*linesize], linesize, bS3, qpc, a, b, h, 0);
00326                     filter_mb_edgeh( &img_cr[4*3*linesize], linesize, bS3, qpc, a, b, h, 0);
00327                 }
00328             }else if(chroma422){
00329                 if(left_type){
00330                     filter_mb_edgecv(&img_cb[2*0<<pixel_shift], uvlinesize, bS4, qpc0, a, b, h, 1);
00331                     filter_mb_edgecv(&img_cr[2*0<<pixel_shift], uvlinesize, bS4, qpc0, a, b, h, 1);
00332                 }
00333                 filter_mb_edgecv(&img_cb[2*2<<pixel_shift], uvlinesize, bS3, qpc, a, b, h, 0);
00334                 filter_mb_edgecv(&img_cr[2*2<<pixel_shift], uvlinesize, bS3, qpc, a, b, h, 0);
00335                 if(top_type){
00336                     filter_mb_edgech(&img_cb[4*0*uvlinesize], uvlinesize, bSH, qpc1, a, b, h, 1);
00337                     filter_mb_edgech(&img_cr[4*0*uvlinesize], uvlinesize, bSH, qpc1, a, b, h, 1);
00338                 }
00339                 filter_mb_edgech(&img_cb[4*1*uvlinesize], uvlinesize, bS3, qpc, a, b, h, 0);
00340                 filter_mb_edgech(&img_cr[4*1*uvlinesize], uvlinesize, bS3, qpc, a, b, h, 0);
00341                 filter_mb_edgech(&img_cb[4*2*uvlinesize], uvlinesize, bS3, qpc, a, b, h, 0);
00342                 filter_mb_edgech(&img_cr[4*2*uvlinesize], uvlinesize, bS3, qpc, a, b, h, 0);
00343                 filter_mb_edgech(&img_cb[4*3*uvlinesize], uvlinesize, bS3, qpc, a, b, h, 0);
00344                 filter_mb_edgech(&img_cr[4*3*uvlinesize], uvlinesize, bS3, qpc, a, b, h, 0);
00345             }else{
00346                 if(left_type){
00347                     filter_mb_edgecv( &img_cb[2*0<<pixel_shift], uvlinesize, bS4, qpc0, a, b, h, 1);
00348                     filter_mb_edgecv( &img_cr[2*0<<pixel_shift], uvlinesize, bS4, qpc0, a, b, h, 1);
00349                 }
00350                 filter_mb_edgecv( &img_cb[2*2<<pixel_shift], uvlinesize, bS3, qpc, a, b, h, 0);
00351                 filter_mb_edgecv( &img_cr[2*2<<pixel_shift], uvlinesize, bS3, qpc, a, b, h, 0);
00352                 if(top_type){
00353                     filter_mb_edgech( &img_cb[2*0*uvlinesize], uvlinesize, bSH, qpc1, a, b, h, 1);
00354                     filter_mb_edgech( &img_cr[2*0*uvlinesize], uvlinesize, bSH, qpc1, a, b, h, 1);
00355                 }
00356                 filter_mb_edgech( &img_cb[2*2*uvlinesize], uvlinesize, bS3, qpc, a, b, h, 0);
00357                 filter_mb_edgech( &img_cr[2*2*uvlinesize], uvlinesize, bS3, qpc, a, b, h, 0);
00358             }
00359         }
00360         return;
00361     } else {
00362         LOCAL_ALIGNED_8(int16_t, bS, [2], [4][4]);
00363         int edges;
00364         if( IS_8x8DCT(mb_type) && (h->cbp&7) == 7 && !chroma444 ) {
00365             edges = 4;
00366             AV_WN64A(bS[0][0], 0x0002000200020002ULL);
00367             AV_WN64A(bS[0][2], 0x0002000200020002ULL);
00368             AV_WN64A(bS[1][0], 0x0002000200020002ULL);
00369             AV_WN64A(bS[1][2], 0x0002000200020002ULL);
00370         } else {
00371             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;
00372             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;
00373             int step =  1+(mb_type>>24); //IS_8x8DCT(mb_type) ? 2 : 1;
00374             edges = 4 - 3*((mb_type>>3) & !(h->cbp & 15)); //(mb_type & MB_TYPE_16x16) && !(h->cbp & 15) ? 1 : 4;
00375             h->h264dsp.h264_loop_filter_strength( bS, h->non_zero_count_cache, h->ref_cache, h->mv_cache,
00376                                               h->list_count==2, edges, step, mask_edge0, mask_edge1, FIELD_PICTURE);
00377         }
00378         if( IS_INTRA(left_type) )
00379             AV_WN64A(bS[0][0], 0x0004000400040004ULL);
00380         if( IS_INTRA(top_type) )
00381             AV_WN64A(bS[1][0], FIELD_PICTURE ? 0x0003000300030003ULL : 0x0004000400040004ULL);
00382 
00383 #define FILTER(hv,dir,edge,intra)\
00384         if(AV_RN64A(bS[dir][edge])) {                                   \
00385             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 );\
00386             if(chroma){\
00387                 if(chroma444){\
00388                     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 );\
00389                     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 );\
00390                 } else if(!(edge&1)) {\
00391                     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 );\
00392                     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 );\
00393                 }\
00394             }\
00395         }
00396         if(left_type)
00397             FILTER(v,0,0,1);
00398         if( edges == 1 ) {
00399             if(top_type)
00400                 FILTER(h,1,0,1);
00401         } else if( IS_8x8DCT(mb_type) ) {
00402             FILTER(v,0,2,0);
00403             if(top_type)
00404                 FILTER(h,1,0,1);
00405             FILTER(h,1,2,0);
00406         } else {
00407             FILTER(v,0,1,0);
00408             FILTER(v,0,2,0);
00409             FILTER(v,0,3,0);
00410             if(top_type)
00411                 FILTER(h,1,0,1);
00412             FILTER(h,1,1,0);
00413             FILTER(h,1,2,0);
00414             FILTER(h,1,3,0);
00415         }
00416 #undef FILTER
00417     }
00418 }
00419 
00420 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) {
00421     assert(!FRAME_MBAFF);
00422     if(!h->h264dsp.h264_loop_filter_strength || h->pps.chroma_qp_diff) {
00423         ff_h264_filter_mb(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize);
00424         return;
00425     }
00426 
00427 #if CONFIG_SMALL
00428     h264_filter_mb_fast_internal(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, h->pixel_shift);
00429 #else
00430     if(h->pixel_shift){
00431         h264_filter_mb_fast_internal(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, 1);
00432     }else{
00433         h264_filter_mb_fast_internal(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, 0);
00434     }
00435 #endif
00436 }
00437 
00438 static int check_mv(H264Context *h, long b_idx, long bn_idx, int mvy_limit){
00439     int v;
00440 
00441     v= h->ref_cache[0][b_idx] != h->ref_cache[0][bn_idx];
00442     if(!v && h->ref_cache[0][b_idx]!=-1)
00443         v= h->mv_cache[0][b_idx][0] - h->mv_cache[0][bn_idx][0] + 3 >= 7U |
00444            FFABS( h->mv_cache[0][b_idx][1] - h->mv_cache[0][bn_idx][1] ) >= mvy_limit;
00445 
00446     if(h->list_count==2){
00447         if(!v)
00448             v = h->ref_cache[1][b_idx] != h->ref_cache[1][bn_idx] |
00449                 h->mv_cache[1][b_idx][0] - h->mv_cache[1][bn_idx][0] + 3 >= 7U |
00450                 FFABS( h->mv_cache[1][b_idx][1] - h->mv_cache[1][bn_idx][1] ) >= mvy_limit;
00451 
00452         if(v){
00453             if(h->ref_cache[0][b_idx] != h->ref_cache[1][bn_idx] |
00454                h->ref_cache[1][b_idx] != h->ref_cache[0][bn_idx])
00455                 return 1;
00456             return
00457                 h->mv_cache[0][b_idx][0] - h->mv_cache[1][bn_idx][0] + 3 >= 7U |
00458                 FFABS( h->mv_cache[0][b_idx][1] - h->mv_cache[1][bn_idx][1] ) >= mvy_limit |
00459                 h->mv_cache[1][b_idx][0] - h->mv_cache[0][bn_idx][0] + 3 >= 7U |
00460                 FFABS( h->mv_cache[1][b_idx][1] - h->mv_cache[0][bn_idx][1] ) >= mvy_limit;
00461         }
00462     }
00463 
00464     return v;
00465 }
00466 
00467 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 a, int b, int chroma, int dir) {
00468     MpegEncContext * const s = &h->s;
00469     int edge;
00470     int chroma_qp_avg[2];
00471     int chroma444 = CHROMA444;
00472     int chroma422 = CHROMA422;
00473     const int mbm_xy = dir == 0 ? mb_xy -1 : h->top_mb_xy;
00474     const int mbm_type = dir == 0 ? h->left_type[LTOP] : h->top_type;
00475 
00476     // how often to recheck mv-based bS when iterating between edges
00477     static const uint8_t mask_edge_tab[2][8]={{0,3,3,3,1,1,1,1},
00478                                               {0,3,1,1,3,3,3,3}};
00479     const int mask_edge = mask_edge_tab[dir][(mb_type>>3)&7];
00480     const int edges = mask_edge== 3 && !(h->cbp&15) ? 1 : 4;
00481 
00482     // how often to recheck mv-based bS when iterating along each edge
00483     const int mask_par0 = mb_type & (MB_TYPE_16x16 | (MB_TYPE_8x16 >> dir));
00484 
00485     if(mbm_type && !first_vertical_edge_done){
00486 
00487         if (FRAME_MBAFF && (dir == 1) && ((mb_y&1) == 0)
00488             && IS_INTERLACED(mbm_type&~mb_type)
00489             ) {
00490             // This is a special case in the norm where the filtering must
00491             // be done twice (one each of the field) even if we are in a
00492             // frame macroblock.
00493             //
00494             unsigned int tmp_linesize   = 2 *   linesize;
00495             unsigned int tmp_uvlinesize = 2 * uvlinesize;
00496             int mbn_xy = mb_xy - 2 * s->mb_stride;
00497             int j;
00498 
00499             for(j=0; j<2; j++, mbn_xy += s->mb_stride){
00500                 DECLARE_ALIGNED(8, int16_t, bS)[4];
00501                 int qp;
00502                 if (IS_INTRA(mb_type | s->current_picture.f.mb_type[mbn_xy])) {
00503                     AV_WN64A(bS, 0x0003000300030003ULL);
00504                 } else {
00505                     if (!CABAC && IS_8x8DCT(s->current_picture.f.mb_type[mbn_xy])) {
00506                         bS[0]= 1+((h->cbp_table[mbn_xy] & 0x4000)||h->non_zero_count_cache[scan8[0]+0]);
00507                         bS[1]= 1+((h->cbp_table[mbn_xy] & 0x4000)||h->non_zero_count_cache[scan8[0]+1]);
00508                         bS[2]= 1+((h->cbp_table[mbn_xy] & 0x8000)||h->non_zero_count_cache[scan8[0]+2]);
00509                         bS[3]= 1+((h->cbp_table[mbn_xy] & 0x8000)||h->non_zero_count_cache[scan8[0]+3]);
00510                     }else{
00511                     const uint8_t *mbn_nnz = h->non_zero_count[mbn_xy] + 3*4;
00512                     int i;
00513                     for( i = 0; i < 4; i++ ) {
00514                         bS[i] = 1 + !!(h->non_zero_count_cache[scan8[0]+i] | mbn_nnz[i]);
00515                     }
00516                     }
00517                 }
00518                 // Do not use s->qscale as luma quantizer because it has not the same
00519                 // value in IPCM macroblocks.
00520                 qp = (s->current_picture.f.qscale_table[mb_xy] + s->current_picture.f.qscale_table[mbn_xy] + 1) >> 1;
00521                 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);
00522                 { int i; for (i = 0; i < 4; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); }
00523                 filter_mb_edgeh( &img_y[j*linesize], tmp_linesize, bS, qp, a, b, h, 0 );
00524                 chroma_qp_avg[0] = (h->chroma_qp[0] + get_chroma_qp(h, 0, s->current_picture.f.qscale_table[mbn_xy]) + 1) >> 1;
00525                 chroma_qp_avg[1] = (h->chroma_qp[1] + get_chroma_qp(h, 1, s->current_picture.f.qscale_table[mbn_xy]) + 1) >> 1;
00526                 if (chroma) {
00527                     if (chroma444) {
00528                         filter_mb_edgeh (&img_cb[j*uvlinesize], tmp_uvlinesize, bS, chroma_qp_avg[0], a, b, h, 0);
00529                         filter_mb_edgeh (&img_cr[j*uvlinesize], tmp_uvlinesize, bS, chroma_qp_avg[1], a, b, h, 0);
00530                     } else {
00531                         filter_mb_edgech(&img_cb[j*uvlinesize], tmp_uvlinesize, bS, chroma_qp_avg[0], a, b, h, 0);
00532                         filter_mb_edgech(&img_cr[j*uvlinesize], tmp_uvlinesize, bS, chroma_qp_avg[1], a, b, h, 0);
00533                     }
00534                 }
00535             }
00536         }else{
00537             DECLARE_ALIGNED(8, int16_t, bS)[4];
00538             int qp;
00539 
00540             if( IS_INTRA(mb_type|mbm_type)) {
00541                 AV_WN64A(bS, 0x0003000300030003ULL);
00542                 if (   (!IS_INTERLACED(mb_type|mbm_type))
00543                     || ((FRAME_MBAFF || (s->picture_structure != PICT_FRAME)) && (dir == 0))
00544                 )
00545                     AV_WN64A(bS, 0x0004000400040004ULL);
00546             } else {
00547                 int i;
00548                 int mv_done;
00549 
00550                 if( dir && FRAME_MBAFF && IS_INTERLACED(mb_type ^ mbm_type)) {
00551                     AV_WN64A(bS, 0x0001000100010001ULL);
00552                     mv_done = 1;
00553                 }
00554                 else if( mask_par0 && ((mbm_type & (MB_TYPE_16x16 | (MB_TYPE_8x16 >> dir)))) ) {
00555                     int b_idx= 8 + 4;
00556                     int bn_idx= b_idx - (dir ? 8:1);
00557 
00558                     bS[0] = bS[1] = bS[2] = bS[3] = check_mv(h, 8 + 4, bn_idx, mvy_limit);
00559                     mv_done = 1;
00560                 }
00561                 else
00562                     mv_done = 0;
00563 
00564                 for( i = 0; i < 4; i++ ) {
00565                     int x = dir == 0 ? 0 : i;
00566                     int y = dir == 0 ? i    : 0;
00567                     int b_idx= 8 + 4 + x + 8*y;
00568                     int bn_idx= b_idx - (dir ? 8:1);
00569 
00570                     if( h->non_zero_count_cache[b_idx] |
00571                         h->non_zero_count_cache[bn_idx] ) {
00572                         bS[i] = 2;
00573                     }
00574                     else if(!mv_done)
00575                     {
00576                         bS[i] = check_mv(h, b_idx, bn_idx, mvy_limit);
00577                     }
00578                 }
00579             }
00580 
00581             /* Filter edge */
00582             // Do not use s->qscale as luma quantizer because it has not the same
00583             // value in IPCM macroblocks.
00584             if(bS[0]+bS[1]+bS[2]+bS[3]){
00585                 qp = (s->current_picture.f.qscale_table[mb_xy] + s->current_picture.f.qscale_table[mbm_xy] + 1) >> 1;
00586                 //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]);
00587                 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);
00588                 //{ int i; for (i = 0; i < 4; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); }
00589                 chroma_qp_avg[0] = (h->chroma_qp[0] + get_chroma_qp(h, 0, s->current_picture.f.qscale_table[mbm_xy]) + 1) >> 1;
00590                 chroma_qp_avg[1] = (h->chroma_qp[1] + get_chroma_qp(h, 1, s->current_picture.f.qscale_table[mbm_xy]) + 1) >> 1;
00591                 if( dir == 0 ) {
00592                     filter_mb_edgev( &img_y[0], linesize, bS, qp, a, b, h, 1 );
00593                     if (chroma) {
00594                         if (chroma444) {
00595                             filter_mb_edgev ( &img_cb[0], uvlinesize, bS, chroma_qp_avg[0], a, b, h, 1);
00596                             filter_mb_edgev ( &img_cr[0], uvlinesize, bS, chroma_qp_avg[1], a, b, h, 1);
00597                         } else {
00598                             filter_mb_edgecv( &img_cb[0], uvlinesize, bS, chroma_qp_avg[0], a, b, h, 1);
00599                             filter_mb_edgecv( &img_cr[0], uvlinesize, bS, chroma_qp_avg[1], a, b, h, 1);
00600                         }
00601                     }
00602                 } else {
00603                     filter_mb_edgeh( &img_y[0], linesize, bS, qp, a, b, h, 1 );
00604                     if (chroma) {
00605                         if (chroma444) {
00606                             filter_mb_edgeh ( &img_cb[0], uvlinesize, bS, chroma_qp_avg[0], a, b, h, 1);
00607                             filter_mb_edgeh ( &img_cr[0], uvlinesize, bS, chroma_qp_avg[1], a, b, h, 1);
00608                         } else {
00609                             filter_mb_edgech( &img_cb[0], uvlinesize, bS, chroma_qp_avg[0], a, b, h, 1);
00610                             filter_mb_edgech( &img_cr[0], uvlinesize, bS, chroma_qp_avg[1], a, b, h, 1);
00611                         }
00612                     }
00613                 }
00614             }
00615         }
00616     }
00617 
00618     /* Calculate bS */
00619     for( edge = 1; edge < edges; edge++ ) {
00620         DECLARE_ALIGNED(8, int16_t, bS)[4];
00621         int qp;
00622         const int deblock_edge = !IS_8x8DCT(mb_type & (edge<<24)); // (edge&1) && IS_8x8DCT(mb_type)
00623 
00624         if (!deblock_edge && (!chroma422 || dir == 0))
00625             continue;
00626 
00627         if( IS_INTRA(mb_type)) {
00628             AV_WN64A(bS, 0x0003000300030003ULL);
00629         } else {
00630             int i;
00631             int mv_done;
00632 
00633             if( edge & mask_edge ) {
00634                 AV_ZERO64(bS);
00635                 mv_done = 1;
00636             }
00637             else if( mask_par0 ) {
00638                 int b_idx= 8 + 4 + edge * (dir ? 8:1);
00639                 int bn_idx= b_idx - (dir ? 8:1);
00640 
00641                 bS[0] = bS[1] = bS[2] = bS[3] = check_mv(h, b_idx, bn_idx, mvy_limit);
00642                 mv_done = 1;
00643             }
00644             else
00645                 mv_done = 0;
00646 
00647             for( i = 0; i < 4; i++ ) {
00648                 int x = dir == 0 ? edge : i;
00649                 int y = dir == 0 ? i    : edge;
00650                 int b_idx= 8 + 4 + x + 8*y;
00651                 int bn_idx= b_idx - (dir ? 8:1);
00652 
00653                 if( h->non_zero_count_cache[b_idx] |
00654                     h->non_zero_count_cache[bn_idx] ) {
00655                     bS[i] = 2;
00656                 }
00657                 else if(!mv_done)
00658                 {
00659                     bS[i] = check_mv(h, b_idx, bn_idx, mvy_limit);
00660                 }
00661             }
00662 
00663             if(bS[0]+bS[1]+bS[2]+bS[3] == 0)
00664                 continue;
00665         }
00666 
00667         /* Filter edge */
00668         // Do not use s->qscale as luma quantizer because it has not the same
00669         // value in IPCM macroblocks.
00670         qp = s->current_picture.f.qscale_table[mb_xy];
00671         //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]);
00672         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);
00673         //{ int i; for (i = 0; i < 4; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); }
00674         if( dir == 0 ) {
00675             filter_mb_edgev( &img_y[4*edge << h->pixel_shift], linesize, bS, qp, a, b, h, 0 );
00676             if (chroma) {
00677                 if (chroma444) {
00678                     filter_mb_edgev ( &img_cb[4*edge << h->pixel_shift], uvlinesize, bS, h->chroma_qp[0], a, b, h, 0);
00679                     filter_mb_edgev ( &img_cr[4*edge << h->pixel_shift], uvlinesize, bS, h->chroma_qp[1], a, b, h, 0);
00680                 } else if( (edge&1) == 0 ) {
00681                     filter_mb_edgecv( &img_cb[2*edge << h->pixel_shift], uvlinesize, bS, h->chroma_qp[0], a, b, h, 0);
00682                     filter_mb_edgecv( &img_cr[2*edge << h->pixel_shift], uvlinesize, bS, h->chroma_qp[1], a, b, h, 0);
00683                 }
00684             }
00685         } else {
00686             if (chroma422) {
00687                 if (deblock_edge)
00688                     filter_mb_edgeh(&img_y[4*edge*linesize], linesize, bS, qp, a, b, h, 0);
00689                 if (chroma) {
00690                     filter_mb_edgech(&img_cb[4*edge*uvlinesize], uvlinesize, bS, h->chroma_qp[0], a, b, h, 0);
00691                     filter_mb_edgech(&img_cr[4*edge*uvlinesize], uvlinesize, bS, h->chroma_qp[1], a, b, h, 0);
00692                 }
00693             } else {
00694                 filter_mb_edgeh(&img_y[4*edge*linesize], linesize, bS, qp, a, b, h, 0);
00695                 if (chroma) {
00696                     if (chroma444) {
00697                         filter_mb_edgeh (&img_cb[4*edge*uvlinesize], uvlinesize, bS, h->chroma_qp[0], a, b, h, 0);
00698                         filter_mb_edgeh (&img_cr[4*edge*uvlinesize], uvlinesize, bS, h->chroma_qp[1], a, b, h, 0);
00699                     } else if ((edge&1) == 0) {
00700                         filter_mb_edgech(&img_cb[2*edge*uvlinesize], uvlinesize, bS, h->chroma_qp[0], a, b, h, 0);
00701                         filter_mb_edgech(&img_cr[2*edge*uvlinesize], uvlinesize, bS, h->chroma_qp[1], a, b, h, 0);
00702                     }
00703                 }
00704             }
00705         }
00706     }
00707 }
00708 
00709 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) {
00710     MpegEncContext * const s = &h->s;
00711     const int mb_xy= mb_x + mb_y*s->mb_stride;
00712     const int mb_type = s->current_picture.f.mb_type[mb_xy];
00713     const int mvy_limit = IS_INTERLACED(mb_type) ? 2 : 4;
00714     int first_vertical_edge_done = 0;
00715     av_unused int dir;
00716     int chroma = !(CONFIG_GRAY && (s->flags&CODEC_FLAG_GRAY));
00717     int qp_bd_offset = 6 * (h->sps.bit_depth_luma - 8);
00718     int a = h->slice_alpha_c0_offset - qp_bd_offset;
00719     int b = h->slice_beta_offset - qp_bd_offset;
00720 
00721     if (FRAME_MBAFF
00722             // and current and left pair do not have the same interlaced type
00723             && IS_INTERLACED(mb_type^h->left_type[LTOP])
00724             // and left mb is in available to us
00725             && h->left_type[LTOP]) {
00726         /* First vertical edge is different in MBAFF frames
00727          * There are 8 different bS to compute and 2 different Qp
00728          */
00729         DECLARE_ALIGNED(8, int16_t, bS)[8];
00730         int qp[2];
00731         int bqp[2];
00732         int rqp[2];
00733         int mb_qp, mbn0_qp, mbn1_qp;
00734         int i;
00735         first_vertical_edge_done = 1;
00736 
00737         if( IS_INTRA(mb_type) ) {
00738             AV_WN64A(&bS[0], 0x0004000400040004ULL);
00739             AV_WN64A(&bS[4], 0x0004000400040004ULL);
00740         } else {
00741             static const uint8_t offset[2][2][8]={
00742                 {
00743                     {3+4*0, 3+4*0, 3+4*0, 3+4*0, 3+4*1, 3+4*1, 3+4*1, 3+4*1},
00744                     {3+4*2, 3+4*2, 3+4*2, 3+4*2, 3+4*3, 3+4*3, 3+4*3, 3+4*3},
00745                 },{
00746                     {3+4*0, 3+4*1, 3+4*2, 3+4*3, 3+4*0, 3+4*1, 3+4*2, 3+4*3},
00747                     {3+4*0, 3+4*1, 3+4*2, 3+4*3, 3+4*0, 3+4*1, 3+4*2, 3+4*3},
00748                 }
00749             };
00750             const uint8_t *off= offset[MB_FIELD][mb_y&1];
00751             for( i = 0; i < 8; i++ ) {
00752                 int j= MB_FIELD ? i>>2 : i&1;
00753                 int mbn_xy = h->left_mb_xy[LEFT(j)];
00754                 int mbn_type= h->left_type[LEFT(j)];
00755 
00756                 if( IS_INTRA( mbn_type ) )
00757                     bS[i] = 4;
00758                 else{
00759                     bS[i] = 1 + !!(h->non_zero_count_cache[12+8*(i>>1)] |
00760                          ((!h->pps.cabac && IS_8x8DCT(mbn_type)) ?
00761                             (h->cbp_table[mbn_xy] & (((MB_FIELD ? (i&2) : (mb_y&1)) ? 8 : 2) << 12))
00762                                                                        :
00763                             h->non_zero_count[mbn_xy][ off[i] ]));
00764                 }
00765             }
00766         }
00767 
00768         mb_qp   = s->current_picture.f.qscale_table[mb_xy];
00769         mbn0_qp = s->current_picture.f.qscale_table[h->left_mb_xy[0]];
00770         mbn1_qp = s->current_picture.f.qscale_table[h->left_mb_xy[1]];
00771         qp[0] = ( mb_qp + mbn0_qp + 1 ) >> 1;
00772         bqp[0] = ( get_chroma_qp( h, 0, mb_qp ) +
00773                    get_chroma_qp( h, 0, mbn0_qp ) + 1 ) >> 1;
00774         rqp[0] = ( get_chroma_qp( h, 1, mb_qp ) +
00775                    get_chroma_qp( h, 1, mbn0_qp ) + 1 ) >> 1;
00776         qp[1] = ( mb_qp + mbn1_qp + 1 ) >> 1;
00777         bqp[1] = ( get_chroma_qp( h, 0, mb_qp ) +
00778                    get_chroma_qp( h, 0, mbn1_qp ) + 1 ) >> 1;
00779         rqp[1] = ( get_chroma_qp( h, 1, mb_qp ) +
00780                    get_chroma_qp( h, 1, mbn1_qp ) + 1 ) >> 1;
00781 
00782         /* Filter edge */
00783         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);
00784         { int i; for (i = 0; i < 8; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); }
00785         if(MB_FIELD){
00786             filter_mb_mbaff_edgev ( h, img_y                ,   linesize, bS  , 1, qp [0], a, b, 1 );
00787             filter_mb_mbaff_edgev ( h, img_y  + 8*  linesize,   linesize, bS+4, 1, qp [1], a, b, 1 );
00788             if (chroma){
00789                 if (CHROMA444) {
00790                     filter_mb_mbaff_edgev ( h, img_cb,                uvlinesize, bS  , 1, bqp[0], a, b, 1 );
00791                     filter_mb_mbaff_edgev ( h, img_cb + 8*uvlinesize, uvlinesize, bS+4, 1, bqp[1], a, b, 1 );
00792                     filter_mb_mbaff_edgev ( h, img_cr,                uvlinesize, bS  , 1, rqp[0], a, b, 1 );
00793                     filter_mb_mbaff_edgev ( h, img_cr + 8*uvlinesize, uvlinesize, bS+4, 1, rqp[1], a, b, 1 );
00794                 } else if (CHROMA422) {
00795                     filter_mb_mbaff_edgecv(h, img_cb,                uvlinesize, bS  , 1, bqp[0], a, b, 1);
00796                     filter_mb_mbaff_edgecv(h, img_cb + 8*uvlinesize, uvlinesize, bS+4, 1, bqp[1], a, b, 1);
00797                     filter_mb_mbaff_edgecv(h, img_cr,                uvlinesize, bS  , 1, rqp[0], a, b, 1);
00798                     filter_mb_mbaff_edgecv(h, img_cr + 8*uvlinesize, uvlinesize, bS+4, 1, rqp[1], a, b, 1);
00799                 }else{
00800                     filter_mb_mbaff_edgecv( h, img_cb,                uvlinesize, bS  , 1, bqp[0], a, b, 1 );
00801                     filter_mb_mbaff_edgecv( h, img_cb + 4*uvlinesize, uvlinesize, bS+4, 1, bqp[1], a, b, 1 );
00802                     filter_mb_mbaff_edgecv( h, img_cr,                uvlinesize, bS  , 1, rqp[0], a, b, 1 );
00803                     filter_mb_mbaff_edgecv( h, img_cr + 4*uvlinesize, uvlinesize, bS+4, 1, rqp[1], a, b, 1 );
00804                 }
00805             }
00806         }else{
00807             filter_mb_mbaff_edgev ( h, img_y              , 2*  linesize, bS  , 2, qp [0], a, b, 1 );
00808             filter_mb_mbaff_edgev ( h, img_y  +   linesize, 2*  linesize, bS+1, 2, qp [1], a, b, 1 );
00809             if (chroma){
00810                 if (CHROMA444) {
00811                     filter_mb_mbaff_edgev ( h, img_cb,              2*uvlinesize, bS  , 2, bqp[0], a, b, 1 );
00812                     filter_mb_mbaff_edgev ( h, img_cb + uvlinesize, 2*uvlinesize, bS+1, 2, bqp[1], a, b, 1 );
00813                     filter_mb_mbaff_edgev ( h, img_cr,              2*uvlinesize, bS  , 2, rqp[0], a, b, 1 );
00814                     filter_mb_mbaff_edgev ( h, img_cr + uvlinesize, 2*uvlinesize, bS+1, 2, rqp[1], a, b, 1 );
00815                 }else{
00816                     filter_mb_mbaff_edgecv( h, img_cb,              2*uvlinesize, bS  , 2, bqp[0], a, b, 1 );
00817                     filter_mb_mbaff_edgecv( h, img_cb + uvlinesize, 2*uvlinesize, bS+1, 2, bqp[1], a, b, 1 );
00818                     filter_mb_mbaff_edgecv( h, img_cr,              2*uvlinesize, bS  , 2, rqp[0], a, b, 1 );
00819                     filter_mb_mbaff_edgecv( h, img_cr + uvlinesize, 2*uvlinesize, bS+1, 2, rqp[1], a, b, 1 );
00820                 }
00821             }
00822         }
00823     }
00824 
00825 #if CONFIG_SMALL
00826     for( dir = 0; dir < 2; dir++ )
00827         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, a, b, chroma, dir);
00828 #else
00829     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, a, b, chroma, 0);
00830     filter_mb_dir(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, 0,                        a, b, chroma, 1);
00831 #endif
00832 }
Generated on Sun Apr 22 2012 21:54:01 for Libav by doxygen 1.7.1