]> git.sesse.net Git - vlc/blob - modules/video_chroma/chain.c
Include vlc_plugin.h as needed
[vlc] / modules / video_chroma / chain.c
1 /*****************************************************************************
2  * chain.c : chain multiple chroma modules as a last resort solution
3  *****************************************************************************
4  * Copyright (C) 2007 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Antoine Cellerier <dionoea at videolan dot org>
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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include <vlc/vlc.h>
33 #include <vlc_plugin.h>
34 #include <vlc_vout.h>
35
36 /*****************************************************************************
37  * Local and extern prototypes.
38  *****************************************************************************/
39 static int  Activate ( vlc_object_t * );
40 static void Destroy  ( vlc_object_t * );
41 static void Chain    ( vout_thread_t *, picture_t *, picture_t * );
42
43 /*****************************************************************************
44  * Module descriptor
45  *****************************************************************************/
46 vlc_module_begin();
47     set_description( _("Chroma conversions using a chain of chroma conversion modules") );
48     set_capability( "chroma", 1 );
49     set_callbacks( Activate, Destroy );
50 vlc_module_end();
51
52 #define MAX_CHROMAS 2
53
54 struct chroma_sys_t
55 {
56     vlc_fourcc_t i_chroma;
57
58     vout_chroma_t chroma1;
59     vout_chroma_t chroma2;
60
61     picture_t *p_tmp;
62 };
63
64 static const vlc_fourcc_t pi_allowed_chromas[] = {
65     VLC_FOURCC('I','4','2','0'),
66     VLC_FOURCC('I','4','2','2'),
67     0
68 };
69
70 /*****************************************************************************
71  * Activate: allocate a chroma function
72  *****************************************************************************
73  * This function allocates and initializes a chroma function
74  *****************************************************************************/
75 static int Activate( vlc_object_t *p_this )
76 {
77     static int hack = 1;
78     vout_thread_t *p_vout = (vout_thread_t *)p_this;
79
80     hack++;
81     if( hack > MAX_CHROMAS )
82     {
83         hack--;
84         msg_Err( p_this, "Preventing chain chroma reccursion (already %d long)",
85                  hack );
86         return VLC_EGENERIC;
87     }
88
89     chroma_sys_t *p_sys = (chroma_sys_t *)malloc( sizeof( chroma_sys_t ) );
90     if( !p_sys )
91     {
92         hack--;
93         return VLC_ENOMEM;
94     }
95     memset( p_sys, 0, sizeof( chroma_sys_t ) );
96
97     int i;
98     vlc_fourcc_t i_output_chroma = p_vout->output.i_chroma;
99     vlc_fourcc_t i_render_chroma = p_vout->render.i_chroma;
100
101     for( i = 0; pi_allowed_chromas[i]; i++ )
102     {
103         msg_Warn( p_vout, "Trying %4s as a chroma chain",
104                   (const char *)&pi_allowed_chromas[i] );
105         p_vout->output.i_chroma = pi_allowed_chromas[i];
106         p_vout->chroma.p_module = module_Need( p_vout, "chroma", NULL, 0 );
107         p_vout->output.i_chroma = i_output_chroma;
108
109         if( !p_vout->chroma.p_module )
110             continue;
111
112         p_sys->chroma1 = p_vout->chroma;
113         memset( &p_vout->chroma, 0, sizeof( vout_chroma_t ) );
114
115         p_vout->render.i_chroma = pi_allowed_chromas[i];
116         p_vout->chroma.p_module = module_Need( p_vout, "chroma", NULL, 0 );
117         p_vout->render.i_chroma = i_render_chroma;
118
119         if( !p_vout->chroma.p_module )
120         {
121             p_vout->chroma = p_sys->chroma1;
122             module_Unneed( p_vout, p_vout->chroma.p_module );
123             continue;
124         }
125
126         p_sys->chroma2 = p_vout->chroma;
127         memset( &p_vout->chroma, 0, sizeof( vout_chroma_t ) );
128
129         p_sys->i_chroma = pi_allowed_chromas[i];
130         p_vout->chroma.pf_convert = Chain;
131         p_vout->chroma.p_sys = p_sys;
132         hack--;
133         printf("Init: p_sys->p_tmp= %p\n", p_sys->p_tmp );
134         return VLC_SUCCESS;
135     }
136
137     free( p_sys );
138     hack--;
139     return VLC_EGENERIC;
140 }
141
142 static void Destroy( vlc_object_t *p_this )
143 {
144     vout_thread_t *p_vout = (vout_thread_t *)p_this;
145     vout_chroma_t chroma = p_vout->chroma;
146
147
148     p_vout->chroma = chroma.p_sys->chroma1;
149     module_Unneed( p_vout, p_vout->chroma.p_module );
150     p_vout->chroma = chroma.p_sys->chroma2;
151     module_Unneed( p_vout, p_vout->chroma.p_module );
152     p_vout->chroma = chroma;
153
154     if( chroma.p_sys->p_tmp )
155     {
156         free( chroma.p_sys->p_tmp->p_data_orig );
157         free( chroma.p_sys->p_tmp );
158     }
159     free( chroma.p_sys );
160     chroma.p_sys = NULL;
161 }
162
163 /*****************************************************************************
164  * Chain
165  *****************************************************************************/
166 static void Chain( vout_thread_t *p_vout, picture_t *p_source,
167                    picture_t *p_dest )
168 {
169     chroma_sys_t *p_sys = p_vout->chroma.p_sys;
170
171     if( !p_sys->p_tmp )
172     {
173         picture_t *p_tmp = malloc( sizeof( picture_t ) );
174         vout_AllocatePicture( VLC_OBJECT( p_vout ), p_tmp,
175                               p_sys->i_chroma,
176                               p_source->p_heap->i_width,
177                               p_source->p_heap->i_height,
178                               p_source->p_heap->i_aspect );
179         if( !p_tmp )
180             return;
181         p_sys->p_tmp = p_tmp;
182         p_tmp->pf_release = NULL;
183         p_tmp->i_status = RESERVED_PICTURE;
184         p_tmp->p_sys = NULL;
185     }
186
187     vout_chroma_t chroma = p_vout->chroma;
188     p_vout->chroma = p_sys->chroma1;
189     p_sys->chroma1.pf_convert( p_vout, p_source, p_sys->p_tmp );
190     p_vout->chroma = p_sys->chroma2;
191     p_sys->chroma2.pf_convert( p_vout, p_sys->p_tmp, p_dest );
192     p_vout->chroma = chroma;
193 }