]> git.sesse.net Git - vlc/blob - src/video_parser/video_fifo.c
. un chti peu plus de synchro video, mais c'est pas encore �a
[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
16 #include "config.h"
17 #include "common.h"
18 #include "mtime.h"
19 #include "vlc_thread.h"
20
21 #include "intf_msg.h"
22 #include "debug.h"                      /* ?? temporaire, requis par netlist.h */
23
24 #include "input.h"
25 #include "input_netlist.h"
26 #include "decoder_fifo.h"
27 #include "video.h"
28 #include "video_output.h"
29
30 #include "vdec_idct.h"
31 #include "video_decoder.h"
32 #include "vdec_motion.h"
33
34 #include "vpar_blocks.h"
35 #include "vpar_headers.h"
36 #include "video_fifo.h"
37 #include "vpar_synchro.h"
38 #include "video_parser.h"
39
40 /*****************************************************************************
41  * vpar_InitFIFO : initialize the video FIFO
42  *****************************************************************************/
43 void vpar_InitFIFO( vpar_thread_t * p_vpar )
44 {
45     int                 i_dummy;
46     
47     /* Initialize mutex and cond */
48     vlc_mutex_init( &p_vpar->vfifo.lock );
49     vlc_cond_init( &p_vpar->vfifo.wait );
50     vlc_mutex_init( &p_vpar->vbuffer.lock );
51     
52     /* Initialize FIFO properties */
53     p_vpar->vfifo.i_start = p_vpar->vfifo.i_end = 0;
54     p_vpar->vfifo.p_vpar = p_vpar;
55     
56     /* Initialize buffer properties */
57     p_vpar->vbuffer.i_index = VFIFO_SIZE; /* all structures are available */
58     for( i_dummy = 0; i_dummy < VFIFO_SIZE + 1; i_dummy++ )
59     {
60         p_vpar->vbuffer.pp_mb_free[i_dummy] = p_vpar->vbuffer.p_macroblocks
61                                                + i_dummy;
62     }
63 }
64
65 /*****************************************************************************
66  * vpar_GetMacroblock : return a macroblock to be decoded
67  *****************************************************************************/
68 macroblock_t * vpar_GetMacroblock( video_fifo_t * p_fifo )
69 {
70     macroblock_t *      p_mb;
71
72     vlc_mutex_lock( &p_fifo->lock );
73     while( VIDEO_FIFO_ISEMPTY( *p_fifo ) )
74     {
75         vlc_cond_wait( &p_fifo->wait, &p_fifo->lock );
76         if( p_fifo->p_vpar->b_die )
77         {
78             vlc_mutex_unlock( &p_fifo->lock );
79             return( NULL );
80         }
81     }
82     
83     p_mb = VIDEO_FIFO_START( *p_fifo );
84     VIDEO_FIFO_INCSTART( *p_fifo );
85
86     vlc_mutex_unlock( &p_fifo->lock );
87     
88     return( p_mb );
89 }
90
91 /*****************************************************************************
92  * vpar_NewMacroblock : return a buffer for the parser
93  *****************************************************************************/
94 macroblock_t * vpar_NewMacroblock( video_fifo_t * p_fifo )
95 {
96     macroblock_t *      p_mb;
97
98 #define P_buffer p_fifo->p_vpar->vbuffer
99     vlc_mutex_lock( &P_buffer.lock );
100     while( P_buffer.i_index == -1 )
101     {
102         /* No more structures available. This should not happen ! */
103         intf_DbgMsg("vpar debug: macroblock list is empty, delaying\n");
104         vlc_mutex_unlock( &P_buffer.lock );
105         msleep(VPAR_IDLE_SLEEP);
106         vlc_mutex_lock( &P_buffer.lock );
107     }
108
109     p_mb = P_buffer.pp_mb_free[ P_buffer.i_index-- ];
110
111     vlc_mutex_unlock( &P_buffer.lock );
112 #undef P_buffer
113     return( p_mb );
114 }
115
116 /*****************************************************************************
117  * vpar_DecodeMacroblock : put a macroblock in the video fifo
118  *****************************************************************************/
119 void vpar_DecodeMacroblock( video_fifo_t * p_fifo, macroblock_t * p_mb )
120 {
121     /* Place picture in the video FIFO */
122     vlc_mutex_lock( &p_fifo->lock );
123         
124     /* By construction, the video FIFO cannot be full */
125     VIDEO_FIFO_END( *p_fifo ) = p_mb;
126     VIDEO_FIFO_INCEND( *p_fifo );
127
128     vlc_mutex_unlock( &p_fifo->lock );
129 }
130
131 /*****************************************************************************
132  * vpar_ReleaseMacroblock : release a macroblock and put the picture in the
133  *                          video output heap, if it is finished
134  *****************************************************************************/
135 void vpar_ReleaseMacroblock( video_fifo_t * p_fifo, macroblock_t * p_mb )
136 {
137     boolean_t      b_finished;
138
139     /* Unlink picture buffer */
140     vlc_mutex_lock( &p_mb->p_picture->lock_deccount );
141     p_mb->p_picture->i_deccount--;
142     b_finished = (p_mb->p_picture->i_deccount == 1);
143     vlc_mutex_unlock( &p_mb->p_picture->lock_deccount );
144 //fprintf(stderr, "%d ", p_mb->p_picture->i_deccount);
145     /* Test if it was the last block of the picture */
146     if( b_finished )
147     {
148 //fprintf(stderr, "Image decodee\n");
149         /* Mark the picture to be displayed */
150         vout_DisplayPicture( p_fifo->p_vpar->p_vout, p_mb->p_picture );
151
152         /* Warn Synchro for its records. */
153         vpar_SynchroEnd( p_fifo->p_vpar );
154      
155         /* Unlink referenced pictures */
156         if( p_mb->p_forward != NULL )
157         {
158                 vout_UnlinkPicture( p_fifo->p_vpar->p_vout, p_mb->p_forward );
159         }
160         if( p_mb->p_backward != NULL )
161         {
162             vout_UnlinkPicture( p_fifo->p_vpar->p_vout, p_mb->p_backward );
163         }
164     }
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     boolean_t       b_finished;
180
181     /* Unlink picture buffer */
182     vlc_mutex_lock( &p_mb->p_picture->lock_deccount );
183     p_mb->p_picture->i_deccount--;
184     b_finished = (p_mb->p_picture->i_deccount == 0);
185     vlc_mutex_unlock( &p_mb->p_picture->lock_deccount );
186
187     /* Test if it was the last block of the picture */
188     if( b_finished )
189     {
190 fprintf(stderr, "Image trashee\n");
191         /* Mark the picture to be displayed */
192         vout_DestroyPicture( p_fifo->p_vpar->p_vout, p_mb->p_picture );
193
194         /* Warn Synchro for its records. */
195         vpar_SynchroEnd( p_fifo->p_vpar );
196
197         /* Unlink referenced pictures */
198         if( p_mb->p_forward != NULL )
199         {
200             vout_UnlinkPicture( p_fifo->p_vpar->p_vout, p_mb->p_forward );
201         }
202         if( p_mb->p_backward != NULL )
203         {
204             vout_UnlinkPicture( p_fifo->p_vpar->p_vout, p_mb->p_backward );
205         }
206     }
207
208     /* Release the macroblock_t structure */
209 #define P_buffer p_fifo->p_vpar->vbuffer
210     vlc_mutex_lock( &P_buffer.lock );
211     P_buffer.pp_mb_free[ ++P_buffer.i_index ] = p_mb;
212     vlc_mutex_unlock( &P_buffer.lock );
213 #undef P_buffer
214 }