]> git.sesse.net Git - vlc/blob - include/video_fifo.h
* Ajout d'un flag VDEC_SMP � commenter si on n'a qu'un seul
[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         msleep(VPAR_OUTMEM_SLEEP);
78         vlc_mutex_lock( &P_buffer.lock );
79     }
80
81     p_mb = P_buffer.pp_mb_free[ P_buffer.i_index-- ];
82
83     vlc_mutex_unlock( &P_buffer.lock );
84 #undef P_buffer
85     return( p_mb );
86 #else
87     return( &p_fifo->buffer );
88 #endif
89 }
90
91 /*****************************************************************************
92  * vpar_DecodeMacroblock : put a macroblock in the video fifo
93  *****************************************************************************/
94 static __inline__ void vpar_DecodeMacroblock( video_fifo_t * p_fifo,
95                                               macroblock_t * p_mb )
96 {
97 #ifdef VDEC_SMP
98     /* Place picture in the video FIFO */
99     vlc_mutex_lock( &p_fifo->lock );
100         
101     /* By construction, the video FIFO cannot be full */
102     VIDEO_FIFO_END( *p_fifo ) = p_mb;
103     VIDEO_FIFO_INCEND( *p_fifo );
104
105     vlc_mutex_unlock( &p_fifo->lock );
106 #endif
107     /* Shouldn't normally be used without SMP. */
108 }
109
110 /*****************************************************************************
111  * vpar_ReleaseMacroblock : release a macroblock and put the picture in the
112  *                          video output heap, if it is finished
113  *****************************************************************************/
114 static __inline__ void vpar_ReleaseMacroblock( video_fifo_t * p_fifo,
115                                                macroblock_t * p_mb )
116 {
117 #ifdef VDEC_SMP
118     boolean_t      b_finished;
119
120     /* Unlink picture buffer */
121     vlc_mutex_lock( &p_mb->p_picture->lock_deccount );
122     p_mb->p_picture->i_deccount--;
123     b_finished = (p_mb->p_picture->i_deccount == 1);
124     vlc_mutex_unlock( &p_mb->p_picture->lock_deccount );
125 //fprintf(stderr, "%d ", p_mb->p_picture->i_deccount);
126     /* Test if it was the last block of the picture */
127     if( b_finished )
128     {
129 //fprintf(stderr, "Image decodee\n");
130         /* Mark the picture to be displayed */
131         vout_DisplayPicture( p_fifo->p_vpar->p_vout, p_mb->p_picture );
132
133         /* Warn Synchro for its records. */
134         vpar_SynchroEnd( p_fifo->p_vpar );
135      
136         /* Unlink referenced pictures */
137         if( p_mb->p_forward != NULL )
138         {
139                 vout_UnlinkPicture( p_fifo->p_vpar->p_vout, p_mb->p_forward );
140         }
141         if( p_mb->p_backward != NULL )
142         {
143             vout_UnlinkPicture( p_fifo->p_vpar->p_vout, p_mb->p_backward );
144         }
145     }
146
147     /* Release the macroblock_t structure */
148 #define P_buffer p_fifo->p_vpar->vbuffer
149     vlc_mutex_lock( &P_buffer.lock );
150     P_buffer.pp_mb_free[ ++P_buffer.i_index ] = p_mb;
151     vlc_mutex_unlock( &P_buffer.lock );
152 #undef P_buffer
153
154 #else
155     p_mb->p_picture->i_deccount--;
156     if( p_mb->p_picture->i_deccount == 1 )
157     {
158         /* Mark the picture to be displayed */
159         vout_DisplayPicture( p_fifo->p_vpar->p_vout, p_mb->p_picture );
160
161         /* Warn Synchro for its records. */
162         vpar_SynchroEnd( p_fifo->p_vpar );
163     }
164 #endif
165 }
166
167 /*****************************************************************************
168  * vpar_DestroyMacroblock : destroy a macroblock in case of error
169  *****************************************************************************/
170 static __inline__ void vpar_DestroyMacroblock( video_fifo_t * p_fifo,
171                                                macroblock_t * p_mb )
172 {
173 #ifdef VDEC_SMP
174     boolean_t       b_finished;
175
176     /* Unlink picture buffer */
177     vlc_mutex_lock( &p_mb->p_picture->lock_deccount );
178     p_mb->p_picture->i_deccount--;
179     b_finished = (p_mb->p_picture->i_deccount == 1);
180     vlc_mutex_unlock( &p_mb->p_picture->lock_deccount );
181
182     /* Test if it was the last block of the picture */
183     if( b_finished )
184     {
185 fprintf(stderr, "Image trashee\n");
186         /* Mark the picture to be trashed */
187         vout_DestroyPicture( p_fifo->p_vpar->p_vout, p_mb->p_picture );
188
189         /* Warn Synchro for its records. */
190         vpar_SynchroEnd( p_fifo->p_vpar );
191
192         /* Unlink referenced pictures */
193         if( p_mb->p_forward != NULL )
194         {
195             vout_UnlinkPicture( p_fifo->p_vpar->p_vout, p_mb->p_forward );
196         }
197         if( p_mb->p_backward != NULL )
198         {
199             vout_UnlinkPicture( p_fifo->p_vpar->p_vout, p_mb->p_backward );
200         }
201     }
202
203     /* Release the macroblock_t structure */
204 #define P_buffer p_fifo->p_vpar->vbuffer
205     vlc_mutex_lock( &P_buffer.lock );
206     P_buffer.pp_mb_free[ ++P_buffer.i_index ] = p_mb;
207     vlc_mutex_unlock( &P_buffer.lock );
208 #undef P_buffer
209
210 #else
211     p_mb->p_picture->i_deccount--;
212     if( p_mb->p_picture->i_deccount == 1 )
213     {
214         /* Mark the picture to be trashed */
215         vout_DestroyPicture( p_fifo->p_vpar->p_vout, p_mb->p_picture );
216
217         /* Warn Synchro for its records. */
218         vpar_SynchroEnd( p_fifo->p_vpar );
219     }
220 #endif
221 }
222
223 /*****************************************************************************
224  * Prototypes
225  *****************************************************************************/
226 void vpar_InitFIFO( struct vpar_thread_s * p_vpar );