]> git.sesse.net Git - vlc/blob - src/video_parser/video_fifo.c
Suite du video_parser et du video_decoder.
[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 #include "video_parser.h"
32
33 #include "macroblock.h"
34 #include "video_fifo.h"
35 #include "video_decoder.h"
36
37 /*****************************************************************************
38  * vpar_InitFIFO : initialize the video FIFO
39  *****************************************************************************/
40 void vpar_InitFIFO( vpar_thread_t * p_vpar )
41 {
42     int                 i_dummy;
43     
44     /* Initialize mutex and cond */
45     vlc_mutex_init( p_vpar->vfifo.lock );
46     vlc_cond_init( p_vpar->vfifo.wait );
47     vlc_mutex_init( p_vpar->vbuffer.lock );
48     
49     /* Initialize FIFO properties */
50     p_vpar->vfifo.i_start = p_vpar->vfifo.i_end = 0;
51     p_vpar->vfifo.p_vpar = p_vpar;
52     
53     /* Initialize buffer properties */
54     i_index = VFIFO_SIZE; /* all structures are available */
55     for( i_dummy = 0; i_dummy < VFIFO_SIZE + 1; i_dummy++ )
56     {
57         p_vpar->vfifo.pp_mb_free[i_dummy] = p_vpar->vfifo.p_macroblocks + i;
58     }
59 }
60
61 /*****************************************************************************
62  * vpar_GetMacroblock : return a macroblock to be decoded
63  *****************************************************************************/
64 macroblock_t * vpar_GetMacroblock( video_fifo_t * p_fifo )
65 {
66     macroblock_t *      p_mb;
67
68     vlc_mutex_lock( &p_fifo->lock );
69     while( VIDEO_FIFO_ISEMPTY( *p_fifo ) )
70     {
71         vlc_cond_wait( &p_fifo->wait, &p_fifo->lock );
72         if( p_fifo->p_vpar->b_die )
73         {
74             vlc_mutex_unlock( &p_fifo->lock );
75             return( NULL );
76         }
77     }
78     
79     p_mb = VIDEO_FIFO_START( *p_fifo );
80     VIDEO_FIFO_INCSTART( *p_fifo );
81     
82     vlc_mutex_unlock( &p_fifo->lock );
83     
84     return( p_mb );
85 }
86
87 /*****************************************************************************
88  * vpar_NewMacroblock : return a buffer for the parser
89  *****************************************************************************/
90 macroblock_t * vpar_NewMacroblock( video_fifo_t * p_fifo )
91 {
92     macroblock_t *      p_mb;
93
94 #define P_buffer p_fifo->p_vpar.vbuffer
95     vlc_mutex_lock( &P_buffer->lock );
96     if( P_buffer.i_index == -1 )
97     {
98         /* No more structures available. This should not happen ! */
99         return NULL;
100     }
101
102     p_mb = P_buffer->pp_undec_free[ P_buffer->i_index-- ];
103 #undef P_buffer
104
105     vlc_mutex_unlock( &P_buffer->lock );
106     return( p_mb );
107 }
108
109 /*****************************************************************************
110  * vpar_DecodeMacroblock : put a macroblock in the video fifo
111  *****************************************************************************/
112 void vpar_DecodeMacroblock( video_fifo_t * p_fifo, macroblock_t * p_mb )
113 {
114     /* Place picture in the video FIFO */
115     vlc_mutex_lock( &p_fifo->lock );
116         
117     /* By construction, the video FIFO cannot be full */
118     VIDEO_FIFO_END( *p_fifo ) = p_mb;
119     VIDEO_FIFO_INCEND( *p_fifo );
120         
121     vlc_mutex_unlock( &p_fifo->lock );
122 }
123
124 /*****************************************************************************
125  * vpar_ReleaseMacroblock : release a macroblock and put the picture in the
126  *                          video output heap, if it is finished
127  *****************************************************************************/
128 void vpar_ReleaseMacroblock( video_fifo_t * p_fifo, macroblock_t * p_mb )
129 {
130     /* Unlink referenced pictures */
131     if( p_mb->p_forw_top != NULL )
132     {
133         vout_UnlinkPicture( p_fifo->p_vpar.p_vout, p_mb->p_forw_top );
134     }
135     if( p_mb->p_backw_top != NULL )
136     {
137         vout_UnlinkPicture( p_fifo->p_vpar.p_vout, p_mb->p_backw_top );
138     }
139     if( p_mb->p_forw_bot != NULL )
140     {
141         vout_UnlinkPicture( p_fifo->p_vpar.p_vout, p_mb->p_forw_bot );
142     }
143     if( p_mb->p_backw_bot != NULL )
144     {
145         vout_UnlinkPicture( p_fifo->p_vpar.p_vout, p_mb->p_backw_bot );
146     }
147
148     /* Unlink picture buffer */
149     vlc_mutex_lock( &p_mb->p_picture->lock_deccount );
150     p_mb->p_picture->i_deccount--;
151     if( p_mb->p_picture->i_deccount == 0 )
152     {
153         /* Mark the picture to be displayed */
154         vout_DisplayPicture( p_fifo->p_vpar.p_vout, p_mb->p_picture );
155
156         /* Warn Synchro for its records. */
157         vpar_SynchroEnd( p_fifo->p_vpar );
158     }
159     vlc_mutex_unlock( & p_mb->p_picture->lock_deccount );
160
161     /* Release the macroblock_t structure */
162 #define P_buffer p_fifo->p_vpar.vbuffer
163     vlc_mutex_lock( &P_buffer->lock );
164     P_buffer->pp_mb_free[ ++P_buffer->i_index ] = p_mb;
165     vlc_mutex_unlock( &P_buffer->lock );
166 #undef P_buffer
167 }
168
169 /*****************************************************************************
170  * vpar_DestroyMacroblock : destroy a macroblock in case of error
171  *****************************************************************************/
172 void vpar_DestroyMacroblock( video_fifo_t * p_fifo, macroblock_t * p_mb )
173 {
174     /* Unlink referenced pictures */
175     if( p_mb->p_forw_top != NULL )
176     {
177         vout_UnlinkPicture( p_fifo->p_vpar.p_vout, p_mb->p_forw_top );
178     }
179     if( p_mb->p_backw_top != NULL )
180     {
181         vout_UnlinkPicture( p_fifo->p_vpar.p_vout, p_mb->p_backw_top );
182     }
183     if( p_mb->p_forw_bot != NULL )
184     {
185         vout_UnlinkPicture( p_fifo->p_vpar.p_vout, p_mb->p_forw_bot );
186     }
187     if( p_mb->p_backw_bot != NULL )
188     {
189         vout_UnlinkPicture( p_fifo->p_vpar.p_vout, p_mb->p_backw_bot );
190     }
191
192     /* Release the macroblock_t structure */
193 #define P_buffer p_fifo->p_vpar.vbuffer
194     vlc_mutex_lock( &P_buffer->lock );
195     P_buffer->pp_mb_free[ ++P_buffer->i_index ] = p_mb;
196     vlc_mutex_unlock( &P_buffer->lock );
197 #undef P_buffer
198 }