]> git.sesse.net Git - vlc/blob - include/video_fifo.h
* Optimisation du parseur ;
[vlc] / include / video_fifo.h
1 /*****************************************************************************
2  * video_fifo.h : FIFO for the pool of video_decoders
3  * (c)1999 VideoLAN
4  *****************************************************************************
5  *****************************************************************************
6  * Requires:
7  *  "config.h"
8  *  "common.h"
9  *  "vlc_thread.h"
10  *  "video_parser.h"
11  *  "undec_picture.h"
12  *****************************************************************************/
13
14 /*****************************************************************************
15  * Macros
16  *****************************************************************************/
17
18 #ifdef VDEC_SMP
19 /* ?? move to inline functions */
20 #define VIDEO_FIFO_ISEMPTY( fifo )    ( (fifo).i_start == (fifo).i_end )
21 #define VIDEO_FIFO_ISFULL( fifo )     ( ( ( (fifo).i_end + 1 - (fifo).i_start ) \
22                                           & VFIFO_SIZE ) == 0 )
23 #define VIDEO_FIFO_START( fifo )      ( (fifo).buffer[ (fifo).i_start ] )
24 #define VIDEO_FIFO_INCSTART( fifo )   ( (fifo).i_start = ((fifo).i_start + 1) \
25                                                            & VFIFO_SIZE ) 
26 #define VIDEO_FIFO_END( fifo )        ( (fifo).buffer[ (fifo).i_end ] )
27 #define VIDEO_FIFO_INCEND( fifo )     ( (fifo).i_end = ((fifo).i_end + 1) \
28                                                          & VFIFO_SIZE )
29 #endif
30
31 /*****************************************************************************
32  * vpar_GetMacroblock : return a macroblock to be decoded
33  *****************************************************************************/
34 static __inline__ macroblock_t * vpar_GetMacroblock( video_fifo_t * p_fifo )
35 {
36 #ifdef VDEC_SMP
37     macroblock_t *      p_mb;
38
39     vlc_mutex_lock( &p_fifo->lock );
40     while( VIDEO_FIFO_ISEMPTY( *p_fifo ) )
41     {
42         vlc_cond_wait( &p_fifo->wait, &p_fifo->lock );
43         if( p_fifo->p_vpar->b_die )
44         {
45             vlc_mutex_unlock( &p_fifo->lock );
46             return( NULL );
47         }
48     }
49     
50     p_mb = VIDEO_FIFO_START( *p_fifo );
51     VIDEO_FIFO_INCSTART( *p_fifo );
52
53     vlc_mutex_unlock( &p_fifo->lock );
54     
55     return( p_mb );
56 #else
57     /* Shouldn't normally be used without SMP. */
58     return NULL;
59 #endif
60 }
61
62 /*****************************************************************************
63  * vpar_NewMacroblock : return a buffer for the parser
64  *****************************************************************************/
65 static __inline__ macroblock_t * vpar_NewMacroblock( video_fifo_t * p_fifo )
66 {
67 #ifdef VDEC_SMP
68     macroblock_t *      p_mb;
69
70 #define P_buffer p_fifo->p_vpar->vbuffer
71     vlc_mutex_lock( &P_buffer.lock );
72     while( P_buffer.i_index == -1 )
73     {
74         /* No more structures available. This should not happen ! */
75         intf_DbgMsg("vpar debug: macroblock list is empty, delaying\n");
76         vlc_mutex_unlock( &P_buffer.lock );
77         if( p_fifo->p_vpar->b_die )
78         {
79             return( NULL );
80         }
81         msleep(VPAR_OUTMEM_SLEEP);
82         vlc_mutex_lock( &P_buffer.lock );
83     }
84
85     p_mb = P_buffer.pp_mb_free[ P_buffer.i_index-- ];
86
87     vlc_mutex_unlock( &P_buffer.lock );
88 #undef P_buffer
89     return( p_mb );
90 #else
91     return( &p_fifo->buffer );
92 #endif
93 }
94
95 /*****************************************************************************
96  * vpar_DecodeMacroblock : put a macroblock in the video fifo
97  *****************************************************************************/
98 static __inline__ void vpar_DecodeMacroblock( video_fifo_t * p_fifo,
99                                               macroblock_t * p_mb )
100 {
101 #ifdef VDEC_SMP
102     /* Place picture in the video FIFO */
103     vlc_mutex_lock( &p_fifo->lock );
104         
105     /* By construction, the video FIFO cannot be full */
106     VIDEO_FIFO_END( *p_fifo ) = p_mb;
107     VIDEO_FIFO_INCEND( *p_fifo );
108
109     vlc_mutex_unlock( &p_fifo->lock );
110 #endif
111     /* Shouldn't normally be used without SMP. */
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 //fprintf(stderr, "%d ", p_mb->p_picture->i_deccount);
130     /* Test if it was the last block of the picture */
131     if( b_finished )
132     {
133 //fprintf(stderr, "Image decodee\n");
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 );
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 );
167     }
168 #endif
169 }
170
171 /*****************************************************************************
172  * vpar_DestroyMacroblock : destroy a macroblock in case of error
173  *****************************************************************************/
174 static __inline__ void vpar_DestroyMacroblock( video_fifo_t * p_fifo,
175                                                macroblock_t * p_mb )
176 {
177 #ifdef VDEC_SMP
178     boolean_t       b_finished;
179
180     /* Unlink picture buffer */
181     vlc_mutex_lock( &p_mb->p_picture->lock_deccount );
182     p_mb->p_picture->i_deccount--;
183     b_finished = (p_mb->p_picture->i_deccount == 1);
184     vlc_mutex_unlock( &p_mb->p_picture->lock_deccount );
185
186     /* Test if it was the last block of the picture */
187     if( b_finished )
188     {
189 fprintf(stderr, "Image trashee\n");
190         /* Mark the picture to be trashed */
191         vout_DestroyPicture( p_fifo->p_vpar->p_vout, p_mb->p_picture );
192
193         /* Warn Synchro for its records. */
194         vpar_SynchroEnd( p_fifo->p_vpar );
195
196         /* Unlink referenced pictures */
197         if( p_mb->p_forward != NULL )
198         {
199             vout_UnlinkPicture( p_fifo->p_vpar->p_vout, p_mb->p_forward );
200         }
201         if( p_mb->p_backward != NULL )
202         {
203             vout_UnlinkPicture( p_fifo->p_vpar->p_vout, p_mb->p_backward );
204         }
205     }
206
207     /* Release the macroblock_t structure */
208 #define P_buffer p_fifo->p_vpar->vbuffer
209     vlc_mutex_lock( &P_buffer.lock );
210     P_buffer.pp_mb_free[ ++P_buffer.i_index ] = p_mb;
211     vlc_mutex_unlock( &P_buffer.lock );
212 #undef P_buffer
213
214 #else
215     p_mb->p_picture->i_deccount--;
216     if( p_mb->p_picture->i_deccount == 1 )
217     {
218         /* Mark the picture to be trashed */
219         vout_DestroyPicture( p_fifo->p_vpar->p_vout, p_mb->p_picture );
220
221         /* Warn Synchro for its records. */
222         vpar_SynchroEnd( p_fifo->p_vpar );
223     }
224 #endif
225 }
226
227 /*****************************************************************************
228  * Prototypes
229  *****************************************************************************/
230 void vpar_InitFIFO( struct vpar_thread_s * p_vpar );