postprocess.c
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:8k
源码类别:

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * postprocess.c: video postprocessing using the ffmpeg library
  3.  *****************************************************************************
  4.  * Copyright (C) 1999-2001 VideoLAN
  5.  * $Id: postprocess.c 8931 2004-10-06 13:07:35Z gbazin $
  6.  *
  7.  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  8.  *          Gildas Bazin <gbazin@netcourrier.com>
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * (at your option) any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  23.  *****************************************************************************/
  24. #include <vlc/vlc.h>
  25. #include <vlc/vout.h>
  26. #include <vlc/decoder.h>
  27. /* ffmpeg header */
  28. #ifdef HAVE_FFMPEG_AVCODEC_H
  29. #   include <ffmpeg/avcodec.h>
  30. #else
  31. #   include <avcodec.h>
  32. #endif
  33. #include "ffmpeg.h"
  34. #ifdef LIBAVCODEC_PP
  35. #ifdef HAVE_POSTPROC_POSTPROCESS_H
  36. #   include <postproc/postprocess.h>
  37. #else
  38. #   include <libpostproc/postprocess.h>
  39. #endif
  40. #ifndef PP_CPU_CAPS_ALTIVEC
  41. #   define PP_CPU_CAPS_ALTIVEC 0
  42. #endif
  43. /*****************************************************************************
  44.  * video_postproc_sys_t : ffmpeg video postprocessing descriptor
  45.  *****************************************************************************/
  46. typedef struct video_postproc_sys_t
  47. {
  48.     pp_context_t *pp_context;
  49.     pp_mode_t    *pp_mode;
  50.     vlc_bool_t   *pb_pp;
  51.     int i_width;
  52.     int i_height;
  53. } video_postproc_sys_t;
  54. static int PPQCallback( vlc_object_t *p_this, char const *psz_cmd,
  55.                         vlc_value_t oldval, vlc_value_t newval, void *p_data );
  56. /*****************************************************************************
  57.  * OpenPostproc: probe and open the postproc
  58.  *****************************************************************************/
  59. void *E_(OpenPostproc)( decoder_t *p_dec, vlc_bool_t *pb_pp )
  60. {
  61.     video_postproc_sys_t *p_sys;
  62.     vlc_value_t val, val_orig, text;
  63.     p_sys = malloc( sizeof(video_postproc_sys_t) );
  64.     p_sys->pp_context = NULL;
  65.     p_sys->pp_mode = NULL;
  66.     *pb_pp = VLC_FALSE;
  67.     p_sys->pb_pp = pb_pp;
  68.     /* Create object variable if not already done */
  69.     if( var_Type( p_dec, "ffmpeg-pp-q" ) == 0 )
  70.     {
  71.         var_Create( p_dec, "ffmpeg-pp-q",
  72.                     VLC_VAR_INTEGER | VLC_VAR_HASCHOICE | VLC_VAR_DOINHERIT );
  73.         text.psz_string = _("Post processing");
  74.         var_Change( p_dec, "ffmpeg-pp-q", VLC_VAR_SETTEXT, &text, NULL );
  75.         var_Get( p_dec, "ffmpeg-pp-q", &val_orig );
  76.         var_Change( p_dec, "ffmpeg-pp-q", VLC_VAR_DELCHOICE, &val_orig, NULL );
  77.         val.i_int = 0; text.psz_string = _("Disable");
  78.         var_Change( p_dec, "ffmpeg-pp-q", VLC_VAR_ADDCHOICE, &val, &text );
  79.         val.i_int = 1; text.psz_string = _("1 (Lowest)");
  80.         var_Change( p_dec, "ffmpeg-pp-q", VLC_VAR_ADDCHOICE, &val, &text );
  81.         val.i_int = 2;
  82.         var_Change( p_dec, "ffmpeg-pp-q", VLC_VAR_ADDCHOICE, &val, NULL );
  83.         val.i_int = 3;
  84.         var_Change( p_dec, "ffmpeg-pp-q", VLC_VAR_ADDCHOICE, &val, NULL );
  85.         val.i_int = 4;
  86.         var_Change( p_dec, "ffmpeg-pp-q", VLC_VAR_ADDCHOICE, &val, NULL );
  87.         val.i_int = 5;
  88.         var_Change( p_dec, "ffmpeg-pp-q", VLC_VAR_ADDCHOICE, &val, NULL );
  89.         val.i_int = 6; text.psz_string = _("6 (Highest)");
  90.         var_Change( p_dec, "ffmpeg-pp-q", VLC_VAR_ADDCHOICE, &val, &text );
  91.         var_AddCallback( p_dec, "ffmpeg-pp-q", PPQCallback, p_sys );
  92.     }
  93.     /* ***** Load post processing if enabled ***** */
  94.     var_Get( p_dec, "ffmpeg-pp-q", &val );
  95.     var_Set( p_dec, "ffmpeg-pp-q", val_orig );
  96.     return p_sys;
  97. }
  98. /*****************************************************************************
  99.  * InitPostproc: 
  100.  *****************************************************************************/
  101. int E_(InitPostproc)( decoder_t *p_dec, void *p_data,
  102.                       int i_width, int i_height, int pix_fmt )
  103. {
  104.     video_postproc_sys_t *p_sys = (video_postproc_sys_t *)p_data;
  105.     int32_t i_cpu = p_dec->p_libvlc->i_cpu;
  106.     int i_flags = 0;
  107.     /* Set CPU capabilities */
  108.     if( i_cpu & CPU_CAPABILITY_MMX )
  109.     {
  110.         i_flags |= PP_CPU_CAPS_MMX;
  111.     }
  112.     if( i_cpu & CPU_CAPABILITY_MMXEXT )
  113.     {
  114.         i_flags |= PP_CPU_CAPS_MMX2;
  115.     }
  116.     if( i_cpu & CPU_CAPABILITY_3DNOW )
  117.     {
  118.         i_flags |= PP_CPU_CAPS_3DNOW;
  119.     }
  120.     if( i_cpu & CPU_CAPABILITY_ALTIVEC )
  121.     {
  122.         i_flags |= PP_CPU_CAPS_ALTIVEC;
  123.     }
  124.     switch( pix_fmt )
  125.     {
  126.     case PIX_FMT_YUV444P:
  127.         i_flags |= PP_FORMAT_444;
  128.         break;
  129.     case PIX_FMT_YUV422P:
  130.         i_flags |= PP_FORMAT_422;
  131.         break;
  132.     case PIX_FMT_YUV411P:
  133.         i_flags |= PP_FORMAT_411;
  134.         break;
  135.     default:
  136.         i_flags |= PP_FORMAT_420;
  137.         break;
  138.     }
  139.     p_sys->pp_context = pp_get_context( i_width, i_height, i_flags );
  140.     p_sys->i_width = i_width;
  141.     p_sys->i_height = i_height;
  142.     return VLC_SUCCESS;
  143. }
  144. /*****************************************************************************
  145.  * PostprocPict: 
  146.  *****************************************************************************/
  147. int E_(PostprocPict)( decoder_t *p_dec, void *p_data,
  148.                       picture_t *p_pic, AVFrame *p_ff_pic )
  149. {
  150.     video_postproc_sys_t *p_sys = (video_postproc_sys_t *)p_data;
  151.     uint8_t *src[3], *dst[3];
  152.     int i_plane, i_src_stride[3], i_dst_stride[3];
  153.     for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )
  154.     {
  155.         src[i_plane] = p_ff_pic->data[i_plane];
  156.         dst[i_plane] = p_pic->p[i_plane].p_pixels;
  157.         i_src_stride[i_plane] = p_ff_pic->linesize[i_plane];
  158.         i_dst_stride[i_plane] = p_pic->p[i_plane].i_pitch;
  159.     }
  160.     pp_postprocess( src, i_src_stride, dst, i_dst_stride,
  161.                     p_sys->i_width, p_sys->i_height,
  162.                     p_ff_pic->qscale_table, p_ff_pic->qstride,
  163.                     p_sys->pp_mode, p_sys->pp_context,
  164.                     p_ff_pic->pict_type );
  165.     return VLC_SUCCESS;
  166. }
  167. /*****************************************************************************
  168.  * ClosePostproc: 
  169.  *****************************************************************************/
  170. void E_(ClosePostproc)( decoder_t *p_dec, void *p_data )
  171. {
  172.     video_postproc_sys_t *p_sys = (video_postproc_sys_t *)p_data;
  173.     if( p_sys && p_sys->pp_mode )
  174.     {
  175.         pp_free_mode( p_sys->pp_mode );
  176.         if( p_sys->pp_context ) pp_free_context( p_sys->pp_context );
  177.     }
  178.     var_DelCallback( p_dec, "ffmpeg-pp-q", PPQCallback, p_sys );
  179.     if( p_sys ) free( p_sys );
  180. }
  181. /*****************************************************************************
  182.  * object variables callbacks: a bunch of object variables are used by the
  183.  * interfaces to interact with the decoder.
  184.  *****************************************************************************/
  185. static int PPQCallback( vlc_object_t *p_this, char const *psz_cmd,
  186.                         vlc_value_t oldval, vlc_value_t newval, void *p_data )
  187. {
  188.     decoder_t *p_dec = (decoder_t *)p_this;
  189.     video_postproc_sys_t *p_sys = (video_postproc_sys_t *)p_data;
  190.     if( newval.i_int > 0 )
  191.     {
  192.         int  i_quality = newval.i_int;
  193.         char *psz_name = config_GetPsz( p_dec, "ffmpeg-pp-name" );
  194.         pp_mode_t *pp_mode;
  195.         if( !psz_name )
  196.         {
  197.             psz_name = strdup( "default" );
  198.         }
  199.         else if( *psz_name == '' )
  200.         {
  201.             free( psz_name );
  202.             psz_name = strdup( "default" );
  203.         }
  204.         pp_mode = pp_get_mode_by_name_and_quality( psz_name, i_quality );
  205.         if( !pp_mode )
  206.         {
  207.             msg_Err( p_dec, "failed getting mode for postproc" );
  208.             newval.i_int = 0;
  209.         }
  210.         else
  211.         {
  212.             msg_Dbg( p_dec, "postprocessing enabled" );
  213.         }
  214.         free( psz_name );
  215.         p_sys->pp_mode = pp_mode;
  216.     }
  217.     else
  218.     {
  219.         msg_Dbg( p_dec, "postprocessing disabled" );
  220.     }
  221.     *p_sys->pb_pp = newval.i_int;
  222.     return VLC_SUCCESS;
  223. }
  224. #endif /* LIBAVCODEC_PP */