]> git.sesse.net Git - vlc/blob - src/video_parser/video_fifo.c
video_fifo.c et vpar_headers.c compilent � peu pr�s. Correction d'environ
[vlc] / src / video_parser / video_fifo.c
1 /*******************************************************************************
2  * video_fifo.c : video FIFO management
3  * (c)1999 VideoLAN
4  *******************************************************************************/
5
6 /*******************************************************************************
7  * Preamble
8  *******************************************************************************/
9 #include <errno.h>
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <unistd.h>
13 #include <string.h>
14 #include <sys/uio.h>
15 #include <X11/Xlib.h>
16 #include <X11/extensions/XShm.h>
17
18 #include "config.h"
19 #include "common.h"
20 #include "mtime.h"
21 #include "vlc_thread.h"
22
23 #include "intf_msg.h"
24 #include "debug.h"                      /* ?? temporaire, requis par netlist.h */
25
26 #include "input.h"
27 #include "input_netlist.h"
28 #include "decoder_fifo.h"
29 #include "video.h"
30 #include "video_output.h"
31
32 #include "vdec_idct.h"
33 #include "video_decoder.h"
34 #include "vdec_motion.h"
35
36 #include "vpar_blocks.h"
37 #include "vpar_headers.h"
38 #include "video_fifo.h"
39 #include "video_parser.h"
40
41 /*****************************************************************************
42  * vpar_InitFIFO : initialize the video FIFO
43  *****************************************************************************/
44 void vpar_InitFIFO( vpar_thread_t * p_vpar )
45 {
46     int                 i_dummy;
47     
48     /* Initialize mutex and cond */
49     vlc_mutex_init( &p_vpar->vfifo.lock );
50     vlc_cond_init( &p_vpar->vfifo.wait );
51     vlc_mutex_init( &p_vpar->vbuffer.lock );
52     
53     /* Initialize FIFO properties */
54     p_vpar->vfifo.i_start = p_vpar->vfifo.i_end = 0;
55     p_vpar->vfifo.p_vpar = p_vpar;
56     
57     /* Initialize buffer properties */
58     p_vpar->vbuffer.i_index = VFIFO_SIZE; /* all structures are available */
59     for( i_dummy = 0; i_dummy < VFIFO_SIZE + 1; i_dummy++ )
60     {
61         p_vpar->vbuffer.pp_mb_free[i_dummy] = p_vpar->vbuffer.p_macroblocks
62                                                + i_dummy;
63     }
64 }
65
66 /*****************************************************************************
67  * vpar_GetMacroblock : return a macroblock to be decoded
68  *****************************************************************************/
69 macroblock_t * vpar_GetMacroblock( video_fifo_t * p_fifo )
70 {
71     macroblock_t *      p_mb;
72
73     vlc_mutex_lock( &p_fifo->lock );
74     while( VIDEO_FIFO_ISEMPTY( *p_fifo ) )
75     {
76         vlc_cond_wait( &p_fifo->wait, &p_fifo->lock );
77         if( p_fifo->p_vpar->b_die )
78         {
79             vlc_mutex_unlock( &p_fifo->lock );
80             return( NULL );
81         }
82     }
83     
84     p_mb = VIDEO_FIFO_START( *p_fifo );
85     VIDEO_FIFO_INCSTART( *p_fifo );
86     
87     vlc_mutex_unlock( &p_fifo->lock );
88     
89     return( p_mb );
90 }
91
92 /*****************************************************************************
93  * vpar_NewMacroblock : return a buffer for the parser
94  *****************************************************************************/
95 macroblock_t * vpar_NewMacroblock( video_fifo_t * p_fifo )
96 {
97     macroblock_t *      p_mb;
98
99 #define P_buffer p_fifo->p_vpar->vbuffer
100     vlc_mutex_lock( &P_buffer.lock );
101     if( P_buffer.i_index == -1 )
102     {
103         /* No more structures available. This should not happen ! */
104         return NULL;
105     }
106
107     p_mb = P_buffer.pp_mb_free[ P_buffer.i_index-- ];
108
109     vlc_mutex_unlock( &P_buffer.lock );
110 #undef P_buffer
111     return( p_mb );
112 }
113
114 /*****************************************************************************
115  * vpar_DecodeMacroblock : put a macroblock in the video fifo
116  *****************************************************************************/
117 void vpar_DecodeMacroblock( video_fifo_t * p_fifo, macroblock_t * p_mb )
118 {
119     /* Place picture in the video FIFO */
120     vlc_mutex_lock( &p_fifo->lock );
121         
122     /* By construction, the video FIFO cannot be full */
123     VIDEO_FIFO_END( *p_fifo ) = p_mb;
124     VIDEO_FIFO_INCEND( *p_fifo );
125
126     vlc_mutex_unlock( &p_fifo->lock );
127 }
128
129 /*****************************************************************************
130  * vpar_ReleaseMacroblock : release a macroblock and put the picture in the
131  *                          video output heap, if it is finished
132  *****************************************************************************/
133 void vpar_ReleaseMacroblock( video_fifo_t * p_fifo, macroblock_t * p_mb )
134 {
135     /* Unlink referenced pictures */
136     if( p_mb->p_forw_top != NULL )
137     {
138         vout_UnlinkPicture( p_fifo->p_vpar->p_vout, p_mb->p_forw_top );
139     }
140     if( p_mb->p_backw_top != NULL )
141     {
142         vout_UnlinkPicture( p_fifo->p_vpar->p_vout, p_mb->p_backw_top );
143     }
144     if( p_mb->p_forw_bot != NULL )
145     {
146         vout_UnlinkPicture( p_fifo->p_vpar->p_vout, p_mb->p_forw_bot );
147     }
148     if( p_mb->p_backw_bot != NULL )
149     {
150         vout_UnlinkPicture( p_fifo->p_vpar->p_vout, p_mb->p_backw_bot );
151     }
152
153     /* Unlink picture buffer */
154     vlc_mutex_lock( &p_mb->p_picture->lock_deccount );
155     p_mb->p_picture->i_deccount--;
156     if( p_mb->p_picture->i_deccount == 0 )
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     vlc_mutex_unlock( & p_mb->p_picture->lock_deccount );
165
166     /* Release the macroblock_t structure */
167 #define P_buffer p_fifo->p_vpar->vbuffer
168     vlc_mutex_lock( &P_buffer.lock );
169     P_buffer.pp_mb_free[ ++P_buffer.i_index ] = p_mb;
170     vlc_mutex_unlock( &P_buffer.lock );
171 #undef P_buffer
172 }
173
174 /*****************************************************************************
175  * vpar_DestroyMacroblock : destroy a macroblock in case of error
176  *****************************************************************************/
177 void vpar_DestroyMacroblock( video_fifo_t * p_fifo, macroblock_t * p_mb )
178 {
179     /* Unlink referenced pictures */
180     if( p_mb->p_forw_top != NULL )
181     {
182         vout_UnlinkPicture( p_fifo->p_vpar->p_vout, p_mb->p_forw_top );
183     }
184     if( p_mb->p_backw_top != NULL )
185     {
186         vout_UnlinkPicture( p_fifo->p_vpar->p_vout, p_mb->p_backw_top );
187     }
188     if( p_mb->p_forw_bot != NULL )
189     {
190         vout_UnlinkPicture( p_fifo->p_vpar->p_vout, p_mb->p_forw_bot );
191     }
192     if( p_mb->p_backw_bot != NULL )
193     {
194         vout_UnlinkPicture( p_fifo->p_vpar->p_vout, p_mb->p_backw_bot );
195     }
196
197     /* Release the macroblock_t structure */
198 #define P_buffer p_fifo->p_vpar->vbuffer
199     vlc_mutex_lock( &P_buffer.lock );
200     P_buffer.pp_mb_free[ ++P_buffer.i_index ] = p_mb;
201     vlc_mutex_unlock( &P_buffer.lock );
202 #undef P_buffer
203 }