1 /*****************************************************************************
2 * chroma.c: chroma conversion using ffmpeg library
3 *****************************************************************************
4 * Copyright (C) 1999-2008 the VideoLAN team
7 * Authors: Gildas Bazin <gbazin@videolan.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
32 #include <vlc_common.h>
34 #include <vlc_filter.h>
37 #ifdef HAVE_LIBAVCODEC_AVCODEC_H
38 # include <libavcodec/avcodec.h>
39 #elif defined(HAVE_FFMPEG_AVCODEC_H)
40 # include <ffmpeg/avcodec.h>
47 static void ChromaConversion( filter_t *, picture_t *, picture_t * );
48 static picture_t *ChromaConversion_Filter( filter_t *, picture_t * );
50 /*****************************************************************************
51 * chroma_sys_t: chroma method descriptor
52 *****************************************************************************
53 * This structure is part of the chroma transformation descriptor, it
54 * describes the chroma plugin specific properties.
55 *****************************************************************************/
59 int i_src_ffmpeg_chroma;
61 int i_dst_ffmpeg_chroma;
63 ImgReSampleContext *p_rsc;
66 /*****************************************************************************
67 * OpenChroma: allocate a chroma function
68 *****************************************************************************
69 * This function allocates and initializes a chroma function
70 *****************************************************************************/
71 int OpenChroma( vlc_object_t *p_this )
73 filter_t *p_filter = (filter_t *)p_this;
74 int i_ffmpeg_chroma[2], i_vlc_chroma[2], i;
77 * Check the source chroma first, then the destination chroma
79 i_vlc_chroma[0] = p_filter->fmt_in.video.i_chroma;
80 i_vlc_chroma[1] = p_filter->fmt_out.video.i_chroma;
81 for( i = 0; i < 2; i++ )
83 i_ffmpeg_chroma[i] = GetFfmpegChroma( i_vlc_chroma[i] );
84 if( i_ffmpeg_chroma[i] < 0 ) return VLC_EGENERIC;
87 p_filter->pf_video_filter = ChromaConversion_Filter;
89 p_filter->p_sys = malloc( sizeof( filter_sys_t ) );
90 if( p_filter->p_sys == NULL )
95 p_filter->p_sys->i_src_vlc_chroma = p_filter->fmt_in.video.i_chroma;
96 p_filter->p_sys->i_dst_vlc_chroma = p_filter->fmt_out.video.i_chroma;
97 p_filter->p_sys->i_src_ffmpeg_chroma = i_ffmpeg_chroma[0];
98 p_filter->p_sys->i_dst_ffmpeg_chroma = i_ffmpeg_chroma[1];
100 if( ( p_filter->fmt_in.video.i_height != p_filter->fmt_out.video.i_height ||
101 p_filter->fmt_in.video.i_width != p_filter->fmt_out.video.i_width ) &&
102 ( p_filter->p_sys->i_dst_vlc_chroma == VLC_FOURCC('I','4','2','0') ||
103 p_filter->p_sys->i_dst_vlc_chroma == VLC_FOURCC('Y','V','1','2') ))
105 msg_Dbg( p_filter, "preparing to resample picture" );
106 p_filter->p_sys->p_rsc =
107 img_resample_init( p_filter->fmt_out.video.i_width,
108 p_filter->fmt_out.video.i_height,
109 p_filter->fmt_in.video.i_width,
110 p_filter->fmt_in.video.i_height );
111 avpicture_alloc( &p_filter->p_sys->tmp_pic,
112 p_filter->p_sys->i_dst_ffmpeg_chroma,
113 p_filter->fmt_in.video.i_width,
114 p_filter->fmt_in.video.i_height );
118 msg_Dbg( p_filter, "no resampling" );
119 p_filter->p_sys->p_rsc = NULL;
125 VIDEO_FILTER_WRAPPER( ChromaConversion )
127 /*****************************************************************************
128 * ChromaConversion: actual chroma conversion function
129 *****************************************************************************/
130 static void ChromaConversion( filter_t *p_filter,
131 picture_t *p_src, picture_t *p_dest )
137 /* Prepare the AVPictures for converion */
138 for( i = 0; i < p_src->i_planes; i++ )
140 src_pic.data[i] = p_src->p[i].p_pixels;
141 src_pic.linesize[i] = p_src->p[i].i_pitch;
143 for( i = 0; i < p_dest->i_planes; i++ )
145 dest_pic.data[i] = p_dest->p[i].p_pixels;
146 dest_pic.linesize[i] = p_dest->p[i].i_pitch;
150 if( p_filter->p_sys->i_src_vlc_chroma == VLC_FOURCC('Y','V','1','2') ||
151 p_filter->p_sys->i_src_vlc_chroma == VLC_FOURCC('Y','V','U','9') )
154 src_pic.data[1] = p_src->p[2].p_pixels;
155 src_pic.data[2] = p_src->p[1].p_pixels;
157 if( p_filter->p_sys->i_dst_vlc_chroma == VLC_FOURCC('Y','V','1','2') ||
158 p_filter->p_sys->i_dst_vlc_chroma == VLC_FOURCC('Y','V','U','9') )
161 dest_pic.data[1] = p_dest->p[2].p_pixels;
162 dest_pic.data[2] = p_dest->p[1].p_pixels;
164 if( p_filter->p_sys->i_src_ffmpeg_chroma == PIX_FMT_RGB24 )
165 if( p_filter->fmt_in.video.i_bmask == 0x00ff0000 )
166 p_filter->p_sys->i_src_ffmpeg_chroma = PIX_FMT_BGR24;
168 if( p_filter->p_sys->p_rsc )
170 img_convert( &p_filter->p_sys->tmp_pic,
171 p_filter->p_sys->i_dst_ffmpeg_chroma,
172 &src_pic, p_filter->p_sys->i_src_ffmpeg_chroma,
173 p_filter->fmt_in.video.i_width,
174 p_filter->fmt_in.video.i_height );
175 img_resample( p_filter->p_sys->p_rsc, &dest_pic,
176 &p_filter->p_sys->tmp_pic );
180 img_convert( &dest_pic, p_filter->p_sys->i_dst_ffmpeg_chroma,
181 &src_pic, p_filter->p_sys->i_src_ffmpeg_chroma,
182 p_filter->fmt_in.video.i_width,
183 p_filter->fmt_in.video.i_height );
187 /*****************************************************************************
188 * CloseChroma: free the chroma function
189 *****************************************************************************
190 * This function frees the previously allocated chroma function
191 *****************************************************************************/
192 void CloseChroma( vlc_object_t *p_this )
194 filter_t *p_filter = (filter_t *)p_this;
195 if( p_filter->p_sys->p_rsc )
197 img_resample_close( p_filter->p_sys->p_rsc );
198 avpicture_free( &p_filter->p_sys->tmp_pic );
200 free( p_filter->p_sys );