]> git.sesse.net Git - vlc/blob - src/video_parser/vpar_synchro.c
* vlc.init becomes ~/.vlcrc
[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             //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
411                 / (p_vpar->sequence.i_frame_rate ) * 1001 );
412 }
413
414 void vpar_SynchroEnd( vpar_thread_t * p_vpar )
415 {
416 }
417
418 void vpar_SynchroKludge( vpar_thread_t * p_vpar, mtime_t date )
419 {
420     mtime_t     show_date;
421     int         temp = p_vpar->synchro.kludge_level;
422
423     p_vpar->synchro.kludge_nbp = p_vpar->synchro.kludge_p ? p_vpar->synchro.kludge_p : 5;
424     p_vpar->synchro.kludge_nbb = p_vpar->synchro.kludge_b ? p_vpar->synchro.kludge_b : 6;
425     show_date = date - mdate();
426     p_vpar->synchro.kludge_p = 0;
427     p_vpar->synchro.kludge_b = 0;
428
429     if (show_date < (SYNC_DELAY - SYNC_TOLERATE) && show_date <= p_vpar->synchro.kludge_prevdate)
430     {
431         p_vpar->synchro.kludge_level--;
432         if (p_vpar->synchro.kludge_level < 0)
433             p_vpar->synchro.kludge_level = 0;
434         else if (p_vpar->synchro.kludge_level >
435                      p_vpar->synchro.kludge_nbp + p_vpar->synchro.kludge_nbb)
436             p_vpar->synchro.kludge_level = p_vpar->synchro.kludge_nbp + p_vpar->synchro.kludge_nbb;
437 #ifdef DEBUG
438         if (temp != p_vpar->synchro.kludge_level)
439             intf_DbgMsg("vdec debug: Level changed from %d to %d (%Ld)\n",
440                         temp, p_vpar->synchro.kludge_level, show_date );
441 #endif
442     }
443     else if (show_date > (SYNC_DELAY + SYNC_TOLERATE) && show_date >= p_vpar->synchro.kludge_prevdate)
444     {
445         p_vpar->synchro.kludge_level++;
446         if (p_vpar->synchro.kludge_level > p_vpar->synchro.kludge_nbp + p_vpar->synchro.kludge_nbb)
447             p_vpar->synchro.kludge_level = p_vpar->synchro.kludge_nbp + p_vpar->synchro.kludge_nbb;
448 #ifdef DEBUG
449         if (temp != p_vpar->synchro.kludge_level)
450             intf_DbgMsg("vdec debug: Level changed from %d to %d (%Ld)\n",
451                         temp, p_vpar->synchro.kludge_level, show_date );
452 #endif
453     }
454
455     p_vpar->synchro.kludge_prevdate = show_date;
456     if ((p_vpar->synchro.kludge_level - p_vpar->synchro.kludge_nbp) > p_vpar->synchro.kludge_nbb)
457         p_vpar->synchro.kludge_level = p_vpar->synchro.kludge_nbb + p_vpar->synchro.kludge_nbp;
458 }
459
460 #endif
461
462
463 #ifdef POLUX_SYNCHRO
464
465 void vpar_SynchroSetCurrentDate( vpar_thread_t * p_vpar, int i_coding_type )
466 {
467     pes_packet_t * p_pes =
468         p_vpar->bit_stream.p_decoder_fifo->buffer[p_vpar->bit_stream.p_decoder_fifo->i_start];
469
470
471     switch( i_coding_type )
472     {
473     case B_CODING_TYPE:
474         if( p_pes->b_has_pts )
475         {
476             if( p_pes->i_pts < p_vpar->synchro.i_current_frame_date )
477             {
478                 intf_ErrMsg( "vpar warning: pts_date < current_date\n" );
479             }
480             p_vpar->synchro.i_current_frame_date = p_pes->i_pts;
481             p_pes->b_has_pts = 0;
482         }
483         else
484         {
485             p_vpar->synchro.i_current_frame_date += 1000000 / (p_vpar->sequence.i_frame_rate) * 1001;
486         }
487         break;
488
489     default:
490
491         if( p_vpar->synchro.i_backward_frame_date == 0 )
492         {
493             p_vpar->synchro.i_current_frame_date += 1000000 / (p_vpar->sequence.i_frame_rate) * 1001;
494         }
495         else
496         {
497             if( p_vpar->synchro.i_backward_frame_date < p_vpar->synchro.i_current_frame_date )
498             {
499                 intf_ErrMsg( "vpar warning: backward_date < current_date (%Ld)\n",
500                          p_vpar->synchro.i_backward_frame_date - p_vpar->synchro.i_current_frame_date );
501             }
502             p_vpar->synchro.i_current_frame_date = p_vpar->synchro.i_backward_frame_date;
503             p_vpar->synchro.i_backward_frame_date = 0;
504         }
505
506         if( p_pes->b_has_pts )
507         {
508             p_vpar->synchro.i_backward_frame_date = p_pes->i_pts;
509             p_pes->b_has_pts = 0;
510         }
511        break;
512     }
513 }
514
515 boolean_t vpar_SynchroChoose( vpar_thread_t * p_vpar, int i_coding_type,
516                               int i_structure )
517 {
518     boolean_t b_result = 1;
519     int i_synchro_level = p_vpar->p_vout->i_synchro_level;
520
521     vpar_SynchroSetCurrentDate( p_vpar, i_coding_type );
522
523     /*
524      * The synchro level is updated by the video input (see SynchroLevelUpdate)
525      * so we just use the synchro_level to decide which frame to trash
526      */
527
528     switch( i_coding_type )
529     {
530     case I_CODING_TYPE:
531
532         p_vpar->synchro.r_p_average =
533             (p_vpar->synchro.r_p_average*(SYNC_AVERAGE_COUNT-1)+p_vpar->synchro.i_p_count)/SYNC_AVERAGE_COUNT;
534         p_vpar->synchro.r_b_average =
535             (p_vpar->synchro.r_b_average*(SYNC_AVERAGE_COUNT-1)+p_vpar->synchro.i_b_count)/SYNC_AVERAGE_COUNT;
536
537         p_vpar->synchro.i_p_nb = (int)(p_vpar->synchro.r_p_average+0.5);
538         p_vpar->synchro.i_b_nb = (int)(p_vpar->synchro.r_b_average+0.5);
539
540         p_vpar->synchro.i_p_count = p_vpar->synchro.i_b_count = 0;
541         p_vpar->synchro.i_b_trasher = p_vpar->synchro.i_b_nb / 2;
542         p_vpar->synchro.i_i_count++;
543        break;
544
545     case P_CODING_TYPE:
546         p_vpar->synchro.i_p_count++;
547         if( p_vpar->synchro.i_p_count > i_synchro_level )
548         {
549             b_result = 0;
550         }
551         break;
552
553     case B_CODING_TYPE:
554         p_vpar->synchro.i_b_count++;
555         if( p_vpar->synchro.i_p_nb >= i_synchro_level )
556         {
557             /* We must trash all the B */
558             b_result = 0;
559         }
560         else
561         {
562             /* We use the brensenham algorithm to decide which B to trash */
563             p_vpar->synchro.i_b_trasher +=
564                 p_vpar->synchro.i_b_nb - (i_synchro_level-p_vpar->synchro.i_p_nb);
565             if( p_vpar->synchro.i_b_trasher >= p_vpar->synchro.i_b_nb )
566             {
567                 b_result = 0;
568                 p_vpar->synchro.i_b_trasher -= p_vpar->synchro.i_b_nb;
569             }
570         }
571         break;
572     }
573
574     return( b_result );
575 }
576
577 void vpar_SynchroTrash( vpar_thread_t * p_vpar, int i_coding_type,
578                         int i_structure )
579 {
580     vpar_SynchroChoose( p_vpar, i_coding_type, i_structure );
581 }
582
583 void vpar_SynchroUpdateLevel()
584 {
585     //vlc_mutex_lock( &level_lock );
586     //vlc_mutex_unlock( &level_lock );
587 }
588
589 mtime_t vpar_SynchroDate( vpar_thread_t * p_vpar )
590 {
591     return( p_vpar->synchro.i_current_frame_date );
592 }
593
594 /* functions with no use */
595
596 void vpar_SynchroEnd( vpar_thread_t * p_vpar )
597 {
598 }
599
600 void vpar_SynchroDecode( vpar_thread_t * p_vpar, int i_coding_type,
601                             int i_structure )
602 {
603 }
604
605 #endif