Changeset 78ff3248b466be5befb709ad42c824dbb37137a6

Show
Ignore:
Timestamp:
04/19/07 19:43:16 (1 year ago)
Author:
Antoine Cellerier <dionoea@videolan.org>
git-committer:
Antoine Cellerier <dionoea@videolan.org> 1177004596 +0000
git-parent:

[b40e111415d8d5d33122e63b1f802393875c1719]

git-author:
Antoine Cellerier <dionoea@videolan.org> 1177004596 +0000
Message:

Optimze nearest neighboor scaling implementation. This is used by the sub pictures core. CPU decrease compared to previous version with my test filter was: 66% for YUVA, 65% for I420 and 71% for RGBA.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • modules/video_filter/scale.c

    r7255a5e r78ff324  
    11/***************************************************************************** 
    2  * resize.c: video scaling module for YUVP/A pictures 
     2 * resize.c: video scaling module for YUVP/A, I420 and RGBA pictures 
    33 *  Uses the low quality "nearest neighbour" algorithm. 
    44 ***************************************************************************** 
    5  * Copyright (C) 2003 the VideoLAN team 
     5 * Copyright (C) 2003-2007 the VideoLAN team 
    66 * $Id$ 
    77 * 
    8  * Author: Gildas Bazin <gbazin@videolan.org> 
     8 * Authors: Gildas Bazin <gbazin@videolan.org> 
     9 *          Antoine Cellerier <dionoea @t videolan dot org> 
    910 * 
    1011 * This program is free software; you can redistribute it and/or modify 
     
    110111{ 
    111112    picture_t *p_pic_dst; 
    112     int i_plane, i, j, k, l
     113    int i_plane
    113114 
    114115    if( !p_pic ) return NULL; 
     
    128129        for( i_plane = 0; i_plane < p_pic_dst->i_planes; i_plane++ ) 
    129130        { 
     131            const int i_src_pitch    = p_pic->p[i_plane].i_pitch; 
     132            const int i_dst_pitch    = p_pic_dst->p[i_plane].i_pitch; 
     133            const int i_src_height   = p_filter->fmt_in.video.i_height; 
     134            const int i_src_width    = p_filter->fmt_in.video.i_width; 
     135            const int i_dst_height   = p_filter->fmt_out.video.i_height; 
     136            const int i_dst_width    = p_filter->fmt_out.video.i_width; 
     137            const int i_dst_visible_lines = 
     138                                       p_pic_dst->p[i_plane].i_visible_lines; 
     139            const int i_dst_visible_pitch = 
     140                                       p_pic_dst->p[i_plane].i_visible_pitch; 
     141            const int i_dst_hidden_pitch  = i_dst_pitch - i_dst_visible_pitch; 
     142#define SHIFT_SIZE 16 
     143            const int i_height_coef  = ( i_src_height << SHIFT_SIZE ) 
     144                                       / i_dst_height; 
     145            const int i_width_coef   = ( i_src_width << SHIFT_SIZE ) 
     146                                       / i_dst_width; 
     147            const int i_src_height_1 = i_src_height - 1; 
     148            const int i_src_width_1  = i_src_width - 1; 
     149 
    130150            uint8_t *p_src = p_pic->p[i_plane].p_pixels; 
    131151            uint8_t *p_dst = p_pic_dst->p[i_plane].p_pixels; 
    132             int i_src_pitch = p_pic->p[i_plane].i_pitch; 
    133             int i_dst_pitch = p_pic_dst->p[i_plane].i_pitch; 
    134  
    135             for( i = 0; i < p_pic_dst->p[i_plane].i_visible_lines; i++ ) 
     152            uint8_t *p_dstendline = p_dst + i_dst_visible_pitch; 
     153            const uint8_t *p_dstend = p_dst + i_dst_visible_lines*i_dst_pitch; 
     154 
     155            int l = 1<<(SHIFT_SIZE-1); 
     156            for( ; p_dst < p_dstend; 
     157                 p_dst += i_dst_hidden_pitch, 
     158                 p_dstendline += i_dst_pitch, l += i_height_coef ) 
    136159            { 
    137                 l = ( p_filter->fmt_in.video.i_height * i + 
    138                       p_filter->fmt_out.video.i_height / 2 ) / 
    139                     p_filter->fmt_out.video.i_height; 
    140  
    141                 l = __MIN( (int)p_filter->fmt_in.video.i_height - 1, l ); 
    142  
    143                 for( j = 0; j < p_pic_dst->p[i_plane].i_visible_pitch; j++ ) 
     160                int k = 1<<(SHIFT_SIZE-1); 
     161                uint8_t *p_srcl = p_src 
     162                       + (__MIN( i_src_height_1, l >> SHIFT_SIZE )*i_src_pitch); 
     163 
     164                for( ; p_dst < p_dstendline; p_dst++, k += i_width_coef ) 
    144165                { 
    145                     k = ( p_filter->fmt_in.video.i_width * j + 
    146                           p_filter->fmt_out.video.i_width / 2 ) / 
    147                         p_filter->fmt_out.video.i_width; 
    148  
    149                     k = __MIN( (int)p_filter->fmt_in.video.i_width - 1, k ); 
    150  
    151                     p_dst[i * i_dst_pitch + j] = p_src[l * i_src_pitch + k]; 
     166                    *p_dst = p_srcl[__MIN( i_src_width_1, k >> SHIFT_SIZE )]; 
    152167                } 
    153168            } 
     
    156171    else /* RGBA */ 
    157172    { 
    158         uint8_t *p_src = p_pic->p->p_pixels; 
    159         uint8_t *p_dst = p_pic_dst->p->p_pixels; 
    160         int i_src_pitch = p_pic->p->i_pitch; 
    161         int i_dst_pitch = p_pic_dst->p->i_pitch; 
    162         for( i = 0; i < p_pic_dst->p->i_visible_lines; i++ ) 
     173        const int i_src_pitch = p_pic->p->i_pitch; 
     174        const int i_dst_pitch = p_pic_dst->p->i_pitch; 
     175        const int i_src_height   = p_filter->fmt_in.video.i_height; 
     176        const int i_src_width    = p_filter->fmt_in.video.i_width; 
     177        const int i_dst_height   = p_filter->fmt_out.video.i_height; 
     178        const int i_dst_width    = p_filter->fmt_out.video.i_width; 
     179        const int i_dst_visible_lines = 
     180                                   p_pic_dst->p->i_visible_lines; 
     181        const int i_dst_visible_pitch = 
     182                                   p_pic_dst->p->i_visible_pitch; 
     183        const int i_dst_hidden_pitch  = i_dst_pitch - i_dst_visible_pitch; 
     184        const int i_height_coef  = ( i_src_height << SHIFT_SIZE ) 
     185                                   / i_dst_height; 
     186        const int i_width_coef   = ( i_src_width << SHIFT_SIZE ) 
     187                                   / i_dst_width; 
     188        const int i_src_height_1 = i_src_height - 1; 
     189        const int i_src_width_1  = i_src_width - 1; 
     190 
     191        uint32_t *p_src = (uint32_t*)p_pic->p->p_pixels; 
     192        uint32_t *p_dst = (uint32_t*)p_pic_dst->p->p_pixels; 
     193        uint32_t *p_dstendline = p_dst + (i_dst_visible_pitch>>2); 
     194        const uint32_t *p_dstend = p_dst + i_dst_visible_lines*(i_dst_pitch>>2); 
     195 
     196        int l = 1<<(SHIFT_SIZE-1); 
     197        for( ; p_dst < p_dstend; 
     198             p_dst += (i_dst_hidden_pitch>>2), 
     199             p_dstendline += (i_dst_pitch>>2), 
     200             l += i_height_coef ) 
    163201        { 
    164             l = ( p_filter->fmt_in.video.i_height * i + 
    165                   p_filter->fmt_out.video.i_height / 2 ) / 
    166                 p_filter->fmt_out.video.i_height; 
    167  
    168             l = __MIN( (int)p_filter->fmt_in.video.i_height - 1, l ); 
    169  
    170             for( j = 0; j < p_pic_dst->p->i_visible_pitch/4; j++ ) 
     202            int k = 1<<(SHIFT_SIZE-1); 
     203            uint32_t *p_srcl = p_src 
     204                    + (__MIN( i_src_height_1, l >> SHIFT_SIZE )*(i_src_pitch>>2)); 
     205            for( ; p_dst < p_dstendline; p_dst++, k += i_width_coef ) 
    171206            { 
    172                 k = ( p_filter->fmt_in.video.i_width * j + 
    173                       p_filter->fmt_out.video.i_width / 2 ) / 
    174                     p_filter->fmt_out.video.i_width; 
    175  
    176                 k = __MIN( (int)p_filter->fmt_in.video.i_width - 1, k ); 
    177  
    178                 *(uint32_t*)(&p_dst[i * i_dst_pitch + 4*j]) = 
    179                     *(uint32_t*)(&p_src[l * i_src_pitch + 4*k]); 
     207                *p_dst = p_srcl[__MIN( i_src_width_1, k >> SHIFT_SIZE )]; 
    180208            } 
    181209        }