]> git.sesse.net Git - vlc/blob - src/video_parser/vpar_synchro.c
. changement cosm�tique
[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( "\n" );
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     switch( i_coding_type )
201     {
202         case I_CODING_TYPE:
203
204             //intf_ErrMsg( " I  %f      %f\nI ", 1000000.0 / p_vpar->synchro.i_theorical_delay, 1000000.0 / p_vpar->synchro.i_delay );
205             return( p_vpar->synchro.b_all_I );
206
207         case P_CODING_TYPE:
208
209             //return(1);
210             if( p_vpar->synchro.b_all_P )
211             {
212                 //intf_ErrMsg( " p  " );
213                 return( 1 );
214             }
215
216             if( p_vpar->synchro.displayable_p * i_delay
217                 < p_vpar->synchro.i_delay )
218             {
219                 //intf_ErrMsg( " -  " );
220                 return( 0 );
221             }
222
223             p_vpar->synchro.displayable_p--;
224             //intf_ErrMsg( " p> " );
225             return( 1 );
226
227         case B_CODING_TYPE:
228
229             if( p_vpar->synchro.b_all_B )
230             {
231                 //intf_ErrMsg( "b " );
232                 return( 1 );
233             }
234
235             if( p_vpar->synchro.displayable_b <= 0 )
236             {
237                 //intf_ErrMsg( "  " );
238                 return( 0 );
239             }
240
241             if( i_delay < 0 )
242             {
243                 //intf_ErrMsg( "· " );
244                 p_vpar->synchro.displayable_b -= 0.5;
245                 return( 0 );
246             }
247
248             //intf_ErrMsg( "b " );
249             p_vpar->synchro.displayable_b--;
250             return( 1 );
251     }
252
253     return( 0 );
254
255 }
256
257 /*****************************************************************************
258  * vpar_SynchroTrash : Update timers when we trash a picture
259  *****************************************************************************/
260 void vpar_SynchroTrash( vpar_thread_t * p_vpar, int i_coding_type,
261                         int i_structure )
262 {
263     vpar_SynchroUpdateStructures (p_vpar, i_coding_type, 0);
264
265 }
266
267 /*****************************************************************************
268  * vpar_SynchroDecode : Update timers when we decide to decode a picture
269  *****************************************************************************/
270 void vpar_SynchroDecode( vpar_thread_t * p_vpar, int i_coding_type,
271                             int i_structure )
272 {
273     vpar_SynchroUpdateStructures (p_vpar, i_coding_type, 1);
274
275     p_vpar->synchro.i_date_fifo[p_vpar->synchro.i_stop] = mdate();
276
277     FIFO_INCREMENT( i_stop );
278
279 }
280
281 /*****************************************************************************
282  * vpar_SynchroEnd : Called when the image is totally decoded
283  *****************************************************************************/
284 void vpar_SynchroEnd( vpar_thread_t * p_vpar )
285 {
286     if( p_vpar->synchro.i_stop != p_vpar->synchro.i_start )
287     {
288         mtime_t i_delay;
289
290         i_delay = ( mdate() -
291             p_vpar->synchro.i_date_fifo[p_vpar->synchro.i_start] )
292               / ( (p_vpar->synchro.i_stop - p_vpar->synchro.i_start) & 0x0f );
293
294         p_vpar->synchro.i_delay =
295             ( 7 * p_vpar->synchro.i_delay + i_delay ) >> 3;
296
297 #if 0
298         intf_ErrMsg( "decode %lli (mean %lli, theorical %lli)\n",
299                      i_delay, p_vpar->synchro.i_delay,
300                      p_vpar->synchro.i_theorical_delay );
301 #endif
302     }
303     else
304     {
305         intf_ErrMsg( "vpar error: critical ! fifo full\n" );
306     }
307
308     FIFO_INCREMENT( i_start );
309 }
310
311 /*****************************************************************************
312  * vpar_SynchroDate : When an image has been decoded, ask for its date
313  *****************************************************************************/
314 mtime_t vpar_SynchroDate( vpar_thread_t * p_vpar )
315 {
316 #if 0
317
318     mtime_t i_displaydate = p_vpar->synchro.i_last_pts;
319
320     static mtime_t i_delta = 0;
321
322     intf_ErrMsg( "displaying image with delay %lli and delta %lli\n",
323         i_displaydate - mdate(),
324         i_displaydate - i_delta );
325
326     intf_ErrMsg ( "theorical fps: %f - actual fps: %f \n",
327         1000000.0 / p_vpar->synchro.i_theorical_delay, 1000000.0 / p_vpar->synchro.i_delay );
328
329     i_delta = i_displaydate;
330
331     return i_displaydate;
332 #else
333
334     return p_vpar->synchro.i_last_pts;
335
336 #endif
337 }
338
339 #endif
340
341 #ifdef MEUUH_SYNCHRO
342
343 /* synchro a deux balles backportee du decodeur de reference. NE MARCHE PAS
344 AVEC LES IMAGES MONOTRAMES */
345
346 boolean_t vpar_SynchroChoose( vpar_thread_t * p_vpar, int i_coding_type,
347                               int i_structure )
348 {
349     switch (i_coding_type)
350     {
351     case B_CODING_TYPE:
352         if ((p_vpar->synchro.kludge_level <= p_vpar->synchro.kludge_nbp))
353         {
354             p_vpar->synchro.kludge_b++;
355             return( 0 );
356         }
357         if (p_vpar->synchro.kludge_b %
358              (p_vpar->synchro.kludge_nbb /
359                 (p_vpar->synchro.kludge_level - p_vpar->synchro.kludge_nbp)))
360         {
361             p_vpar->synchro.kludge_b++;
362             return( 0 );
363         }
364         p_vpar->synchro.kludge_b++;
365         return( 1 );
366
367     case P_CODING_TYPE:
368         if (p_vpar->synchro.kludge_p++ >= p_vpar->synchro.kludge_level)
369         {
370             return( 0 );
371         }
372         return( 1 );
373
374     default:
375         return( 1 );
376     }
377 }
378
379 void vpar_SynchroTrash( vpar_thread_t * p_vpar, int i_coding_type,
380                         int i_structure )
381 {
382     if (DECODER_FIFO_START(p_vpar->fifo)->b_has_pts && i_coding_type == I_CODING_TYPE)
383     {
384         p_vpar->synchro.kludge_nbframes = 0;
385         p_vpar->synchro.kludge_date = DECODER_FIFO_START(p_vpar->fifo)->i_pts;
386     }
387     else
388         p_vpar->synchro.kludge_nbframes++;
389     DECODER_FIFO_START(p_vpar->fifo)->b_has_pts = 0;
390 }
391
392 void vpar_SynchroDecode( vpar_thread_t * p_vpar, int i_coding_type,
393                             int i_structure )
394 {
395     if (DECODER_FIFO_START(p_vpar->fifo)->b_has_pts && i_coding_type == I_CODING_TYPE)
396     {
397         p_vpar->synchro.kludge_nbframes = 0;
398         p_vpar->synchro.kludge_date = DECODER_FIFO_START(p_vpar->fifo)->i_pts;
399         DECODER_FIFO_START(p_vpar->fifo)->b_has_pts = 0;
400     }
401     else
402         p_vpar->synchro.kludge_nbframes++;
403 }
404
405 mtime_t vpar_SynchroDate( vpar_thread_t * p_vpar )
406 {
407     return( p_vpar->synchro.kludge_date
408             + p_vpar->synchro.kludge_nbframes*1000000/(p_vpar->sequence.r_frame_rate ) );
409 }
410
411 void vpar_SynchroEnd( vpar_thread_t * p_vpar )
412 {
413 }
414
415 void vpar_SynchroKludge( vpar_thread_t * p_vpar, mtime_t date )
416 {
417     mtime_t     show_date;
418     int         temp = p_vpar->synchro.kludge_level;
419
420     p_vpar->synchro.kludge_nbp = p_vpar->synchro.kludge_p ? p_vpar->synchro.kludge_p : 5;
421     p_vpar->synchro.kludge_nbb = p_vpar->synchro.kludge_b ? p_vpar->synchro.kludge_b : 6;
422     show_date = date - mdate();
423     p_vpar->synchro.kludge_p = 0;
424     p_vpar->synchro.kludge_b = 0;
425
426     if (show_date < (SYNC_DELAY - SYNC_TOLERATE) && show_date <= p_vpar->synchro.kludge_prevdate)
427     {
428         p_vpar->synchro.kludge_level--;
429         if (p_vpar->synchro.kludge_level < 0)
430             p_vpar->synchro.kludge_level = 0;
431         else if (p_vpar->synchro.kludge_level >
432                      p_vpar->synchro.kludge_nbp + p_vpar->synchro.kludge_nbb)
433             p_vpar->synchro.kludge_level = p_vpar->synchro.kludge_nbp + p_vpar->synchro.kludge_nbb;
434 #ifdef DEBUG
435         if (temp != p_vpar->synchro.kludge_level)
436             intf_DbgMsg("vdec debug: Level changed from %d to %d (%Ld)\n",
437                         temp, p_vpar->synchro.kludge_level, show_date );
438 #endif
439     }
440     else if (show_date > (SYNC_DELAY + SYNC_TOLERATE) && show_date >= p_vpar->synchro.kludge_prevdate)
441     {
442         p_vpar->synchro.kludge_level++;
443         if (p_vpar->synchro.kludge_level > p_vpar->synchro.kludge_nbp + p_vpar->synchro.kludge_nbb)
444             p_vpar->synchro.kludge_level = p_vpar->synchro.kludge_nbp + p_vpar->synchro.kludge_nbb;
445 #ifdef DEBUG
446         if (temp != p_vpar->synchro.kludge_level)
447             intf_DbgMsg("vdec debug: Level changed from %d to %d (%Ld)\n",
448                         temp, p_vpar->synchro.kludge_level, show_date );
449 #endif
450     }
451
452     p_vpar->synchro.kludge_prevdate = show_date;
453     if ((p_vpar->synchro.kludge_level - p_vpar->synchro.kludge_nbp) > p_vpar->synchro.kludge_nbb)
454         p_vpar->synchro.kludge_level = p_vpar->synchro.kludge_nbb + p_vpar->synchro.kludge_nbp;
455 }
456
457 #endif
458
459
460 #ifdef POLUX_SYNCHRO
461
462 void vpar_SynchroSetCurrentDate( vpar_thread_t * p_vpar, int i_coding_type )
463 {
464     pes_packet_t * p_pes =
465         p_vpar->bit_stream.p_decoder_fifo->buffer[p_vpar->bit_stream.p_decoder_fifo->i_start];
466
467
468     switch( i_coding_type )
469     {
470     case B_CODING_TYPE:
471         if( p_pes->b_has_pts )
472         {
473             if( p_pes->i_pts < p_vpar->synchro.i_current_frame_date )
474             {
475                 intf_ErrMsg( "vpar warning: pts_date < current_date\n" );
476             }
477             p_vpar->synchro.i_current_frame_date = p_pes->i_pts;
478             p_pes->b_has_pts = 0;
479         }
480         else
481         {
482             p_vpar->synchro.i_current_frame_date += 1000000/(p_vpar->sequence.r_frame_rate);
483         }
484         break;
485
486     default:
487
488         if( p_vpar->synchro.i_backward_frame_date == 0 )
489         {
490             p_vpar->synchro.i_current_frame_date += 1000000/(p_vpar->sequence.r_frame_rate);
491         }
492         else
493         {
494             if( p_vpar->synchro.i_backward_frame_date < p_vpar->synchro.i_current_frame_date )
495             {
496                 intf_ErrMsg( "vpar warning: backward_date < current_date (%Ld)\n",
497                          p_vpar->synchro.i_backward_frame_date - p_vpar->synchro.i_current_frame_date );
498             }
499             p_vpar->synchro.i_current_frame_date = p_vpar->synchro.i_backward_frame_date;
500             p_vpar->synchro.i_backward_frame_date = 0;
501         }
502
503         if( p_pes->b_has_pts )
504         {
505             p_vpar->synchro.i_backward_frame_date = p_pes->i_pts;
506             p_pes->b_has_pts = 0;
507         }
508        break;
509     }
510 }
511
512 boolean_t vpar_SynchroChoose( vpar_thread_t * p_vpar, int i_coding_type,
513                               int i_structure )
514 {
515     boolean_t b_result = 1;
516     int i_synchro_level = p_vpar->p_vout->i_synchro_level;
517
518     vpar_SynchroSetCurrentDate( p_vpar, i_coding_type );
519
520     /*
521      * The synchro level is updated by the video input (see SynchroLevelUpdate)
522      * so we just use the synchro_level to decide which frame to trash
523      */
524
525     switch( i_coding_type )
526     {
527     case I_CODING_TYPE:
528
529         p_vpar->synchro.r_p_average =
530             (p_vpar->synchro.r_p_average*(SYNC_AVERAGE_COUNT-1)+p_vpar->synchro.i_p_count)/SYNC_AVERAGE_COUNT;
531         p_vpar->synchro.r_b_average =
532             (p_vpar->synchro.r_b_average*(SYNC_AVERAGE_COUNT-1)+p_vpar->synchro.i_b_count)/SYNC_AVERAGE_COUNT;
533
534         p_vpar->synchro.i_p_nb = (int)(p_vpar->synchro.r_p_average+0.5);
535         p_vpar->synchro.i_b_nb = (int)(p_vpar->synchro.r_b_average+0.5);
536
537         p_vpar->synchro.i_p_count = p_vpar->synchro.i_b_count = 0;
538         p_vpar->synchro.i_b_trasher = p_vpar->synchro.i_b_nb / 2;
539         p_vpar->synchro.i_i_count++;
540        break;
541
542     case P_CODING_TYPE:
543         p_vpar->synchro.i_p_count++;
544         if( p_vpar->synchro.i_p_count > i_synchro_level )
545         {
546             b_result = 0;
547         }
548         break;
549
550     case B_CODING_TYPE:
551         p_vpar->synchro.i_b_count++;
552         if( p_vpar->synchro.i_p_nb >= i_synchro_level )
553         {
554             /* We must trash all the B */
555             b_result = 0;
556         }
557         else
558         {
559             /* We use the brensenham algorithm to decide which B to trash */
560             p_vpar->synchro.i_b_trasher +=
561                 p_vpar->synchro.i_b_nb - (i_synchro_level-p_vpar->synchro.i_p_nb);
562             if( p_vpar->synchro.i_b_trasher >= p_vpar->synchro.i_b_nb )
563             {
564                 b_result = 0;
565                 p_vpar->synchro.i_b_trasher -= p_vpar->synchro.i_b_nb;
566             }
567         }
568         break;
569     }
570
571     return( b_result );
572 }
573
574 void vpar_SynchroTrash( vpar_thread_t * p_vpar, int i_coding_type,
575                         int i_structure )
576 {
577     vpar_SynchroChoose( p_vpar, i_coding_type, i_structure );
578 }
579
580 void vpar_SynchroUpdateLevel()
581 {
582     //vlc_mutex_lock( &level_lock );
583     //vlc_mutex_unlock( &level_lock );
584 }
585
586 mtime_t vpar_SynchroDate( vpar_thread_t * p_vpar )
587 {
588     return( p_vpar->synchro.i_current_frame_date );
589 }
590
591 /* functions with no use */
592
593 void vpar_SynchroEnd( vpar_thread_t * p_vpar )
594 {
595 }
596
597 void vpar_SynchroDecode( vpar_thread_t * p_vpar, int i_coding_type,
598                             int i_structure )
599 {
600 }
601
602 #endif