]> git.sesse.net Git - vlc/blob - modules/video_output/picture.c
51028ba9a34396fce706f5644cc27699a72ad83e
[vlc] / modules / video_output / picture.c
1 /*****************************************************************************
2  * picture.c:
3  *****************************************************************************
4  * Copyright (C) 1998-2001 VideoLAN
5  * $Id: $
6  *
7  * Authors: Antoine Cellerier <dionoea@videolan.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>                                                 /* ENOMEM */
28 #include <stdlib.h>                                                /* free() */
29 #include <string.h>                                            /* strerror() */
30
31 #include <vlc/vlc.h>
32 #include <vlc/intf.h>
33 #include <vlc/vout.h>
34 #include <vlc/aout.h>
35
36 #include <sys/types.h>
37 #ifndef WIN32
38 #   include <netinet/in.h>                            /* BSD: struct in_addr */
39 #endif
40
41 /***********************************************************************
42 *
43 ***********************************************************************/
44 struct vout_sys_t
45 {
46     int i_picture_pos; /* picture position in p_picture_vout */
47 };
48
49 #include "picture.h"
50
51 /***********************************************************************
52 * Local prototypes
53 ***********************************************************************/
54
55 static int  Open    ( vlc_object_t * );
56 static void Close   ( vlc_object_t * );
57 static int  Init    ( vout_thread_t * );
58 static void End     ( vout_thread_t * );
59 static int  Manage  ( vout_thread_t * );
60 static void Display ( vout_thread_t *, picture_t * );
61
62 /***********************************************************************
63 * Module descriptor
64 ***********************************************************************/
65 vlc_module_begin();
66     set_description(_("VLC Internal Picture video output") );
67     set_capability( "video output", 70 );
68     set_callbacks( Open, Close );
69 vlc_module_end();
70
71 /***********************************************************************
72 * Open : allocate video thread output method
73 ***********************************************************************/
74 static int Open ( vlc_object_t *p_this )
75 {
76     vout_thread_t *p_vout = (vout_thread_t *)p_this;
77     libvlc_t *p_libvlc = p_vout->p_libvlc;
78     struct picture_vout_t *p_picture_vout = NULL;
79     vlc_value_t val;
80
81     p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
82     if( p_vout->p_sys == NULL )
83     {
84         msg_Err( p_vout, "out of memory" );
85         return VLC_ENOMEM;
86     }
87
88     if( var_Get( p_libvlc, "p_picture_vout", &val ) != VLC_SUCCESS ){
89         msg_Err( p_vout, "p_picture_vout not found" );
90         p_picture_vout = malloc( sizeof( struct picture_vout_t ) );
91         if( p_vout->p_sys == NULL )
92         {
93             msg_Err( p_vout, "out of memory" );
94             return VLC_ENOMEM;
95         }
96
97         vlc_mutex_init( p_libvlc, &p_picture_vout->lock );
98         vlc_mutex_lock( &p_picture_vout->lock );
99         var_Create( p_libvlc, "p_picture_vout", VLC_VAR_ADDRESS );
100         val.p_address = p_picture_vout;
101         var_Set( p_libvlc, "p_picture_vout", val );
102
103         p_picture_vout->i_picture_num = 0;
104         p_picture_vout->p_pic = NULL;
105     } else {
106         p_picture_vout = val.p_address;
107         msg_Err( p_vout, "p_picture_vout found" );
108         vlc_mutex_lock( &p_picture_vout->lock );
109     }
110
111     p_vout->p_sys->i_picture_pos = p_picture_vout->i_picture_num;
112
113     p_picture_vout->p_pic = realloc( p_picture_vout->p_pic,
114       (p_picture_vout->i_picture_num+1) * sizeof( struct picture_vout_e_t ) );
115
116     p_picture_vout->p_pic[p_picture_vout->i_picture_num].p_picture = NULL;
117     p_picture_vout->p_pic[p_picture_vout->i_picture_num].i_status
118       = PICTURE_VOUT_E_OCCUPIED;
119     p_picture_vout->i_picture_num++;
120
121     vlc_mutex_unlock( &p_picture_vout->lock );
122
123     p_vout->pf_init = Init;
124     p_vout->pf_end = End;
125     p_vout->pf_manage = Manage;
126     p_vout->pf_render = NULL;
127     p_vout->pf_display = Display;
128
129     return VLC_SUCCESS;
130 }
131
132
133 /***********************************************************************
134 * Init
135 ***********************************************************************/
136 static int Init( vout_thread_t *p_vout )
137 {
138
139     picture_t *p_pic;
140     int i_index;
141
142     I_OUTPUTPICTURES = 0;
143
144     p_vout->output.i_chroma = p_vout->render.i_chroma;
145     p_vout->output.i_width  = p_vout->render.i_width;
146     p_vout->output.i_height = p_vout->render.i_height;
147     p_vout->output.i_aspect = p_vout->render.i_aspect;
148
149     while( VLC_TRUE )
150     {
151         p_pic = NULL;
152
153         for( i_index = 0 ; i_index < VOUT_MAX_PICTURES ; i_index++ )
154         {
155             if( p_vout->p_picture[ i_index ].i_status == FREE_PICTURE )
156             {
157                 p_pic = p_vout->p_picture + i_index;
158                 break;
159             }
160         }
161
162         if( p_pic == NULL )
163         {
164             return VLC_SUCCESS;
165         }
166
167         vout_AllocatePicture( VLC_OBJECT(p_vout), p_pic,
168                               p_vout->output.i_chroma,
169                               p_vout->output.i_width, p_vout->output.i_height,
170                               p_vout->output.i_aspect );
171
172         if( p_pic->i_planes == 0 )
173         {
174             return VLC_EGENERIC;
175         }
176
177         p_pic->i_status = DESTROYED_PICTURE;
178         p_pic->i_type   = DIRECT_PICTURE;
179
180         PP_OUTPUTPICTURE[ I_OUTPUTPICTURES ] = p_pic;
181
182         I_OUTPUTPICTURES++;
183
184         //return VLC_SUCCESS;
185     }
186
187 }
188
189 /***********************************************************************
190 * End
191 ***********************************************************************/
192 static void End( vout_thread_t *p_vout )
193 {
194     return;
195 }
196
197 /***********************************************************************
198 * Close
199 ***********************************************************************/
200 static void Close ( vlc_object_t *p_this )
201 {
202     vout_thread_t * p_vout = (vout_thread_t *)p_this;
203
204     libvlc_t *p_libvlc = p_vout->p_libvlc;
205     struct picture_vout_t *p_picture_vout = NULL;
206     vlc_value_t val;
207     int i_flag=0, i;
208
209     msg_Dbg( p_vout, "Closing Picture Vout ...");
210     var_Get( p_libvlc, "p_picture_vout", &val );
211     p_picture_vout = val.p_address;
212
213     vlc_mutex_lock( &p_picture_vout->lock );
214
215     if( p_picture_vout->p_pic[p_vout->p_sys->i_picture_pos].p_picture )
216     {
217     /* FIXME */
218         free( p_picture_vout->p_pic[p_vout->p_sys->i_picture_pos].p_picture );
219     }
220     p_picture_vout->p_pic[p_vout->p_sys->i_picture_pos].i_status
221       = PICTURE_VOUT_E_AVAILABLE;
222
223     for( i = 0; i < p_picture_vout->i_picture_num; i ++)
224     {
225         if( p_picture_vout->p_pic[i].i_status == PICTURE_VOUT_E_OCCUPIED ) {
226             i_flag = 1;
227             break;
228         }
229     }
230
231     if( i_flag == 1 ){
232         vlc_mutex_unlock( &p_picture_vout->lock );
233         fprintf( stderr, "this wasn't the last picture\n");
234     } else {
235         free( p_picture_vout->p_pic );
236         vlc_mutex_unlock( &p_picture_vout->lock );
237         vlc_mutex_destroy( &p_picture_vout->lock );
238         var_Destroy( p_libvlc, "p_picture_vout" );
239         fprintf( stderr, "this was the last picture\n");
240     }
241
242     free( p_vout->p_sys );
243 }
244
245 /***********************************************************************
246 * Manage
247 ***********************************************************************/
248 static int Manage( vout_thread_t *p_vout )
249 {
250     return VLC_SUCCESS;
251 }
252
253 /***********************************************************************
254 * Display
255 ***********************************************************************/
256 static void Display( vout_thread_t *p_vout, picture_t *p_pic )
257 {
258     libvlc_t *p_libvlc = p_vout->p_libvlc;
259     vlc_value_t val;
260     struct picture_vout_t *p_picture_vout;
261
262     var_Get( p_libvlc, "p_picture_vout", &val );
263     p_picture_vout = val.p_address;
264
265     /*
266     src : p_pic
267     dest : p_picture_pout->p_pic[p_vout->p_sys.i_picture_pos]->p_picture
268     */
269
270
271     vlc_mutex_lock( &p_picture_vout->lock );
272     if( p_picture_vout->p_pic[p_vout->p_sys->i_picture_pos].p_picture )
273     {
274       // FIXME !!!
275       //nfprintf( stderr, "i_type : %i ( MEMORY_PICTURE == %i)\n", p_picture_vout->p_pic[p_vout->p_sys->i_picture_pos].p_picture->i_type, MEMORY_PICTURE );
276       if( p_picture_vout->p_pic[p_vout->p_sys->i_picture_pos].p_picture->i_type  == 200 /* MEMORY_PICTURE*/)
277       {
278         free( p_picture_vout->p_pic[p_vout->p_sys->i_picture_pos]
279                         .p_picture->p_data_orig );
280       }
281       free( p_picture_vout->p_pic[p_vout->p_sys->i_picture_pos].p_picture );
282     }
283
284     p_picture_vout->p_pic[p_vout->p_sys->i_picture_pos].p_picture
285              = (picture_t*)malloc( sizeof( picture_t )) ;
286     vout_AllocatePicture( p_vout,
287          p_picture_vout->p_pic[p_vout->p_sys->i_picture_pos].p_picture,
288          p_pic->format.i_chroma,
289          p_pic->format.i_width,
290          p_pic->format.i_height,
291          VOUT_ASPECT_FACTOR * p_pic->format.i_height / p_pic->format.i_width );
292
293     p_picture_vout->p_pic[p_vout->p_sys->i_picture_pos].p_picture->i_status = DESTROYED_PICTURE;
294     p_picture_vout->p_pic[p_vout->p_sys->i_picture_pos].p_picture->i_type   = DIRECT_PICTURE;
295
296     vout_CopyPicture( p_vout,
297         p_picture_vout->p_pic[p_vout->p_sys->i_picture_pos].p_picture,
298         p_pic);
299
300     vlc_mutex_unlock( &p_picture_vout->lock );
301 }