]> git.sesse.net Git - vlc/blob - src/video_parser/vpar_synchro.c
. vir� les aliases � xvlc �, � ggivlc � etc. qui faisaient un peu
[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     int             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 += 1024;
104             if( b_kept ) p_vpar->synchro.i_P_kept += 1024;
105             break;
106
107         case B_CODING_TYPE:
108             p_vpar->synchro.i_B_seen += 1024;
109             if( b_kept ) p_vpar->synchro.i_B_kept += 1024;
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                       1024 * ( i_pts - p_vpar->synchro.i_last_seen_I_pts )
122                           / ( 1024 + 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 = 
131                 ( (i_pts - p_vpar->synchro.i_last_kept_I_pts) << 10 )
132                                 / p_vpar->synchro.i_delay;
133
134             p_vpar->synchro.b_all_I = 0;
135             p_vpar->synchro.b_all_B = 0;
136             p_vpar->synchro.b_all_P = 0;
137             p_vpar->synchro.displayable_p = 0;
138             p_vpar->synchro.displayable_b = 0;
139
140             if( ( p_vpar->synchro.b_all_I = ( i_can_display >= 1024 ) ) )
141             {
142                 i_can_display -= 1024;
143
144                 if( !( p_vpar->synchro.b_all_P
145                         = ( i_can_display > p_vpar->synchro.i_P_seen ) ) )
146                 {
147                     p_vpar->synchro.displayable_p = i_can_display;
148                 }
149                 else
150                 {
151                     i_can_display -= p_vpar->synchro.i_P_seen;
152
153                     if( !( p_vpar->synchro.b_all_B
154                             = ( i_can_display > p_vpar->synchro.i_B_seen ) ) )
155                     {
156                         p_vpar->synchro.displayable_b = i_can_display;
157                     }
158                 }
159             }
160
161 #if 1
162             if( p_vpar->synchro.b_all_I )
163                 intf_ErrMsg( " I: 1024/1024  " );
164             if( p_vpar->synchro.b_all_P )
165                 intf_ErrMsg( "P: %i/%i  ", p_vpar->synchro.i_P_seen,
166                                            p_vpar->synchro.i_P_seen );
167             else if( p_vpar->synchro.displayable_p > 0 )
168                 intf_ErrMsg( "P: %i/%i  ", p_vpar->synchro.displayable_p,
169                                              p_vpar->synchro.i_P_seen );
170             if( p_vpar->synchro.b_all_B )
171                 intf_ErrMsg( "B: %i/%i", p_vpar->synchro.i_B_seen,
172                                          p_vpar->synchro.i_B_seen );
173             else if( p_vpar->synchro.displayable_b > 0 )
174                 intf_ErrMsg( "B: %i/%i", p_vpar->synchro.displayable_b,
175                                            p_vpar->synchro.i_B_seen );
176 //            intf_ErrMsg( "                             \r" );
177             intf_ErrMsg( "\n" );
178 #endif
179             p_vpar->synchro.i_P_seen = 0;
180             p_vpar->synchro.i_B_seen = 0;
181
182             /* update some values */
183             if( b_kept )
184             {
185                 p_vpar->synchro.i_last_kept_I_pts = i_pts;
186                 p_vpar->synchro.i_P_kept = 0;
187                 p_vpar->synchro.i_B_kept = 0;
188             }
189
190             break;
191     }
192 }
193
194 /*****************************************************************************
195  * vpar_SynchroChoose : Decide whether we will decode a picture or not
196  *****************************************************************************/
197 boolean_t vpar_SynchroChoose( vpar_thread_t * p_vpar, int i_coding_type,
198                               int i_structure )
199 {
200     mtime_t i_delay = p_vpar->synchro.i_last_pts - mdate();
201
202     switch( i_coding_type )
203     {
204         case I_CODING_TYPE:
205
206             if( p_vpar->synchro.i_type != VPAR_SYNCHRO_DEFAULT )
207             {
208                 /* I, IP, IP+, IPB */
209                 return( 1 );
210             }
211
212             return( p_vpar->synchro.b_all_I );
213
214         case P_CODING_TYPE:
215
216             if( p_vpar->synchro.i_type == VPAR_SYNCHRO_I ) /* I */
217             {
218                 return( 0 );
219             }
220
221             if( p_vpar->synchro.i_type >= VPAR_SYNCHRO_IP ) /* IP, IP+, IPB */
222             {
223                 return( 1 );
224             }
225
226             if( p_vpar->synchro.b_all_P )
227             {
228                 return( 1 );
229             }
230
231             if( p_vpar->synchro.displayable_p * i_delay
232                 < p_vpar->synchro.i_delay )
233             {
234                 return( 0 );
235             }
236
237             p_vpar->synchro.displayable_p -= 1024;
238
239             return( 1 );
240
241         case B_CODING_TYPE:
242
243             if( p_vpar->synchro.i_type != VPAR_SYNCHRO_DEFAULT )
244             {
245                 if( p_vpar->synchro.i_type <= VPAR_SYNCHRO_IP ) /* I, IP */
246                 {
247                     return( 0 );
248                 }
249                 else if( p_vpar->synchro.i_type == VPAR_SYNCHRO_IPB ) /* IPB */
250                 {
251                     return( 1 );
252                 }
253
254                 if( p_vpar->synchro.b_dropped_last_B ) /* IP+ */
255                 {
256                     p_vpar->synchro.b_dropped_last_B = 0;
257                     return( 1 );
258                 }
259
260                 p_vpar->synchro.b_dropped_last_B = 1;
261                 return( 0 );
262             }
263
264             if( p_vpar->synchro.b_all_B )
265             {
266                 return( 1 );
267             }
268
269             if( p_vpar->synchro.displayable_b <= 0 )
270             {
271                 return( 0 );
272             }
273
274             if( i_delay < 0 )
275             {
276                 p_vpar->synchro.displayable_b -= 512;
277                 return( 0 );
278             }
279
280             p_vpar->synchro.displayable_b -= 1024;
281             return( 1 );
282     }
283
284     return( 0 );
285
286 }
287
288 /*****************************************************************************
289  * vpar_SynchroTrash : Update timers when we trash a picture
290  *****************************************************************************/
291 void vpar_SynchroTrash( vpar_thread_t * p_vpar, int i_coding_type,
292                         int i_structure )
293 {
294     vpar_SynchroUpdateStructures (p_vpar, i_coding_type, 0);
295
296 }
297
298 /*****************************************************************************
299  * vpar_SynchroDecode : Update timers when we decide to decode a picture
300  *****************************************************************************/
301 void vpar_SynchroDecode( vpar_thread_t * p_vpar, int i_coding_type,
302                             int i_structure )
303 {
304     vpar_SynchroUpdateStructures (p_vpar, i_coding_type, 1);
305
306     p_vpar->synchro.i_date_fifo[p_vpar->synchro.i_stop] = mdate();
307
308     FIFO_INCREMENT( i_stop );
309
310 }
311
312 /*****************************************************************************
313  * vpar_SynchroEnd : Called when the image is totally decoded
314  *****************************************************************************/
315 void vpar_SynchroEnd( vpar_thread_t * p_vpar )
316 {
317     if( p_vpar->synchro.i_stop != p_vpar->synchro.i_start )
318     {
319         mtime_t i_delay;
320
321         i_delay = ( mdate() -
322             p_vpar->synchro.i_date_fifo[p_vpar->synchro.i_start] )
323               / ( (p_vpar->synchro.i_stop - p_vpar->synchro.i_start) & 0x0f );
324
325         p_vpar->synchro.i_delay =
326             ( 7 * p_vpar->synchro.i_delay + i_delay ) >> 3;
327
328 #if 0
329         intf_ErrMsg( "decode %lli (mean %lli, theorical %lli)\n",
330                      i_delay, p_vpar->synchro.i_delay,
331                      p_vpar->synchro.i_theorical_delay );
332 #endif
333     }
334     else
335     {
336         intf_ErrMsg( "vpar error: critical ! fifo full\n" );
337     }
338
339     FIFO_INCREMENT( i_start );
340 }
341
342 /*****************************************************************************
343  * vpar_SynchroDate : When an image has been decoded, ask for its date
344  *****************************************************************************/
345 mtime_t vpar_SynchroDate( vpar_thread_t * p_vpar )
346 {
347 #if 0
348
349     mtime_t i_displaydate = p_vpar->synchro.i_last_pts;
350
351     static mtime_t i_delta = 0;
352
353     intf_ErrMsg( "displaying image with delay %lli and delta %lli\n",
354         i_displaydate - mdate(),
355         i_displaydate - i_delta );
356
357     intf_ErrMsg ( "theorical fps: %f - actual fps: %f \n",
358         1000000.0 / p_vpar->synchro.i_theorical_delay, 1000000.0 / p_vpar->synchro.i_delay );
359
360     i_delta = i_displaydate;
361
362     return i_displaydate;
363 #else
364
365     return p_vpar->synchro.i_last_pts;
366
367 #endif
368 }
369
370 #endif
371
372 #ifdef MEUUH_SYNCHRO
373
374 /* synchro a deux balles backportee du decodeur de reference. NE MARCHE PAS
375 AVEC LES IMAGES MONOTRAMES */
376
377 boolean_t vpar_SynchroChoose( vpar_thread_t * p_vpar, int i_coding_type,
378                               int i_structure )
379 {
380     switch (i_coding_type)
381     {
382     case B_CODING_TYPE:
383         if ((p_vpar->synchro.kludge_level <= p_vpar->synchro.kludge_nbp))
384         {
385             p_vpar->synchro.kludge_b++;
386             return( 0 );
387         }
388         if (p_vpar->synchro.kludge_b %
389              (p_vpar->synchro.kludge_nbb /
390                 (p_vpar->synchro.kludge_level - p_vpar->synchro.kludge_nbp)))
391         {
392             p_vpar->synchro.kludge_b++;
393             return( 0 );
394         }
395         p_vpar->synchro.kludge_b++;
396         return( 1 );
397
398     case P_CODING_TYPE:
399         if (p_vpar->synchro.kludge_p++ >= p_vpar->synchro.kludge_level)
400         {
401             return( 0 );
402         }
403         return( 1 );
404
405     default:
406         return( 1 );
407     }
408 }
409
410 void vpar_SynchroTrash( vpar_thread_t * p_vpar, int i_coding_type,
411                         int i_structure )
412 {
413     if (DECODER_FIFO_START(p_vpar->fifo)->b_has_pts && i_coding_type == I_CODING_TYPE)
414     {
415         p_vpar->synchro.kludge_nbframes = 0;
416         p_vpar->synchro.kludge_date = DECODER_FIFO_START(p_vpar->fifo)->i_pts;
417     }
418     else
419         p_vpar->synchro.kludge_nbframes++;
420     DECODER_FIFO_START(p_vpar->fifo)->b_has_pts = 0;
421 }
422
423 void vpar_SynchroDecode( vpar_thread_t * p_vpar, int i_coding_type,
424                             int i_structure )
425 {
426     if (DECODER_FIFO_START(p_vpar->fifo)->b_has_pts && i_coding_type == I_CODING_TYPE)
427     {
428         p_vpar->synchro.kludge_nbframes = 0;
429         p_vpar->synchro.kludge_date = DECODER_FIFO_START(p_vpar->fifo)->i_pts;
430         DECODER_FIFO_START(p_vpar->fifo)->b_has_pts = 0;
431     }
432     else
433         p_vpar->synchro.kludge_nbframes++;
434 }
435
436 mtime_t vpar_SynchroDate( vpar_thread_t * p_vpar )
437 {
438     return( p_vpar->synchro.kludge_date
439             + p_vpar->synchro.kludge_nbframes * 1000000
440                 / (p_vpar->sequence.i_frame_rate ) * 1001 );
441 }
442
443 void vpar_SynchroEnd( vpar_thread_t * p_vpar )
444 {
445 }
446
447 void vpar_SynchroKludge( vpar_thread_t * p_vpar, mtime_t date )
448 {
449     mtime_t     show_date;
450     int         temp = p_vpar->synchro.kludge_level;
451
452     p_vpar->synchro.kludge_nbp = p_vpar->synchro.kludge_p ? p_vpar->synchro.kludge_p : 5;
453     p_vpar->synchro.kludge_nbb = p_vpar->synchro.kludge_b ? p_vpar->synchro.kludge_b : 6;
454     show_date = date - mdate();
455     p_vpar->synchro.kludge_p = 0;
456     p_vpar->synchro.kludge_b = 0;
457
458     if (show_date < (SYNC_DELAY - SYNC_TOLERATE) && show_date <= p_vpar->synchro.kludge_prevdate)
459     {
460         p_vpar->synchro.kludge_level--;
461         if (p_vpar->synchro.kludge_level < 0)
462             p_vpar->synchro.kludge_level = 0;
463         else if (p_vpar->synchro.kludge_level >
464                      p_vpar->synchro.kludge_nbp + p_vpar->synchro.kludge_nbb)
465             p_vpar->synchro.kludge_level = p_vpar->synchro.kludge_nbp + p_vpar->synchro.kludge_nbb;
466 #ifdef DEBUG
467         if (temp != p_vpar->synchro.kludge_level)
468             intf_DbgMsg("vdec debug: Level changed from %d to %d (%Ld)\n",
469                         temp, p_vpar->synchro.kludge_level, show_date );
470 #endif
471     }
472     else if (show_date > (SYNC_DELAY + SYNC_TOLERATE) && show_date >= p_vpar->synchro.kludge_prevdate)
473     {
474         p_vpar->synchro.kludge_level++;
475         if (p_vpar->synchro.kludge_level > p_vpar->synchro.kludge_nbp + p_vpar->synchro.kludge_nbb)
476             p_vpar->synchro.kludge_level = p_vpar->synchro.kludge_nbp + p_vpar->synchro.kludge_nbb;
477 #ifdef DEBUG
478         if (temp != p_vpar->synchro.kludge_level)
479             intf_DbgMsg("vdec debug: Level changed from %d to %d (%Ld)\n",
480                         temp, p_vpar->synchro.kludge_level, show_date );
481 #endif
482     }
483
484     p_vpar->synchro.kludge_prevdate = show_date;
485     if ((p_vpar->synchro.kludge_level - p_vpar->synchro.kludge_nbp) > p_vpar->synchro.kludge_nbb)
486         p_vpar->synchro.kludge_level = p_vpar->synchro.kludge_nbb + p_vpar->synchro.kludge_nbp;
487 }
488
489 #endif
490
491
492 #ifdef POLUX_SYNCHRO
493
494 void vpar_SynchroSetCurrentDate( vpar_thread_t * p_vpar, int i_coding_type )
495 {
496     pes_packet_t * p_pes =
497         p_vpar->bit_stream.p_decoder_fifo->buffer[p_vpar->bit_stream.p_decoder_fifo->i_start];
498
499
500     switch( i_coding_type )
501     {
502     case B_CODING_TYPE:
503         if( p_pes->b_has_pts )
504         {
505             if( p_pes->i_pts < p_vpar->synchro.i_current_frame_date )
506             {
507                 intf_ErrMsg( "vpar warning: pts_date < current_date\n" );
508             }
509             p_vpar->synchro.i_current_frame_date = p_pes->i_pts;
510             p_pes->b_has_pts = 0;
511         }
512         else
513         {
514             p_vpar->synchro.i_current_frame_date += 1000000 / (p_vpar->sequence.i_frame_rate) * 1001;
515         }
516         break;
517
518     default:
519
520         if( p_vpar->synchro.i_backward_frame_date == 0 )
521         {
522             p_vpar->synchro.i_current_frame_date += 1000000 / (p_vpar->sequence.i_frame_rate) * 1001;
523         }
524         else
525         {
526             if( p_vpar->synchro.i_backward_frame_date < p_vpar->synchro.i_current_frame_date )
527             {
528                 intf_ErrMsg( "vpar warning: backward_date < current_date (%Ld)\n",
529                          p_vpar->synchro.i_backward_frame_date - p_vpar->synchro.i_current_frame_date );
530             }
531             p_vpar->synchro.i_current_frame_date = p_vpar->synchro.i_backward_frame_date;
532             p_vpar->synchro.i_backward_frame_date = 0;
533         }
534
535         if( p_pes->b_has_pts )
536         {
537             p_vpar->synchro.i_backward_frame_date = p_pes->i_pts;
538             p_pes->b_has_pts = 0;
539         }
540        break;
541     }
542 }
543
544 boolean_t vpar_SynchroChoose( vpar_thread_t * p_vpar, int i_coding_type,
545                               int i_structure )
546 {
547     boolean_t b_result = 1;
548     int i_synchro_level = p_vpar->p_vout->i_synchro_level;
549
550     vpar_SynchroSetCurrentDate( p_vpar, i_coding_type );
551
552     /*
553      * The synchro level is updated by the video input (see SynchroLevelUpdate)
554      * so we just use the synchro_level to decide which frame to trash
555      */
556
557     switch( i_coding_type )
558     {
559     case I_CODING_TYPE:
560
561         p_vpar->synchro.r_p_average =
562             (p_vpar->synchro.r_p_average*(SYNC_AVERAGE_COUNT-1)+p_vpar->synchro.i_p_count)/SYNC_AVERAGE_COUNT;
563         p_vpar->synchro.r_b_average =
564             (p_vpar->synchro.r_b_average*(SYNC_AVERAGE_COUNT-1)+p_vpar->synchro.i_b_count)/SYNC_AVERAGE_COUNT;
565
566         p_vpar->synchro.i_p_nb = (int)(p_vpar->synchro.r_p_average+0.5);
567         p_vpar->synchro.i_b_nb = (int)(p_vpar->synchro.r_b_average+0.5);
568
569         p_vpar->synchro.i_p_count = p_vpar->synchro.i_b_count = 0;
570         p_vpar->synchro.i_b_trasher = p_vpar->synchro.i_b_nb / 2;
571         p_vpar->synchro.i_i_count++;
572        break;
573
574     case P_CODING_TYPE:
575         p_vpar->synchro.i_p_count++;
576         if( p_vpar->synchro.i_p_count > i_synchro_level )
577         {
578             b_result = 0;
579         }
580         break;
581
582     case B_CODING_TYPE:
583         p_vpar->synchro.i_b_count++;
584         if( p_vpar->synchro.i_p_nb >= i_synchro_level )
585         {
586             /* We must trash all the B */
587             b_result = 0;
588         }
589         else
590         {
591             /* We use the brensenham algorithm to decide which B to trash */
592             p_vpar->synchro.i_b_trasher +=
593                 p_vpar->synchro.i_b_nb - (i_synchro_level-p_vpar->synchro.i_p_nb);
594             if( p_vpar->synchro.i_b_trasher >= p_vpar->synchro.i_b_nb )
595             {
596                 b_result = 0;
597                 p_vpar->synchro.i_b_trasher -= p_vpar->synchro.i_b_nb;
598             }
599         }
600         break;
601     }
602
603     return( b_result );
604 }
605
606 void vpar_SynchroTrash( vpar_thread_t * p_vpar, int i_coding_type,
607                         int i_structure )
608 {
609     vpar_SynchroChoose( p_vpar, i_coding_type, i_structure );
610 }
611
612 void vpar_SynchroUpdateLevel()
613 {
614     //vlc_mutex_lock( &level_lock );
615     //vlc_mutex_unlock( &level_lock );
616 }
617
618 mtime_t vpar_SynchroDate( vpar_thread_t * p_vpar )
619 {
620     return( p_vpar->synchro.i_current_frame_date );
621 }
622
623 /* functions with no use */
624
625 void vpar_SynchroEnd( vpar_thread_t * p_vpar )
626 {
627 }
628
629 void vpar_SynchroDecode( vpar_thread_t * p_vpar, int i_coding_type,
630                             int i_structure )
631 {
632 }
633
634 #endif