Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

chroma.c

00001 /*****************************************************************************
00002  * chroma.c: chroma conversion using ffmpeg library
00003  *****************************************************************************
00004  * Copyright (C) 1999-2001 the VideoLAN team
00005  * $Id: chroma.c 11664 2005-07-09 06:17:09Z courmisch $
00006  *
00007  * Authors: Gildas Bazin <[email protected]>
00008  *
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00022  *****************************************************************************/
00023 
00024 /*****************************************************************************
00025  * Preamble
00026  *****************************************************************************/
00027 #include <vlc/vlc.h>
00028 #include <vlc/vout.h>
00029 
00030 /* ffmpeg header */
00031 #ifdef HAVE_FFMPEG_AVCODEC_H
00032 #   include <ffmpeg/avcodec.h>
00033 #else
00034 #   include <avcodec.h>
00035 #endif
00036 
00037 #include "ffmpeg.h"
00038 
00039 void E_(InitLibavcodec) ( vlc_object_t *p_object );
00040 static void ChromaConversion( vout_thread_t *, picture_t *, picture_t * );
00041 
00042 /*****************************************************************************
00043  * chroma_sys_t: chroma method descriptor
00044  *****************************************************************************
00045  * This structure is part of the chroma transformation descriptor, it
00046  * describes the chroma plugin specific properties.
00047  *****************************************************************************/
00048 struct chroma_sys_t
00049 {
00050     int i_src_vlc_chroma;
00051     int i_src_ffmpeg_chroma;
00052     int i_dst_vlc_chroma;
00053     int i_dst_ffmpeg_chroma;
00054     AVPicture tmp_pic;
00055     ImgReSampleContext *p_rsc;
00056 };
00057 
00058 /*****************************************************************************
00059  * OpenChroma: allocate a chroma function
00060  *****************************************************************************
00061  * This function allocates and initializes a chroma function
00062  *****************************************************************************/
00063 int E_(OpenChroma)( vlc_object_t *p_this )
00064 {
00065     vout_thread_t *p_vout = (vout_thread_t *)p_this;
00066     int i_ffmpeg_chroma[2], i_vlc_chroma[2], i;
00067 
00068     /*
00069      * Check the source chroma first, then the destination chroma
00070      */
00071     i_vlc_chroma[0] = p_vout->render.i_chroma;
00072     i_vlc_chroma[1] = p_vout->output.i_chroma;
00073     for( i = 0; i < 2; i++ )
00074     {
00075         i_ffmpeg_chroma[i] = E_(GetFfmpegChroma)( i_vlc_chroma[i] );
00076         if( i_ffmpeg_chroma[i] < 0 ) return VLC_EGENERIC;
00077     }
00078 
00079     p_vout->chroma.pf_convert = ChromaConversion;
00080 
00081     p_vout->chroma.p_sys = malloc( sizeof( chroma_sys_t ) );
00082     if( p_vout->chroma.p_sys == NULL )
00083     {
00084         return VLC_EGENERIC;
00085     }
00086 
00087     p_vout->chroma.p_sys->i_src_vlc_chroma = p_vout->render.i_chroma;
00088     p_vout->chroma.p_sys->i_dst_vlc_chroma = p_vout->output.i_chroma;
00089     p_vout->chroma.p_sys->i_src_ffmpeg_chroma = i_ffmpeg_chroma[0];
00090     p_vout->chroma.p_sys->i_dst_ffmpeg_chroma = i_ffmpeg_chroma[1];
00091 
00092     if( ( p_vout->render.i_height != p_vout->output.i_height ||
00093           p_vout->render.i_width != p_vout->output.i_width ) &&
00094         ( p_vout->chroma.p_sys->i_dst_vlc_chroma == VLC_FOURCC('I','4','2','0')  ||
00095           p_vout->chroma.p_sys->i_dst_vlc_chroma == VLC_FOURCC('Y','V','1','2') ))
00096         
00097     {
00098         msg_Dbg( p_vout, "preparing to resample picture" );
00099         p_vout->chroma.p_sys->p_rsc =
00100             img_resample_init( p_vout->output.i_width, p_vout->output.i_height,
00101                                p_vout->render.i_width, p_vout->render.i_height );
00102         avpicture_alloc( &p_vout->chroma.p_sys->tmp_pic,
00103                          p_vout->chroma.p_sys->i_dst_ffmpeg_chroma,
00104                          p_vout->render.i_width, p_vout->render.i_height );
00105     }
00106     else
00107     {
00108         msg_Dbg( p_vout, "no resampling" );
00109         p_vout->chroma.p_sys->p_rsc = NULL;
00110     }
00111 
00112     /* libavcodec needs to be initialized for some chroma conversions */
00113     E_(InitLibavcodec)(p_this);
00114 
00115     return VLC_SUCCESS;
00116 }
00117 
00118 /*****************************************************************************
00119  * ChromaConversion: actual chroma conversion function
00120  *****************************************************************************/
00121 static void ChromaConversion( vout_thread_t *p_vout,
00122                               picture_t *p_src, picture_t *p_dest )
00123 {
00124     AVPicture src_pic;
00125     AVPicture dest_pic;
00126     int i;
00127 
00128     /* Prepare the AVPictures for converion */
00129     for( i = 0; i < p_src->i_planes; i++ )
00130     {
00131         src_pic.data[i] = p_src->p[i].p_pixels;
00132         src_pic.linesize[i] = p_src->p[i].i_pitch;
00133     }
00134     for( i = 0; i < p_dest->i_planes; i++ )
00135     {
00136         dest_pic.data[i] = p_dest->p[i].p_pixels;
00137         dest_pic.linesize[i] = p_dest->p[i].i_pitch;
00138     }
00139 
00140     /* Special cases */
00141     if( p_vout->chroma.p_sys->i_src_vlc_chroma == VLC_FOURCC('Y','V','1','2') ||
00142         p_vout->chroma.p_sys->i_src_vlc_chroma == VLC_FOURCC('Y','V','U','9') )
00143     {
00144         /* Invert U and V */
00145         src_pic.data[1] = p_src->p[2].p_pixels;
00146         src_pic.data[2] = p_src->p[1].p_pixels;
00147     }
00148     if( p_vout->chroma.p_sys->i_dst_vlc_chroma == VLC_FOURCC('Y','V','1','2') ||
00149         p_vout->chroma.p_sys->i_dst_vlc_chroma == VLC_FOURCC('Y','V','U','9') )
00150     {
00151         /* Invert U and V */
00152         dest_pic.data[1] = p_dest->p[2].p_pixels;
00153         dest_pic.data[2] = p_dest->p[1].p_pixels;
00154     }
00155     if( p_vout->chroma.p_sys->i_src_ffmpeg_chroma == PIX_FMT_RGB24 )
00156         if( p_vout->render.i_bmask == 0x00ff0000 )
00157             p_vout->chroma.p_sys->i_src_ffmpeg_chroma = PIX_FMT_BGR24;
00158 
00159     if( p_vout->chroma.p_sys->p_rsc )
00160     {
00161         img_convert( &p_vout->chroma.p_sys->tmp_pic,
00162                      p_vout->chroma.p_sys->i_dst_ffmpeg_chroma,
00163                      &src_pic, p_vout->chroma.p_sys->i_src_ffmpeg_chroma,
00164                      p_vout->render.i_width, p_vout->render.i_height );
00165         img_resample( p_vout->chroma.p_sys->p_rsc, &dest_pic,
00166                       &p_vout->chroma.p_sys->tmp_pic );
00167     }
00168     else
00169     {
00170         img_convert( &dest_pic, p_vout->chroma.p_sys->i_dst_ffmpeg_chroma,
00171                      &src_pic, p_vout->chroma.p_sys->i_src_ffmpeg_chroma,
00172                      p_vout->render.i_width, p_vout->render.i_height );
00173     }
00174 }
00175 
00176 /*****************************************************************************
00177  * CloseChroma: free the chroma function
00178  *****************************************************************************
00179  * This function frees the previously allocated chroma function
00180  *****************************************************************************/
00181 void E_(CloseChroma)( vlc_object_t *p_this )
00182 {
00183     vout_thread_t *p_vout = (vout_thread_t *)p_this;
00184     if( p_vout->chroma.p_sys->p_rsc )
00185     {
00186         img_resample_close( p_vout->chroma.p_sys->p_rsc );
00187         avpicture_free( &p_vout->chroma.p_sys->tmp_pic );
00188     }
00189     free( p_vout->chroma.p_sys );
00190 }

Generated on Tue Dec 20 10:14:29 2005 for vlc-0.8.4a by  doxygen 1.4.2