]> git.sesse.net Git - vlc/blob - include/video_fifo.h
* Check that OS support SSE optimization for PIII (to avoid illegal hardware instruct...
[vlc] / include / video_fifo.h
1 /*****************************************************************************
2  * video_fifo.h : FIFO for the pool of video_decoders
3  *****************************************************************************
4  * Copyright (C) 1999, 2000 VideoLAN
5  * $Id: video_fifo.h,v 1.19 2001/06/03 12:47:21 sam Exp $
6  *
7  * Authors: Christophe Massiot <massiot@via.ecp.fr>
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  * Requires:
26  *  "config.h"
27  *  "common.h"
28  *  "threads.h"
29  *  "video_parser.h"
30  *  "undec_picture.h"
31  *****************************************************************************/
32
33 /*****************************************************************************
34  * Macros
35  *****************************************************************************/
36
37 #ifdef VDEC_SMP
38 /* FIXME: move to inline functions ??*/
39 #define VIDEO_FIFO_ISEMPTY( fifo )    ( (fifo).i_start == (fifo).i_end )
40 #define VIDEO_FIFO_ISFULL( fifo )     ( ( ( (fifo).i_end + 1 - (fifo).i_start )\
41                                           & VFIFO_SIZE ) == 0 )
42 #define VIDEO_FIFO_START( fifo )      ( (fifo).buffer[ (fifo).i_start ] )
43 #define VIDEO_FIFO_INCSTART( fifo )   ( (fifo).i_start = ((fifo).i_start + 1) \
44                                                            & VFIFO_SIZE )
45 #define VIDEO_FIFO_END( fifo )        ( (fifo).buffer[ (fifo).i_end ] )
46 #define VIDEO_FIFO_INCEND( fifo )     ( (fifo).i_end = ((fifo).i_end + 1) \
47                                                          & VFIFO_SIZE )
48 #endif
49
50 /*****************************************************************************
51  * vpar_GetMacroblock : return a macroblock to be decoded
52  *****************************************************************************/
53 static __inline__ macroblock_t * vpar_GetMacroblock( video_fifo_t * p_fifo )
54 {
55 #ifdef VDEC_SMP
56     macroblock_t *      p_mb;
57
58     vlc_mutex_lock( &p_fifo->lock );
59     while( VIDEO_FIFO_ISEMPTY( *p_fifo ) )
60     {
61         vlc_cond_wait( &p_fifo->wait, &p_fifo->lock );
62         if( p_fifo->p_vpar->p_fifo->b_die )
63         {
64             vlc_mutex_unlock( &p_fifo->lock );
65             return( NULL );
66         }
67     }
68
69     p_mb = VIDEO_FIFO_START( *p_fifo );
70     VIDEO_FIFO_INCSTART( *p_fifo );
71
72     vlc_mutex_unlock( &p_fifo->lock );
73
74     return( p_mb );
75 #else
76     /* Shouldn't normally be used without SMP. */
77     return NULL;
78 #endif
79 }
80
81 /*****************************************************************************
82  * vpar_NewMacroblock : return a buffer for the parser
83  *****************************************************************************/
84 static __inline__ macroblock_t * vpar_NewMacroblock( video_fifo_t * p_fifo )
85 {
86 #ifdef VDEC_SMP
87     macroblock_t *      p_mb;
88
89 #define P_buffer p_fifo->p_vpar->vbuffer
90     vlc_mutex_lock( &P_buffer.lock );
91     while( P_buffer.i_index == -1 )
92     {
93         /* No more structures available. This should not happen ! */
94         intf_DbgMsg("vpar debug: macroblock list is empty, delaying");
95         vlc_mutex_unlock( &P_buffer.lock );
96         if( p_fifo->p_vpar->p_fifo->b_die )
97         {
98             return( NULL );
99         }
100         msleep(VPAR_OUTMEM_SLEEP);
101         vlc_mutex_lock( &P_buffer.lock );
102     }
103
104     p_mb = P_buffer.pp_mb_free[ P_buffer.i_index-- ];
105
106     vlc_mutex_unlock( &P_buffer.lock );
107 #undef P_buffer
108     return( p_mb );
109 #else
110     return( &p_fifo->buffer );
111 #endif
112 }
113
114 /*****************************************************************************
115  * vpar_ReleaseMacroblock : release a macroblock and put the picture in the
116  *                          video output heap, if it is finished
117  *****************************************************************************/
118 static __inline__ void vpar_ReleaseMacroblock( video_fifo_t * p_fifo,
119                                                macroblock_t * p_mb )
120 {
121 #ifdef VDEC_SMP
122     boolean_t      b_finished;
123
124     /* Unlink picture buffer */
125     vlc_mutex_lock( &p_mb->p_picture->lock_deccount );
126     p_mb->p_picture->i_deccount--;
127     b_finished = (p_mb->p_picture->i_deccount == 1);
128     vlc_mutex_unlock( &p_mb->p_picture->lock_deccount );
129 //intf_DbgMsg( "%d ", p_mb->p_picture->i_deccount );
130     /* Test if it was the last block of the picture */
131     if( b_finished )
132     {
133 //intf_DbgMsg( "Image decodee" );
134         /* Mark the picture to be displayed */
135         vout_DisplayPicture( p_fifo->p_vpar->p_vout, p_mb->p_picture );
136
137         /* Warn Synchro for its records. */
138         vpar_SynchroEnd( p_fifo->p_vpar, 0 );
139
140         /* Unlink referenced pictures */
141         if( p_mb->p_forward != NULL )
142         {
143             vout_UnlinkPicture( p_fifo->p_vpar->p_vout, p_mb->p_forward );
144         }
145         if( p_mb->p_backward != NULL )
146         {
147             vout_UnlinkPicture( p_fifo->p_vpar->p_vout, p_mb->p_backward );
148         }
149     }
150
151     /* Release the macroblock_t structure */
152 #define P_buffer p_fifo->p_vpar->vbuffer
153     vlc_mutex_lock( &P_buffer.lock );
154     P_buffer.pp_mb_free[ ++P_buffer.i_index ] = p_mb;
155     vlc_mutex_unlock( &P_buffer.lock );
156 #undef P_buffer
157
158 #else
159     p_mb->p_picture->i_deccount--;
160     if( p_mb->p_picture->i_deccount == 1 )
161     {
162         /* Mark the picture to be displayed */
163         vout_DisplayPicture( p_fifo->p_vpar->p_vout, p_mb->p_picture );
164
165         /* Warn Synchro for its records. */
166         vpar_SynchroEnd( p_fifo->p_vpar, 0 );
167     }
168 #endif
169 }
170
171 /*****************************************************************************
172  * vpar_DecodeMacroblock : put a macroblock in the video fifo
173  *****************************************************************************/
174 static __inline__ void vpar_DecodeMacroblock( video_fifo_t * p_fifo,
175                                               macroblock_t * p_mb )
176 {
177 #ifdef VDEC_SMP
178     /* Place picture in the video FIFO */
179     vlc_mutex_lock( &p_fifo->lock );
180
181     /* By construction, the video FIFO cannot be full */
182     VIDEO_FIFO_END( *p_fifo ) = p_mb;
183     VIDEO_FIFO_INCEND( *p_fifo );
184
185     vlc_mutex_unlock( &p_fifo->lock );
186 #else
187     p_fifo->p_vpar->pf_decode_mb_c( p_fifo->p_vpar->pp_vdec[0], p_mb );
188     vpar_ReleaseMacroblock( &p_fifo->p_vpar->vfifo, p_mb );
189 #endif
190 }
191
192 /*****************************************************************************
193  * vpar_DestroyMacroblock : destroy a macroblock in case of error
194  *****************************************************************************/
195 static __inline__ void vpar_DestroyMacroblock( video_fifo_t * p_fifo,
196                                                macroblock_t * p_mb )
197 {
198 #ifdef VDEC_SMP
199     boolean_t       b_finished;
200
201     /* Unlink picture buffer */
202     vlc_mutex_lock( &p_mb->p_picture->lock_deccount );
203     p_mb->p_picture->i_deccount--;
204     b_finished = (p_mb->p_picture->i_deccount == 1);
205     vlc_mutex_unlock( &p_mb->p_picture->lock_deccount );
206
207     /* Test if it was the last block of the picture */
208     if( b_finished )
209     {
210         intf_DbgMsg( "Image trashee" );
211         /* Mark the picture to be trashed */
212         vout_DestroyPicture( p_fifo->p_vpar->p_vout, p_mb->p_picture );
213
214         /* Warn Synchro for its records. */
215         vpar_SynchroEnd( p_fifo->p_vpar, 1 );
216
217         /* Unlink referenced pictures */
218         if( p_mb->p_forward != NULL )
219         {
220             vout_UnlinkPicture( p_fifo->p_vpar->p_vout, p_mb->p_forward );
221         }
222         if( p_mb->p_backward != NULL )
223         {
224             vout_UnlinkPicture( p_fifo->p_vpar->p_vout, p_mb->p_backward );
225         }
226     }
227
228     /* Release the macroblock_t structure */
229 #define P_buffer p_fifo->p_vpar->vbuffer
230     vlc_mutex_lock( &P_buffer.lock );
231     P_buffer.pp_mb_free[ ++P_buffer.i_index ] = p_mb;
232     vlc_mutex_unlock( &P_buffer.lock );
233 #undef P_buffer
234
235 #else
236     p_mb->p_picture->i_deccount--;
237     if( p_mb->p_picture->i_deccount == 1 )
238     {
239         /* Mark the picture to be trashed */
240         vout_DestroyPicture( p_fifo->p_vpar->p_vout, p_mb->p_picture );
241
242         /* Warn Synchro for its records. */
243         vpar_SynchroEnd( p_fifo->p_vpar, 1 );
244     }
245 #endif
246 }
247
248 /*****************************************************************************
249  * vpar_FreeMacroblock : destroy a macroblock in case of error, without
250  * updating the macroblock counters
251  *****************************************************************************/
252 static __inline__ void vpar_FreeMacroblock( video_fifo_t * p_fifo,
253                                             macroblock_t * p_mb )
254 {
255 #ifdef VDEC_SMP
256     /* Release the macroblock_t structure */
257 #define P_buffer p_fifo->p_vpar->vbuffer
258     vlc_mutex_lock( &P_buffer.lock );
259     P_buffer.pp_mb_free[ ++P_buffer.i_index ] = p_mb;
260     vlc_mutex_unlock( &P_buffer.lock );
261 #undef P_buffer
262
263 #else
264     ;
265 #endif
266 }
267 /*****************************************************************************
268  * Prototypes
269  *****************************************************************************/
270 void vpar_InitFIFO( struct vpar_thread_s * p_vpar );