Commit 5e3df08c authored by Jean-Paul Saman's avatar Jean-Paul Saman

davinci resizer rewrite to video_filter2

parent 15e440e9
......@@ -5,6 +5,7 @@
* $Id$
*
* Authors: Antoine Cellerier <dionoea at videolan dot org>
* Jean-Paul Saman <jean-paul saman at m2x dot 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
......@@ -25,6 +26,16 @@
* Preamble
*****************************************************************************/
#undef _FILE_OFFSET_BITS /* mmap() will fail if we use 64bits offsets */
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_filter.h>
#include <vlc_vout.h>
#include <string.h> /* strerror() */
#include <stdlib.h> /* malloc(), free() */
#include <fcntl.h>
......@@ -32,21 +43,22 @@
#include <unistd.h>
#include <sys/mman.h>
/* hmm, should have been a user headerfile */
#include <asm-arm/arch-davinci/davinci_resizer.h>
#include <vlc/vlc.h>
#include <vlc/vout.h>
/*****************************************************************************
* Local and extern prototypes.
*****************************************************************************/
static int Open( vlc_object_t * );
static void Close( vlc_object_t * );
static int Open( filter_t * );
static void Close( filter_t * );
static void Convert( vout_thread_t *, picture_t *, picture_t * );
static uint8_t *GetBuffer( vout_thread_t *p_vout, int buf_type, int size, int *offset );
static void DAVINCI_RESIZER( filter_t *, picture_t *, picture_t * );
static picture_t *DAVINCI_RESIZER_Filter( filter_t *, picture_t * );
struct chroma_sys_t
static uint8_t *GetBuffer( filter_t *, int buf_type, int size, int *offset );
static void FreeBuffer( filter_t *, uint8_t *p_buffer, int *i_size );
struct filter_sys_t
{
int i_fd; /* /dev/davinci_resizer */
......@@ -57,26 +69,27 @@ struct chroma_sys_t
uint8_t *p_out;
int i_out_size;
vlc_bool_t b_inited;
bool b_inited;
};
/*****************************************************************************
* Module descriptor.
*****************************************************************************/
vlc_module_begin();
set_description( _("Conversions using /dev/davinci_resizer") );
set_capability( "chroma", 200 );
set_description( N_("Conversions using /dev/davinci_resizer") );
set_capability( "video filter2", 200 );
set_callbacks( Open, Close );
vlc_module_end();
/*****************************************************************************
*
*****************************************************************************/
static int Open( vlc_object_t *p_this )
static int Open( filter_t *p_this )
{
vout_thread_t *p_vout = (vout_thread_t *)p_this;
filter_t *p_filter = (filter_t *)p_this;
filter_sys_t *p_sys;
switch( p_vout->render.i_chroma )
switch( p_filter->fmt_in.video.i_chroma )
{
#if 0
case VLC_FOURCC('Y','V','1','2'):
......@@ -86,12 +99,12 @@ static int Open( vlc_object_t *p_this )
case VLC_FOURCC('U','Y','V','Y'):
case VLC_FOURCC('U','Y','N','V'):
case VLC_FOURCC('Y','4','2','2'):
switch( p_vout->output.i_chroma )
switch( p_filter->fmt_out.video.i_chroma )
{
case VLC_FOURCC('U','Y','V','Y'):
case VLC_FOURCC('U','Y','N','V'):
case VLC_FOURCC('Y','4','2','2'):
p_vout->chroma.pf_convert = Convert;
p_filter->pf_video_filter = DAVINCI_RESIZER_Filter;
break;
default:
......@@ -103,41 +116,52 @@ static int Open( vlc_object_t *p_this )
return VLC_EGENERIC;
}
p_vout->chroma.p_sys = malloc( sizeof( chroma_sys_t ) );
if( !p_vout->chroma.p_sys )
p_filter->p_sys = p_sys = calloc( 1, sizeof( filter_sys_t ) );
if( !p_sys )
return VLC_ENOMEM;
chroma_sys_t *p_sys = p_vout->chroma.p_sys;
memset( p_sys, 0, sizeof( chroma_sys_t ) );
p_sys->i_fd = open( "/dev/davinci_resizer", O_RDWR );
if( p_sys->i_fd == -1 )
{
msg_Err( p_vout, "Failed to open /dev/davinci_resizer (%m)." );
msg_Err( p_filter, "Failed to open /dev/davinci_resizer (%m)." );
free( p_sys );
return VLC_EGENERIC;
}
p_sys->b_inited = VLC_FALSE;
p_sys->b_inited = false;
if( p_filter->fmt_in.video.i_chroma != p_filter->fmt_out.video.i_chroma )
msg_Dbg( p_filter, "Davinci resizer %4.4s to %4.4s converter",
(const char*)&p_filter->fmt_in.video.i_chroma,
(const char*)&p_filter->fmt_out.video.i_chroma );
else
msg_Dbg( p_filter, "Davinci resizer %dx%d to %dx%d scaler",
p_filter->fmt_in.video.i_width, p_filter->fmt_in.video.i_height,
p_filter->fmt_out.video.i_width, p_filter->fmt_out.video.i_height );
return VLC_SUCCESS;
}
static void Close( vlc_object_t *p_this )
static void Close( filter_t *p_filter )
{
chroma_sys_t *p_sys = ((vout_thread_t*)p_this)->chroma.p_sys;
filter_sys_t *p_sys = p_filter->p_sys;
FreeBuffer( p_filter, p_sys->p_in, &p_sys->i_in_size );
FreeBuffer( p_filter, p_sys->p_out, &p_sys->i_out_size );
close( p_sys->i_fd );
free( p_sys );
}
/* Following functions are local */
static uint8_t *GetBuffer( vout_thread_t *p_vout, int buf_type, int size,
static uint8_t *GetBuffer( filter_t *p_filter, int buf_type, int size,
int *offset )
{
chroma_sys_t *p_sys = p_vout->chroma.p_sys;
filter_sys_t *p_sys = p_filter->p_sys;
uint8_t *p_buf;
rsz_reqbufs_t reqbufs;
rsz_buffer_t buffer;
memset( &reqbufs, 0, sizeof( reqbufs ) );
memset( &buffer, 0, sizeof( buffer ) );
......@@ -145,57 +169,61 @@ static uint8_t *GetBuffer( vout_thread_t *p_vout, int buf_type, int size,
reqbufs.size = size;
reqbufs.count = 1;
msg_Dbg( p_vout, "Asking %s for buffers: size 0x%x, count %d",
#if 1
msg_Dbg( p_filter, "Asking %s for buffers: size 0x%x, count %d",
buf_type == RSZ_BUF_IN ? "input" : "output",
reqbufs.size, reqbufs.count );
if( ioctl( p_sys->i_fd, RSZ_REQBUF, &reqbufs ) )
#endif
if( ioctl( p_sys->i_fd, RSZ_REQBUF, &reqbufs ) == -1 )
{
msg_Err( p_vout, "RSZ_REQBUF failed (%m)" );
msg_Err( p_filter, "RSZ_REQBUF failed (%m)" );
return NULL;
}
buffer.buf_type = buf_type;
buffer.index = 0;
if( ioctl( p_sys->i_fd, RSZ_QUERYBUF, &buffer ) )
if( ioctl( p_sys->i_fd, RSZ_QUERYBUF, &buffer ) == -1 )
{
msg_Err( p_vout, "RSZ_QUERYBUF failed (%m)" );
msg_Err( p_filter, "RSZ_QUERYBUF failed (%m)" );
return NULL;
}
msg_Dbg( p_vout, "Got buffer: index %d, offset 0x%x",
#if 1
msg_Dbg( p_filter, "Got buffer: index %d, offset 0x%x",
buffer.index, buffer.offset );
#endif
if( offset ) *offset = buffer.offset;
p_buf = mmap( NULL, reqbufs.size, PROT_READ|PROT_WRITE, MAP_SHARED,
p_sys->i_fd, buffer.offset );
if( p_buf == MAP_FAILED )
{
msg_Err( p_vout, "mmap to buffer failed (%m)" );
msg_Err( p_filter, "mmap to buffer failed (%m)" );
return NULL;
}
return p_buf;
}
#if 0
static double u( double s )
static void FreeBuffer( filter_t *p_filter, uint8_t *p_buffer, int *i_size )
{
if( s < 0 ) s = -s;
if( 0. <= s && s <= 1. )
return 3./2.*s*s*s-5./2.*s*s+1.;
else if( s <= 2. )
return -1./2.*s*s*s+5./2.*s*s-4.*s+2.;
else
return 0.;
if( p_buffer )
{
if( munmap( p_buffer, *i_size ) < 0 )
{
msg_Err( p_filter, "munmap on buffer failed (%m)" );
}
p_buffer = NULL;
*i_size = 0;
}
}
#endif
static int Init( vout_thread_t *p_vout, picture_t *p_source,
picture_t *p_dest )
static int Init( filter_t *p_filter, picture_t *p_source, picture_t *p_dest )
{
chroma_sys_t *p_sys = p_vout->chroma.p_sys;
filter_sys_t *p_sys = p_filter->p_sys;
int i;
/**
......@@ -203,18 +231,20 @@ static int Init( vout_thread_t *p_vout, picture_t *p_source,
*/
if( !p_sys->p_in )
{
p_sys->i_in_size = p_source->p->i_pitch * p_source->p->i_visible_lines;//p_vout->render.i_width*p_vout->render.i_height*2;
p_sys->p_in = GetBuffer( p_vout, RSZ_BUF_IN, p_sys->i_in_size, &p_sys->resize.in_buf.offset );
p_sys->i_in_size = p_source->p->i_pitch * p_source->p->i_visible_lines;
p_sys->p_in = GetBuffer( p_filter, RSZ_BUF_IN, p_sys->i_in_size, &p_sys->resize.in_buf.offset );
p_sys->resize.in_buf.index = 0;
if( !p_sys->p_in ) return VLC_EGENERIC;
if( !p_sys->p_in )
return VLC_EGENERIC;
}
if( !p_sys->p_out )
{
p_sys->i_out_size = p_dest->p->i_pitch * p_dest->p->i_visible_lines;
p_sys->p_out = GetBuffer( p_vout, RSZ_BUF_OUT, p_sys->i_out_size, &p_sys->resize.out_buf.offset );
p_sys->p_out = GetBuffer( p_filter, RSZ_BUF_OUT, p_sys->i_out_size, &p_sys->resize.out_buf.offset );
p_sys->resize.out_buf.index = 0;
if( !p_sys->p_out ) return VLC_EGENERIC;
if( !p_sys->p_out )
return VLC_EGENERIC;
}
/**
......@@ -231,32 +261,7 @@ static int Init( vout_thread_t *p_vout, picture_t *p_source,
params.out_vsize = p_dest->p->i_visible_lines;
params.out_pitch = p_dest->p->i_pitch;
#if 0
/* Bicubic interpolation coefficients as defined in spraai7a */
for( i = 0; i < 8; i++ )
{
double n = ((double)i)/8.;
params.hfilt_coeffs[4*i] =
params.vfilt_coeffs[4*i] = (int)(u(n+1.)*256.);
params.hfilt_coeffs[4*i+1] =
params.vfilt_coeffs[4*i+1] = (int)(u(n)*256.);
params.hfilt_coeffs[4*i+2] =
params.vfilt_coeffs[4*i+2] = (int)(u(1.-n)*256.);
params.hfilt_coeffs[4*i+3] =
params.vfilt_coeffs[4*i+3] = (int)(u(2.-i)*256.);
}
#endif
const short coefs[] = {
#if 0
0, 256, 0, 0,
-12, 246, 23, -1,
-18, 222, 58, -6,
-18, 186, 99, -11,
-16, 144, 144, -16,
-11, 99, 186, -18,
-6, 58, 222, -18,
-1, 23, 246, -12 };
#else
0, 256, 0, 0,
-11, 245, 23, -1,
-17, 220, 58, -5,
......@@ -265,15 +270,14 @@ static int Init( vout_thread_t *p_vout, picture_t *p_source,
-10, 100, 184, -18,
-5, 58, 220, -17,
-1, 23, 245, -11 };
#endif
for( i = 0; i < 32; i++ )
params.hfilt_coeffs[i] = params.vfilt_coeffs[i] = coefs[i];
params.yenh_params.type = RSZ_YENH_DISABLE;
if( ioctl( p_sys->i_fd, RSZ_S_PARAM, &params ) )
if( ioctl( p_sys->i_fd, RSZ_S_PARAM, &params ) == -1 )
{
msg_Err( p_vout, "Failed setting resizer parameters (%m)" );
msg_Err( p_filter, "Failed setting resizer parameters (%m)" );
return VLC_EGENERIC;
}
......@@ -281,9 +285,9 @@ static int Init( vout_thread_t *p_vout, picture_t *p_source,
* Set resizer speed to fastest
*/
int i_speed = 0;
if( ioctl( p_sys->i_fd, RSZ_S_EXP, &i_speed ) )
if( ioctl( p_sys->i_fd, RSZ_S_EXP, &i_speed ) == -1 )
{
msg_Err( p_vout, "Failed setting resizer speed (%m)" );
msg_Err( p_filter, "Failed setting resizer speed (%m)" );
return VLC_EGENERIC;
}
......@@ -291,24 +295,27 @@ static int Init( vout_thread_t *p_vout, picture_t *p_source,
p_sys->resize.in_buf.size = p_sys->i_in_size;
p_sys->resize.out_buf.size = p_sys->i_out_size;
p_sys->b_inited = VLC_TRUE;
p_filter->p_sys->b_inited = true;
return VLC_SUCCESS;
}
static void Convert( vout_thread_t *p_vout, picture_t *p_source,
picture_t *p_dest )
/* Chroma conversion routine using Davinic Resizer */
VIDEO_FILTER_WRAPPER(DAVINCI_RESIZER)
static void DAVINCI_RESIZER( filter_t *p_filter, picture_t *p_source, picture_t *p_dest )
{
chroma_sys_t *p_sys = p_vout->chroma.p_sys;
filter_sys_t *p_sys = p_filter->p_sys;
if( !p_sys->b_inited && Init( p_vout, p_source, p_dest ) != VLC_SUCCESS )
if( !p_sys->b_inited &&
Init( p_filter, p_source, p_dest ) != VLC_SUCCESS )
return;
memcpy( p_sys->p_in, p_source->p->p_pixels, p_sys->i_in_size );
if( ioctl( p_sys->i_fd, RSZ_RESIZE, &p_sys->resize ) )
{
msg_Err( p_vout, "Resize request failed." );
msg_Err( p_filter, "Resize request failed." );
return;
}
......
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