Commit 612836aa authored by Jean-Paul Saman's avatar Jean-Paul Saman

davinci: resizer.c: resizer.h: resizer_coefs.c: Update DaVinci resizer implementation

Update the DaVinci resizer implementation modules/codec/davinci to latest
state of Rafael Carre his work. This introduces one new file 'resizer_coefs.c'.
parent 5bb9468d
......@@ -6,9 +6,13 @@ SOURCES_davinci = \
fourcc.c \
$(NULL)
# Davinci resizer/scaling hack
# The decoder does not know the eventual screen size
# so optimizing by resizing to screen size is not
# feasible here
# resizer_coefs.c \
# resizer.c \
# reziser.h
# resizer.h \
# $(NULL)
if ENABLE_SOUT
SOURCES_davinci += encoder.c audio_encoder.c video_encoder.c audio1_encoder.c
......
This diff is collapsed.
/*****************************************************************************
* resizer.c: Resize pictures directly into framebuffer (DaVinci specific)
* resizer.c : DaVinci resizer
*****************************************************************************
* Copyright (C) 2008-2009 M2X BV
* Copyright © 2010 Rafaël Carré
*
* Authors: Rafaël Carré <rcarre@m2x.nl>
* Authors: Rafaël Carré <rafael at gmail>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -20,56 +20,31 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef RESIZER_H
#define RESIZER_H
#ifndef VLC_DAVINCI_RESIZER_H
#define VLC_DAVINCI_RESIZER_H 1
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/fb.h>
#include <video/davincifb.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <ti/sdo/ce/osal/Memory.h>
#include <inttypes.h>
#include <asm-arm/arch-davinci/davinci_resizer.h>
#include <math.h>
#include <assert.h>
#define NUM_BUFFERS 1 /* XXX: mesure performance with 3 buffers if needed */
typedef struct resizer_t davinci_resizer_t;
#define BPP 16
void resizer_close(struct resizer_t *rsz);
#define PI 3.1415926535897932384626
struct resizer_t *resizer_open(vlc_object_t *p_this,
int in_width, int in_height,
int *out_width, int *out_height);
typedef struct
{
int i_fd;
unsigned int i_height;
unsigned int i_width;
int resizer_resize(vlc_object_t *p_this,
struct resizer_t *rsz, uint8_t *in, uint8_t *out);
uint8_t *p_yuyv;
int offset;
int i_yuyv;
void resizer_copy_picture(vlc_object_t *p_this,
uint8_t *out, uint8_t *in, int width, int height);
unsigned int i_out_width;
unsigned int i_out_height;
/** FIXME: arbritary values make them more configurable */
#define OUT_WIDTH 720
#define OUT_HEIGHT 480
bool b_direct;
} davinci_resizer_t;
/* define if VLC picture buffers are allocated with Memorycontig_Alloc() */
#define DIRECT_OUTPUT
/* Resize: resize and/or enhance input picture
* \param p_dec : pointer to decoder_t structure
* \param rsz : pointer to davinci_resizer_t structure
* \param b_scale : rescale to output size
* \param in : input buffer as XDM_BufDesc
* \param out : output buffer as XDM_BufDesc
* \return VLC_SUCCESS on success and VLC_EGENERIC on failure
*/
int Resize( decoder_t *p_dec, davinci_resizer_t *rsz, bool b_scale,
XDM_BufDesc in, XDM_BufDesc out );
int ResizerOpen( vlc_object_t *p_this, davinci_resizer_t *rsz );
void ResizerClose( davinci_resizer_t *rsz );
#endif /* RESIZER_H */
#endif /* VLC_DAVINCI_RESIZER_H */
/*****************************************************************************
* resizer_coefs.c: Resize coefs (DaVinci specific)
*****************************************************************************
* Copyright (C) 2008-2010 M2X BV
*
* Authors: Rafaël Carré <rcarre@m2x.nl>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
/*
* Resizer parameters calculation
* Based on SPRAAI7B documentation from TI
*
*/
#include <assert.h>
#include <math.h>
#include <stdlib.h>
#define VOUT_ASPECT_FACTOR 432000
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_in, unsigned int i_out )
{
assert( i_out > 1 );
assert( i_in > 7 );
float f_deinterleave_coef[ 32 ];
float f_windows[ 32+1 ];
unsigned int i_rsz;
if( i_in == i_out )
i_rsz = 256;
else
{
i_rsz = ((i_in - 7) * 256) / (i_out - 1);
if( i_rsz <= 512 )
{
i_rsz = ((i_in - 4) * 256) / (i_out - 1);
if( i_rsz > 512 ) i_rsz = 512;
}
}
int i_nphases, i_ntaps, i_winlen, i_phase_offset, i, j;
float f_fc;
if( i_rsz > 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_rsz < 256) ? (1. / i_nphases) : 256. / (i_rsz * i_nphases);
for( i = 0 ; i <= i_winlen ; i++ )
f_windows[i] = .42 - .5 * cos( 2 * M_PI * i / i_winlen ) +
.08 * cos( 4 * M_PI * i / i_winlen );
/* 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_rsz == 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;
}
}
}
void resize_coefs(unsigned int i_vidw, unsigned int i_vidh,
unsigned int *i_width, unsigned int *i_height,
short hcoefs[32], short vcoefs[32])
{
unsigned int i_hratio = VOUT_ASPECT_FACTOR * *i_height / i_vidh;
unsigned int i_wratio = VOUT_ASPECT_FACTOR * *i_width / i_vidw;
/* Davinci Resizer can only do from x0.25 to x4 */
if( i_hratio > VOUT_ASPECT_FACTOR * 4 )
i_hratio = VOUT_ASPECT_FACTOR * 4;
else if( i_hratio < VOUT_ASPECT_FACTOR / 4 )
i_hratio = VOUT_ASPECT_FACTOR / 4;
/* do that also for the width */
if( i_wratio > VOUT_ASPECT_FACTOR * 4 )
i_wratio = VOUT_ASPECT_FACTOR * 4;
else if( i_wratio < VOUT_ASPECT_FACTOR / 4 )
i_wratio = VOUT_ASPECT_FACTOR / 4;
/* choose the minimum for both axes */
i_hratio = i_wratio = i_hratio < i_wratio ? i_hratio : i_wratio;
/* Now calculate hrsz and vrsz */
int i_hrsz = 256 * VOUT_ASPECT_FACTOR / i_wratio;
int i_vrsz = 256 * VOUT_ASPECT_FACTOR / i_hratio;
/* Then recalculate final resolution */
int i_htap = i_hrsz > 512 ? 7 : 4;
int i_vtap = i_vrsz > 512 ? 7 : 4;
*i_width = ((i_vidw - 7) * 256 - (i_htap == 7 ? 32 : 16)) / i_hrsz + 1;
*i_height = ((i_vidh - i_vtap) * 256 - (i_vtap == 7 ? 32 : 16)) / i_vrsz + 1;
/* width must be a factor of 16 : davinci resizer limitation when doing
* vertical upscaling, 16 bytes per output line
*/
*i_width = ( *i_width + 15 ) & ~15;
get_coeffs( hcoefs, i_vidw, *i_width );
get_coeffs( vcoefs, i_vidh, *i_height );
}
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