]> git.sesse.net Git - vlc/blob - src/video_parser/vpar_synchro.c
Encore un commit venu tout droit des abysses de l'enfer, d�sol� pour
[vlc] / src / video_parser / vpar_synchro.c
1 /*****************************************************************************
2  * vpar_motion.c : motion vectors parsing
3  *****************************************************************************
4  * Copyright (C) 1999, 2000 VideoLAN
5  *
6  * Authors:
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public
19  * License along with this program; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <stdlib.h>                                                /* free() */
28 #include <sys/types.h>                        /* on BSD, uio.h needs types.h */
29 #include <sys/uio.h>                                            /* "input.h" */
30
31 #include "config.h"
32 #include "common.h"
33 #include "mtime.h"
34 #include "threads.h"
35
36 #include "intf_msg.h"
37
38 #include "input.h"
39 #include "decoder_fifo.h"
40 #include "video.h"
41 #include "video_output.h"
42
43 #include "vdec_idct.h"
44 #include "video_decoder.h"
45 #include "vdec_motion.h"
46
47 #include "vpar_blocks.h"
48 #include "vpar_headers.h"
49 #include "vpar_synchro.h"
50 #include "video_parser.h"
51
52 #define MAX_COUNT 3
53
54 /*
55  * Local prototypes
56  */
57
58 #ifdef SAM_SYNCHRO
59 /*****************************************************************************
60  * vpar_SynchroUpdateTab : Update a mean table in the synchro structure
61  *****************************************************************************/
62 float vpar_SynchroUpdateTab( video_synchro_tab_t * tab, int count )
63 {
64
65     tab->mean = ( tab->mean + MAX_COUNT * count ) / ( MAX_COUNT + 1 );
66     tab->deviation = ( tab->deviation + MAX_COUNT * abs (tab->mean - count) )
67                         / ( MAX_COUNT + 1 );
68
69     return tab->deviation;
70 }
71
72 /*****************************************************************************
73  * vpar_SynchroUpdateStructures : Update the synchro structures
74  *****************************************************************************/
75 void vpar_SynchroUpdateStructures( vpar_thread_t * p_vpar,
76                                    int i_coding_type, int dropped )
77 {
78     float candidate_deviation;
79     float optimal_deviation;
80     float predict;
81     mtime_t i_current_pts;
82     mtime_t i_delay;
83     mtime_t i_displaydate;
84     decoder_fifo_t * decoder_fifo = p_vpar->bit_stream.p_decoder_fifo;
85
86     /* interpolate the current _decode_ PTS */
87     i_current_pts = decoder_fifo->buffer[decoder_fifo->i_start]->b_has_pts ?
88                     decoder_fifo->buffer[decoder_fifo->i_start]->i_pts :
89                     0;
90     if( !i_current_pts )
91     {
92         i_current_pts = p_vpar->synchro.i_last_decode_pts
93                        + 1000000.0 / (1 + p_vpar->synchro.actual_fps);
94     }
95     p_vpar->synchro.i_last_decode_pts = i_current_pts;
96
97     /* see if the current image has a pts - if not, set to 0 */
98     p_vpar->synchro.fifo[p_vpar->synchro.i_fifo_stop].i_pts
99             = i_current_pts;
100
101     /* update display time */
102     i_displaydate = decoder_fifo->buffer[decoder_fifo->i_start]->b_has_pts ?
103                     decoder_fifo->buffer[decoder_fifo->i_start]->i_pts :
104                     0;
105     if( !i_displaydate || i_coding_type != I_CODING_TYPE )
106     {
107         if (!p_vpar->synchro.i_images_since_pts )
108             p_vpar->synchro.i_images_since_pts = 10;
109
110         i_displaydate = p_vpar->synchro.i_last_display_pts
111                        + 1000000.0 / (p_vpar->synchro.theorical_fps);
112         //fprintf (stderr, "  ");
113     }
114
115     decoder_fifo->buffer[decoder_fifo->i_start]->b_has_pts = 0;
116
117     /* else fprintf (stderr, "R ");
118     if (dropped) fprintf (stderr, "  "); else fprintf (stderr, "* ");
119     fprintf (stderr, "%i ", i_coding_type);
120     fprintf (stderr, "pts %lli delta %lli\n", i_displaydate, i_displaydate - p_vpar->synchro.i_last_display_pts); */
121
122     p_vpar->synchro.i_images_since_pts--;
123     p_vpar->synchro.i_last_display_pts = i_displaydate;
124
125
126
127     /* update structures */
128     switch(i_coding_type)
129     {
130         case P_CODING_TYPE:
131
132             p_vpar->synchro.current_p_count++;
133             if( !dropped ) p_vpar->synchro.nondropped_p_count++;
134             break;
135
136         case B_CODING_TYPE:
137             p_vpar->synchro.current_b_count++;
138             if( !dropped ) p_vpar->synchro.nondropped_b_count++;
139             break;
140
141         case I_CODING_TYPE:
142
143             /* update information about images we can decode */
144             if (i_current_pts != p_vpar->synchro.i_last_i_pts)
145             {
146                 if ( p_vpar->synchro.i_last_i_pts && i_current_pts != p_vpar->synchro.i_last_i_pts)
147                 {
148                     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;
149                 }
150                 p_vpar->synchro.i_last_i_pts = i_current_pts;
151             }
152
153             if( !dropped )
154             {
155                 if ( p_vpar->synchro.i_last_nondropped_i_pts && i_current_pts != p_vpar->synchro.i_last_nondropped_i_pts)
156                 {
157                     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;
158                 }
159
160             }
161
162
163             /* update all the structures for P images */
164
165             /* period == 1 */
166             optimal_deviation = vpar_SynchroUpdateTab(
167                             &p_vpar->synchro.tab_p[0],
168                             p_vpar->synchro.current_p_count);
169             predict = p_vpar->synchro.tab_p[0].mean;
170
171             /* period == 2 */
172             candidate_deviation = vpar_SynchroUpdateTab(
173                             &p_vpar->synchro.tab_p[1 + (p_vpar->synchro.modulo & 0x1)],
174                             p_vpar->synchro.current_p_count);
175             if (candidate_deviation < optimal_deviation)
176             {
177                 optimal_deviation = candidate_deviation;
178                 predict = p_vpar->synchro.tab_p[1 + (p_vpar->synchro.modulo & 0x1)].mean;
179             }
180
181             /* period == 3 */
182             candidate_deviation = vpar_SynchroUpdateTab(
183                             &p_vpar->synchro.tab_p[3 + (p_vpar->synchro.modulo % 3)],
184                             p_vpar->synchro.current_p_count);
185             if (candidate_deviation < optimal_deviation)
186             {
187                 optimal_deviation = candidate_deviation;
188                 predict = p_vpar->synchro.tab_p[1 + (p_vpar->synchro.modulo % 3)].mean;
189             }
190
191             p_vpar->synchro.p_count_predict = predict;
192             p_vpar->synchro.current_p_count = 0;
193
194
195             /* update all the structures for B images */
196
197             /* period == 1 */
198             optimal_deviation = vpar_SynchroUpdateTab(
199                             &p_vpar->synchro.tab_b[0],
200                             p_vpar->synchro.current_b_count);
201             predict = p_vpar->synchro.tab_b[0].mean;
202
203             /* period == 2 */
204             candidate_deviation = vpar_SynchroUpdateTab(
205                             &p_vpar->synchro.tab_b[1 + (p_vpar->synchro.modulo & 0x1)],
206                             p_vpar->synchro.current_b_count);
207             if (candidate_deviation < optimal_deviation)
208             {
209                 optimal_deviation = candidate_deviation;
210                 predict = p_vpar->synchro.tab_b[1 + (p_vpar->synchro.modulo & 0x1)].mean;
211             }
212
213             /* period == 3 */
214             candidate_deviation = vpar_SynchroUpdateTab(
215                             &p_vpar->synchro.tab_b[3 + (p_vpar->synchro.modulo % 3)],
216                             p_vpar->synchro.current_b_count);
217             if (candidate_deviation < optimal_deviation)
218             {
219                 optimal_deviation = candidate_deviation;
220                 predict = p_vpar->synchro.tab_b[1 + (p_vpar->synchro.modulo % 3)].mean;
221             }
222
223             p_vpar->synchro.b_count_predict = predict;
224             p_vpar->synchro.current_b_count = 0;
225
226             /* now we calculated all statistics, it's time to
227              * decide what we have the time to display
228              */
229             i_delay = i_current_pts - p_vpar->synchro.i_last_nondropped_i_pts;
230
231             p_vpar->synchro.can_display_i
232                 = ( p_vpar->synchro.i_mean_decode_time < i_delay );
233
234             p_vpar->synchro.can_display_p
235                     = ( p_vpar->synchro.i_mean_decode_time
236                     * (1 + p_vpar->synchro.p_count_predict) < i_delay );
237
238             if( !p_vpar->synchro.can_display_p )
239             {
240                 p_vpar->synchro.displayable_p
241                     = -1 + i_delay / p_vpar->synchro.i_mean_decode_time;
242                 if( p_vpar->synchro.displayable_p < 0 )
243                     p_vpar->synchro.displayable_p = 0;
244             }
245             else
246                 p_vpar->synchro.displayable_p = 0;
247
248             if( p_vpar->synchro.can_display_p
249                 && !(p_vpar->synchro.can_display_b
250                     = ( p_vpar->synchro.i_mean_decode_time
251                     * (1 + p_vpar->synchro.b_count_predict
252                         + p_vpar->synchro.p_count_predict)) < i_delay) )
253             {
254                 p_vpar->synchro.displayable_b
255                     = -2.0 + i_delay / p_vpar->synchro.i_mean_decode_time
256                         - p_vpar->synchro.can_display_p;
257             }
258             else
259                 p_vpar->synchro.displayable_b = 0;
260
261 #if 0
262             fprintf( stderr,
263                 "I %i  P %i (%f)  B %i (%f)\n",
264                 p_vpar->synchro.can_display_i,
265                 p_vpar->synchro.can_display_p,
266                 p_vpar->synchro.displayable_p,
267                 p_vpar->synchro.can_display_b,
268                 p_vpar->synchro.displayable_b );
269 #endif
270
271             /* update some values */
272             if( !dropped )
273             {
274                 p_vpar->synchro.i_last_nondropped_i_pts = i_current_pts;
275                 p_vpar->synchro.nondropped_p_count = 0;
276                 p_vpar->synchro.nondropped_b_count = 0;
277             }
278
279             break;
280
281     }
282
283     p_vpar->synchro.modulo++;
284
285 }
286
287 /*****************************************************************************
288  * vpar_SynchroChoose : Decide whether we will decode a picture or not
289  *****************************************************************************/
290 boolean_t vpar_SynchroChoose( vpar_thread_t * p_vpar, int i_coding_type,
291                               int i_structure )
292 {
293     mtime_t i_delay = p_vpar->synchro.i_last_decode_pts - mdate();
294
295     switch( i_coding_type )
296     {
297         case I_CODING_TYPE:
298
299             return( p_vpar->synchro.can_display_i );
300
301         case P_CODING_TYPE:
302
303             if( p_vpar->synchro.can_display_p )
304                 return( 1 );
305
306             if( p_vpar->synchro.displayable_p * i_delay
307                 < p_vpar->synchro.i_mean_decode_time )
308             {
309                 //fprintf( stderr, "trashed a P\n");
310                 return( 0 );
311             }
312
313             p_vpar->synchro.displayable_p--;
314             return( 1 );
315
316         case B_CODING_TYPE:
317
318             if( p_vpar->synchro.can_display_b )
319                 return( 1 );
320
321             /* modulo & 0x3 is here to add some randomness */
322             if( i_delay < (1 + (p_vpar->synchro.modulo & 0x3))
323                 * p_vpar->synchro.i_mean_decode_time )
324             {
325                 //fprintf( stderr, "trashed a B\n");
326                 return( 0 );
327             }
328
329             if( p_vpar->synchro.displayable_b <= 0 )
330                 return( 0 );
331
332             p_vpar->synchro.displayable_b--;
333             return( 1 );
334     }
335
336     return( 0 );
337
338 }
339
340 /*****************************************************************************
341  * vpar_SynchroTrash : Update timers when we trash a picture
342  *****************************************************************************/
343 void vpar_SynchroTrash( vpar_thread_t * p_vpar, int i_coding_type,
344                         int i_structure )
345 {
346     vpar_SynchroUpdateStructures (p_vpar, i_coding_type, 1);
347
348 }
349
350 /*****************************************************************************
351  * vpar_SynchroDecode : Update timers when we decide to decode a picture
352  *****************************************************************************/
353 void vpar_SynchroDecode( vpar_thread_t * p_vpar, int i_coding_type,
354                             int i_structure )
355 {
356     vpar_SynchroUpdateStructures (p_vpar, i_coding_type, 0);
357
358     p_vpar->synchro.fifo[p_vpar->synchro.i_fifo_stop].i_decode_date = mdate();
359     p_vpar->synchro.fifo[p_vpar->synchro.i_fifo_stop].i_image_type
360         = i_coding_type;
361
362     p_vpar->synchro.i_fifo_stop = (p_vpar->synchro.i_fifo_stop + 1) & 0xf;
363
364 }
365
366 /*****************************************************************************
367  * vpar_SynchroEnd : Called when the image is totally decoded
368  *****************************************************************************/
369 void vpar_SynchroEnd( vpar_thread_t * p_vpar )
370 {
371     mtime_t i_decode_time;
372
373     i_decode_time = (mdate() -
374             p_vpar->synchro.fifo[p_vpar->synchro.i_fifo_start].i_decode_date)
375         / ( (p_vpar->synchro.i_fifo_stop - p_vpar->synchro.i_fifo_start) & 0x0f);
376
377     p_vpar->synchro.i_mean_decode_time =
378         ( 7 * p_vpar->synchro.i_mean_decode_time + i_decode_time ) / 8;
379
380     /* fprintf (stderr,
381         "decoding time was %lli\n",
382         p_vpar->synchro.i_mean_decode_time); */
383
384     p_vpar->synchro.i_fifo_start = (p_vpar->synchro.i_fifo_start + 1) & 0xf;
385
386 }
387
388 /*****************************************************************************
389  * vpar_SynchroDate : When an image has been decoded, ask for its date
390  *****************************************************************************/
391 mtime_t vpar_SynchroDate( vpar_thread_t * p_vpar )
392 {
393     mtime_t i_displaydate = p_vpar->synchro.i_last_display_pts;
394
395 #if 0
396     static mtime_t i_delta = 0;
397
398     fprintf( stderr,
399         "displaying type %i with delay %lli and delta %lli\n",
400         p_vpar->synchro.fifo[p_vpar->synchro.i_fifo_start].i_image_type,
401         i_displaydate - mdate(),
402         i_displaydate - i_delta );
403
404     fprintf (stderr,
405         "theorical fps: %f - actual fps: %f \n",
406         p_vpar->synchro.theorical_fps, p_vpar->synchro.actual_fps );
407
408     i_delta = i_displaydate;
409 #endif
410
411     return i_displaydate;
412 }
413
414 #endif
415
416 #ifdef MEUUH_SYNCHRO
417
418 /* synchro a deux balles backportee du decodeur de reference. NE MARCHE PAS
419 AVEC LES IMAGES MONOTRAMES */
420
421 boolean_t vpar_SynchroChoose( vpar_thread_t * p_vpar, int i_coding_type,
422                               int i_structure )
423 {
424     switch (i_coding_type)
425     {
426     case B_CODING_TYPE:
427         if ((p_vpar->synchro.kludge_level <= p_vpar->synchro.kludge_nbp))
428         {
429             p_vpar->synchro.kludge_b++;
430             return( 0 );
431         }
432         if (p_vpar->synchro.kludge_b %
433              (p_vpar->synchro.kludge_nbb /
434                 (p_vpar->synchro.kludge_level - p_vpar->synchro.kludge_nbp)))
435         {
436             p_vpar->synchro.kludge_b++;
437             return( 0 );
438         }
439         p_vpar->synchro.kludge_b++;
440         return( 1 );
441
442     case P_CODING_TYPE:
443         if (p_vpar->synchro.kludge_p++ >= p_vpar->synchro.kludge_level)
444         {
445             return( 0 );
446         }
447         return( 1 );
448
449     default:
450         return( 1 );
451     }
452 }
453
454 void vpar_SynchroTrash( vpar_thread_t * p_vpar, int i_coding_type,
455                         int i_structure )
456 {
457     if (DECODER_FIFO_START(p_vpar->fifo)->b_has_pts && i_coding_type == I_CODING_TYPE)
458     {
459         p_vpar->synchro.kludge_nbframes = 0;
460         p_vpar->synchro.kludge_date = DECODER_FIFO_START(p_vpar->fifo)->i_pts;
461     }
462     else
463         p_vpar->synchro.kludge_nbframes++;
464     DECODER_FIFO_START(p_vpar->fifo)->b_has_pts = 0;
465 }
466
467 void vpar_SynchroDecode( vpar_thread_t * p_vpar, int i_coding_type,
468                             int i_structure )
469 {
470     if (DECODER_FIFO_START(p_vpar->fifo)->b_has_pts && i_coding_type == I_CODING_TYPE)
471     {
472         p_vpar->synchro.kludge_nbframes = 0;
473         p_vpar->synchro.kludge_date = DECODER_FIFO_START(p_vpar->fifo)->i_pts;
474         DECODER_FIFO_START(p_vpar->fifo)->b_has_pts = 0;
475     }
476     else
477         p_vpar->synchro.kludge_nbframes++;
478 }
479
480 mtime_t vpar_SynchroDate( vpar_thread_t * p_vpar )
481 {
482     return( p_vpar->synchro.kludge_date
483             + p_vpar->synchro.kludge_nbframes*1000000/(p_vpar->sequence.r_frame_rate ) );
484 }
485
486 void vpar_SynchroEnd( vpar_thread_t * p_vpar )
487 {
488 }
489
490 void vpar_SynchroKludge( vpar_thread_t * p_vpar, mtime_t date )
491 {
492     mtime_t     show_date;
493     int         temp = p_vpar->synchro.kludge_level;
494
495     p_vpar->synchro.kludge_nbp = p_vpar->synchro.kludge_p ? p_vpar->synchro.kludge_p : 5;
496     p_vpar->synchro.kludge_nbb = p_vpar->synchro.kludge_b ? p_vpar->synchro.kludge_b : 6;
497     show_date = date - mdate();
498     p_vpar->synchro.kludge_p = 0;
499     p_vpar->synchro.kludge_b = 0;
500
501     if (show_date < (SYNC_DELAY - SYNC_TOLERATE) && show_date <= p_vpar->synchro.kludge_prevdate)
502     {
503         p_vpar->synchro.kludge_level--;
504         if (p_vpar->synchro.kludge_level < 0)
505             p_vpar->synchro.kludge_level = 0;
506         else if (p_vpar->synchro.kludge_level >
507                      p_vpar->synchro.kludge_nbp + p_vpar->synchro.kludge_nbb)
508             p_vpar->synchro.kludge_level = p_vpar->synchro.kludge_nbp + p_vpar->synchro.kludge_nbb;
509 #ifdef DEBUG
510         if (temp != p_vpar->synchro.kludge_level)
511             intf_DbgMsg("vdec debug: Level changed from %d to %d (%Ld)\n",
512                         temp, p_vpar->synchro.kludge_level, show_date );
513 #endif
514     }
515     else if (show_date > (SYNC_DELAY + SYNC_TOLERATE) && show_date >= p_vpar->synchro.kludge_prevdate)
516     {
517         p_vpar->synchro.kludge_level++;
518         if (p_vpar->synchro.kludge_level > p_vpar->synchro.kludge_nbp + p_vpar->synchro.kludge_nbb)
519             p_vpar->synchro.kludge_level = p_vpar->synchro.kludge_nbp + p_vpar->synchro.kludge_nbb;
520 #ifdef DEBUG
521         if (temp != p_vpar->synchro.kludge_level)
522             intf_DbgMsg("vdec debug: Level changed from %d to %d (%Ld)\n",
523                         temp, p_vpar->synchro.kludge_level, show_date );
524 #endif
525     }
526
527     p_vpar->synchro.kludge_prevdate = show_date;
528     if ((p_vpar->synchro.kludge_level - p_vpar->synchro.kludge_nbp) > p_vpar->synchro.kludge_nbb)
529         p_vpar->synchro.kludge_level = p_vpar->synchro.kludge_nbb + p_vpar->synchro.kludge_nbp;
530 }
531
532 #endif
533
534
535 #ifdef POLUX_SYNCHRO
536
537 void vpar_SynchroSetCurrentDate( vpar_thread_t * p_vpar, int i_coding_type )
538 {
539     pes_packet_t * p_pes =
540         p_vpar->bit_stream.p_decoder_fifo->buffer[p_vpar->bit_stream.p_decoder_fifo->i_start];
541
542
543     switch( i_coding_type )
544     {
545     case B_CODING_TYPE:
546         if( p_pes->b_has_pts )
547         {
548             if( p_pes->i_pts < p_vpar->synchro.i_current_frame_date )
549             {
550                 intf_ErrMsg( "vpar warning: pts_date < current_date\n" );
551             }
552             p_vpar->synchro.i_current_frame_date = p_pes->i_pts;
553             p_pes->b_has_pts = 0;
554         }
555         else
556         {
557             p_vpar->synchro.i_current_frame_date += 1000000/(p_vpar->sequence.r_frame_rate);
558         }
559         break;
560
561     default:
562
563         if( p_vpar->synchro.i_backward_frame_date == 0 )
564         {
565             p_vpar->synchro.i_current_frame_date += 1000000/(p_vpar->sequence.r_frame_rate);
566         }
567         else
568         {
569             if( p_vpar->synchro.i_backward_frame_date < p_vpar->synchro.i_current_frame_date )
570             {
571                 intf_ErrMsg( "vpar warning: backward_date < current_date (%Ld)\n",
572                          p_vpar->synchro.i_backward_frame_date - p_vpar->synchro.i_current_frame_date );
573             }
574             p_vpar->synchro.i_current_frame_date = p_vpar->synchro.i_backward_frame_date;
575             p_vpar->synchro.i_backward_frame_date = 0;
576         }
577
578         if( p_pes->b_has_pts )
579         {
580             p_vpar->synchro.i_backward_frame_date = p_pes->i_pts;
581             p_pes->b_has_pts = 0;
582         }
583        break;
584     }
585 }
586
587 boolean_t vpar_SynchroChoose( vpar_thread_t * p_vpar, int i_coding_type,
588                               int i_structure )
589 {
590     boolean_t b_result = 1;
591     int i_synchro_level = p_vpar->p_vout->i_synchro_level;
592
593     vpar_SynchroSetCurrentDate( p_vpar, i_coding_type );
594
595     /*
596      * The synchro level is updated by the video input (see SynchroLevelUpdate)
597      * so we just use the synchro_level to decide which frame to trash
598      */
599
600     switch( i_coding_type )
601     {
602     case I_CODING_TYPE:
603
604 //fprintf( stderr, "p : %d (%d), b : %d (%d)\n", p_vpar->synchro.i_p_count, p_vpar->synchro.i_p_nb,
605 //         p_vpar->synchro.i_b_count, p_vpar->synchro.i_b_nb );
606
607         p_vpar->synchro.r_p_average =
608             (p_vpar->synchro.r_p_average*(SYNC_AVERAGE_COUNT-1)+p_vpar->synchro.i_p_count)/SYNC_AVERAGE_COUNT;
609         p_vpar->synchro.r_b_average =
610             (p_vpar->synchro.r_b_average*(SYNC_AVERAGE_COUNT-1)+p_vpar->synchro.i_b_count)/SYNC_AVERAGE_COUNT;
611
612         p_vpar->synchro.i_p_nb = (int)(p_vpar->synchro.r_p_average+0.5);
613         p_vpar->synchro.i_b_nb = (int)(p_vpar->synchro.r_b_average+0.5);
614
615         p_vpar->synchro.i_p_count = p_vpar->synchro.i_b_count = 0;
616         p_vpar->synchro.i_b_trasher = p_vpar->synchro.i_b_nb / 2;
617         p_vpar->synchro.i_i_count++;
618        break;
619
620     case P_CODING_TYPE:
621         p_vpar->synchro.i_p_count++;
622         if( p_vpar->synchro.i_p_count > i_synchro_level )
623         {
624             b_result = 0;
625         }
626         break;
627
628     case B_CODING_TYPE:
629         p_vpar->synchro.i_b_count++;
630         if( p_vpar->synchro.i_p_nb >= i_synchro_level )
631         {
632             /* We must trash all the B */
633             b_result = 0;
634         }
635         else
636         {
637             /* We use the brensenham algorithm to decide which B to trash */
638             p_vpar->synchro.i_b_trasher +=
639                 p_vpar->synchro.i_b_nb - (i_synchro_level-p_vpar->synchro.i_p_nb);
640             if( p_vpar->synchro.i_b_trasher >= p_vpar->synchro.i_b_nb )
641             {
642                 b_result = 0;
643                 p_vpar->synchro.i_b_trasher -= p_vpar->synchro.i_b_nb;
644             }
645         }
646         break;
647     }
648
649     return( b_result );
650 }
651
652 void vpar_SynchroTrash( vpar_thread_t * p_vpar, int i_coding_type,
653                         int i_structure )
654 {
655     vpar_SynchroChoose( p_vpar, i_coding_type, i_structure );
656 }
657
658 void vpar_SynchroUpdateLevel()
659 {
660     //vlc_mutex_lock( &level_lock );
661     //vlc_mutex_unlock( &level_lock );
662 }
663
664 mtime_t vpar_SynchroDate( vpar_thread_t * p_vpar )
665 {
666 //fprintf( stderr, "delay : %Ld\n" , mdate() - p_vpar->synchro.i_current_frame_date );
667     return( p_vpar->synchro.i_current_frame_date );
668 }
669
670 /* functions with no use */
671
672 void vpar_SynchroEnd( vpar_thread_t * p_vpar )
673 {
674 }
675
676 void vpar_SynchroDecode( vpar_thread_t * p_vpar, int i_coding_type,
677                             int i_structure )
678 {
679 }
680
681 #endif