Commit c91faf2e authored by Jean-Paul Saman's avatar Jean-Paul Saman

New chroma module using /dev/davinci_resizer.

Conflicts:

	modules/video_chroma/Modules.am
parent e2585139
......@@ -4498,6 +4498,16 @@ AC_ARG_ENABLE(fb,
])
fi
dnl
dnl Linux DaVinci resizer and chroma conversion module
dnl
AC_ARG_ENABLE(davinciresizer,
[ --enable-davinciresizer Linux davinci resizer and chroma conversion support (default disabled on Linux)])
if test "${enable_davinciresizer}" = "yes"
then
VLC_ADD_PLUGINS([davinci_resizer])
fi
dnl
dnl Linux MGA module
dnl
......
......@@ -83,3 +83,7 @@ libvlc_LTLIBRARIES += \
libi420_rgb_plugin.la \
libgrey_yuv_plugin.la \
$(NULL)
SOURCES_davinci_resizer = \
davinci.c \
$(NULL)
/*****************************************************************************
* davinci.c : DaVinci resizer module
*****************************************************************************
* Copyright (C) 2008 the VideoLAN team
* $Id$
*
* Authors: Antoine Cellerier <dionoea at videolan dot org>
*
* 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.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <string.h> /* strerror() */
#include <stdlib.h> /* malloc(), free() */
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <sys/mman.h>
/* FIXME */
#include "/home/dionoea/videolan/m2x/neuros/linux-davinci-2.6/include/asm-arm/arch-davinci/davinci_resizer.h"
#include <vlc/vlc.h>
#include <vlc/vout.h>
/* Use some memory buffers from the device ... slower */
#define USE_BUFFERS
#ifndef USE_BUFFERS
/* Hack alert */
# define PAGE_OFFSET -0x40000000
# define PHYS_OFFSET -0x80000000
# define virt_to_phys(x) ((x) - PAGE_OFFSET + PHYS_OFFSET)
# define phys_to_virt(x) ((x) - PHYS_OFFSET + PAGE_OFFSET)
#endif
/*****************************************************************************
* Local and extern prototypes.
*****************************************************************************/
static int Open( vlc_object_t * );
static void Close( vlc_object_t * );
static void Convert( vout_thread_t *, picture_t *, picture_t * );
#ifdef USE_BUFFERS
static uint8_t *GetBuffer( vout_thread_t *p_vout, int buf_type, int size, int *offset );
#endif
struct chroma_sys_t
{
int i_fd; /* /dev/davinci_resizer */
rsz_resize_t resize;
uint8_t *p_in;
int i_in_size;
uint8_t *p_out;
int i_out_size;
};
/*****************************************************************************
* Module descriptor.
*****************************************************************************/
vlc_module_begin();
set_description( _("Conversions using /dev/davinci_resizer") );
set_capability( "chroma", 200 );
set_callbacks( Open, Close );
vlc_module_end();
/*****************************************************************************
*
*****************************************************************************/
static int Open( vlc_object_t *p_this )
{
vout_thread_t *p_vout = (vout_thread_t *)p_this;
if( p_vout->render.i_width & 1 || p_vout->render.i_height & 1 )
{
return -1;
}
switch( p_vout->render.i_chroma )
{
case VLC_FOURCC('Y','V','1','2'):
case VLC_FOURCC('I','4','2','0'):
case VLC_FOURCC('I','Y','U','V'):
switch( p_vout->output.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;
break;
default:
return VLC_EGENERIC;
}
break;
default:
return VLC_EGENERIC;
}
p_vout->chroma.p_sys = malloc( sizeof( chroma_sys_t ) );
if( !p_vout->chroma.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)" );
goto err;
}
msg_Info( p_vout, "/dev/davinci_resizer opened ("
#ifdef USE_BUFFERS
"using buffers"
#else
"not using buffers"
#endif
")" );
/**
* Get the input and output buffers
*/
p_sys->i_in_size = (p_vout->render.i_width*p_vout->render.i_height*3)/2;
#ifdef USE_BUFFERS
p_sys->p_in = GetBuffer( p_vout, RSZ_BUF_IN, p_sys->i_in_size, &p_sys->resize.in_buf.offset );
if( !p_sys->p_in ) goto err;
p_sys->resize.in_buf.index = 0;
#endif
p_sys->i_out_size = p_vout->output.i_width*p_vout->output.i_height*2;
#ifdef USE_BUFFERS
p_sys->p_out = GetBuffer( p_vout, RSZ_BUF_OUT, p_sys->i_out_size, &p_sys->resize.out_buf.offset );
if( !p_sys->p_out ) goto err;
p_sys->resize.out_buf.index = 0;
#endif
/**
* Set the parameters
*/
rsz_params_t params;
memset( &params, 0, sizeof( params ) );
params.in_hsize = p_vout->render.i_width;
params.in_vsize = p_vout->render.i_height;
params.in_pitch = p_vout->render.i_width * 2; /* FIXME: should be p_pic->p->i_pitch and not p_pic->p->i_visible_pitch */
params.inptyp = RSZ_INTYPE_PLANAR_8BIT;
params.pix_fmt = RSZ_PIX_FMT_PLANAR; /* Is this the input or output? */
params.pix_fmt = RSZ_PIX_FMT_UYVY; /* Is this the input or output? */
params.out_hsize = p_vout->output.i_width;
params.out_vsize = p_vout->output.i_height;
params.out_pitch = p_vout->output.i_width * 2; /* FIXME: should be p_pic->p->i_pitch and not p_pic->p->i_visible_pitch */
/* What does this do? :) */
params.hfilt_coeffs[0] = 256;
params.vfilt_coeffs[0] = 256;
#if 0
params.vfilt_coeffs[16] = -32;
params.vfilt_coeffs[17] = 160;
params.vfilt_coeffs[18] = 160;
params.vfilt_coeffs[19] = -32;
#endif
if( ioctl( p_sys->i_fd, RSZ_S_PARAM, &params ) )
{
msg_Err( p_vout, "Failed setting resizer parameters (%m)" );
goto err;
}
/**
* Set resizer speed to fastest
*/
int i_speed = 0;
if( ioctl( p_sys->i_fd, RSZ_S_EXP, &i_speed ) )
{
msg_Err( p_vout, "Failed setting resizer speed (%m)" );
goto err;
}
/**
* Initialize resize structure
*/
#ifndef USE_BUFFERS
p_sys->resize.in_buf.index = -1; /* User supplied */
#endif
p_sys->resize.in_buf.size = p_sys->i_in_size;
#ifndef USE_BUFFERS
p_sys->resize.out_buf.index = -1; /* User supplied */
#endif
p_sys->resize.out_buf.size = p_sys->i_out_size;
/**
* We're done
*/
msg_Info( p_vout, "davinci resizer initialized correctly (I hope...)" );
return VLC_SUCCESS;
err:
if( p_sys->i_fd != -1 ) close( p_sys->i_fd );
free( p_sys );
return VLC_EGENERIC;
}
static void Close( vlc_object_t *p_this )
{
vout_thread_t *p_vout = (vout_thread_t *)p_this;
chroma_sys_t *p_sys = p_vout->chroma.p_sys;
close( p_sys->i_fd );
free( p_sys );
}
/* Following functions are local */
#ifdef USE_BUFFERS
/*****************************************************************************
*
*****************************************************************************/
static uint8_t *GetBuffer( vout_thread_t *p_vout, int buf_type, int size,
int *offset )
{
chroma_sys_t *p_sys = p_vout->chroma.p_sys;
uint8_t *p_buf;
rsz_reqbufs_t reqbufs;
rsz_buffer_t buffer;
memset( &reqbufs, 0, sizeof( reqbufs ) );
memset( &buffer, 0, sizeof( buffer ) );
reqbufs.buf_type = buf_type;
reqbufs.size = size;
reqbufs.count = 1;
msg_Dbg( p_vout, "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 ) )
{
msg_Err( p_vout, "RSZ_REQBUF failed (%m)" );
return NULL;
}
buffer.buf_type = buf_type;
buffer.index = 0;
if( ioctl( p_sys->i_fd, RSZ_QUERYBUF, &buffer ) )
{
msg_Err( p_vout, "RSZ_QUERYBUF failed (%m)" );
return NULL;
}
msg_Dbg( p_vout, "Got buffer: index %d, offset 0x%x",
buffer.index, buffer.offset );
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)" );
return NULL;
}
return p_buf;
}
#endif
/*****************************************************************************
*
*****************************************************************************/
static void Convert( vout_thread_t *p_vout, picture_t *p_source,
picture_t *p_dest )
{
chroma_sys_t *p_sys = p_vout->chroma.p_sys;
#ifdef USE_BUFFERS
memcpy( p_sys->p_in, p_source->p->p_pixels, p_sys->i_in_size );
#else
p_sys->resize.in_buf.offset = virt_to_phys( p_source->p->p_pixels );
p_sys->resize.out_buf.offset = virt_to_phys( p_dest->p->p_pixels );
msg_Err( p_vout, "p_data: %p, %p\n", p_source->p->p_pixels, p_dest->p->p_pixels );
msg_Err( p_vout, "offsets: %x, %x\n", p_sys->resize.in_buf.offset, p_sys->resize.out_buf.offset );
#endif
if( ioctl( p_sys->i_fd, RSZ_RESIZE, &p_sys->resize ) )
{
msg_Err( p_vout, "Resize request failed." );
return;
}
msg_Dbg( p_vout, "Looks like resize worked!" );
#ifdef USE_BUFFERS
memcpy( p_dest->p->p_pixels, p_sys->p_out, p_sys->i_out_size );
msg_Dbg( p_vout, "Memcpy too!" );
#endif
}
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