]> git.sesse.net Git - vlc/blob - plugins/filter/invert.c
* Initialize SDL before opening the SDL audio output.
[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.2 2001/12/19 03:50:22 sam 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 #define MODULE_NAME filter_invert
25 #include "modules_inner.h"
26
27 /*****************************************************************************
28  * Preamble
29  *****************************************************************************/
30 #include "defs.h"
31
32 #include <errno.h>
33 #include <stdlib.h>                                      /* malloc(), free() */
34 #include <string.h>
35
36 #include "common.h"                                     /* boolean_t, byte_t */
37 #include "intf_msg.h"
38 #include "threads.h"
39 #include "mtime.h"
40 #include "tests.h"
41
42 #include "video.h"
43 #include "video_output.h"
44
45 #include "filter_common.h"
46
47 #include "modules.h"
48 #include "modules_export.h"
49
50 /*****************************************************************************
51  * Capabilities defined in the other files.
52  *****************************************************************************/
53 static void vout_getfunctions( function_list_t * p_function_list );
54
55 /*****************************************************************************
56  * Build configuration tree.
57  *****************************************************************************/
58 MODULE_CONFIG_START
59 ADD_WINDOW( "Configuration for Invert module" )
60     ADD_COMMENT( "Ha, ha -- nothing to configure yet" )
61 MODULE_CONFIG_STOP
62
63 MODULE_INIT_START
64     p_module->i_capabilities = MODULE_CAPABILITY_NULL
65                                 | MODULE_CAPABILITY_VOUT;
66     p_module->psz_longname = "invert video module";
67 MODULE_INIT_STOP
68
69 MODULE_ACTIVATE_START
70     vout_getfunctions( &p_module->p_functions->vout );
71 MODULE_ACTIVATE_STOP
72
73 MODULE_DEACTIVATE_START
74 MODULE_DEACTIVATE_STOP
75
76 /*****************************************************************************
77  * vout_sys_t: Invert video output method descriptor
78  *****************************************************************************
79  * This structure is part of the video output thread descriptor.
80  * It describes the Invert specific properties of an output thread.
81  *****************************************************************************/
82 typedef struct vout_sys_s
83 {
84     struct vout_thread_s *p_vout;
85
86 } vout_sys_t;
87
88 /*****************************************************************************
89  * Local prototypes
90  *****************************************************************************/
91 static int  vout_Probe     ( probedata_t *p_data );
92 static int  vout_Create    ( struct vout_thread_s * );
93 static int  vout_Init      ( struct vout_thread_s * );
94 static void vout_End       ( struct vout_thread_s * );
95 static void vout_Destroy   ( struct vout_thread_s * );
96 static int  vout_Manage    ( struct vout_thread_s * );
97 static void vout_Display   ( struct vout_thread_s *, struct picture_s * );
98
99 /*****************************************************************************
100  * Functions exported as capabilities. They are declared as static so that
101  * we don't pollute the namespace too much.
102  *****************************************************************************/
103 static void vout_getfunctions( function_list_t * p_function_list )
104 {
105     p_function_list->pf_probe = vout_Probe;
106     p_function_list->functions.vout.pf_create     = vout_Create;
107     p_function_list->functions.vout.pf_init       = vout_Init;
108     p_function_list->functions.vout.pf_end        = vout_End;
109     p_function_list->functions.vout.pf_destroy    = vout_Destroy;
110     p_function_list->functions.vout.pf_manage     = vout_Manage;
111     p_function_list->functions.vout.pf_display    = vout_Display;
112     p_function_list->functions.vout.pf_setpalette = NULL;
113 }
114
115 /*****************************************************************************
116  * intf_Probe: return a score
117  *****************************************************************************/
118 static int vout_Probe( probedata_t *p_data )
119 {
120     if( TestMethod( VOUT_FILTER_VAR, "invert" ) )
121     {
122         return( 999 );
123     }
124
125     /* If we weren't asked to filter, don't filter. */
126     return( 0 );
127 }
128
129 /*****************************************************************************
130  * vout_Create: allocates Invert video thread output method
131  *****************************************************************************
132  * This function allocates and initializes a Invert vout method.
133  *****************************************************************************/
134 static int vout_Create( vout_thread_t *p_vout )
135 {
136     /* Allocate structure */
137     p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
138     if( p_vout->p_sys == NULL )
139     {
140         intf_ErrMsg("error: %s", strerror(ENOMEM) );
141         return( 1 );
142     }
143
144     return( 0 );
145 }
146
147 /*****************************************************************************
148  * vout_Init: initialize Invert video thread output method
149  *****************************************************************************/
150 static int vout_Init( vout_thread_t *p_vout )
151 {
152     int i_index;
153     char *psz_filter;
154     picture_t *p_pic;
155     
156     I_OUTPUTPICTURES = 0;
157
158     /* Initialize the output structure */
159     switch( p_vout->render.i_chroma )
160     {
161         case YUV_420_PICTURE:
162             p_vout->output.i_chroma = p_vout->render.i_chroma;
163             p_vout->output.i_width  = p_vout->render.i_width;
164             p_vout->output.i_height = p_vout->render.i_height;
165             p_vout->output.i_aspect = p_vout->render.i_aspect;
166             break;
167
168         default:
169             return( 0 ); /* unknown chroma */
170             break;
171     }
172
173     /* Try to open the real video output */
174     psz_filter = main_GetPszVariable( VOUT_FILTER_VAR, "" );
175     main_PutPszVariable( VOUT_FILTER_VAR, "" );
176
177     intf_WarnMsg( 1, "filter: spawning the real video output" );
178         
179     p_vout->p_sys->p_vout =
180         vout_CreateThread( NULL,
181                            p_vout->render.i_width, p_vout->render.i_height,
182                            p_vout->render.i_chroma, p_vout->render.i_aspect );
183
184     /* Everything failed */
185     if( p_vout->p_sys->p_vout == NULL )
186     {
187         intf_ErrMsg( "filter error: can't open vout, aborting" );
188
189         return( 0 );
190     }
191  
192     main_PutPszVariable( VOUT_FILTER_VAR, psz_filter );
193
194     ALLOCATE_DIRECTBUFFERS( VOUT_MAX_PICTURES );
195
196     return( 0 );
197 }
198
199 /*****************************************************************************
200  * vout_End: terminate Invert video thread output method
201  *****************************************************************************/
202 static void vout_End( vout_thread_t *p_vout )
203 {
204     int i_index;
205
206     /* Free the fake output buffers we allocated */
207     for( i_index = I_OUTPUTPICTURES ; i_index ; )
208     {
209         i_index--;
210         free( PP_OUTPUTPICTURE[ i_index ]->planes[ 0 ].p_data );
211     }
212 }
213
214 /*****************************************************************************
215  * vout_Destroy: destroy Invert video thread output method
216  *****************************************************************************
217  * Terminate an output method created by InvertCreateOutputMethod
218  *****************************************************************************/
219 static void vout_Destroy( vout_thread_t *p_vout )
220 {
221     vout_DestroyThread( p_vout->p_sys->p_vout, NULL );
222
223     free( p_vout->p_sys );
224 }
225
226 /*****************************************************************************
227  * vout_Manage: handle Invert events
228  *****************************************************************************
229  * This function should be called regularly by video output thread. It manages
230  * console events. It returns a non null value on error.
231  *****************************************************************************/
232 static int vout_Manage( vout_thread_t *p_vout )
233 {
234     return( 0 );
235 }
236
237 /*****************************************************************************
238  * vout_Display: displays previously rendered output
239  *****************************************************************************
240  * This function send the currently rendered image to Invert image, waits
241  * until it is displayed and switch the two rendering buffers, preparing next
242  * frame.
243  *****************************************************************************/
244 static void vout_Display( vout_thread_t *p_vout, picture_t *p_pic )
245 {
246     picture_t *p_outpic;
247     int i_index;
248
249     /* This is a new frame. Get a structure from the video_output. */
250     while( ( p_outpic = vout_CreatePicture( p_vout->p_sys->p_vout, 0, 0, 0 ) )
251               == NULL )
252     {
253         if( p_vout->b_die || p_vout->b_error )
254         {
255             return;
256         }
257         msleep( VOUT_OUTMEM_SLEEP );
258     }   
259
260     vout_DatePicture( p_vout->p_sys->p_vout, p_outpic, mdate() + 50000 );
261     vout_LinkPicture( p_vout->p_sys->p_vout, p_outpic );
262
263     for( i_index = 0 ; i_index < p_pic->i_planes ; i_index++ )
264     {
265         pixel_data_t *p_in, *p_in_end, *p_out;
266
267         p_in = p_pic->planes[ i_index ].p_data;
268         p_in_end = p_in + p_pic->planes[ i_index ].i_bytes - 64;
269
270         p_out = p_outpic->planes[ i_index ].p_data;
271
272         for( ; p_in < p_in_end ; )
273         {
274             /* Do 64 pixels at a time */
275             *((u64*)p_out)++ = ~( *((u64*)p_in)++ );
276             *((u64*)p_out)++ = ~( *((u64*)p_in)++ );
277             *((u64*)p_out)++ = ~( *((u64*)p_in)++ );
278             *((u64*)p_out)++ = ~( *((u64*)p_in)++ );
279             *((u64*)p_out)++ = ~( *((u64*)p_in)++ );
280             *((u64*)p_out)++ = ~( *((u64*)p_in)++ );
281             *((u64*)p_out)++ = ~( *((u64*)p_in)++ );
282             *((u64*)p_out)++ = ~( *((u64*)p_in)++ );
283         }
284
285         p_in_end += 64;
286
287         for( ; p_in < p_in_end ; )
288         {
289             /* Do 1 pixel at a time */
290             *p_out++ = ~( *p_in++ );
291         }
292     }
293
294     vout_UnlinkPicture( p_vout->p_sys->p_vout, p_outpic );
295
296     vout_DisplayPicture( p_vout->p_sys->p_vout, p_outpic );
297 }
298