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 $
7 * Authors: Christophe Massiot <massiot@via.ecp.fr>
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 /*****************************************************************************
31 *****************************************************************************/
33 /*****************************************************************************
35 *****************************************************************************/
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 )\
42 #define VIDEO_FIFO_START( fifo ) ( (fifo).buffer[ (fifo).i_start ] )
43 #define VIDEO_FIFO_INCSTART( fifo ) ( (fifo).i_start = ((fifo).i_start + 1) \
45 #define VIDEO_FIFO_END( fifo ) ( (fifo).buffer[ (fifo).i_end ] )
46 #define VIDEO_FIFO_INCEND( fifo ) ( (fifo).i_end = ((fifo).i_end + 1) \
50 /*****************************************************************************
51 * vpar_GetMacroblock : return a macroblock to be decoded
52 *****************************************************************************/
53 static __inline__ macroblock_t * vpar_GetMacroblock( video_fifo_t * p_fifo )
58 vlc_mutex_lock( &p_fifo->lock );
59 while( VIDEO_FIFO_ISEMPTY( *p_fifo ) )
61 vlc_cond_wait( &p_fifo->wait, &p_fifo->lock );
62 if( p_fifo->p_vpar->p_fifo->b_die )
64 vlc_mutex_unlock( &p_fifo->lock );
69 p_mb = VIDEO_FIFO_START( *p_fifo );
70 VIDEO_FIFO_INCSTART( *p_fifo );
72 vlc_mutex_unlock( &p_fifo->lock );
76 /* Shouldn't normally be used without SMP. */
81 /*****************************************************************************
82 * vpar_NewMacroblock : return a buffer for the parser
83 *****************************************************************************/
84 static __inline__ macroblock_t * vpar_NewMacroblock( video_fifo_t * p_fifo )
89 #define P_buffer p_fifo->p_vpar->vbuffer
90 vlc_mutex_lock( &P_buffer.lock );
91 while( P_buffer.i_index == -1 )
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 )
100 msleep(VPAR_OUTMEM_SLEEP);
101 vlc_mutex_lock( &P_buffer.lock );
104 p_mb = P_buffer.pp_mb_free[ P_buffer.i_index-- ];
106 vlc_mutex_unlock( &P_buffer.lock );
110 return( &p_fifo->buffer );
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 )
122 boolean_t b_finished;
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 */
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 );
137 /* Warn Synchro for its records. */
138 vpar_SynchroEnd( p_fifo->p_vpar, 0 );
140 /* Unlink referenced pictures */
141 if( p_mb->p_forward != NULL )
143 vout_UnlinkPicture( p_fifo->p_vpar->p_vout, p_mb->p_forward );
145 if( p_mb->p_backward != NULL )
147 vout_UnlinkPicture( p_fifo->p_vpar->p_vout, p_mb->p_backward );
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 );
159 p_mb->p_picture->i_deccount--;
160 if( p_mb->p_picture->i_deccount == 1 )
162 /* Mark the picture to be displayed */
163 vout_DisplayPicture( p_fifo->p_vpar->p_vout, p_mb->p_picture );
165 /* Warn Synchro for its records. */
166 vpar_SynchroEnd( p_fifo->p_vpar, 0 );
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 )
178 /* Place picture in the video FIFO */
179 vlc_mutex_lock( &p_fifo->lock );
181 /* By construction, the video FIFO cannot be full */
182 VIDEO_FIFO_END( *p_fifo ) = p_mb;
183 VIDEO_FIFO_INCEND( *p_fifo );
185 vlc_mutex_unlock( &p_fifo->lock );
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 );
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 )
199 boolean_t b_finished;
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 );
207 /* Test if it was the last block of the picture */
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 );
214 /* Warn Synchro for its records. */
215 vpar_SynchroEnd( p_fifo->p_vpar, 1 );
217 /* Unlink referenced pictures */
218 if( p_mb->p_forward != NULL )
220 vout_UnlinkPicture( p_fifo->p_vpar->p_vout, p_mb->p_forward );
222 if( p_mb->p_backward != NULL )
224 vout_UnlinkPicture( p_fifo->p_vpar->p_vout, p_mb->p_backward );
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 );
236 p_mb->p_picture->i_deccount--;
237 if( p_mb->p_picture->i_deccount == 1 )
239 /* Mark the picture to be trashed */
240 vout_DestroyPicture( p_fifo->p_vpar->p_vout, p_mb->p_picture );
242 /* Warn Synchro for its records. */
243 vpar_SynchroEnd( p_fifo->p_vpar, 1 );
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 )
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 );
267 /*****************************************************************************
269 *****************************************************************************/
270 void vpar_InitFIFO( struct vpar_thread_s * p_vpar );