]> git.sesse.net Git - vlc/blob - modules/codec/ffmpeg/chroma.c
* modules/codec/ffmpeg/*: ported the ffmpeg audio and video decoders to the new api.
[vlc] / modules / codec / ffmpeg / chroma.c
1 /*****************************************************************************
2  * chroma.c: chroma conversion using ffmpeg library
3  *****************************************************************************
4  * Copyright (C) 1999-2001 VideoLAN
5  * $Id: chroma.c,v 1.3 2003/10/27 01:04:38 gbazin Exp $
6  *
7  * Authors: Gildas Bazin <gbazin@netcourrier.com>
8  *
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.
13  *
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.
18  *
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., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <stdlib.h>                                      /* malloc(), free() */
28
29 #include <vlc/vlc.h>
30 #include <vlc/vout.h>
31
32 /* ffmpeg header */
33 #ifdef HAVE_FFMPEG_AVCODEC_H
34 #   include <ffmpeg/avcodec.h>
35 #else
36 #   include <avcodec.h>
37 #endif
38
39 #include "ffmpeg.h"
40
41 void E_(InitLibavcodec) ( vlc_object_t *p_object );
42 static void ChromaConversion( vout_thread_t *, picture_t *, picture_t * );
43
44 /*****************************************************************************
45  * chroma_sys_t: chroma method descriptor
46  *****************************************************************************
47  * This structure is part of the chroma transformation descriptor, it
48  * describes the chroma plugin specific properties.
49  *****************************************************************************/
50 struct chroma_sys_t
51 {
52     int i_src_vlc_chroma;
53     int i_src_ffmpeg_chroma;
54     int i_dst_vlc_chroma;
55     int i_dst_ffmpeg_chroma;
56 };
57
58 /*****************************************************************************
59  * OpenChroma: allocate a chroma function
60  *****************************************************************************
61  * This function allocates and initializes a chroma function
62  *****************************************************************************/
63 int E_(OpenChroma)( vlc_object_t *p_this )
64 {
65     vout_thread_t *p_vout = (vout_thread_t *)p_this;
66     int i_ffmpeg_chroma[2], i_vlc_chroma[2], i;
67
68     /*
69      * Check the source chroma first, then the destination chroma
70      */
71     i_vlc_chroma[0] = p_vout->render.i_chroma;
72     i_vlc_chroma[1] = p_vout->output.i_chroma;
73     for( i = 0; i < 2; i++ )
74     {
75         switch( i_vlc_chroma[i] )
76         {
77
78         /* Planar YUV formats */
79         case VLC_FOURCC('I','4','4','4'):
80             i_ffmpeg_chroma[i] = PIX_FMT_YUV444P;
81             break;
82
83         case VLC_FOURCC('I','4','2','2'):
84             i_ffmpeg_chroma[i] = PIX_FMT_YUV422P;
85             break;
86
87         case VLC_FOURCC('Y','V','1','2'):
88         case VLC_FOURCC('I','4','2','0'):
89         case VLC_FOURCC('I','Y','U','V'):
90             i_ffmpeg_chroma[i] = PIX_FMT_YUV420P;
91             break;
92
93         case VLC_FOURCC('I','4','1','1'):
94             i_ffmpeg_chroma[i] = PIX_FMT_YUV411P;
95             break;
96
97         case VLC_FOURCC('I','4','1','0'):
98             i_ffmpeg_chroma[i] = PIX_FMT_YUV410P;
99             break;
100
101         /* Packed YUV formats */
102
103         case VLC_FOURCC('Y','U','Y','2'):
104         case VLC_FOURCC('U','Y','V','Y'):
105             i_ffmpeg_chroma[i] = PIX_FMT_YUV422;
106             break;
107
108         /* Packed RGB formats */
109
110         case VLC_FOURCC('R','V','3','2'):
111             i_ffmpeg_chroma[i] = PIX_FMT_RGBA32;
112             break;
113
114         case VLC_FOURCC('R','V','2','4'):
115             i_ffmpeg_chroma[i] = PIX_FMT_RGB24;
116             //i_ffmpeg_chroma[i] = PIX_FMT_BGR24;
117             break;
118
119         case VLC_FOURCC('R','V','1','6'):
120             i_ffmpeg_chroma[i] = PIX_FMT_RGB565;
121             break;
122
123         case VLC_FOURCC('R','V','1','5'):
124             i_ffmpeg_chroma[i] = PIX_FMT_RGB555;
125             break;
126
127         case VLC_FOURCC('R','G','B','2'):
128             i_ffmpeg_chroma[i] = PIX_FMT_GRAY8;
129             break;
130
131         default:
132             return VLC_EGENERIC;
133             break;
134         }
135     }
136
137     p_vout->chroma.pf_convert = ChromaConversion;
138
139     p_vout->chroma.p_sys = malloc( sizeof( chroma_sys_t ) );
140     if( p_vout->chroma.p_sys == NULL )
141     {
142         return VLC_EGENERIC;
143     }
144
145     p_vout->chroma.p_sys->i_src_vlc_chroma = p_vout->render.i_chroma;
146     p_vout->chroma.p_sys->i_dst_vlc_chroma = p_vout->output.i_chroma;
147     p_vout->chroma.p_sys->i_src_ffmpeg_chroma = i_ffmpeg_chroma[0];
148     p_vout->chroma.p_sys->i_dst_ffmpeg_chroma = i_ffmpeg_chroma[1];
149
150     /* libavcodec needs to be initialized for some chroma conversions */
151     E_(InitLibavcodec)(p_this);
152
153     return VLC_SUCCESS;
154 }
155
156 /*****************************************************************************
157  * ChromaConversion: actual chroma conversion function
158  *****************************************************************************/
159 static void ChromaConversion( vout_thread_t *p_vout,
160                               picture_t *p_src, picture_t *p_dest )
161 {
162     AVPicture src_pic;
163     AVPicture dest_pic;
164     int i;
165
166     /* Prepare the AVPictures for converion */
167     for( i = 0; i < p_src->i_planes; i++ )
168     {
169         src_pic.data[i] = p_src->p[i].p_pixels;
170         src_pic.linesize[i] = p_src->p[i].i_pitch;
171     }
172     for( i = 0; i < p_dest->i_planes; i++ )
173     {
174         dest_pic.data[i] = p_dest->p[i].p_pixels;
175         dest_pic.linesize[i] = p_dest->p[i].i_pitch;
176     }
177
178     /* Special cases */
179     if( p_vout->chroma.p_sys->i_src_vlc_chroma == VLC_FOURCC('Y','V','1','2') )
180     {
181         /* Invert U and V */
182         src_pic.data[1] = p_src->p[2].p_pixels;
183         src_pic.data[2] = p_src->p[1].p_pixels;
184     }
185     if( p_vout->chroma.p_sys->i_dst_vlc_chroma == VLC_FOURCC('Y','V','1','2') )
186     {
187         /* Invert U and V */
188         dest_pic.data[1] = p_dest->p[2].p_pixels;
189         dest_pic.data[2] = p_dest->p[1].p_pixels;
190     }
191
192     img_convert( &dest_pic, p_vout->chroma.p_sys->i_dst_ffmpeg_chroma,
193                  &src_pic, p_vout->chroma.p_sys->i_src_ffmpeg_chroma,
194                  p_vout->render.i_width, p_vout->render.i_height );
195 }