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

libavcodec/h264dsp.c

Go to the documentation of this file.
00001 /*
00002  * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder
00003  * Copyright (c) 2003-2010 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 <stdint.h>
00029 #include "avcodec.h"
00030 #include "h264dsp.h"
00031 
00032 #define op_scale1(x)  block[x] = av_clip_uint8( (block[x]*weight + offset) >> log2_denom )
00033 #define op_scale2(x)  dst[x] = av_clip_uint8( (src[x]*weights + dst[x]*weightd + offset) >> (log2_denom+1))
00034 #define H264_WEIGHT(W,H) \
00035 static void weight_h264_pixels ## W ## x ## H ## _c(uint8_t *block, int stride, int log2_denom, int weight, int offset){ \
00036     int y; \
00037     offset <<= log2_denom; \
00038     if(log2_denom) offset += 1<<(log2_denom-1); \
00039     for(y=0; y<H; y++, block += stride){ \
00040         op_scale1(0); \
00041         op_scale1(1); \
00042         if(W==2) continue; \
00043         op_scale1(2); \
00044         op_scale1(3); \
00045         if(W==4) continue; \
00046         op_scale1(4); \
00047         op_scale1(5); \
00048         op_scale1(6); \
00049         op_scale1(7); \
00050         if(W==8) continue; \
00051         op_scale1(8); \
00052         op_scale1(9); \
00053         op_scale1(10); \
00054         op_scale1(11); \
00055         op_scale1(12); \
00056         op_scale1(13); \
00057         op_scale1(14); \
00058         op_scale1(15); \
00059     } \
00060 } \
00061 static void biweight_h264_pixels ## W ## x ## H ## _c(uint8_t *dst, uint8_t *src, int stride, int log2_denom, int weightd, int weights, int offset){ \
00062     int y; \
00063     offset = ((offset + 1) | 1) << log2_denom; \
00064     for(y=0; y<H; y++, dst += stride, src += stride){ \
00065         op_scale2(0); \
00066         op_scale2(1); \
00067         if(W==2) continue; \
00068         op_scale2(2); \
00069         op_scale2(3); \
00070         if(W==4) continue; \
00071         op_scale2(4); \
00072         op_scale2(5); \
00073         op_scale2(6); \
00074         op_scale2(7); \
00075         if(W==8) continue; \
00076         op_scale2(8); \
00077         op_scale2(9); \
00078         op_scale2(10); \
00079         op_scale2(11); \
00080         op_scale2(12); \
00081         op_scale2(13); \
00082         op_scale2(14); \
00083         op_scale2(15); \
00084     } \
00085 }
00086 
00087 H264_WEIGHT(16,16)
00088 H264_WEIGHT(16,8)
00089 H264_WEIGHT(8,16)
00090 H264_WEIGHT(8,8)
00091 H264_WEIGHT(8,4)
00092 H264_WEIGHT(4,8)
00093 H264_WEIGHT(4,4)
00094 H264_WEIGHT(4,2)
00095 H264_WEIGHT(2,4)
00096 H264_WEIGHT(2,2)
00097 
00098 #undef op_scale1
00099 #undef op_scale2
00100 #undef H264_WEIGHT
00101 
00102 static av_always_inline av_flatten void h264_loop_filter_luma_c(uint8_t *pix, int xstride, int ystride, int alpha, int beta, int8_t *tc0)
00103 {
00104     int i, d;
00105     for( i = 0; i < 4; i++ ) {
00106         if( tc0[i] < 0 ) {
00107             pix += 4*ystride;
00108             continue;
00109         }
00110         for( d = 0; d < 4; d++ ) {
00111             const int p0 = pix[-1*xstride];
00112             const int p1 = pix[-2*xstride];
00113             const int p2 = pix[-3*xstride];
00114             const int q0 = pix[0];
00115             const int q1 = pix[1*xstride];
00116             const int q2 = pix[2*xstride];
00117 
00118             if( FFABS( p0 - q0 ) < alpha &&
00119                 FFABS( p1 - p0 ) < beta &&
00120                 FFABS( q1 - q0 ) < beta ) {
00121 
00122                 int tc = tc0[i];
00123                 int i_delta;
00124 
00125                 if( FFABS( p2 - p0 ) < beta ) {
00126                     if(tc0[i])
00127                     pix[-2*xstride] = p1 + av_clip( (( p2 + ( ( p0 + q0 + 1 ) >> 1 ) ) >> 1) - p1, -tc0[i], tc0[i] );
00128                     tc++;
00129                 }
00130                 if( FFABS( q2 - q0 ) < beta ) {
00131                     if(tc0[i])
00132                     pix[   xstride] = q1 + av_clip( (( q2 + ( ( p0 + q0 + 1 ) >> 1 ) ) >> 1) - q1, -tc0[i], tc0[i] );
00133                     tc++;
00134                 }
00135 
00136                 i_delta = av_clip( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc );
00137                 pix[-xstride] = av_clip_uint8( p0 + i_delta );    /* p0' */
00138                 pix[0]        = av_clip_uint8( q0 - i_delta );    /* q0' */
00139             }
00140             pix += ystride;
00141         }
00142     }
00143 }
00144 static void h264_v_loop_filter_luma_c(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0)
00145 {
00146     h264_loop_filter_luma_c(pix, stride, 1, alpha, beta, tc0);
00147 }
00148 static void h264_h_loop_filter_luma_c(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0)
00149 {
00150     h264_loop_filter_luma_c(pix, 1, stride, alpha, beta, tc0);
00151 }
00152 
00153 static av_always_inline av_flatten void h264_loop_filter_luma_intra_c(uint8_t *pix, int xstride, int ystride, int alpha, int beta)
00154 {
00155     int d;
00156     for( d = 0; d < 16; d++ ) {
00157         const int p2 = pix[-3*xstride];
00158         const int p1 = pix[-2*xstride];
00159         const int p0 = pix[-1*xstride];
00160 
00161         const int q0 = pix[ 0*xstride];
00162         const int q1 = pix[ 1*xstride];
00163         const int q2 = pix[ 2*xstride];
00164 
00165         if( FFABS( p0 - q0 ) < alpha &&
00166             FFABS( p1 - p0 ) < beta &&
00167             FFABS( q1 - q0 ) < beta ) {
00168 
00169             if(FFABS( p0 - q0 ) < (( alpha >> 2 ) + 2 )){
00170                 if( FFABS( p2 - p0 ) < beta)
00171                 {
00172                     const int p3 = pix[-4*xstride];
00173                     /* p0', p1', p2' */
00174                     pix[-1*xstride] = ( p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4 ) >> 3;
00175                     pix[-2*xstride] = ( p2 + p1 + p0 + q0 + 2 ) >> 2;
00176                     pix[-3*xstride] = ( 2*p3 + 3*p2 + p1 + p0 + q0 + 4 ) >> 3;
00177                 } else {
00178                     /* p0' */
00179                     pix[-1*xstride] = ( 2*p1 + p0 + q1 + 2 ) >> 2;
00180                 }
00181                 if( FFABS( q2 - q0 ) < beta)
00182                 {
00183                     const int q3 = pix[3*xstride];
00184                     /* q0', q1', q2' */
00185                     pix[0*xstride] = ( p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4 ) >> 3;
00186                     pix[1*xstride] = ( p0 + q0 + q1 + q2 + 2 ) >> 2;
00187                     pix[2*xstride] = ( 2*q3 + 3*q2 + q1 + q0 + p0 + 4 ) >> 3;
00188                 } else {
00189                     /* q0' */
00190                     pix[0*xstride] = ( 2*q1 + q0 + p1 + 2 ) >> 2;
00191                 }
00192             }else{
00193                 /* p0', q0' */
00194                 pix[-1*xstride] = ( 2*p1 + p0 + q1 + 2 ) >> 2;
00195                 pix[ 0*xstride] = ( 2*q1 + q0 + p1 + 2 ) >> 2;
00196             }
00197         }
00198         pix += ystride;
00199     }
00200 }
00201 static void h264_v_loop_filter_luma_intra_c(uint8_t *pix, int stride, int alpha, int beta)
00202 {
00203     h264_loop_filter_luma_intra_c(pix, stride, 1, alpha, beta);
00204 }
00205 static void h264_h_loop_filter_luma_intra_c(uint8_t *pix, int stride, int alpha, int beta)
00206 {
00207     h264_loop_filter_luma_intra_c(pix, 1, stride, alpha, beta);
00208 }
00209 
00210 static av_always_inline av_flatten void h264_loop_filter_chroma_c(uint8_t *pix, int xstride, int ystride, int alpha, int beta, int8_t *tc0)
00211 {
00212     int i, d;
00213     for( i = 0; i < 4; i++ ) {
00214         const int tc = tc0[i];
00215         if( tc <= 0 ) {
00216             pix += 2*ystride;
00217             continue;
00218         }
00219         for( d = 0; d < 2; d++ ) {
00220             const int p0 = pix[-1*xstride];
00221             const int p1 = pix[-2*xstride];
00222             const int q0 = pix[0];
00223             const int q1 = pix[1*xstride];
00224 
00225             if( FFABS( p0 - q0 ) < alpha &&
00226                 FFABS( p1 - p0 ) < beta &&
00227                 FFABS( q1 - q0 ) < beta ) {
00228 
00229                 int delta = av_clip( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc );
00230 
00231                 pix[-xstride] = av_clip_uint8( p0 + delta );    /* p0' */
00232                 pix[0]        = av_clip_uint8( q0 - delta );    /* q0' */
00233             }
00234             pix += ystride;
00235         }
00236     }
00237 }
00238 static void h264_v_loop_filter_chroma_c(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0)
00239 {
00240     h264_loop_filter_chroma_c(pix, stride, 1, alpha, beta, tc0);
00241 }
00242 static void h264_h_loop_filter_chroma_c(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0)
00243 {
00244     h264_loop_filter_chroma_c(pix, 1, stride, alpha, beta, tc0);
00245 }
00246 
00247 static av_always_inline av_flatten void h264_loop_filter_chroma_intra_c(uint8_t *pix, int xstride, int ystride, int alpha, int beta)
00248 {
00249     int d;
00250     for( d = 0; d < 8; d++ ) {
00251         const int p0 = pix[-1*xstride];
00252         const int p1 = pix[-2*xstride];
00253         const int q0 = pix[0];
00254         const int q1 = pix[1*xstride];
00255 
00256         if( FFABS( p0 - q0 ) < alpha &&
00257             FFABS( p1 - p0 ) < beta &&
00258             FFABS( q1 - q0 ) < beta ) {
00259 
00260             pix[-xstride] = ( 2*p1 + p0 + q1 + 2 ) >> 2;   /* p0' */
00261             pix[0]        = ( 2*q1 + q0 + p1 + 2 ) >> 2;   /* q0' */
00262         }
00263         pix += ystride;
00264     }
00265 }
00266 static void h264_v_loop_filter_chroma_intra_c(uint8_t *pix, int stride, int alpha, int beta)
00267 {
00268     h264_loop_filter_chroma_intra_c(pix, stride, 1, alpha, beta);
00269 }
00270 static void h264_h_loop_filter_chroma_intra_c(uint8_t *pix, int stride, int alpha, int beta)
00271 {
00272     h264_loop_filter_chroma_intra_c(pix, 1, stride, alpha, beta);
00273 }
00274 
00275 void ff_h264dsp_init(H264DSPContext *c)
00276 {
00277     c->h264_idct_add= ff_h264_idct_add_c;
00278     c->h264_idct8_add= ff_h264_idct8_add_c;
00279     c->h264_idct_dc_add= ff_h264_idct_dc_add_c;
00280     c->h264_idct8_dc_add= ff_h264_idct8_dc_add_c;
00281     c->h264_idct_add16     = ff_h264_idct_add16_c;
00282     c->h264_idct8_add4     = ff_h264_idct8_add4_c;
00283     c->h264_idct_add8      = ff_h264_idct_add8_c;
00284     c->h264_idct_add16intra= ff_h264_idct_add16intra_c;
00285 
00286     c->weight_h264_pixels_tab[0]= weight_h264_pixels16x16_c;
00287     c->weight_h264_pixels_tab[1]= weight_h264_pixels16x8_c;
00288     c->weight_h264_pixels_tab[2]= weight_h264_pixels8x16_c;
00289     c->weight_h264_pixels_tab[3]= weight_h264_pixels8x8_c;
00290     c->weight_h264_pixels_tab[4]= weight_h264_pixels8x4_c;
00291     c->weight_h264_pixels_tab[5]= weight_h264_pixels4x8_c;
00292     c->weight_h264_pixels_tab[6]= weight_h264_pixels4x4_c;
00293     c->weight_h264_pixels_tab[7]= weight_h264_pixels4x2_c;
00294     c->weight_h264_pixels_tab[8]= weight_h264_pixels2x4_c;
00295     c->weight_h264_pixels_tab[9]= weight_h264_pixels2x2_c;
00296     c->biweight_h264_pixels_tab[0]= biweight_h264_pixels16x16_c;
00297     c->biweight_h264_pixels_tab[1]= biweight_h264_pixels16x8_c;
00298     c->biweight_h264_pixels_tab[2]= biweight_h264_pixels8x16_c;
00299     c->biweight_h264_pixels_tab[3]= biweight_h264_pixels8x8_c;
00300     c->biweight_h264_pixels_tab[4]= biweight_h264_pixels8x4_c;
00301     c->biweight_h264_pixels_tab[5]= biweight_h264_pixels4x8_c;
00302     c->biweight_h264_pixels_tab[6]= biweight_h264_pixels4x4_c;
00303     c->biweight_h264_pixels_tab[7]= biweight_h264_pixels4x2_c;
00304     c->biweight_h264_pixels_tab[8]= biweight_h264_pixels2x4_c;
00305     c->biweight_h264_pixels_tab[9]= biweight_h264_pixels2x2_c;
00306 
00307     c->h264_v_loop_filter_luma= h264_v_loop_filter_luma_c;
00308     c->h264_h_loop_filter_luma= h264_h_loop_filter_luma_c;
00309     c->h264_v_loop_filter_luma_intra= h264_v_loop_filter_luma_intra_c;
00310     c->h264_h_loop_filter_luma_intra= h264_h_loop_filter_luma_intra_c;
00311     c->h264_v_loop_filter_chroma= h264_v_loop_filter_chroma_c;
00312     c->h264_h_loop_filter_chroma= h264_h_loop_filter_chroma_c;
00313     c->h264_v_loop_filter_chroma_intra= h264_v_loop_filter_chroma_intra_c;
00314     c->h264_h_loop_filter_chroma_intra= h264_h_loop_filter_chroma_intra_c;
00315     c->h264_loop_filter_strength= NULL;
00316 
00317     if (ARCH_ARM) ff_h264dsp_init_arm(c);
00318     if (HAVE_ALTIVEC) ff_h264dsp_init_ppc(c);
00319     if (HAVE_MMX) ff_h264dsp_init_x86(c);
00320 }

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