]> git.sesse.net Git - vlc/blob - plugins/filter/invert.c
341add646acd1e22ba3a85ddf50208730ce744f8
[vlc] / plugins / filter / invert.c
1 /*****************************************************************************
2  * invert.c : Invert video plugin for vlc
3  *****************************************************************************
4  * Copyright (C) 2000, 2001 VideoLAN
5  * $Id: invert.c,v 1.11 2002/05/19 12:57:32 gbazin Exp $
6  *
7  * Authors: Samuel Hocevar <sam@zoy.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., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <errno.h>
28 #include <stdlib.h>                                      /* malloc(), free() */
29 #include <string.h>
30
31 #include <videolan/vlc.h>
32
33 #include "video.h"
34 #include "video_output.h"
35
36 #include "filter_common.h"
37
38 /*****************************************************************************
39  * Capabilities defined in the other files.
40  *****************************************************************************/
41 static void vout_getfunctions( function_list_t * p_function_list );
42
43 /*****************************************************************************
44  * Build configuration tree.
45  *****************************************************************************/
46 MODULE_CONFIG_START
47 MODULE_CONFIG_STOP
48
49 MODULE_INIT_START
50     SET_DESCRIPTION( _("invert video module") )
51     /* Capability score set to 0 because we don't want to be spawned
52      * as a video output unless explicitly requested to */
53     ADD_CAPABILITY( VOUT, 0 )
54     ADD_SHORTCUT( "invert" )
55 MODULE_INIT_STOP
56
57 MODULE_ACTIVATE_START
58     vout_getfunctions( &p_module->p_functions->vout );
59 MODULE_ACTIVATE_STOP
60
61 MODULE_DEACTIVATE_START
62 MODULE_DEACTIVATE_STOP
63
64 /*****************************************************************************
65  * vout_sys_t: Invert video output method descriptor
66  *****************************************************************************
67  * This structure is part of the video output thread descriptor.
68  * It describes the Invert specific properties of an output thread.
69  *****************************************************************************/
70 typedef struct vout_sys_s
71 {
72     struct vout_thread_s *p_vout;
73
74 } vout_sys_t;
75
76 /*****************************************************************************
77  * Local prototypes
78  *****************************************************************************/
79 static int  vout_Create    ( struct vout_thread_s * );
80 static int  vout_Init      ( struct vout_thread_s * );
81 static void vout_End       ( struct vout_thread_s * );
82 static void vout_Destroy   ( struct vout_thread_s * );
83 static int  vout_Manage    ( struct vout_thread_s * );
84 static void vout_Render    ( struct vout_thread_s *, struct picture_s * );
85 static void vout_Display   ( struct vout_thread_s *, struct picture_s * );
86
87 /*****************************************************************************
88  * Functions exported as capabilities. They are declared as static so that
89  * we don't pollute the namespace too much.
90  *****************************************************************************/
91 static void vout_getfunctions( function_list_t * p_function_list )
92 {
93     p_function_list->functions.vout.pf_create     = vout_Create;
94     p_function_list->functions.vout.pf_init       = vout_Init;
95     p_function_list->functions.vout.pf_end        = vout_End;
96     p_function_list->functions.vout.pf_destroy    = vout_Destroy;
97     p_function_list->functions.vout.pf_manage     = vout_Manage;
98     p_function_list->functions.vout.pf_render     = vout_Render;
99     p_function_list->functions.vout.pf_display    = vout_Display;
100 }
101
102 /*****************************************************************************
103  * vout_Create: allocates Invert video thread output method
104  *****************************************************************************
105  * This function allocates and initializes a Invert vout method.
106  *****************************************************************************/
107 static int vout_Create( vout_thread_t *p_vout )
108 {
109     /* Allocate structure */
110     p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
111     if( p_vout->p_sys == NULL )
112     {
113         intf_ErrMsg("error: %s", strerror(ENOMEM) );
114         return( 1 );
115     }
116
117     return( 0 );
118 }
119
120 /*****************************************************************************
121  * vout_Init: initialize Invert video thread output method
122  *****************************************************************************/
123 static int vout_Init( vout_thread_t *p_vout )
124 {
125     int i_index;
126     char *psz_filter;
127     picture_t *p_pic;
128
129     I_OUTPUTPICTURES = 0;
130
131     /* Initialize the output structure */
132     p_vout->output.i_chroma = p_vout->render.i_chroma;
133     p_vout->output.i_width  = p_vout->render.i_width;
134     p_vout->output.i_height = p_vout->render.i_height;
135     p_vout->output.i_aspect = p_vout->render.i_aspect;
136
137     /* Try to open the real video output */
138     psz_filter = config_GetPszVariable( "filter" );
139     config_PutPszVariable( "filter", NULL );
140
141     intf_WarnMsg( 1, "filter: spawning the real video output" );
142
143     p_vout->p_sys->p_vout =
144         vout_CreateThread( NULL,
145                            p_vout->render.i_width, p_vout->render.i_height,
146                            p_vout->render.i_chroma, p_vout->render.i_aspect );
147
148     config_PutPszVariable( "filter", psz_filter );
149     if( psz_filter ) free( psz_filter );
150
151     /* Everything failed */
152     if( p_vout->p_sys->p_vout == NULL )
153     {
154         intf_ErrMsg( "filter error: can't open vout, aborting" );
155
156         return( 0 );
157     }
158  
159     ALLOCATE_DIRECTBUFFERS( VOUT_MAX_PICTURES );
160
161     return( 0 );
162 }
163
164 /*****************************************************************************
165  * vout_End: terminate Invert video thread output method
166  *****************************************************************************/
167 static void vout_End( vout_thread_t *p_vout )
168 {
169     int i_index;
170
171     /* Free the fake output buffers we allocated */
172     for( i_index = I_OUTPUTPICTURES ; i_index ; )
173     {
174         i_index--;
175         free( PP_OUTPUTPICTURE[ i_index ]->p_data_orig );
176     }
177 }
178
179 /*****************************************************************************
180  * vout_Destroy: destroy Invert video thread output method
181  *****************************************************************************
182  * Terminate an output method created by InvertCreateOutputMethod
183  *****************************************************************************/
184 static void vout_Destroy( vout_thread_t *p_vout )
185 {
186     vout_DestroyThread( p_vout->p_sys->p_vout, NULL );
187
188     free( p_vout->p_sys );
189 }
190
191 /*****************************************************************************
192  * vout_Manage: handle Invert events
193  *****************************************************************************
194  * This function should be called regularly by video output thread. It manages
195  * console events. It returns a non null value on error.
196  *****************************************************************************/
197 static int vout_Manage( vout_thread_t *p_vout )
198 {
199     return( 0 );
200 }
201
202 /*****************************************************************************
203  * vout_Render: displays previously rendered output
204  *****************************************************************************
205  * This function send the currently rendered image to Invert image, waits
206  * until it is displayed and switch the two rendering buffers, preparing next
207  * frame.
208  *****************************************************************************/
209 static void vout_Render( vout_thread_t *p_vout, picture_t *p_pic )
210 {
211     picture_t *p_outpic;
212     int i_index;
213
214     /* This is a new frame. Get a structure from the video_output. */
215     while( ( p_outpic = vout_CreatePicture( p_vout->p_sys->p_vout, 0, 0, 0 ) )
216               == NULL )
217     {
218         if( p_vout->b_die || p_vout->b_error )
219         {
220             return;
221         }
222         msleep( VOUT_OUTMEM_SLEEP );
223     }   
224
225     vout_DatePicture( p_vout->p_sys->p_vout, p_outpic, p_pic->date );
226     vout_LinkPicture( p_vout->p_sys->p_vout, p_outpic );
227
228     for( i_index = 0 ; i_index < p_pic->i_planes ; i_index++ )
229     {
230         u8 *p_in, *p_in_end, *p_out;
231
232         p_in = p_pic->p[i_index].p_pixels;
233         p_in_end = p_in - 64 + p_pic->p[i_index].i_lines
234                                 * p_pic->p[i_index].i_pitch;
235
236         p_out = p_outpic->p[i_index].p_pixels;
237
238         for( ; p_in < p_in_end ; )
239         {
240             /* Do 64 pixels at a time */
241             *((u64*)p_out)++ = ~( *((u64*)p_in)++ );
242             *((u64*)p_out)++ = ~( *((u64*)p_in)++ );
243             *((u64*)p_out)++ = ~( *((u64*)p_in)++ );
244             *((u64*)p_out)++ = ~( *((u64*)p_in)++ );
245             *((u64*)p_out)++ = ~( *((u64*)p_in)++ );
246             *((u64*)p_out)++ = ~( *((u64*)p_in)++ );
247             *((u64*)p_out)++ = ~( *((u64*)p_in)++ );
248             *((u64*)p_out)++ = ~( *((u64*)p_in)++ );
249         }
250
251         p_in_end += 64;
252
253         for( ; p_in < p_in_end ; )
254         {
255             /* Do 1 pixel at a time */
256             *p_out++ = ~( *p_in++ );
257         }
258     }
259
260     vout_UnlinkPicture( p_vout->p_sys->p_vout, p_outpic );
261
262     vout_DisplayPicture( p_vout->p_sys->p_vout, p_outpic );
263 }
264
265 /*****************************************************************************
266  * vout_Display: displays previously rendered output
267  *****************************************************************************
268  * This function send the currently rendered image to Invert image, waits
269  * until it is displayed and switch the two rendering buffers, preparing next
270  * frame.
271  *****************************************************************************/
272 static void vout_Display( vout_thread_t *p_vout, picture_t *p_pic )
273 {
274     ;
275 }
276