snap: Added jack plug
[vlc.git] / src / misc / filter.c
1 /*****************************************************************************
2  * filter.c : filter_t helpers.
3  *****************************************************************************
4  * Copyright (C) 2009 Laurent Aimar
5  *
6  * Author: Laurent Aimar <fenrir _AT_ videolan _DOT_ org>
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation; either version 2.1 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21  *****************************************************************************/
22
23 #ifdef HAVE_CONFIG_H
24 # include "config.h"
25 #endif
26
27 #include <assert.h>
28
29 #include <vlc_common.h>
30 #include <libvlc.h>
31 #include <vlc_filter.h>
32 #include <vlc_modules.h>
33 #include "../misc/variables.h"
34
35 /* */
36
37 static int TriggerFilterCallback(vlc_object_t *p_this, char const *psz_var,
38                                  vlc_value_t oldval, vlc_value_t newval,
39                                  void *p_data)
40 {
41     (void) p_this; (void) oldval;
42     var_Set((filter_t *)p_data, psz_var, newval);
43     return 0;
44 }
45
46 #undef filter_AddProxyCallbacks
47 void filter_AddProxyCallbacks( vlc_object_t *obj, filter_t *filter,
48                                vlc_callback_t restart_cb )
49 {
50     char **names = var_GetAllNames(VLC_OBJECT(filter));
51     if (names == NULL)
52         return;
53
54     for (char **pname = names; *pname != NULL; pname++)
55     {
56         char *name = *pname;
57         int var_type = var_Type(filter, name);
58         if (var_Type(obj, name) || config_GetType(name) == 0)
59         {
60             free(name);
61             continue;
62         }
63         var_Create(obj, name,
64                    var_type | VLC_VAR_DOINHERIT | VLC_VAR_ISCOMMAND);
65         if ((var_type & VLC_VAR_ISCOMMAND))
66             var_AddCallback(obj, name, TriggerFilterCallback, filter);
67         else
68             var_AddCallback(obj, name, restart_cb, obj);
69         free(name);
70     }
71     free(names);
72 }
73
74 #undef filter_DelProxyCallbacks
75 void filter_DelProxyCallbacks( vlc_object_t *obj, filter_t *filter,
76                                vlc_callback_t restart_cb )
77 {
78     char **names = var_GetAllNames(VLC_OBJECT(filter));
79     if (names == NULL)
80         return;
81
82     for (char **pname = names; *pname != NULL; pname++)
83     {
84         char *name = *pname;
85         if (!(var_Type(obj, name) & VLC_VAR_ISCOMMAND))
86         {
87             free(name);
88             continue;
89         }
90         int filter_var_type = var_Type(filter, name);
91
92         if (filter_var_type & VLC_VAR_ISCOMMAND)
93             var_DelCallback(obj, name, TriggerFilterCallback, filter);
94         else if (filter_var_type)
95             var_DelCallback(obj, name, restart_cb, obj);
96         var_Destroy(obj, name);
97         free(name);
98     }
99     free(names);
100 }
101
102 /* */
103
104 vlc_blender_t *filter_NewBlend( vlc_object_t *p_this,
105                            const video_format_t *p_dst_chroma )
106 {
107     vlc_blender_t *p_blend = vlc_custom_create( p_this, sizeof(*p_blend), "blend" );
108     if( !p_blend )
109         return NULL;
110
111     es_format_Init( &p_blend->fmt_in, VIDEO_ES, 0 );
112
113     es_format_Init( &p_blend->fmt_out, VIDEO_ES, 0 );
114
115     p_blend->fmt_out.i_codec        =
116     p_blend->fmt_out.video.i_chroma = p_dst_chroma->i_chroma;
117     p_blend->fmt_out.video.i_rmask  = p_dst_chroma->i_rmask;
118     p_blend->fmt_out.video.i_gmask  = p_dst_chroma->i_gmask;
119     p_blend->fmt_out.video.i_bmask  = p_dst_chroma->i_bmask;
120
121     /* The blend module will be loaded when needed with the real
122     * input format */
123     p_blend->p_module = NULL;
124
125     return p_blend;
126 }
127
128 int filter_ConfigureBlend( vlc_blender_t *p_blend,
129                            int i_dst_width, int i_dst_height,
130                            const video_format_t *p_src )
131 {
132     /* */
133     if( p_blend->p_module &&
134         p_blend->fmt_in.video.i_chroma != p_src->i_chroma )
135     {
136         /* The chroma is not the same, we need to reload the blend module */
137         module_unneed( p_blend, p_blend->p_module );
138         p_blend->p_module = NULL;
139     }
140
141     /* */
142
143     p_blend->fmt_in.i_codec = p_src->i_chroma;
144     p_blend->fmt_in.video   = *p_src;
145
146     /* */
147     p_blend->fmt_out.video.i_width          =
148     p_blend->fmt_out.video.i_visible_width  = i_dst_width;
149     p_blend->fmt_out.video.i_height         =
150     p_blend->fmt_out.video.i_visible_height = i_dst_height;
151
152     /* */
153     if( !p_blend->p_module )
154         p_blend->p_module = module_need( p_blend, "video blending", NULL, false );
155     if( !p_blend->p_module )
156         return VLC_EGENERIC;
157     return VLC_SUCCESS;
158 }
159
160 int filter_Blend( vlc_blender_t *p_blend,
161                   picture_t *p_dst, int i_dst_x, int i_dst_y,
162                   const picture_t *p_src, int i_alpha )
163 {
164     if( !p_blend->p_module )
165         return VLC_EGENERIC;
166
167     p_blend->pf_video_blend( p_blend, p_dst, p_src, i_dst_x, i_dst_y, i_alpha );
168     return VLC_SUCCESS;
169 }
170
171 void filter_DeleteBlend( vlc_blender_t *p_blend )
172 {
173     if( p_blend->p_module )
174         module_unneed( p_blend, p_blend->p_module );
175
176     vlc_object_delete(p_blend);
177 }
178
179 /* */
180 #include <vlc_video_splitter.h>
181
182 video_splitter_t *video_splitter_New( vlc_object_t *p_this,
183                                       const char *psz_name,
184                                       const video_format_t *p_fmt )
185 {
186     video_splitter_t *p_splitter = vlc_custom_create( p_this,
187                                        sizeof(*p_splitter), "video splitter" );
188     if( !p_splitter )
189         return NULL;
190
191     video_format_Copy( &p_splitter->fmt, p_fmt );
192
193     /* */
194     p_splitter->p_module = module_need( p_splitter, "video splitter", psz_name, true );
195     if( ! p_splitter->p_module )
196     {
197         video_splitter_Delete( p_splitter );
198         return NULL;
199     }
200
201     return p_splitter;
202 }
203
204 void video_splitter_Delete( video_splitter_t *p_splitter )
205 {
206     if( p_splitter->p_module )
207         module_unneed( p_splitter, p_splitter->p_module );
208
209     video_format_Clean( &p_splitter->fmt );
210     vlc_object_delete(p_splitter);
211 }
212