]> git.sesse.net Git - vlc/blob - src/video_parser/vpar_synchro.c
. rajout de l'option -Winline
[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
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
21  *****************************************************************************/
22
23 /*****************************************************************************
24  * Preamble
25  *****************************************************************************/
26 #include "defs.h"
27
28 #include <stdlib.h>                                                /* free() */
29 #include <sys/types.h>                        /* on BSD, uio.h needs types.h */
30 #include <sys/uio.h>                                            /* "input.h" */
31
32 #include "config.h"
33 #include "common.h"
34 #include "threads.h"
35 #include "mtime.h"
36 #include "plugins.h"
37
38 #include "intf_msg.h"
39
40 #include "input.h"
41 #include "decoder_fifo.h"
42 #include "video.h"
43 #include "video_output.h"
44
45 #include "vdec_idct.h"
46 #include "video_decoder.h"
47 #include "vdec_motion.h"
48
49 #include "vpar_blocks.h"
50 #include "vpar_headers.h"
51 #include "vpar_synchro.h"
52 #include "video_parser.h"
53
54 #define MAX_COUNT 3
55
56 /*
57  * Local prototypes
58  */
59
60 #ifdef SAM_SYNCHRO
61
62 /*****************************************************************************
63  * vpar_SynchroUpdateStructures : Update the synchro structures
64  *****************************************************************************/
65 void vpar_SynchroUpdateStructures( vpar_thread_t * p_vpar,
66                                    int i_coding_type, boolean_t b_kept )
67 {
68     double          i_can_display;
69     mtime_t         i_pts;
70     pes_packet_t *  p_pes = p_vpar->bit_stream.p_decoder_fifo->buffer[
71                                p_vpar->bit_stream.p_decoder_fifo->i_start ];
72
73     /* try to guess the current DTS and PTS */
74     if( p_pes->b_has_pts )
75     {
76         i_pts = p_pes->i_pts;
77
78         /* if the image is I type, then the presentation timestamp is
79          * the PTS of the PES. Otherwise, we calculate it with the
80          * theorical framerate value */
81         if( i_coding_type == I_CODING_TYPE )
82         {
83             p_vpar->synchro.i_last_pts = p_pes->i_pts;
84         }
85         else
86         {
87             p_vpar->synchro.i_last_pts += p_vpar->synchro.i_theorical_delay;
88         }
89
90         p_pes->b_has_pts = 0;
91     }
92     else
93     {
94         p_vpar->synchro.i_last_pts += p_vpar->synchro.i_theorical_delay;
95         i_pts = p_vpar->synchro.i_last_pts;
96     }
97
98     /* update structures */
99     switch(i_coding_type)
100     {
101         case P_CODING_TYPE:
102
103             p_vpar->synchro.i_P_seen++;
104             if( b_kept ) p_vpar->synchro.i_P_kept++;
105             break;
106
107         case B_CODING_TYPE:
108             p_vpar->synchro.i_B_seen++;
109             if( b_kept ) p_vpar->synchro.i_B_kept++;
110             break;
111
112         case I_CODING_TYPE:
113
114             /* update the last I PTS we have, we need it to
115              * calculate the theorical framerate */
116             if (i_pts != p_vpar->synchro.i_last_seen_I_pts)
117             {
118                 if ( p_vpar->synchro.i_last_seen_I_pts )
119                 {
120                     p_vpar->synchro.i_theorical_delay =
121                             ( i_pts - p_vpar->synchro.i_last_seen_I_pts )
122                           / ( 1 + p_vpar->synchro.i_B_seen
123                                 + p_vpar->synchro.i_P_seen);
124                 }
125                 p_vpar->synchro.i_last_seen_I_pts = i_pts;
126             }
127
128             /* now we calculated all statistics, it's time to
129              * decide what we have the time to display */
130             i_can_display = (float)(i_pts - p_vpar->synchro.i_last_kept_I_pts)
131                                 / p_vpar->synchro.i_delay;
132
133             p_vpar->synchro.b_all_I = 0;
134             p_vpar->synchro.b_all_B = 0;
135             p_vpar->synchro.b_all_P = 0;
136             p_vpar->synchro.displayable_p = 0;
137             p_vpar->synchro.displayable_b = 0;
138
139             if( ( p_vpar->synchro.b_all_I = ( i_can_display > 1 ) ) )
140             {
141                 i_can_display -= 1;
142
143                 if( !( p_vpar->synchro.b_all_P
144                         = ( i_can_display > p_vpar->synchro.i_P_seen ) ) )
145                 {
146                     p_vpar->synchro.displayable_p = i_can_display;
147                 }
148                 else
149                 {
150                     i_can_display -= p_vpar->synchro.i_P_seen;
151
152                     if( !( p_vpar->synchro.b_all_B
153                             = ( i_can_display > p_vpar->synchro.i_B_seen ) ) )
154                     {
155                         p_vpar->synchro.displayable_b = i_can_display;
156                     }
157                 }
158             }
159
160 #if 1
161             if( p_vpar->synchro.b_all_I )
162                 intf_ErrMsg( " I: 1/1  " );
163             if( p_vpar->synchro.b_all_P )
164                 intf_ErrMsg( "P: %i/%i  ", p_vpar->synchro.i_P_seen,
165                                            p_vpar->synchro.i_P_seen );
166             else if( p_vpar->synchro.displayable_p > 0 )
167                 intf_ErrMsg( "P: %.2f/%i  ", p_vpar->synchro.displayable_p,
168                                              p_vpar->synchro.i_P_seen );
169             if( p_vpar->synchro.b_all_B )
170                 intf_ErrMsg( "B: %i/%i", p_vpar->synchro.i_B_seen,
171                                          p_vpar->synchro.i_B_seen );
172             else if( p_vpar->synchro.displayable_b > 0 )
173                 intf_ErrMsg( "B: %.2f/%i", p_vpar->synchro.displayable_b,
174                                            p_vpar->synchro.i_B_seen );
175             intf_ErrMsg( "                    \r" );
176 #endif
177             p_vpar->synchro.i_P_seen = 0;
178             p_vpar->synchro.i_B_seen = 0;
179
180             /* update some values */
181             if( b_kept )
182             {
183                 p_vpar->synchro.i_last_kept_I_pts = i_pts;
184                 p_vpar->synchro.i_P_kept = 0;
185                 p_vpar->synchro.i_B_kept = 0;
186             }
187
188             break;
189     }
190 }
191
192 /*****************************************************************************
193  * vpar_SynchroChoose : Decide whether we will decode a picture or not
194  *****************************************************************************/
195 boolean_t vpar_SynchroChoose( vpar_thread_t * p_vpar, int i_coding_type,
196                               int i_structure )
197 {
198     mtime_t i_delay = p_vpar->synchro.i_last_pts - mdate();
199
200     //return (i_coding_type == I_CODING_TYPE);
201
202     switch( i_coding_type )
203     {
204         case I_CODING_TYPE:
205
206             //intf_ErrMsg( " I  %f      %f\nI ", 1000000.0 / p_vpar->synchro.i_theorical_delay, 1000000.0 / p_vpar->synchro.i_delay );
207             return( p_vpar->synchro.b_all_I );
208
209         case P_CODING_TYPE:
210
211             //return(1);
212             if( p_vpar->synchro.b_all_P )
213             {
214                 //intf_ErrMsg( " p  " );
215                 return( 1 );
216             }
217
218             if( p_vpar->synchro.displayable_p * i_delay
219                 < p_vpar->synchro.i_delay )
220             {
221                 //intf_ErrMsg( " -  " );
222                 return( 0 );
223             }
224
225             p_vpar->synchro.displayable_p--;
226             //intf_ErrMsg( " p> " );
227             return( 1 );
228
229         case B_CODING_TYPE:
230
231             if( p_vpar->synchro.b_all_B )
232             {
233                 //intf_ErrMsg( "b " );
234                 return( 1 );
235             }
236
237             if( p_vpar->synchro.displayable_b <= 0 )
238             {
239                 //intf_ErrMsg( "  " );
240                 return( 0 );
241             }
242
243             if( i_delay < 0 )
244             {
245                 //intf_ErrMsg( "· " );
246                 p_vpar->synchro.displayable_b -= 0.5;
247                 return( 0 );
248             }
249
250             //intf_ErrMsg( "b " );
251             p_vpar->synchro.displayable_b--;
252             return( 1 );
253     }
254
255     return( 0 );
256
257 }
258
259 /*****************************************************************************
260  * vpar_SynchroTrash : Update timers when we trash a picture
261  *****************************************************************************/
262 void vpar_SynchroTrash( vpar_thread_t * p_vpar, int i_coding_type,
263                         int i_structure )
264 {
265     vpar_SynchroUpdateStructures (p_vpar, i_coding_type, 0);
266
267 }
268
269 /*****************************************************************************
270  * vpar_SynchroDecode : Update timers when we decide to decode a picture
271  *****************************************************************************/
272 void vpar_SynchroDecode( vpar_thread_t * p_vpar, int i_coding_type,
273                             int i_structure )
274 {
275     vpar_SynchroUpdateStructures (p_vpar, i_coding_type, 1);
276
277     p_vpar->synchro.i_date_fifo[p_vpar->synchro.i_stop] = mdate();
278
279     FIFO_INCREMENT( i_stop );
280
281 }
282
283 /*****************************************************************************
284  * vpar_SynchroEnd : Called when the image is totally decoded
285  *****************************************************************************/
286 void vpar_SynchroEnd( vpar_thread_t * p_vpar )
287 {
288     if( p_vpar->synchro.i_stop != p_vpar->synchro.i_start )
289     {
290         mtime_t i_delay;
291
292         i_delay = ( mdate() -
293             p_vpar->synchro.i_date_fifo[p_vpar->synchro.i_start] )
294               / ( (p_vpar->synchro.i_stop - p_vpar->synchro.i_start) & 0x0f );
295
296         p_vpar->synchro.i_delay =
297             ( 7 * p_vpar->synchro.i_delay + i_delay ) >> 3;
298
299 #if 0
300         intf_ErrMsg( "decode %lli (mean %lli, theorical %lli)\n",
301                      i_delay, p_vpar->synchro.i_delay,
302                      p_vpar->synchro.i_theorical_delay );
303 #endif
304     }
305     else
306     {
307         intf_ErrMsg( "vpar error: critical ! fifo full\n" );
308     }
309
310     FIFO_INCREMENT( i_start );
311 }
312
313 /*****************************************************************************
314  * vpar_SynchroDate : When an image has been decoded, ask for its date
315  *****************************************************************************/
316 mtime_t vpar_SynchroDate( vpar_thread_t * p_vpar )
317 {
318 #if 0
319
320     mtime_t i_displaydate = p_vpar->synchro.i_last_pts;
321
322     static mtime_t i_delta = 0;
323
324     intf_ErrMsg( "displaying image with delay %lli and delta %lli\n",
325         i_displaydate - mdate(),
326         i_displaydate - i_delta );
327
328     intf_ErrMsg ( "theorical fps: %f - actual fps: %f \n",
329         1000000.0 / p_vpar->synchro.i_theorical_delay, 1000000.0 / p_vpar->synchro.i_delay );
330
331     i_delta = i_displaydate;
332
333     return i_displaydate;
334 #else
335
336     return p_vpar->synchro.i_last_pts;
337
338 #endif
339 }
340
341 #endif
342
343 #ifdef MEUUH_SYNCHRO
344
345 /* synchro a deux balles backportee du decodeur de reference. NE MARCHE PAS
346 AVEC LES IMAGES MONOTRAMES */
347
348 boolean_t vpar_SynchroChoose( vpar_thread_t * p_vpar, int i_coding_type,
349                               int i_structure )
350 {
351     switch (i_coding_type)
352     {
353     case B_CODING_TYPE:
354         if ((p_vpar->synchro.kludge_level <= p_vpar->synchro.kludge_nbp))
355         {
356             p_vpar->synchro.kludge_b++;
357             return( 0 );
358         }
359         if (p_vpar->synchro.kludge_b %
360              (p_vpar->synchro.kludge_nbb /
361                 (p_vpar->synchro.kludge_level - p_vpar->synchro.kludge_nbp)))
362         {
363             p_vpar->synchro.kludge_b++;
364             return( 0 );
365         }
366         p_vpar->synchro.kludge_b++;
367         return( 1 );
368
369     case P_CODING_TYPE:
370         if (p_vpar->synchro.kludge_p++ >= p_vpar->synchro.kludge_level)
371         {
372             return( 0 );
373         }
374         return( 1 );
375
376     default:
377         return( 1 );
378     }
379 }
380
381 void vpar_SynchroTrash( vpar_thread_t * p_vpar, int i_coding_type,
382                         int i_structure )
383 {
384     if (DECODER_FIFO_START(p_vpar->fifo)->b_has_pts && i_coding_type == I_CODING_TYPE)
385     {
386         p_vpar->synchro.kludge_nbframes = 0;
387         p_vpar->synchro.kludge_date = DECODER_FIFO_START(p_vpar->fifo)->i_pts;
388     }
389     else
390         p_vpar->synchro.kludge_nbframes++;
391     DECODER_FIFO_START(p_vpar->fifo)->b_has_pts = 0;
392 }
393
394 void vpar_SynchroDecode( vpar_thread_t * p_vpar, int i_coding_type,
395                             int i_structure )
396 {
397     if (DECODER_FIFO_START(p_vpar->fifo)->b_has_pts && i_coding_type == I_CODING_TYPE)
398     {
399         p_vpar->synchro.kludge_nbframes = 0;
400         p_vpar->synchro.kludge_date = DECODER_FIFO_START(p_vpar->fifo)->i_pts;
401         DECODER_FIFO_START(p_vpar->fifo)->b_has_pts = 0;
402     }
403     else
404         p_vpar->synchro.kludge_nbframes++;
405 }
406
407 mtime_t vpar_SynchroDate( vpar_thread_t * p_vpar )
408 {
409     return( p_vpar->synchro.kludge_date
410             + p_vpar->synchro.kludge_nbframes*1000000/(p_vpar->sequence.r_frame_rate ) );
411 }
412
413 void vpar_SynchroEnd( vpar_thread_t * p_vpar )
414 {
415 }
416
417 void vpar_SynchroKludge( vpar_thread_t * p_vpar, mtime_t date )
418 {
419     mtime_t     show_date;
420     int         temp = p_vpar->synchro.kludge_level;
421
422     p_vpar->synchro.kludge_nbp = p_vpar->synchro.kludge_p ? p_vpar->synchro.kludge_p : 5;
423     p_vpar->synchro.kludge_nbb = p_vpar->synchro.kludge_b ? p_vpar->synchro.kludge_b : 6;
424     show_date = date - mdate();
425     p_vpar->synchro.kludge_p = 0;
426     p_vpar->synchro.kludge_b = 0;
427
428     if (show_date < (SYNC_DELAY - SYNC_TOLERATE) && show_date <= p_vpar->synchro.kludge_prevdate)
429     {
430         p_vpar->synchro.kludge_level--;
431         if (p_vpar->synchro.kludge_level < 0)
432             p_vpar->synchro.kludge_level = 0;
433         else if (p_vpar->synchro.kludge_level >
434                      p_vpar->synchro.kludge_nbp + p_vpar->synchro.kludge_nbb)
435             p_vpar->synchro.kludge_level = p_vpar->synchro.kludge_nbp + p_vpar->synchro.kludge_nbb;
436 #ifdef DEBUG
437         if (temp != p_vpar->synchro.kludge_level)
438             intf_DbgMsg("vdec debug: Level changed from %d to %d (%Ld)\n",
439                         temp, p_vpar->synchro.kludge_level, show_date );
440 #endif
441     }
442     else if (show_date > (SYNC_DELAY + SYNC_TOLERATE) && show_date >= p_vpar->synchro.kludge_prevdate)
443     {
444         p_vpar->synchro.kludge_level++;
445         if (p_vpar->synchro.kludge_level > p_vpar->synchro.kludge_nbp + p_vpar->synchro.kludge_nbb)
446             p_vpar->synchro.kludge_level = p_vpar->synchro.kludge_nbp + p_vpar->synchro.kludge_nbb;
447 #ifdef DEBUG
448         if (temp != p_vpar->synchro.kludge_level)
449             intf_DbgMsg("vdec debug: Level changed from %d to %d (%Ld)\n",
450                         temp, p_vpar->synchro.kludge_level, show_date );
451 #endif
452     }
453
454     p_vpar->synchro.kludge_prevdate = show_date;
455     if ((p_vpar->synchro.kludge_level - p_vpar->synchro.kludge_nbp) > p_vpar->synchro.kludge_nbb)
456         p_vpar->synchro.kludge_level = p_vpar->synchro.kludge_nbb + p_vpar->synchro.kludge_nbp;
457 }
458
459 #endif
460
461
462 #ifdef POLUX_SYNCHRO
463
464 void vpar_SynchroSetCurrentDate( vpar_thread_t * p_vpar, int i_coding_type )
465 {
466     pes_packet_t * p_pes =
467         p_vpar->bit_stream.p_decoder_fifo->buffer[p_vpar->bit_stream.p_decoder_fifo->i_start];
468
469
470     switch( i_coding_type )
471     {
472     case B_CODING_TYPE:
473         if( p_pes->b_has_pts )
474         {
475             if( p_pes->i_pts < p_vpar->synchro.i_current_frame_date )
476             {
477                 intf_ErrMsg( "vpar warning: pts_date < current_date\n" );
478             }
479             p_vpar->synchro.i_current_frame_date = p_pes->i_pts;
480             p_pes->b_has_pts = 0;
481         }
482         else
483         {
484             p_vpar->synchro.i_current_frame_date += 1000000/(p_vpar->sequence.r_frame_rate);
485         }
486         break;
487
488     default:
489
490         if( p_vpar->synchro.i_backward_frame_date == 0 )
491         {
492             p_vpar->synchro.i_current_frame_date += 1000000/(p_vpar->sequence.r_frame_rate);
493         }
494         else
495         {
496             if( p_vpar->synchro.i_backward_frame_date < p_vpar->synchro.i_current_frame_date )
497             {
498                 intf_ErrMsg( "vpar warning: backward_date < current_date (%Ld)\n",
499                          p_vpar->synchro.i_backward_frame_date - p_vpar->synchro.i_current_frame_date );
500             }
501             p_vpar->synchro.i_current_frame_date = p_vpar->synchro.i_backward_frame_date;
502             p_vpar->synchro.i_backward_frame_date = 0;
503         }
504
505         if( p_pes->b_has_pts )
506         {
507             p_vpar->synchro.i_backward_frame_date = p_pes->i_pts;
508             p_pes->b_has_pts = 0;
509         }
510        break;
511     }
512 }
513
514 boolean_t vpar_SynchroChoose( vpar_thread_t * p_vpar, int i_coding_type,
515                               int i_structure )
516 {
517     boolean_t b_result = 1;
518     int i_synchro_level = p_vpar->p_vout->i_synchro_level;
519
520     vpar_SynchroSetCurrentDate( p_vpar, i_coding_type );
521
522     /*
523      * The synchro level is updated by the video input (see SynchroLevelUpdate)
524      * so we just use the synchro_level to decide which frame to trash
525      */
526
527     switch( i_coding_type )
528     {
529     case I_CODING_TYPE:
530
531         p_vpar->synchro.r_p_average =
532             (p_vpar->synchro.r_p_average*(SYNC_AVERAGE_COUNT-1)+p_vpar->synchro.i_p_count)/SYNC_AVERAGE_COUNT;
533         p_vpar->synchro.r_b_average =
534             (p_vpar->synchro.r_b_average*(SYNC_AVERAGE_COUNT-1)+p_vpar->synchro.i_b_count)/SYNC_AVERAGE_COUNT;
535
536         p_vpar->synchro.i_p_nb = (int)(p_vpar->synchro.r_p_average+0.5);
537         p_vpar->synchro.i_b_nb = (int)(p_vpar->synchro.r_b_average+0.5);
538
539         p_vpar->synchro.i_p_count = p_vpar->synchro.i_b_count = 0;
540         p_vpar->synchro.i_b_trasher = p_vpar->synchro.i_b_nb / 2;
541         p_vpar->synchro.i_i_count++;
542        break;
543
544     case P_CODING_TYPE:
545         p_vpar->synchro.i_p_count++;
546         if( p_vpar->synchro.i_p_count > i_synchro_level )
547         {
548             b_result = 0;
549         }
550         break;
551
552     case B_CODING_TYPE:
553         p_vpar->synchro.i_b_count++;
554         if( p_vpar->synchro.i_p_nb >= i_synchro_level )
555         {
556             /* We must trash all the B */
557             b_result = 0;
558         }
559         else
560         {
561             /* We use the brensenham algorithm to decide which B to trash */
562             p_vpar->synchro.i_b_trasher +=
563                 p_vpar->synchro.i_b_nb - (i_synchro_level-p_vpar->synchro.i_p_nb);
564             if( p_vpar->synchro.i_b_trasher >= p_vpar->synchro.i_b_nb )
565             {
566                 b_result = 0;
567                 p_vpar->synchro.i_b_trasher -= p_vpar->synchro.i_b_nb;
568             }
569         }
570         break;
571     }
572
573     return( b_result );
574 }
575
576 void vpar_SynchroTrash( vpar_thread_t * p_vpar, int i_coding_type,
577                         int i_structure )
578 {
579     vpar_SynchroChoose( p_vpar, i_coding_type, i_structure );
580 }
581
582 void vpar_SynchroUpdateLevel()
583 {
584     //vlc_mutex_lock( &level_lock );
585     //vlc_mutex_unlock( &level_lock );
586 }
587
588 mtime_t vpar_SynchroDate( vpar_thread_t * p_vpar )
589 {
590     return( p_vpar->synchro.i_current_frame_date );
591 }
592
593 /* functions with no use */
594
595 void vpar_SynchroEnd( vpar_thread_t * p_vpar )
596 {
597 }
598
599 void vpar_SynchroDecode( vpar_thread_t * p_vpar, int i_coding_type,
600                             int i_structure )
601 {
602 }
603
604 #endif