]> git.sesse.net Git - vlc/blob - src/video_parser/vpar_synchro.c
Am�lioration de la synchro.
[vlc] / src / video_parser / vpar_synchro.c
1 /*****************************************************************************
2  * vpar_motion.c : motion vectors parsing
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 "vpar_synchro.h"
37 #include "video_parser.h"
38 #include "video_fifo.h"
39
40 #define MAX_COUNT 3
41
42 /*
43  * Local prototypes
44  */
45
46 /*****************************************************************************
47  * vpar_SynchroUpdateTab : Update a mean table in the synchro structure
48  *****************************************************************************/
49 float vpar_SynchroUpdateTab( video_synchro_tab_t * tab, int count )
50 {
51         
52     tab->mean = ( tab->mean + MAX_COUNT * count ) / ( MAX_COUNT + 1 );
53     tab->deviation = ( tab->deviation + MAX_COUNT * abs (tab->mean - count) )
54                         / ( MAX_COUNT + 1 );
55
56     return tab->deviation;
57 }
58
59 /*****************************************************************************
60  * vpar_SynchroUpdateStructures : Update the synchro structures
61  *****************************************************************************/
62 void vpar_SynchroUpdateStructures( vpar_thread_t * p_vpar,
63                                    int i_coding_type, int dropped )
64 {
65     float candidate_deviation;
66     float optimal_deviation;
67     float predict;
68     mtime_t i_current_pts;
69     mtime_t i_delay;
70     mtime_t i_displaydate;
71     decoder_fifo_t * decoder_fifo = p_vpar->bit_stream.p_decoder_fifo;
72
73     /* interpolate the current _decode_ PTS */
74     i_current_pts = decoder_fifo->buffer[decoder_fifo->i_start]->b_has_pts ?
75                     decoder_fifo->buffer[decoder_fifo->i_start]->i_pts :
76                     0;
77     if( !i_current_pts )
78     {
79         i_current_pts = p_vpar->synchro.i_last_decode_pts
80                        + 1000000.0 / (1 + p_vpar->synchro.actual_fps);
81     }
82     p_vpar->synchro.i_last_decode_pts = i_current_pts;
83  
84     /* see if the current image has a pts - if not, set to 0 */
85     p_vpar->synchro.fifo[p_vpar->synchro.i_fifo_stop].i_pts
86             = i_current_pts;
87
88     /* update display time */
89     i_displaydate = decoder_fifo->buffer[decoder_fifo->i_start]->b_has_pts ?
90                     decoder_fifo->buffer[decoder_fifo->i_start]->i_pts :
91                     0;
92     if( !i_displaydate /* || i_coding_type != I_CODING_TYPE */ )
93     {
94         if (!p_vpar->synchro.i_images_since_pts )
95             p_vpar->synchro.i_images_since_pts = 10;
96
97         i_displaydate = p_vpar->synchro.i_last_display_pts
98                        + 1000000.0 / (p_vpar->synchro.theorical_fps);
99         //fprintf (stderr, "  ");
100     }
101     
102     /* else fprintf (stderr, "R ");
103     if (dropped) fprintf (stderr, "  "); else fprintf (stderr, "* ");
104     fprintf (stderr, "%i ", i_coding_type);
105     fprintf (stderr, "pts %lli delta %lli\n", i_displaydate, i_displaydate - p_vpar->synchro.i_last_display_pts); */
106
107     p_vpar->synchro.i_images_since_pts--;
108     p_vpar->synchro.i_last_display_pts = i_displaydate;
109
110
111
112     /* update structures */
113     switch(i_coding_type)
114     {
115         case P_CODING_TYPE:
116
117             p_vpar->synchro.current_p_count++;
118             if( !dropped ) p_vpar->synchro.nondropped_p_count++;
119             break;
120
121         case B_CODING_TYPE:
122             p_vpar->synchro.current_b_count++;
123             if( !dropped ) p_vpar->synchro.nondropped_b_count++;
124             break;
125
126         case I_CODING_TYPE:
127
128             /* update information about images we can decode */
129             if (i_current_pts != p_vpar->synchro.i_last_i_pts)
130             {
131                 if ( p_vpar->synchro.i_last_i_pts && i_current_pts != p_vpar->synchro.i_last_i_pts)
132                 {
133                     p_vpar->synchro.theorical_fps = (p_vpar->synchro.theorical_fps + 1000000.0 * (1 + p_vpar->synchro.current_b_count + p_vpar->synchro.current_p_count) / (i_current_pts - p_vpar->synchro.i_last_i_pts)) / 2;
134                 }
135                 p_vpar->synchro.i_last_i_pts = i_current_pts;
136             }
137
138             if( !dropped )
139             {
140                 if ( p_vpar->synchro.i_last_nondropped_i_pts && i_current_pts != p_vpar->synchro.i_last_nondropped_i_pts)
141                 {
142                     p_vpar->synchro.actual_fps = (p_vpar->synchro.actual_fps + 1000000.0 * (1 + p_vpar->synchro.nondropped_b_count + p_vpar->synchro.nondropped_p_count) / (i_current_pts - p_vpar->synchro.i_last_nondropped_i_pts)) / 2;
143                 }
144     
145             }
146
147
148             /* update all the structures for P images */
149
150             /* period == 1 */
151             optimal_deviation = vpar_SynchroUpdateTab(
152                             &p_vpar->synchro.tab_p[0],
153                             p_vpar->synchro.current_p_count);
154             predict = p_vpar->synchro.tab_p[0].mean;
155
156             /* period == 2 */
157             candidate_deviation = vpar_SynchroUpdateTab(
158                             &p_vpar->synchro.tab_p[1 + (p_vpar->synchro.modulo & 0x1)],
159                             p_vpar->synchro.current_p_count);
160             if (candidate_deviation < optimal_deviation)
161             {
162                 optimal_deviation = candidate_deviation;
163                 predict = p_vpar->synchro.tab_p[1 + (p_vpar->synchro.modulo & 0x1)].mean;
164             }
165
166             /* period == 3 */
167             candidate_deviation = vpar_SynchroUpdateTab(
168                             &p_vpar->synchro.tab_p[3 + (p_vpar->synchro.modulo % 3)],
169                             p_vpar->synchro.current_p_count);
170             if (candidate_deviation < optimal_deviation)
171             {
172                 optimal_deviation = candidate_deviation;
173                 predict = p_vpar->synchro.tab_p[1 + (p_vpar->synchro.modulo % 3)].mean;
174             }
175
176             p_vpar->synchro.p_count_predict = predict;
177             p_vpar->synchro.current_p_count = 0;
178
179
180             /* update all the structures for B images */
181
182             /* period == 1 */
183             optimal_deviation = vpar_SynchroUpdateTab(
184                             &p_vpar->synchro.tab_b[0],
185                             p_vpar->synchro.current_b_count);
186             predict = p_vpar->synchro.tab_b[0].mean;
187
188             /* period == 2 */
189             candidate_deviation = vpar_SynchroUpdateTab(
190                             &p_vpar->synchro.tab_b[1 + (p_vpar->synchro.modulo & 0x1)],
191                             p_vpar->synchro.current_b_count);
192             if (candidate_deviation < optimal_deviation)
193             {
194                 optimal_deviation = candidate_deviation;
195                 predict = p_vpar->synchro.tab_b[1 + (p_vpar->synchro.modulo & 0x1)].mean;
196             }
197
198             /* period == 3 */
199             candidate_deviation = vpar_SynchroUpdateTab(
200                             &p_vpar->synchro.tab_b[3 + (p_vpar->synchro.modulo % 3)],
201                             p_vpar->synchro.current_b_count);
202             if (candidate_deviation < optimal_deviation)
203             {
204                 optimal_deviation = candidate_deviation;
205                 predict = p_vpar->synchro.tab_b[1 + (p_vpar->synchro.modulo % 3)].mean;
206             }
207
208             p_vpar->synchro.b_count_predict = predict;
209             p_vpar->synchro.current_b_count = 0;
210             
211             /* now we calculated all statistics, it's time to
212              * decide what we have the time to display
213              */
214             i_delay = i_current_pts - p_vpar->synchro.i_last_nondropped_i_pts;
215
216             p_vpar->synchro.can_display_i
217                 = ( p_vpar->synchro.i_mean_decode_time < i_delay );
218
219             p_vpar->synchro.can_display_p
220                     = ( p_vpar->synchro.i_mean_decode_time
221                     * (1 + p_vpar->synchro.p_count_predict) < i_delay );
222
223             if( !p_vpar->synchro.can_display_p )
224             {
225                 p_vpar->synchro.displayable_p
226                     = -1 + i_delay / p_vpar->synchro.i_mean_decode_time;
227                 if( p_vpar->synchro.displayable_p < 0 )
228                     p_vpar->synchro.displayable_p = 0;
229             }
230             else
231                 p_vpar->synchro.displayable_p = 0;
232
233             if( p_vpar->synchro.can_display_p
234                 && !(p_vpar->synchro.can_display_b 
235                     = ( p_vpar->synchro.i_mean_decode_time
236                     * (1 + p_vpar->synchro.b_count_predict
237                         + p_vpar->synchro.p_count_predict)) < i_delay) )
238             {
239                 p_vpar->synchro.displayable_b
240                     = -2.0 + i_delay / p_vpar->synchro.i_mean_decode_time
241                         - p_vpar->synchro.can_display_p;
242             }
243             else
244                 p_vpar->synchro.displayable_b = 0;
245
246 #if 0
247             fprintf( stderr,
248                 "I %i  P %i (%f)  B %i (%f)\n",
249                 p_vpar->synchro.can_display_i,
250                 p_vpar->synchro.can_display_p,
251                 p_vpar->synchro.displayable_p,
252                 p_vpar->synchro.can_display_b,
253                 p_vpar->synchro.displayable_b );
254 #endif
255
256             /* update some values */
257             if( !dropped )
258             {
259                 p_vpar->synchro.i_last_nondropped_i_pts = i_current_pts;
260                 p_vpar->synchro.nondropped_p_count = 0;
261                 p_vpar->synchro.nondropped_b_count = 0;
262             }
263
264             break;
265
266     }
267
268     p_vpar->synchro.modulo++;
269
270 }
271
272 /*****************************************************************************
273  * vpar_SynchroChoose : Decide whether we will decode a picture or not
274  *****************************************************************************/
275 boolean_t vpar_SynchroChoose( vpar_thread_t * p_vpar, int i_coding_type,
276                               int i_structure )
277 {
278     mtime_t i_delay = p_vpar->synchro.i_last_decode_pts - mdate();
279
280     switch( i_coding_type )
281     {
282         case I_CODING_TYPE:
283
284             return( p_vpar->synchro.can_display_i );
285
286         case P_CODING_TYPE:
287
288             if( p_vpar->synchro.can_display_p )
289                 return( 1 );
290
291             if( p_vpar->synchro.displayable_p * i_delay
292                 < p_vpar->synchro.i_mean_decode_time )
293             {
294                 //fprintf( stderr, "trashed a P\n");
295                 return( 0 );
296             }
297
298             p_vpar->synchro.displayable_p--;
299             return( 1 );
300    
301         case B_CODING_TYPE:
302
303             if( p_vpar->synchro.can_display_b )
304                 return( 1 );
305
306             /* modulo & 0x3 is here to add some randomness */
307             if( i_delay < (1 + (p_vpar->synchro.modulo & 0x3))
308                 * p_vpar->synchro.i_mean_decode_time )
309             {
310                 //fprintf( stderr, "trashed a B\n");
311                 return( 0 );
312             }
313  
314             if( p_vpar->synchro.displayable_b <= 0 )
315                 return( 0 );
316
317             p_vpar->synchro.displayable_b--;
318             return( 1 );
319     }
320
321     return( 0 );
322
323 }
324
325 /*****************************************************************************
326  * vpar_SynchroTrash : Update timers when we trash a picture
327  *****************************************************************************/
328 void vpar_SynchroTrash( vpar_thread_t * p_vpar, int i_coding_type,
329                         int i_structure )
330 {
331     vpar_SynchroUpdateStructures (p_vpar, i_coding_type, 1);
332
333 }
334
335 /*****************************************************************************
336  * vpar_SynchroDecode : Update timers when we decide to decode a picture
337  *****************************************************************************/
338 void vpar_SynchroDecode( vpar_thread_t * p_vpar, int i_coding_type,
339                             int i_structure )
340 {
341     vpar_SynchroUpdateStructures (p_vpar, i_coding_type, 0);
342
343     p_vpar->synchro.fifo[p_vpar->synchro.i_fifo_stop].i_decode_date = mdate();
344     p_vpar->synchro.fifo[p_vpar->synchro.i_fifo_stop].i_image_type
345         = i_coding_type;
346
347     p_vpar->synchro.i_fifo_stop = (p_vpar->synchro.i_fifo_stop + 1) & 0xf;
348
349 }
350
351 /*****************************************************************************
352  * vpar_SynchroEnd : Called when the image is totally decoded
353  *****************************************************************************/
354 void vpar_SynchroEnd( vpar_thread_t * p_vpar )
355 {
356     mtime_t i_decode_time;
357
358     i_decode_time = (mdate() -
359             p_vpar->synchro.fifo[p_vpar->synchro.i_fifo_start].i_decode_date)
360         / (p_vpar->synchro.i_fifo_stop - p_vpar->synchro.i_fifo_start & 0x0f);
361
362     p_vpar->synchro.i_mean_decode_time =
363         ( 7 * p_vpar->synchro.i_mean_decode_time + i_decode_time ) / 8;
364
365     /* fprintf (stderr,
366         "decoding time was %lli\n",
367         p_vpar->synchro.i_mean_decode_time); */
368
369     p_vpar->synchro.i_fifo_start = (p_vpar->synchro.i_fifo_start + 1) & 0xf;
370
371 }
372
373 /*****************************************************************************
374  * vpar_SynchroDate : When an image has been decoded, ask for its date
375  *****************************************************************************/
376 mtime_t vpar_SynchroDate( vpar_thread_t * p_vpar )
377 {
378     mtime_t i_displaydate = p_vpar->synchro.i_last_display_pts;
379     
380 #if 0
381     static mtime_t i_delta = 0;
382
383     fprintf( stderr,
384         "displaying type %i with delay %lli and delta %lli\n",
385         p_vpar->synchro.fifo[p_vpar->synchro.i_fifo_start].i_image_type,
386         i_displaydate - mdate(),
387         i_displaydate - i_delta );
388
389     fprintf (stderr,
390         "theorical fps: %f - actual fps: %f \n",
391         p_vpar->synchro.theorical_fps, p_vpar->synchro.actual_fps );
392
393     i_delta = i_displaydate;
394 #endif
395
396     return i_displaydate;
397 }
398