Commit a5344ee9 authored by Rafaël Carré's avatar Rafaël Carré Committed by Jean-Paul Saman

Generate resizer coefficients at runtime using bicubic interpolation

parent 420f53ed
......@@ -714,7 +714,7 @@ AM_CONDITIONAL(BUILD_GETOPT, ${need_getopt})
if test "${SYS}" != "mingw32" -a "${SYS}" != "mingwce"; then
AC_TYPE_SIGNAL
AC_CHECK_LIB(m,cos,[
VLC_ADD_LIBS([adjust wave ripple psychedelic gradient a52tofloat32 dtstofloat32 x264 goom visual panoramix rotate noise grain scene],[-lm])
VLC_ADD_LIBS([adjust wave ripple psychedelic gradient a52tofloat32 dtstofloat32 x264 goom visual panoramix rotate noise grain scene davinci],[-lm])
])
AC_CHECK_LIB(m,pow,[
VLC_ADD_LIBS([avcodec avformat swscale postproc ffmpegaltivec stream_out_transrate i420_rgb faad twolame equalizer spatializer param_eq libvlccore vorbis freetype mod mpc dmo quicktime realaudio realvideo galaktos opengl],[-lm])
......
......@@ -43,9 +43,11 @@
#include <ti/sdo/ce/osal/Memory.h>
#include <inttypes.h>
#include <asm-arm/arch-davinci/davinci_resizer.h>
#include <math.h>
#define NUM_BUFFERS 1//3 //FIXME
#define BPP 16
#define PI 3.1415926535897932384626
#endif
/*****************************************************************************
......@@ -80,6 +82,8 @@ struct decoder_sys_t
};
#ifdef DAVINCI_HACK
static int OpenFB( const char *psz_name )
{
int i_fd = -1;
......@@ -109,6 +113,135 @@ static int OpenFB( const char *psz_name )
} while(1);
}
static float bicubic_core( float s )
{
if( s < 0 ) s = -s;
if( 0. <= s && s <= 1. )
return 1.5 * s * s * s - 2.5 * s * s + 1.;
else if( s <= 2. )
return -.5 * s * s * s + 2.5 * s * s - 4. *s + 2.;
else
return 0.;
}
static void get_coeffs( short coefs[32], unsigned int i_h_in,
unsigned int i_w_in, unsigned int i_h_out, unsigned int i_w_out )
{
assert( i_h_out > 1 );
assert( i_h_in > 7 );
float f_deinterleave_coef[ 32 ];
float f_windows[ 32+1 ];
unsigned int i_hrsz;
if( i_h_in == i_h_out )
i_hrsz = 256;
else
{
i_hrsz = ((i_h_in - 7) * 256) / (i_h_out - 1);
if( i_hrsz <= 512 )
{
i_hrsz = ((i_h_in - 4) * 256) / (i_h_out - 1);
if( i_hrsz > 512 ) i_hrsz = 512;
}
}
int i_nphases, i_ntaps, i_winlen, i_phase_offset, i, j;
float f_fc;
if( i_hrsz > 512 )
{
i_nphases = 4;
i_ntaps = 7;
i_phase_offset = 8;
}
else
{
i_nphases = 8;
i_ntaps = 4;
i_phase_offset = 4;
}
i_winlen = i_nphases * i_ntaps;
/* calculating the cut-off frequency, normalized by fs/2 */
f_fc = ( i_hrsz < 256) ? (1. / i_nphases) : 256. / (i_hrsz * i_nphases);
for( i = 0 ; i <= i_winlen ; i++ )
f_windows[i] = .42 - .5 * cos( 2 * PI * i / i_winlen ) +
.08 * cos( 4 * PI * i / i_winlen );
i_nphases = 8;
i_ntaps = 4;
i_phase_offset = 4;
/* calculating the bi-cubic coefficients */
for( i = 0 ; i < i_nphases ; i++ )
{
float f_alpha = ((float)i) / i_nphases;
f_deinterleave_coef[i_phase_offset*i] = bicubic_core( f_alpha + 1. );
f_deinterleave_coef[i_phase_offset*i+1] = bicubic_core( f_alpha );
f_deinterleave_coef[i_phase_offset*i+2] = bicubic_core( 1. - f_alpha );
f_deinterleave_coef[i_phase_offset*i+3] = bicubic_core( 2. - f_alpha );
}
/* de-interleave into phases */
for( i = 0 ; i < i_nphases ; i++ )
{ /* i=phase */
float f_gain = 0;
for( j = 0 ; j < i_ntaps ; j++ ) /* j=tap */
f_gain += f_deinterleave_coef[i_phase_offset * i + j];
for( j = 0 ; j < i_ntaps ; j ++)
coefs[i_phase_offset * i + j] = (short)
(f_deinterleave_coef[i_phase_offset*i+j] * 256 / f_gain + 0.5 );
if( i_ntaps == 7 )
coefs[i_phase_offset * i + 7] = 0.;
}
/* adjust the gain to make it exactly one */
for( i = 0 ; i < i_nphases ; i++ )
{
int max = coefs[i_phase_offset*i];
int max2 = 0;
int index = 0;
int index2 = 0;
int total_gain = max;
int delta;
for( j = 1 ; j < i_ntaps ; j++ )
{
total_gain += coefs[i_phase_offset*i+j];
if( abs( coefs[i_phase_offset*i+j] ) >= max )
{
max2 = max;
index2 = index;
index = j;
max = abs( coefs[i_phase_offset*i+j] );
}
}
delta = 256 - total_gain;
if(max - max2 < 10)
{
coefs[i_phase_offset*i+index2] += (delta>>1);
coefs[i_phase_offset*i+index] += (delta-(delta>>1));
}
else
coefs[i_phase_offset*i+index] += delta;
}
if( i_hrsz == 256 )
{ /* no resizing, all pass filtering */
for( i = 0 ; i < i_nphases * i_ntaps ; i+= 4 )
{
coefs[i] = 256;
coefs[i+1] = coefs[i+2] = coefs[i+3] = 0;
}
}
}
#endif
/*****************************************************************************
* OpenDecoder: probe the decoder and return score
*****************************************************************************/
......@@ -572,16 +705,9 @@ static picture_t *DecodeVideoBlockInner( decoder_t *p_dec, block_t **pp_block, i
rsz_params.out_vsize = p_sys->var_info.yres;
rsz_params.out_pitch = p_sys->fix_info.line_length;
const short coefs[] = {
/* FIXME : generate the coefficients at runtime */
0, 256, 0, 0,
-11, 245, 23, -1,
-17, 220, 58, -5,
-18, 184, 100, -10,
-15, 143, 143, -15,
-10, 100, 184, -18,
-5, 58, 220, -17,
-1, 23, 245, -11 };
short coefs[32];
get_coeffs( coefs , rsz_params.in_hsize, rsz_params.in_vsize,
rsz_params.out_hsize, rsz_params.out_vsize);
for( i = 0; i < 32; i++ )
rsz_params.hfilt_coeffs[i] = rsz_params.vfilt_coeffs[i] = coefs[i];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment