1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2004-2005 VideoLAN
7 * Authors: Antoine Cellerier <dionoea@videolan.org>
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.
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.
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 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
27 #include <errno.h> /* ENOMEM */
28 #include <stdlib.h> /* free() */
29 #include <string.h> /* strerror() */
36 #include <sys/types.h>
38 # include <netinet/in.h> /* BSD: struct in_addr */
41 /***********************************************************************
43 ***********************************************************************/
46 int i_picture_pos; /* picture position in p_picture_vout */
51 /***********************************************************************
53 ***********************************************************************/
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 * );
62 /***********************************************************************
64 ***********************************************************************/
66 set_description(_("VLC Internal Picture video output") );
67 set_capability( "video output", 70 );
68 set_callbacks( Open, Close );
71 /***********************************************************************
72 * Open : allocate video thread output method
73 ***********************************************************************/
74 static int Open ( vlc_object_t *p_this )
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;
81 p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
82 if( p_vout->p_sys == NULL )
84 msg_Err( p_vout, "out of memory" );
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 )
93 msg_Err( p_vout, "out of memory" );
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 );
103 p_picture_vout->i_picture_num = 0;
104 p_picture_vout->p_pic = NULL;
106 p_picture_vout = val.p_address;
107 msg_Err( p_vout, "p_picture_vout found" );
108 vlc_mutex_lock( &p_picture_vout->lock );
111 p_vout->p_sys->i_picture_pos = p_picture_vout->i_picture_num;
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 ) );
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++;
121 vlc_mutex_unlock( &p_picture_vout->lock );
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;
133 /***********************************************************************
135 ***********************************************************************/
136 static int Init( vout_thread_t *p_vout )
142 I_OUTPUTPICTURES = 0;
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;
153 for( i_index = 0 ; i_index < VOUT_MAX_PICTURES ; i_index++ )
155 if( p_vout->p_picture[ i_index ].i_status == FREE_PICTURE )
157 p_pic = p_vout->p_picture + i_index;
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 );
172 if( p_pic->i_planes == 0 )
177 p_pic->i_status = DESTROYED_PICTURE;
178 p_pic->i_type = DIRECT_PICTURE;
180 PP_OUTPUTPICTURE[ I_OUTPUTPICTURES ] = p_pic;
184 //return VLC_SUCCESS;
189 /***********************************************************************
191 ***********************************************************************/
192 static void End( vout_thread_t *p_vout )
197 /***********************************************************************
199 ***********************************************************************/
200 static void Close ( vlc_object_t *p_this )
202 vout_thread_t * p_vout = (vout_thread_t *)p_this;
204 libvlc_t *p_libvlc = p_vout->p_libvlc;
205 struct picture_vout_t *p_picture_vout = NULL;
209 msg_Dbg( p_vout, "Closing Picture Vout ...");
210 var_Get( p_libvlc, "p_picture_vout", &val );
211 p_picture_vout = val.p_address;
213 vlc_mutex_lock( &p_picture_vout->lock );
215 if( p_picture_vout->p_pic[p_vout->p_sys->i_picture_pos].p_picture )
218 free( p_picture_vout->p_pic[p_vout->p_sys->i_picture_pos].p_picture );
220 p_picture_vout->p_pic[p_vout->p_sys->i_picture_pos].i_status
221 = PICTURE_VOUT_E_AVAILABLE;
223 for( i = 0; i < p_picture_vout->i_picture_num; i ++)
225 if( p_picture_vout->p_pic[i].i_status == PICTURE_VOUT_E_OCCUPIED ) {
232 vlc_mutex_unlock( &p_picture_vout->lock );
234 free( p_picture_vout->p_pic );
235 vlc_mutex_unlock( &p_picture_vout->lock );
236 vlc_mutex_destroy( &p_picture_vout->lock );
237 var_Destroy( p_libvlc, "p_picture_vout" );
240 free( p_vout->p_sys );
243 /***********************************************************************
245 ***********************************************************************/
246 static int Manage( vout_thread_t *p_vout )
251 /***********************************************************************
253 ***********************************************************************/
254 static void Display( vout_thread_t *p_vout, picture_t *p_pic )
256 libvlc_t *p_libvlc = p_vout->p_libvlc;
258 struct picture_vout_t *p_picture_vout;
260 var_Get( p_libvlc, "p_picture_vout", &val );
261 p_picture_vout = val.p_address;
265 dest : p_picture_pout->p_pic[p_vout->p_sys.i_picture_pos]->p_picture
268 vlc_mutex_lock( &p_picture_vout->lock );
269 if( p_picture_vout->p_pic[p_vout->p_sys->i_picture_pos].p_picture )
271 if( p_picture_vout->p_pic[p_vout->p_sys->i_picture_pos].p_picture->p_data_orig )
273 free( p_picture_vout->p_pic[p_vout->p_sys->i_picture_pos]
274 .p_picture->p_data_orig );
276 free( p_picture_vout->p_pic[p_vout->p_sys->i_picture_pos].p_picture );
279 p_picture_vout->p_pic[p_vout->p_sys->i_picture_pos].p_picture
280 = (picture_t*)malloc( sizeof( picture_t )) ;
281 vout_AllocatePicture( p_vout,
282 p_picture_vout->p_pic[p_vout->p_sys->i_picture_pos].p_picture,
283 p_pic->format.i_chroma,
284 p_pic->format.i_width,
285 p_pic->format.i_height,
286 VOUT_ASPECT_FACTOR * p_pic->format.i_height / p_pic->format.i_width );
288 p_picture_vout->p_pic[p_vout->p_sys->i_picture_pos].p_picture->i_status = DESTROYED_PICTURE;
289 p_picture_vout->p_pic[p_vout->p_sys->i_picture_pos].p_picture->i_type = DIRECT_PICTURE;
291 vout_CopyPicture( p_vout,
292 p_picture_vout->p_pic[p_vout->p_sys->i_picture_pos].p_picture,
295 vlc_mutex_unlock( &p_picture_vout->lock );