Commit d25c5e06 authored by Laurent Aimar's avatar Laurent Aimar

* add post processing modules.( As defined in MPEG4 ISO) There are C,

mmx, mmxext version, but only mmxext is really usable (other need a
 _lot_ of CPU power).

There are new options for ffmpeg plugins :
 --ffmpeg-pp to choose postprocessing module( c, mmx, mmext or mmx2 )
 --ffmpeg-pp-q to choose quality( 0..6 )
 --ffmpeg-db-?? ( where first ? is for y or c, and the other ? for v or h )
to force deblocking on luminance(y)/chrominance(c) horizontally or
vertically.
 --ffmpeg-dr-? ( where ? is y or c ) to force dering on ...
parent 25235c6d
ffmpeg_SOURCES = ffmpeg.c ffmpeg_SOURCES = ffmpeg.c
This diff is collapsed.
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ffmpeg_vdec.h: video decoder using ffmpeg library * ffmpeg_vdec.h: video decoder using ffmpeg library
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: ffmpeg.h,v 1.1 2002/08/04 17:23:42 sam Exp $ * $Id: ffmpeg.h,v 1.2 2002/08/04 22:13:05 fenrir Exp $
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -41,6 +41,38 @@ typedef struct bitmapinfoheader_s ...@@ -41,6 +41,38 @@ typedef struct bitmapinfoheader_s
} bitmapinfoheader_t; } bitmapinfoheader_t;
typedef struct videodec_thread_s
{
decoder_fifo_t *p_fifo;
bitmapinfoheader_t format;
AVCodecContext context, *p_context;
AVCodec *p_codec;
vout_thread_t *p_vout;
/* for post processing */
u32 i_pp_mode; /* valid only with I420 and YV12 */
postprocessing_t *p_pp;
char *psz_namecodec;
/* for frame skipping algo */
int b_hurry_up;
int i_frame_error;
int i_frame_skip;
int i_frame_late; /* how may frame decoded are in late */
/* private */
mtime_t i_pts;
int i_framesize;
u8 *p_framedata;
u8 *p_buffer; /* buffer for gather pes */
int i_buffer_size; /* size of allocated p_framedata */
} videodec_thread_t;
/* MPEG4 video */ /* MPEG4 video */
#define FOURCC_DIVX VLC_FOURCC('D','I','V','X') #define FOURCC_DIVX VLC_FOURCC('D','I','V','X')
#define FOURCC_divx VLC_FOURCC('d','i','v','x') #define FOURCC_divx VLC_FOURCC('d','i','v','x')
...@@ -171,7 +203,7 @@ static int ffmpeg_GetFfmpegCodec( vlc_fourcc_t i_fourcc, ...@@ -171,7 +203,7 @@ static int ffmpeg_GetFfmpegCodec( vlc_fourcc_t i_fourcc,
i_codec = CODEC_ID_MPEG4; i_codec = CODEC_ID_MPEG4;
psz_name = "MPEG-4"; psz_name = "MPEG-4";
break; break;
/* FIXME FOURCC_H263P exist but what fourcc ? */
case FOURCC_H263: case FOURCC_H263:
case FOURCC_h263: case FOURCC_h263:
case FOURCC_U263: case FOURCC_U263:
...@@ -196,25 +228,45 @@ static int ffmpeg_GetFfmpegCodec( vlc_fourcc_t i_fourcc, ...@@ -196,25 +228,45 @@ static int ffmpeg_GetFfmpegCodec( vlc_fourcc_t i_fourcc,
return VLC_FALSE; return VLC_FALSE;
} }
/* FIXME FIXME some of them are wrong */
typedef struct videodec_thread_s static int i_ffmpeg_PixFmtToChroma[] =
{ {
decoder_fifo_t *p_fifo; /* PIX_FMT_ANY = -1, PIX_FMT_YUV420P,
PIX_FMT_YUV422, PIX_FMT_RGB24,
bitmapinfoheader_t format; PIX_FMT_BGR24, PIX_FMT_YUV422P,
PIX_FMT_YUV444P, PIX_FMT_YUV410P
*/
0, VLC_FOURCC('I','4','2','0'),
VLC_FOURCC('I','4','2','0'), VLC_FOURCC('R','V','2','4'),
0, VLC_FOURCC('Y','4','2','2'),
VLC_FOURCC('I','4','4','4'), 0
};
AVCodecContext context, *p_context; static inline u32 ffmpeg_PixFmtToChroma( int i_ffmpegchroma )
AVCodec *p_codec; {
vout_thread_t *p_vout; if( ++i_ffmpegchroma > 7 )
{
return( 0 );
}
else
{
return( i_ffmpeg_PixFmtToChroma[i_ffmpegchroma] );
}
}
char *psz_namecodec; static inline int ffmpeg_FfAspect( int i_width, int i_height, int i_ffaspect )
/* private */ {
mtime_t i_pts; switch( i_ffaspect )
int i_framesize; {
byte_t *p_framedata; case( FF_ASPECT_4_3_625 ):
case( FF_ASPECT_4_3_525 ):
return( VOUT_ASPECT_FACTOR * 4 / 3);
case( FF_ASPECT_16_9_625 ):
case( FF_ASPECT_16_9_525 ):
return( VOUT_ASPECT_FACTOR * 16 / 9 );
case( FF_ASPECT_SQUARE ):
default:
return( VOUT_ASPECT_FACTOR * i_width / i_height );
}
}
int i_frame_error;
int i_frame_skip;
int i_frame_late; /* how may frame decoded are in late */
} videodec_thread_t;
postprocessing_c_SOURCES = postprocessing.c postprocessing_c.c
postprocessing_mmx_SOURCES = postprocessing.c postprocessing_mmx.c
postprocessing_mmxext_SOURCES = postprocessing.c postprocessing_mmxext.c
/*****************************************************************************
* postprocessing.c
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: postprocessing.c,v 1.1 2002/08/04 22:13:06 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <stdlib.h>
#include <string.h>
#include <vlc/vlc.h>
#include <vlc/vout.h>
#include "postprocessing.h"
#include "postprocessing_common.h"
static int Open ( vlc_object_t *p_this );
static u32 pp_getmode( int i_quality, int b_autolevel );
static int pp_postprocess( picture_t *,
QT_STORE_T *, unsigned int,
unsigned int i_mode );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin();
#ifdef MODULE_NAME_IS_postprocessing_c
set_description( _("C Post Processing module") );
set_capability( "postprocessing", 50 );
add_shortcut( "c" );
#elif defined( MODULE_NAME_IS_postprocessing_mmx )
set_description( _("MMX Post Processing module") );
set_capability( "postprocessing", 100 );
add_requirement( MMX );
add_shortcut( "mmx" );
#elif defined( MODULE_NAME_IS_postprocessing_mmxext )
set_description( _("MMXEXT Post Processing module") );
set_capability( "postprocessing", 150 );
add_requirement( MMXEXT );
add_shortcut( "mmxext" );
add_shortcut( "mmx2" );
#endif
set_callbacks( Open, NULL );
vlc_module_end();
/*****************************************************************************
* Module initializer
*****************************************************************************/
static int Open ( vlc_object_t *p_this )
{
postprocessing_t *p_pp = (postprocessing_t *)p_this;
p_pp->pf_getmode = pp_getmode;
p_pp->pf_postprocess = pp_postprocess;
return VLC_SUCCESS;
}
static u32 pp_getmode( int i_quality, int b_autolevel )
{
u32 i_mode;
i_quality = i_quality < 0 ? 0 : i_quality;
i_quality = i_quality > 6 ? 6 : i_quality;
switch( i_quality )
{
case( 0 ):
i_mode = 0;
break;
case( 1 ):
i_mode = PP_DEBLOCK_Y_H;
break;
case( 2 ):
i_mode = PP_DEBLOCK_Y_H|PP_DEBLOCK_Y_V;
break;
case( 3 ):
i_mode = PP_DEBLOCK_Y_H|PP_DEBLOCK_Y_V|
PP_DEBLOCK_C_H;
break;
case( 4 ):
i_mode = PP_DEBLOCK_Y_H|PP_DEBLOCK_Y_V|
PP_DEBLOCK_C_H|PP_DEBLOCK_C_V;
break;
case( 5 ):
i_mode = PP_DEBLOCK_Y_H|PP_DEBLOCK_Y_V|
PP_DEBLOCK_C_H|PP_DEBLOCK_C_V|
PP_DERING_Y;
break;
case( 6 ):
i_mode = PP_DEBLOCK_Y_H|PP_DEBLOCK_Y_V|
PP_DEBLOCK_C_H|PP_DEBLOCK_C_V|
PP_DERING_Y|PP_DERING_C;
break;
default:
i_mode = 0;
}
if( b_autolevel )
{
i_mode |= PP_AUTOLEVEL;
}
return( i_mode );
}
/*****************************************************************************
* pp_postprocess : make post-filter as defined in MPEG4-ISO
*****************************************************************************
*****************************************************************************/
static int pp_postprocess( picture_t *p_pic,
QT_STORE_T *p_QP_store, unsigned int i_QP_stride,
unsigned int i_mode )
{
/* Some sanity checks */
// if( ( p_pic->i_height&0x0f )||( p_pic->i_width&0x0f )||
if( ( p_pic->p_heap->i_chroma != VLC_FOURCC( 'I', '4', '2', '0' ) )&&
( p_pic->p_heap->i_chroma != VLC_FOURCC( 'Y', 'V', '1', '2' ) ) )
{
return( PP_ERR_INVALID_PICTURE );
}
if( ( !p_QP_store )||( i_QP_stride < p_pic->p_heap->i_width >> 4 ) )
{
return( PP_ERR_INVALID_QP );
}
/* First do vertical deblocking and then horizontal */
/* Luminance */
if( i_mode&PP_DEBLOCK_Y_V )
{
E_( pp_deblock_V )( p_pic->Y_PIXELS,
p_pic->p_heap->i_width, p_pic->p_heap->i_height, p_pic->Y_PITCH,
p_QP_store, i_QP_stride,
0 );
}
if( i_mode&PP_DEBLOCK_Y_H )
{
E_( pp_deblock_H )( p_pic->Y_PIXELS,
p_pic->p_heap->i_width, p_pic->p_heap->i_height, p_pic->Y_PITCH,
p_QP_store, i_QP_stride,
0 );
}
/* Chrominance */
if( i_mode&PP_DEBLOCK_C_V )
{
E_( pp_deblock_V )( p_pic->U_PIXELS,
p_pic->p_heap->i_width >> 1, p_pic->p_heap->i_height >> 1,
p_pic->U_PITCH,
p_QP_store, i_QP_stride,
1 );
E_( pp_deblock_V )( p_pic->V_PIXELS,
p_pic->p_heap->i_width >> 1, p_pic->p_heap->i_height >> 1,
p_pic->V_PITCH,
p_QP_store, i_QP_stride,
1 );
}
if( i_mode&PP_DEBLOCK_C_H )
{
E_( pp_deblock_H )( p_pic->U_PIXELS,
p_pic->p_heap->i_width >> 1, p_pic->p_heap->i_height >> 1,
p_pic->U_PITCH,
p_QP_store, i_QP_stride,
1 );
E_( pp_deblock_H )( p_pic->V_PIXELS,
p_pic->p_heap->i_width >> 1, p_pic->p_heap->i_height >> 1,
p_pic->V_PITCH,
p_QP_store, i_QP_stride,
1 );
}
/* After deblocking do dering */
/* TODO check for min size */
if( i_mode&PP_DERING_Y )
{
E_( pp_dering_Y )( p_pic->Y_PIXELS,
p_pic->p_heap->i_width, p_pic->p_heap->i_height,
p_pic->Y_PITCH,
p_QP_store, i_QP_stride );
}
if( i_mode&PP_DERING_C )
{
E_( pp_dering_C )( p_pic->U_PIXELS,
p_pic->p_heap->i_width >> 1, p_pic->p_heap->i_height >> 1,
p_pic->U_PITCH,
p_QP_store, i_QP_stride );
E_( pp_dering_C )( p_pic->V_PIXELS,
p_pic->p_heap->i_width >> 1, p_pic->p_heap->i_height >> 1,
p_pic->V_PITCH,
p_QP_store, i_QP_stride );
}
#if defined( MODULE_NAME_IS_postprocessing_mmx )||defined( MODULE_NAME_IS_postprocessing_mmxext )
/* We have used MMX so return to safe FPU state */
__asm__ __volatile__ ( "emms" );
#endif
return( PP_ERR_OK );
}
/*****************************************************************************
* postprocessing.h
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: postprocessing.h,v 1.1 2002/08/04 22:13:06 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#define QT_STORE_T int
/* postprocessing available using to create i_mode */
#define PP_DEBLOCK_Y_H 0x00000001
#define PP_DEBLOCK_Y_V 0x00000002
#define PP_DEBLOCK_C_H 0x00000004
#define PP_DEBLOCK_C_V 0x00000008
#define PP_DERING_Y 0x00000010
#define PP_DERING_C 0x00000020
#define PP_AUTOLEVEL 0x80000000
/* error code, not really used */
#define PP_ERR_OK 0 /* no problem */
#define PP_ERR_INVALID_PICTURE 1 /* wrong picture size or chroma */
#define PP_ERR_INVALID_QP 2 /* need valid QP to make the postprocess */
#define PP_ERR_UNKNOWN 255
typedef struct postprocessing_s
{
VLC_COMMON_MEMBERS
module_t * p_module;
u32 (*pf_getmode)( int i_quality, int b_autolevel );
int (*pf_postprocess)( picture_t *p_pic,
QT_STORE_T *p_QP_store, unsigned int i_QP_stride,
unsigned int i_mode );
} postprocessing_t;
This diff is collapsed.
/*****************************************************************************
* postprocessing_common.h
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: postprocessing_common.h,v 1.1 2002/08/04 22:13:06 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
//#define PP_USE_3DNOW /* Nothing done yet */
//#define PP_USE_MMX /* when only MMX is supported */
//#define PP_USE_MMXEXT /* when MMXEXT is also supported, imply MMX */
/* thresholds for deblocking, I've taken value given by ISO */
#define PP_THR1 2ULL /* threshold for deblocking */
#define PP_2xTHR1 ( 2 * PP_THR1 )/* internal usage */
#define PP_THR2 6ULL
/* Some usefull macros */
#define PP_MAX( a, b ) ( a > b ? (a) : (b) )
#define PP_MIN( a, b ) ( a < b ? (a) : (b) )
#define PP_ABS( x ) ( ( x < 0 ) ? (-(x)) : (x) )
#define PP_SGN( x ) ( ( x < 0 ) ? -1 : 1 )
#define PP_MIN3( a, b, c ) ( PP_MIN( (a), PP_MIN( (b), (c) ) ) )
#define PP_CLIP( x, a, b ) ( PP_MAX( (a), PP_MIN( (x), (b) ) ) )
void E_( pp_deblock_V )();
void E_( pp_deblock_H )();
void E_( pp_dering_Y )();
void E_( pp_dering_C )();
This diff is collapsed.
This diff is collapsed.
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