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

davinci resizer rewrite to video_filter2

parent 15e440e9
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
* $Id$ * $Id$
* *
* Authors: Antoine Cellerier <dionoea at videolan dot org> * 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 * 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 * it under the terms of the GNU General Public License as published by
...@@ -25,6 +26,16 @@ ...@@ -25,6 +26,16 @@
* Preamble * Preamble
*****************************************************************************/ *****************************************************************************/
#undef _FILE_OFFSET_BITS /* mmap() will fail if we use 64bits offsets */ #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 <string.h> /* strerror() */
#include <stdlib.h> /* malloc(), free() */ #include <stdlib.h> /* malloc(), free() */
#include <fcntl.h> #include <fcntl.h>
...@@ -32,21 +43,22 @@ ...@@ -32,21 +43,22 @@
#include <unistd.h> #include <unistd.h>
#include <sys/mman.h> #include <sys/mman.h>
/* hmm, should have been a user headerfile */
#include <asm-arm/arch-davinci/davinci_resizer.h> #include <asm-arm/arch-davinci/davinci_resizer.h>
#include <vlc/vlc.h>
#include <vlc/vout.h>
/***************************************************************************** /*****************************************************************************
* Local and extern prototypes. * Local and extern prototypes.
*****************************************************************************/ *****************************************************************************/
static int Open( vlc_object_t * ); static int Open( filter_t * );
static void Close( vlc_object_t * ); static void Close( filter_t * );
static void Convert( vout_thread_t *, picture_t *, picture_t * ); static void DAVINCI_RESIZER( filter_t *, picture_t *, picture_t * );
static uint8_t *GetBuffer( vout_thread_t *p_vout, int buf_type, int size, int *offset ); 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 */ int i_fd; /* /dev/davinci_resizer */
...@@ -57,26 +69,27 @@ struct chroma_sys_t ...@@ -57,26 +69,27 @@ struct chroma_sys_t
uint8_t *p_out; uint8_t *p_out;
int i_out_size; int i_out_size;
vlc_bool_t b_inited; bool b_inited;
}; };
/***************************************************************************** /*****************************************************************************
* Module descriptor. * Module descriptor.
*****************************************************************************/ *****************************************************************************/
vlc_module_begin(); vlc_module_begin();
set_description( _("Conversions using /dev/davinci_resizer") ); set_description( N_("Conversions using /dev/davinci_resizer") );
set_capability( "chroma", 200 ); set_capability( "video filter2", 200 );
set_callbacks( Open, Close ); set_callbacks( Open, Close );
vlc_module_end(); 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 #if 0
case VLC_FOURCC('Y','V','1','2'): case VLC_FOURCC('Y','V','1','2'):
...@@ -86,12 +99,12 @@ static int Open( vlc_object_t *p_this ) ...@@ -86,12 +99,12 @@ static int Open( vlc_object_t *p_this )
case VLC_FOURCC('U','Y','V','Y'): case VLC_FOURCC('U','Y','V','Y'):
case VLC_FOURCC('U','Y','N','V'): case VLC_FOURCC('U','Y','N','V'):
case VLC_FOURCC('Y','4','2','2'): 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','V','Y'):
case VLC_FOURCC('U','Y','N','V'): case VLC_FOURCC('U','Y','N','V'):
case VLC_FOURCC('Y','4','2','2'): case VLC_FOURCC('Y','4','2','2'):
p_vout->chroma.pf_convert = Convert; p_filter->pf_video_filter = DAVINCI_RESIZER_Filter;
break; break;
default: default:
...@@ -103,41 +116,52 @@ static int Open( vlc_object_t *p_this ) ...@@ -103,41 +116,52 @@ static int Open( vlc_object_t *p_this )
return VLC_EGENERIC; return VLC_EGENERIC;
} }
p_vout->chroma.p_sys = malloc( sizeof( chroma_sys_t ) ); p_filter->p_sys = p_sys = calloc( 1, sizeof( filter_sys_t ) );
if( !p_vout->chroma.p_sys ) if( !p_sys )
return VLC_ENOMEM; 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 ); p_sys->i_fd = open( "/dev/davinci_resizer", O_RDWR );
if( p_sys->i_fd == -1 ) 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 ); free( p_sys );
return VLC_EGENERIC; 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; 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 ); close( p_sys->i_fd );
free( p_sys ); free( p_sys );
} }
/* Following functions are local */ /* 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 ) 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; uint8_t *p_buf;
rsz_reqbufs_t reqbufs; rsz_reqbufs_t reqbufs;
rsz_buffer_t buffer; rsz_buffer_t buffer;
memset( &reqbufs, 0, sizeof( reqbufs ) ); memset( &reqbufs, 0, sizeof( reqbufs ) );
memset( &buffer, 0, sizeof( buffer ) ); memset( &buffer, 0, sizeof( buffer ) );
...@@ -145,57 +169,61 @@ static uint8_t *GetBuffer( vout_thread_t *p_vout, int buf_type, int size, ...@@ -145,57 +169,61 @@ static uint8_t *GetBuffer( vout_thread_t *p_vout, int buf_type, int size,
reqbufs.size = size; reqbufs.size = size;
reqbufs.count = 1; 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", buf_type == RSZ_BUF_IN ? "input" : "output",
reqbufs.size, reqbufs.count ); 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; return NULL;
} }
buffer.buf_type = buf_type; buffer.buf_type = buf_type;
buffer.index = 0; 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; 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 ); buffer.index, buffer.offset );
#endif
if( offset ) *offset = buffer.offset; if( offset ) *offset = buffer.offset;
p_buf = mmap( NULL, reqbufs.size, PROT_READ|PROT_WRITE, MAP_SHARED, p_buf = mmap( NULL, reqbufs.size, PROT_READ|PROT_WRITE, MAP_SHARED,
p_sys->i_fd, buffer.offset ); p_sys->i_fd, buffer.offset );
if( p_buf == MAP_FAILED ) 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 NULL;
} }
return p_buf; return p_buf;
} }
#if 0 static void FreeBuffer( filter_t *p_filter, uint8_t *p_buffer, int *i_size )
static double u( double s )
{ {
if( s < 0 ) s = -s; if( p_buffer )
if( 0. <= s && s <= 1. ) {
return 3./2.*s*s*s-5./2.*s*s+1.; if( munmap( p_buffer, *i_size ) < 0 )
else if( s <= 2. ) {
return -1./2.*s*s*s+5./2.*s*s-4.*s+2.; msg_Err( p_filter, "munmap on buffer failed (%m)" );
else }
return 0.; p_buffer = NULL;
*i_size = 0;
}
} }
#endif
static int Init( vout_thread_t *p_vout, picture_t *p_source, static int Init( filter_t *p_filter, picture_t *p_source, picture_t *p_dest )
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; int i;
/** /**
...@@ -203,18 +231,20 @@ static int Init( vout_thread_t *p_vout, picture_t *p_source, ...@@ -203,18 +231,20 @@ static int Init( vout_thread_t *p_vout, picture_t *p_source,
*/ */
if( !p_sys->p_in ) 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->i_in_size = p_source->p->i_pitch * p_source->p->i_visible_lines;
p_sys->p_in = GetBuffer( p_vout, RSZ_BUF_IN, p_sys->i_in_size, &p_sys->resize.in_buf.offset ); 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; 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 ) if( !p_sys->p_out )
{ {
p_sys->i_out_size = p_dest->p->i_pitch * p_dest->p->i_visible_lines; 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; 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, ...@@ -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_vsize = p_dest->p->i_visible_lines;
params.out_pitch = p_dest->p->i_pitch; 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[] = { 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, 0, 256, 0, 0,
-11, 245, 23, -1, -11, 245, 23, -1,
-17, 220, 58, -5, -17, 220, 58, -5,
...@@ -265,15 +270,14 @@ static int Init( vout_thread_t *p_vout, picture_t *p_source, ...@@ -265,15 +270,14 @@ static int Init( vout_thread_t *p_vout, picture_t *p_source,
-10, 100, 184, -18, -10, 100, 184, -18,
-5, 58, 220, -17, -5, 58, 220, -17,
-1, 23, 245, -11 }; -1, 23, 245, -11 };
#endif
for( i = 0; i < 32; i++ ) for( i = 0; i < 32; i++ )
params.hfilt_coeffs[i] = params.vfilt_coeffs[i] = coefs[i]; params.hfilt_coeffs[i] = params.vfilt_coeffs[i] = coefs[i];
params.yenh_params.type = RSZ_YENH_DISABLE; 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; return VLC_EGENERIC;
} }
...@@ -281,9 +285,9 @@ static int Init( vout_thread_t *p_vout, picture_t *p_source, ...@@ -281,9 +285,9 @@ static int Init( vout_thread_t *p_vout, picture_t *p_source,
* Set resizer speed to fastest * Set resizer speed to fastest
*/ */
int i_speed = 0; 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; return VLC_EGENERIC;
} }
...@@ -291,24 +295,27 @@ static int Init( vout_thread_t *p_vout, picture_t *p_source, ...@@ -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.in_buf.size = p_sys->i_in_size;
p_sys->resize.out_buf.size = p_sys->i_out_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; return VLC_SUCCESS;
} }
static void Convert( vout_thread_t *p_vout, picture_t *p_source, /* Chroma conversion routine using Davinic Resizer */
picture_t *p_dest ) 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 &&
return; 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 ); 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 ) ) 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; 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