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