• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • 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 FFmpeg.
00006  *
00007  * FFmpeg 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  * FFmpeg 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 FFmpeg; 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 static void av_always_inline filter_mb_edgev( uint8_t *pix, int stride, int16_t bS[4], unsigned int qp, H264Context *h) {
00104     const unsigned int index_a = qp + h->slice_alpha_c0_offset;
00105     const int alpha = alpha_table[index_a];
00106     const int beta  = beta_table[qp + h->slice_beta_offset];
00107     if (alpha ==0 || beta == 0) return;
00108 
00109     if( bS[0] < 4 ) {
00110         int8_t tc[4];
00111         tc[0] = tc0_table[index_a][bS[0]];
00112         tc[1] = tc0_table[index_a][bS[1]];
00113         tc[2] = tc0_table[index_a][bS[2]];
00114         tc[3] = tc0_table[index_a][bS[3]];
00115         h->h264dsp.h264_h_loop_filter_luma(pix, stride, alpha, beta, tc);
00116     } else {
00117         h->h264dsp.h264_h_loop_filter_luma_intra(pix, stride, alpha, beta);
00118     }
00119 }
00120 static void av_always_inline filter_mb_edgecv( uint8_t *pix, int stride, int16_t bS[4], unsigned int qp, H264Context *h ) {
00121     const unsigned int index_a = qp + h->slice_alpha_c0_offset;
00122     const int alpha = alpha_table[index_a];
00123     const int beta  = beta_table[qp + h->slice_beta_offset];
00124     if (alpha ==0 || beta == 0) return;
00125 
00126     if( bS[0] < 4 ) {
00127         int8_t tc[4];
00128         tc[0] = tc0_table[index_a][bS[0]]+1;
00129         tc[1] = tc0_table[index_a][bS[1]]+1;
00130         tc[2] = tc0_table[index_a][bS[2]]+1;
00131         tc[3] = tc0_table[index_a][bS[3]]+1;
00132         h->h264dsp.h264_h_loop_filter_chroma(pix, stride, alpha, beta, tc);
00133     } else {
00134         h->h264dsp.h264_h_loop_filter_chroma_intra(pix, stride, alpha, beta);
00135     }
00136 }
00137 
00138 static void filter_mb_mbaff_edgev( H264Context *h, uint8_t *pix, int stride, int16_t bS[4], int bsi, int qp ) {
00139     int i;
00140     int index_a = qp + h->slice_alpha_c0_offset;
00141     int alpha = alpha_table[index_a];
00142     int beta  = beta_table[qp + h->slice_beta_offset];
00143     for( i = 0; i < 8; i++, pix += stride) {
00144         const int bS_index = (i >> 1) * bsi;
00145 
00146         if( bS[bS_index] == 0 ) {
00147             continue;
00148         }
00149 
00150         if( bS[bS_index] < 4 ) {
00151             const int tc0 = tc0_table[index_a][bS[bS_index]];
00152             const int p0 = pix[-1];
00153             const int p1 = pix[-2];
00154             const int p2 = pix[-3];
00155             const int q0 = pix[0];
00156             const int q1 = pix[1];
00157             const int q2 = pix[2];
00158 
00159             if( FFABS( p0 - q0 ) < alpha &&
00160                 FFABS( p1 - p0 ) < beta &&
00161                 FFABS( q1 - q0 ) < beta ) {
00162                 int tc = tc0;
00163                 int i_delta;
00164 
00165                 if( FFABS( p2 - p0 ) < beta ) {
00166                     if(tc0)
00167                     pix[-2] = p1 + av_clip( ( p2 + ( ( p0 + q0 + 1 ) >> 1 ) - ( p1 << 1 ) ) >> 1, -tc0, tc0 );
00168                     tc++;
00169                 }
00170                 if( FFABS( q2 - q0 ) < beta ) {
00171                     if(tc0)
00172                     pix[1] = q1 + av_clip( ( q2 + ( ( p0 + q0 + 1 ) >> 1 ) - ( q1 << 1 ) ) >> 1, -tc0, tc0 );
00173                     tc++;
00174                 }
00175 
00176                 i_delta = av_clip( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc );
00177                 pix[-1] = av_clip_uint8( p0 + i_delta );    /* p0' */
00178                 pix[0]  = av_clip_uint8( q0 - i_delta );    /* q0' */
00179                 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);
00180             }
00181         }else{
00182             const int p0 = pix[-1];
00183             const int p1 = pix[-2];
00184             const int p2 = pix[-3];
00185 
00186             const int q0 = pix[0];
00187             const int q1 = pix[1];
00188             const int q2 = pix[2];
00189 
00190             if( FFABS( p0 - q0 ) < alpha &&
00191                 FFABS( p1 - p0 ) < beta &&
00192                 FFABS( q1 - q0 ) < beta ) {
00193 
00194                 if(FFABS( p0 - q0 ) < (( alpha >> 2 ) + 2 )){
00195                     if( FFABS( p2 - p0 ) < beta)
00196                     {
00197                         const int p3 = pix[-4];
00198                         /* p0', p1', p2' */
00199                         pix[-1] = ( p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4 ) >> 3;
00200                         pix[-2] = ( p2 + p1 + p0 + q0 + 2 ) >> 2;
00201                         pix[-3] = ( 2*p3 + 3*p2 + p1 + p0 + q0 + 4 ) >> 3;
00202                     } else {
00203                         /* p0' */
00204                         pix[-1] = ( 2*p1 + p0 + q1 + 2 ) >> 2;
00205                     }
00206                     if( FFABS( q2 - q0 ) < beta)
00207                     {
00208                         const int q3 = pix[3];
00209                         /* q0', q1', q2' */
00210                         pix[0] = ( p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4 ) >> 3;
00211                         pix[1] = ( p0 + q0 + q1 + q2 + 2 ) >> 2;
00212                         pix[2] = ( 2*q3 + 3*q2 + q1 + q0 + p0 + 4 ) >> 3;
00213                     } else {
00214                         /* q0' */
00215                         pix[0] = ( 2*q1 + q0 + p1 + 2 ) >> 2;
00216                     }
00217                 }else{
00218                     /* p0', q0' */
00219                     pix[-1] = ( 2*p1 + p0 + q1 + 2 ) >> 2;
00220                     pix[ 0] = ( 2*q1 + q0 + p1 + 2 ) >> 2;
00221                 }
00222                 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]);
00223             }
00224         }
00225     }
00226 }
00227 static void filter_mb_mbaff_edgecv( H264Context *h, uint8_t *pix, int stride, int16_t bS[4], int bsi, int qp ) {
00228     int i;
00229     int index_a = qp + h->slice_alpha_c0_offset;
00230     int alpha = alpha_table[index_a];
00231     int beta  = beta_table[qp + h->slice_beta_offset];
00232     for( i = 0; i < 4; i++, pix += stride) {
00233         const int bS_index = i*bsi;
00234 
00235         if( bS[bS_index] == 0 ) {
00236             continue;
00237         }
00238 
00239         if( bS[bS_index] < 4 ) {
00240             const int tc = tc0_table[index_a][bS[bS_index]] + 1;
00241             const int p0 = pix[-1];
00242             const int p1 = pix[-2];
00243             const int q0 = pix[0];
00244             const int q1 = pix[1];
00245 
00246             if( FFABS( p0 - q0 ) < alpha &&
00247                 FFABS( p1 - p0 ) < beta &&
00248                 FFABS( q1 - q0 ) < beta ) {
00249                 const int i_delta = av_clip( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc );
00250 
00251                 pix[-1] = av_clip_uint8( p0 + i_delta );    /* p0' */
00252                 pix[0]  = av_clip_uint8( q0 - i_delta );    /* q0' */
00253                 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);
00254             }
00255         }else{
00256             const int p0 = pix[-1];
00257             const int p1 = pix[-2];
00258             const int q0 = pix[0];
00259             const int q1 = pix[1];
00260 
00261             if( FFABS( p0 - q0 ) < alpha &&
00262                 FFABS( p1 - p0 ) < beta &&
00263                 FFABS( q1 - q0 ) < beta ) {
00264 
00265                 pix[-1] = ( 2*p1 + p0 + q1 + 2 ) >> 2;   /* p0' */
00266                 pix[0]  = ( 2*q1 + q0 + p1 + 2 ) >> 2;   /* q0' */
00267                 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]);
00268             }
00269         }
00270     }
00271 }
00272 
00273 static void av_always_inline filter_mb_edgeh( uint8_t *pix, int stride, int16_t bS[4], unsigned int qp, H264Context *h ) {
00274     const unsigned int index_a = qp + h->slice_alpha_c0_offset;
00275     const int alpha = alpha_table[index_a];
00276     const int beta  = beta_table[qp + h->slice_beta_offset];
00277     if (alpha ==0 || beta == 0) return;
00278 
00279     if( bS[0] < 4 ) {
00280         int8_t tc[4];
00281         tc[0] = tc0_table[index_a][bS[0]];
00282         tc[1] = tc0_table[index_a][bS[1]];
00283         tc[2] = tc0_table[index_a][bS[2]];
00284         tc[3] = tc0_table[index_a][bS[3]];
00285         h->h264dsp.h264_v_loop_filter_luma(pix, stride, alpha, beta, tc);
00286     } else {
00287         h->h264dsp.h264_v_loop_filter_luma_intra(pix, stride, alpha, beta);
00288     }
00289 }
00290 
00291 static void av_always_inline filter_mb_edgech( uint8_t *pix, int stride, int16_t bS[4], unsigned int qp, H264Context *h ) {
00292     const unsigned int index_a = qp + h->slice_alpha_c0_offset;
00293     const int alpha = alpha_table[index_a];
00294     const int beta  = beta_table[qp + h->slice_beta_offset];
00295     if (alpha ==0 || beta == 0) return;
00296 
00297     if( bS[0] < 4 ) {
00298         int8_t tc[4];
00299         tc[0] = tc0_table[index_a][bS[0]]+1;
00300         tc[1] = tc0_table[index_a][bS[1]]+1;
00301         tc[2] = tc0_table[index_a][bS[2]]+1;
00302         tc[3] = tc0_table[index_a][bS[3]]+1;
00303         h->h264dsp.h264_v_loop_filter_chroma(pix, stride, alpha, beta, tc);
00304     } else {
00305         h->h264dsp.h264_v_loop_filter_chroma_intra(pix, stride, alpha, beta);
00306     }
00307 }
00308 
00309 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) {
00310     MpegEncContext * const s = &h->s;
00311     int mb_xy;
00312     int mb_type, left_type;
00313     int qp, qp0, qp1, qpc, qpc0, qpc1, qp_thresh;
00314 
00315     mb_xy = h->mb_xy;
00316 
00317     if(!h->top_type || !h->h264dsp.h264_loop_filter_strength || h->pps.chroma_qp_diff) {
00318         ff_h264_filter_mb(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize);
00319         return;
00320     }
00321     assert(!FRAME_MBAFF);
00322     left_type= h->left_type[0];
00323 
00324     mb_type = s->current_picture.mb_type[mb_xy];
00325     qp = s->current_picture.qscale_table[mb_xy];
00326     qp0 = s->current_picture.qscale_table[mb_xy-1];
00327     qp1 = s->current_picture.qscale_table[h->top_mb_xy];
00328     qpc = get_chroma_qp( h, 0, qp );
00329     qpc0 = get_chroma_qp( h, 0, qp0 );
00330     qpc1 = get_chroma_qp( h, 0, qp1 );
00331     qp0 = (qp + qp0 + 1) >> 1;
00332     qp1 = (qp + qp1 + 1) >> 1;
00333     qpc0 = (qpc + qpc0 + 1) >> 1;
00334     qpc1 = (qpc + qpc1 + 1) >> 1;
00335     qp_thresh = 15+52 - h->slice_alpha_c0_offset;
00336     if(qp <= qp_thresh && qp0 <= qp_thresh && qp1 <= qp_thresh &&
00337        qpc <= qp_thresh && qpc0 <= qp_thresh && qpc1 <= qp_thresh)
00338         return;
00339 
00340     if( IS_INTRA(mb_type) ) {
00341         int16_t bS4[4] = {4,4,4,4};
00342         int16_t bS3[4] = {3,3,3,3};
00343         int16_t *bSH = FIELD_PICTURE ? bS3 : bS4;
00344         if(left_type)
00345             filter_mb_edgev( &img_y[4*0], linesize, bS4, qp0, h);
00346         if( IS_8x8DCT(mb_type) ) {
00347             filter_mb_edgev( &img_y[4*2], linesize, bS3, qp, h);
00348             filter_mb_edgeh( &img_y[4*0*linesize], linesize, bSH, qp1, h);
00349             filter_mb_edgeh( &img_y[4*2*linesize], linesize, bS3, qp, h);
00350         } else {
00351             filter_mb_edgev( &img_y[4*1], linesize, bS3, qp, h);
00352             filter_mb_edgev( &img_y[4*2], linesize, bS3, qp, h);
00353             filter_mb_edgev( &img_y[4*3], linesize, bS3, qp, h);
00354             filter_mb_edgeh( &img_y[4*0*linesize], linesize, bSH, qp1, h);
00355             filter_mb_edgeh( &img_y[4*1*linesize], linesize, bS3, qp, h);
00356             filter_mb_edgeh( &img_y[4*2*linesize], linesize, bS3, qp, h);
00357             filter_mb_edgeh( &img_y[4*3*linesize], linesize, bS3, qp, h);
00358         }
00359         if(left_type){
00360             filter_mb_edgecv( &img_cb[2*0], uvlinesize, bS4, qpc0, h);
00361             filter_mb_edgecv( &img_cr[2*0], uvlinesize, bS4, qpc0, h);
00362         }
00363         filter_mb_edgecv( &img_cb[2*2], uvlinesize, bS3, qpc, h);
00364         filter_mb_edgecv( &img_cr[2*2], uvlinesize, bS3, qpc, h);
00365         filter_mb_edgech( &img_cb[2*0*uvlinesize], uvlinesize, bSH, qpc1, h);
00366         filter_mb_edgech( &img_cb[2*2*uvlinesize], uvlinesize, bS3, qpc, h);
00367         filter_mb_edgech( &img_cr[2*0*uvlinesize], uvlinesize, bSH, qpc1, h);
00368         filter_mb_edgech( &img_cr[2*2*uvlinesize], uvlinesize, bS3, qpc, h);
00369         return;
00370     } else {
00371         LOCAL_ALIGNED_8(int16_t, bS, [2], [4][4]);
00372         int edges;
00373         if( IS_8x8DCT(mb_type) && (h->cbp&7) == 7 ) {
00374             edges = 4;
00375             AV_WN64A(bS[0][0], 0x0002000200020002ULL);
00376             AV_WN64A(bS[0][2], 0x0002000200020002ULL);
00377             AV_WN64A(bS[1][0], 0x0002000200020002ULL);
00378             AV_WN64A(bS[1][2], 0x0002000200020002ULL);
00379         } else {
00380             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;
00381             int mask_edge0 = 3*((mask_edge1>>1) & ((5*left_type)>>5)&1); // (mb_type & (MB_TYPE_16x16 | MB_TYPE_8x16)) && (h->left_type[0] & (MB_TYPE_16x16 | MB_TYPE_8x16)) ? 3 : 0;
00382             int step =  1+(mb_type>>24); //IS_8x8DCT(mb_type) ? 2 : 1;
00383             edges = 4 - 3*((mb_type>>3) & !(h->cbp & 15)); //(mb_type & MB_TYPE_16x16) && !(h->cbp & 15) ? 1 : 4;
00384             h->h264dsp.h264_loop_filter_strength( bS, h->non_zero_count_cache, h->ref_cache, h->mv_cache,
00385                                               h->list_count==2, edges, step, mask_edge0, mask_edge1, FIELD_PICTURE);
00386         }
00387         if( IS_INTRA(left_type) )
00388             AV_WN64A(bS[0][0], 0x0004000400040004ULL);
00389         if( IS_INTRA(h->top_type) )
00390             AV_WN64A(bS[1][0], FIELD_PICTURE ? 0x0003000300030003ULL : 0x0004000400040004ULL);
00391 
00392 #define FILTER(hv,dir,edge)\
00393         if(AV_RN64A(bS[dir][edge])) {                                   \
00394             filter_mb_edge##hv( &img_y[4*edge*(dir?linesize:1)], linesize, bS[dir][edge], edge ? qp : qp##dir, h );\
00395             if(!(edge&1)) {\
00396                 filter_mb_edgec##hv( &img_cb[2*edge*(dir?uvlinesize:1)], uvlinesize, bS[dir][edge], edge ? qpc : qpc##dir, h );\
00397                 filter_mb_edgec##hv( &img_cr[2*edge*(dir?uvlinesize:1)], uvlinesize, bS[dir][edge], edge ? qpc : qpc##dir, h );\
00398             }\
00399         }
00400         if(left_type)
00401             FILTER(v,0,0);
00402         if( edges == 1 ) {
00403             FILTER(h,1,0);
00404         } else if( IS_8x8DCT(mb_type) ) {
00405             FILTER(v,0,2);
00406             FILTER(h,1,0);
00407             FILTER(h,1,2);
00408         } else {
00409             FILTER(v,0,1);
00410             FILTER(v,0,2);
00411             FILTER(v,0,3);
00412             FILTER(h,1,0);
00413             FILTER(h,1,1);
00414             FILTER(h,1,2);
00415             FILTER(h,1,3);
00416         }
00417 #undef FILTER
00418     }
00419 }
00420 
00421 static int check_mv(H264Context *h, long b_idx, long bn_idx, int mvy_limit){
00422     int v;
00423 
00424     v= h->ref_cache[0][b_idx] != h->ref_cache[0][bn_idx];
00425     if(!v && h->ref_cache[0][b_idx]!=-1)
00426         v= h->mv_cache[0][b_idx][0] - h->mv_cache[0][bn_idx][0] + 3 >= 7U |
00427            FFABS( h->mv_cache[0][b_idx][1] - h->mv_cache[0][bn_idx][1] ) >= mvy_limit;
00428 
00429     if(h->list_count==2){
00430         if(!v)
00431             v = h->ref_cache[1][b_idx] != h->ref_cache[1][bn_idx] |
00432                 h->mv_cache[1][b_idx][0] - h->mv_cache[1][bn_idx][0] + 3 >= 7U |
00433                 FFABS( h->mv_cache[1][b_idx][1] - h->mv_cache[1][bn_idx][1] ) >= mvy_limit;
00434 
00435         if(v){
00436             if(h->ref_cache[0][b_idx] != h->ref_cache[1][bn_idx] |
00437                h->ref_cache[1][b_idx] != h->ref_cache[0][bn_idx])
00438                 return 1;
00439             return
00440                 h->mv_cache[0][b_idx][0] - h->mv_cache[1][bn_idx][0] + 3 >= 7U |
00441                 FFABS( h->mv_cache[0][b_idx][1] - h->mv_cache[1][bn_idx][1] ) >= mvy_limit |
00442                 h->mv_cache[1][b_idx][0] - h->mv_cache[0][bn_idx][0] + 3 >= 7U |
00443                 FFABS( h->mv_cache[1][b_idx][1] - h->mv_cache[0][bn_idx][1] ) >= mvy_limit;
00444         }
00445     }
00446 
00447     return v;
00448 }
00449 
00450 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) {
00451     MpegEncContext * const s = &h->s;
00452     int edge;
00453     const int mbm_xy = dir == 0 ? mb_xy -1 : h->top_mb_xy;
00454     const int mbm_type = dir == 0 ? h->left_type[0] : h->top_type;
00455 
00456     // how often to recheck mv-based bS when iterating between edges
00457     static const uint8_t mask_edge_tab[2][8]={{0,3,3,3,1,1,1,1},
00458                                               {0,3,1,1,3,3,3,3}};
00459     const int mask_edge = mask_edge_tab[dir][(mb_type>>3)&7];
00460     const int edges = mask_edge== 3 && !(h->cbp&15) ? 1 : 4;
00461 
00462     // how often to recheck mv-based bS when iterating along each edge
00463     const int mask_par0 = mb_type & (MB_TYPE_16x16 | (MB_TYPE_8x16 >> dir));
00464 
00465     if(mbm_type && !first_vertical_edge_done){
00466 
00467         if (FRAME_MBAFF && (dir == 1) && ((mb_y&1) == 0)
00468             && IS_INTERLACED(mbm_type&~mb_type)
00469             ) {
00470             // This is a special case in the norm where the filtering must
00471             // be done twice (one each of the field) even if we are in a
00472             // frame macroblock.
00473             //
00474             unsigned int tmp_linesize   = 2 *   linesize;
00475             unsigned int tmp_uvlinesize = 2 * uvlinesize;
00476             int mbn_xy = mb_xy - 2 * s->mb_stride;
00477             int j;
00478 
00479             for(j=0; j<2; j++, mbn_xy += s->mb_stride){
00480                 DECLARE_ALIGNED(8, int16_t, bS)[4];
00481                 int qp;
00482                 if( IS_INTRA(mb_type|s->current_picture.mb_type[mbn_xy]) ) {
00483                     AV_WN64A(bS, 0x0003000300030003ULL);
00484                 } else {
00485                     if(!CABAC && IS_8x8DCT(s->current_picture.mb_type[mbn_xy])){
00486                         bS[0]= 1+((h->cbp_table[mbn_xy] & 4)||h->non_zero_count_cache[scan8[0]+0]);
00487                         bS[1]= 1+((h->cbp_table[mbn_xy] & 4)||h->non_zero_count_cache[scan8[0]+1]);
00488                         bS[2]= 1+((h->cbp_table[mbn_xy] & 8)||h->non_zero_count_cache[scan8[0]+2]);
00489                         bS[3]= 1+((h->cbp_table[mbn_xy] & 8)||h->non_zero_count_cache[scan8[0]+3]);
00490                     }else{
00491                     const uint8_t *mbn_nnz = h->non_zero_count[mbn_xy] + 4+3*8;
00492                     int i;
00493                     for( i = 0; i < 4; i++ ) {
00494                         bS[i] = 1 + !!(h->non_zero_count_cache[scan8[0]+i] | mbn_nnz[i]);
00495                     }
00496                     }
00497                 }
00498                 // Do not use s->qscale as luma quantizer because it has not the same
00499                 // value in IPCM macroblocks.
00500                 qp = ( s->current_picture.qscale_table[mb_xy] + s->current_picture.qscale_table[mbn_xy] + 1 ) >> 1;
00501                 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);
00502                 { int i; for (i = 0; i < 4; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); }
00503                 filter_mb_edgeh( &img_y[j*linesize], tmp_linesize, bS, qp, h );
00504                 filter_mb_edgech( &img_cb[j*uvlinesize], tmp_uvlinesize, bS,
00505                                 ( h->chroma_qp[0] + get_chroma_qp( h, 0, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1, h);
00506                 filter_mb_edgech( &img_cr[j*uvlinesize], tmp_uvlinesize, bS,
00507                                 ( h->chroma_qp[1] + get_chroma_qp( h, 1, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1, h);
00508             }
00509         }else{
00510             DECLARE_ALIGNED(8, int16_t, bS)[4];
00511             int qp;
00512 
00513             if( IS_INTRA(mb_type|mbm_type)) {
00514                 AV_WN64A(bS, 0x0003000300030003ULL);
00515                 if (   (!IS_INTERLACED(mb_type|mbm_type))
00516                     || ((FRAME_MBAFF || (s->picture_structure != PICT_FRAME)) && (dir == 0))
00517                 )
00518                     AV_WN64A(bS, 0x0004000400040004ULL);
00519             } else {
00520                 int i;
00521                 int mv_done;
00522 
00523                 if( dir && FRAME_MBAFF && IS_INTERLACED(mb_type ^ mbm_type)) {
00524                     AV_WN64A(bS, 0x0001000100010001ULL);
00525                     mv_done = 1;
00526                 }
00527                 else if( mask_par0 && ((mbm_type & (MB_TYPE_16x16 | (MB_TYPE_8x16 >> dir)))) ) {
00528                     int b_idx= 8 + 4;
00529                     int bn_idx= b_idx - (dir ? 8:1);
00530 
00531                     bS[0] = bS[1] = bS[2] = bS[3] = check_mv(h, 8 + 4, bn_idx, mvy_limit);
00532                     mv_done = 1;
00533                 }
00534                 else
00535                     mv_done = 0;
00536 
00537                 for( i = 0; i < 4; i++ ) {
00538                     int x = dir == 0 ? 0 : i;
00539                     int y = dir == 0 ? i    : 0;
00540                     int b_idx= 8 + 4 + x + 8*y;
00541                     int bn_idx= b_idx - (dir ? 8:1);
00542 
00543                     if( h->non_zero_count_cache[b_idx] |
00544                         h->non_zero_count_cache[bn_idx] ) {
00545                         bS[i] = 2;
00546                     }
00547                     else if(!mv_done)
00548                     {
00549                         bS[i] = check_mv(h, b_idx, bn_idx, mvy_limit);
00550                     }
00551                 }
00552             }
00553 
00554             /* Filter edge */
00555             // Do not use s->qscale as luma quantizer because it has not the same
00556             // value in IPCM macroblocks.
00557             if(bS[0]+bS[1]+bS[2]+bS[3]){
00558                 qp = ( s->current_picture.qscale_table[mb_xy] + s->current_picture.qscale_table[mbm_xy] + 1 ) >> 1;
00559                 //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]);
00560                 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);
00561                 //{ int i; for (i = 0; i < 4; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); }
00562                 if( dir == 0 ) {
00563                     filter_mb_edgev( &img_y[0], linesize, bS, qp, h );
00564                     {
00565                         int qp= ( h->chroma_qp[0] + get_chroma_qp( h, 0, s->current_picture.qscale_table[mbm_xy] ) + 1 ) >> 1;
00566                         filter_mb_edgecv( &img_cb[0], uvlinesize, bS, qp, h);
00567                         if(h->pps.chroma_qp_diff)
00568                             qp= ( h->chroma_qp[1] + get_chroma_qp( h, 1, s->current_picture.qscale_table[mbm_xy] ) + 1 ) >> 1;
00569                         filter_mb_edgecv( &img_cr[0], uvlinesize, bS, qp, h);
00570                     }
00571                 } else {
00572                     filter_mb_edgeh( &img_y[0], linesize, bS, qp, h );
00573                     {
00574                         int qp= ( h->chroma_qp[0] + get_chroma_qp( h, 0, s->current_picture.qscale_table[mbm_xy] ) + 1 ) >> 1;
00575                         filter_mb_edgech( &img_cb[0], uvlinesize, bS, qp, h);
00576                         if(h->pps.chroma_qp_diff)
00577                             qp= ( h->chroma_qp[1] + get_chroma_qp( h, 1, s->current_picture.qscale_table[mbm_xy] ) + 1 ) >> 1;
00578                         filter_mb_edgech( &img_cr[0], uvlinesize, bS, qp, h);
00579                     }
00580                 }
00581             }
00582         }
00583     }
00584 
00585     /* Calculate bS */
00586     for( edge = 1; edge < edges; edge++ ) {
00587         DECLARE_ALIGNED(8, int16_t, bS)[4];
00588         int qp;
00589 
00590         if( IS_8x8DCT(mb_type & (edge<<24)) ) // (edge&1) && IS_8x8DCT(mb_type)
00591             continue;
00592 
00593         if( IS_INTRA(mb_type)) {
00594             AV_WN64A(bS, 0x0003000300030003ULL);
00595         } else {
00596             int i;
00597             int mv_done;
00598 
00599             if( edge & mask_edge ) {
00600                 AV_ZERO64(bS);
00601                 mv_done = 1;
00602             }
00603             else if( mask_par0 ) {
00604                 int b_idx= 8 + 4 + edge * (dir ? 8:1);
00605                 int bn_idx= b_idx - (dir ? 8:1);
00606 
00607                 bS[0] = bS[1] = bS[2] = bS[3] = check_mv(h, b_idx, bn_idx, mvy_limit);
00608                 mv_done = 1;
00609             }
00610             else
00611                 mv_done = 0;
00612 
00613             for( i = 0; i < 4; i++ ) {
00614                 int x = dir == 0 ? edge : i;
00615                 int y = dir == 0 ? i    : edge;
00616                 int b_idx= 8 + 4 + x + 8*y;
00617                 int bn_idx= b_idx - (dir ? 8:1);
00618 
00619                 if( h->non_zero_count_cache[b_idx] |
00620                     h->non_zero_count_cache[bn_idx] ) {
00621                     bS[i] = 2;
00622                 }
00623                 else if(!mv_done)
00624                 {
00625                     bS[i] = check_mv(h, b_idx, bn_idx, mvy_limit);
00626                 }
00627             }
00628 
00629             if(bS[0]+bS[1]+bS[2]+bS[3] == 0)
00630                 continue;
00631         }
00632 
00633         /* Filter edge */
00634         // Do not use s->qscale as luma quantizer because it has not the same
00635         // value in IPCM macroblocks.
00636         qp = s->current_picture.qscale_table[mb_xy];
00637         //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]);
00638         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);
00639         //{ int i; for (i = 0; i < 4; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); }
00640         if( dir == 0 ) {
00641             filter_mb_edgev( &img_y[4*edge], linesize, bS, qp, h );
00642             if( (edge&1) == 0 ) {
00643                 filter_mb_edgecv( &img_cb[2*edge], uvlinesize, bS, h->chroma_qp[0], h);
00644                 filter_mb_edgecv( &img_cr[2*edge], uvlinesize, bS, h->chroma_qp[1], h);
00645             }
00646         } else {
00647             filter_mb_edgeh( &img_y[4*edge*linesize], linesize, bS, qp, h );
00648             if( (edge&1) == 0 ) {
00649                 filter_mb_edgech( &img_cb[2*edge*uvlinesize], uvlinesize, bS, h->chroma_qp[0], h);
00650                 filter_mb_edgech( &img_cr[2*edge*uvlinesize], uvlinesize, bS, h->chroma_qp[1], h);
00651             }
00652         }
00653     }
00654 }
00655 
00656 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) {
00657     MpegEncContext * const s = &h->s;
00658     const int mb_xy= mb_x + mb_y*s->mb_stride;
00659     const int mb_type = s->current_picture.mb_type[mb_xy];
00660     const int mvy_limit = IS_INTERLACED(mb_type) ? 2 : 4;
00661     int first_vertical_edge_done = 0;
00662     av_unused int dir;
00663 
00664     if (FRAME_MBAFF
00665             // and current and left pair do not have the same interlaced type
00666             && IS_INTERLACED(mb_type^h->left_type[0])
00667             // and left mb is in available to us
00668             && h->left_type[0]) {
00669         /* First vertical edge is different in MBAFF frames
00670          * There are 8 different bS to compute and 2 different Qp
00671          */
00672         DECLARE_ALIGNED(8, int16_t, bS)[8];
00673         int qp[2];
00674         int bqp[2];
00675         int rqp[2];
00676         int mb_qp, mbn0_qp, mbn1_qp;
00677         int i;
00678         first_vertical_edge_done = 1;
00679 
00680         if( IS_INTRA(mb_type) ) {
00681             AV_WN64A(&bS[0], 0x0004000400040004ULL);
00682             AV_WN64A(&bS[4], 0x0004000400040004ULL);
00683         } else {
00684             static const uint8_t offset[2][2][8]={
00685                 {
00686                     {7+8*0, 7+8*0, 7+8*0, 7+8*0, 7+8*1, 7+8*1, 7+8*1, 7+8*1},
00687                     {7+8*2, 7+8*2, 7+8*2, 7+8*2, 7+8*3, 7+8*3, 7+8*3, 7+8*3},
00688                 },{
00689                     {7+8*0, 7+8*1, 7+8*2, 7+8*3, 7+8*0, 7+8*1, 7+8*2, 7+8*3},
00690                     {7+8*0, 7+8*1, 7+8*2, 7+8*3, 7+8*0, 7+8*1, 7+8*2, 7+8*3},
00691                 }
00692             };
00693             const uint8_t *off= offset[MB_FIELD][mb_y&1];
00694             for( i = 0; i < 8; i++ ) {
00695                 int j= MB_FIELD ? i>>2 : i&1;
00696                 int mbn_xy = h->left_mb_xy[j];
00697                 int mbn_type= h->left_type[j];
00698 
00699                 if( IS_INTRA( mbn_type ) )
00700                     bS[i] = 4;
00701                 else{
00702                     bS[i] = 1 + !!(h->non_zero_count_cache[12+8*(i>>1)] |
00703                          ((!h->pps.cabac && IS_8x8DCT(mbn_type)) ?
00704                             (h->cbp_table[mbn_xy] & ((MB_FIELD ? (i&2) : (mb_y&1)) ? 8 : 2))
00705                                                                        :
00706                             h->non_zero_count[mbn_xy][ off[i] ]));
00707                 }
00708             }
00709         }
00710 
00711         mb_qp = s->current_picture.qscale_table[mb_xy];
00712         mbn0_qp = s->current_picture.qscale_table[h->left_mb_xy[0]];
00713         mbn1_qp = s->current_picture.qscale_table[h->left_mb_xy[1]];
00714         qp[0] = ( mb_qp + mbn0_qp + 1 ) >> 1;
00715         bqp[0] = ( get_chroma_qp( h, 0, mb_qp ) +
00716                    get_chroma_qp( h, 0, mbn0_qp ) + 1 ) >> 1;
00717         rqp[0] = ( get_chroma_qp( h, 1, mb_qp ) +
00718                    get_chroma_qp( h, 1, mbn0_qp ) + 1 ) >> 1;
00719         qp[1] = ( mb_qp + mbn1_qp + 1 ) >> 1;
00720         bqp[1] = ( get_chroma_qp( h, 0, mb_qp ) +
00721                    get_chroma_qp( h, 0, mbn1_qp ) + 1 ) >> 1;
00722         rqp[1] = ( get_chroma_qp( h, 1, mb_qp ) +
00723                    get_chroma_qp( h, 1, mbn1_qp ) + 1 ) >> 1;
00724 
00725         /* Filter edge */
00726         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);
00727         { int i; for (i = 0; i < 8; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); }
00728         if(MB_FIELD){
00729             filter_mb_mbaff_edgev ( h, img_y                ,   linesize, bS  , 1, qp [0] );
00730             filter_mb_mbaff_edgev ( h, img_y  + 8*  linesize,   linesize, bS+4, 1, qp [1] );
00731             filter_mb_mbaff_edgecv( h, img_cb,                uvlinesize, bS  , 1, bqp[0] );
00732             filter_mb_mbaff_edgecv( h, img_cb + 4*uvlinesize, uvlinesize, bS+4, 1, bqp[1] );
00733             filter_mb_mbaff_edgecv( h, img_cr,                uvlinesize, bS  , 1, rqp[0] );
00734             filter_mb_mbaff_edgecv( h, img_cr + 4*uvlinesize, uvlinesize, bS+4, 1, rqp[1] );
00735         }else{
00736             filter_mb_mbaff_edgev ( h, img_y              , 2*  linesize, bS  , 2, qp [0] );
00737             filter_mb_mbaff_edgev ( h, img_y  +   linesize, 2*  linesize, bS+1, 2, qp [1] );
00738             filter_mb_mbaff_edgecv( h, img_cb,              2*uvlinesize, bS  , 2, bqp[0] );
00739             filter_mb_mbaff_edgecv( h, img_cb + uvlinesize, 2*uvlinesize, bS+1, 2, bqp[1] );
00740             filter_mb_mbaff_edgecv( h, img_cr,              2*uvlinesize, bS  , 2, rqp[0] );
00741             filter_mb_mbaff_edgecv( h, img_cr + uvlinesize, 2*uvlinesize, bS+1, 2, rqp[1] );
00742         }
00743     }
00744 
00745 #if CONFIG_SMALL
00746     for( dir = 0; dir < 2; dir++ )
00747         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);
00748 #else
00749     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);
00750     filter_mb_dir(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, 0, 1);
00751 #endif
00752 }

Generated on Fri Sep 16 2011 17:17:37 for FFmpeg by  doxygen 1.7.1