]> git.sesse.net Git - vlc/blob - src/input/input_pcr.c
a4f9cb26b73d502363979ada49e8ca0c799cc946
[vlc] / src / input / input_pcr.c
1 /*******************************************************************************
2  * pcr.c: PCR management 
3  * (c)1999 VideoLAN
4  *******************************************************************************
5  * Manages structures containing PCR information.
6  *******************************************************************************/
7
8 /*******************************************************************************
9  * Preamble
10  *******************************************************************************/
11 #include <stdio.h>
12 #include <sys/uio.h>                                                 /* iovec */
13 #include <stdlib.h>                               /* atoi(), malloc(), free() */
14 #include <netinet/in.h>
15
16 #include "config.h"
17 #include "common.h"
18 #include "mtime.h"
19 #include "vlc_thread.h"
20 #include "debug.h"
21 #include "input.h"
22 #include "intf_msg.h"
23 #include "input_pcr.h"
24
25 /* Note:
26  *   
27  *   SYNCHRONIZATION METHOD
28  *   
29  *   We compute an average for the pcr because we want to eliminate the
30  *   network jitter and keep the low frequency variations. The average is
31  *   in fact a low pass filter and the jitter is a high frequency signal
32  *   that is why it is eliminated by the filter/average.
33  *   
34  *   The low frequency variations enable us to synchronize the client clock
35  *   with the server clock because they represent the time variation between
36  *   the 2 clocks. Those variations (ie the filtered pcr) are used to compute
37  *   the presentation dates for the audio and video frames. With those dates
38  *   we can decoding (or trashing) the MPEG2 stream at "exactly" the same rate
39  *   as it is sent by the server and so we keep the synchronization between
40  *   the server and the client.
41  *   
42  *   It is a very important matter if you want to avoid underflow or overflow
43  *   in all the FIFOs, but it may be not enough.
44  *
45  */
46
47 /******************************************************************************
48  * input_PcrReInit : Reinitialize the pcr_descriptor
49  ******************************************************************************/
50 void input_PcrReInit( input_thread_t *p_input )
51 {
52     ASSERT( p_input );
53
54     p_input->p_pcr->delta_pcr       = 0;
55     p_input->p_pcr->last_pcr        = 0;
56     p_input->p_pcr->c_average_count = 0;
57 }
58
59 /******************************************************************************
60  * input_PcrInit : Initialize PCR decoder
61  ******************************************************************************/
62 int input_PcrInit( input_thread_t *p_input )
63 {
64     ASSERT( p_input );
65
66     if( (p_input->p_pcr = malloc(sizeof(pcr_descriptor_t))) == NULL )
67     {
68         return( -1 );
69     }
70     input_PcrReInit(p_input);
71     p_input->p_pcr->i_synchro_state = SYNCHRO_NOT_STARTED;
72     
73     return( 0 );
74 }
75
76 /******************************************************************************
77  * input_PcrDecode : Decode a PCR frame
78  ******************************************************************************/
79 void input_PcrDecode( input_thread_t *p_input, es_descriptor_t *p_es,
80                       u8* p_pcr_data )
81 {
82     mtime_t pcr_time, sys_time, delta_pcr;
83     pcr_descriptor_t *p_pcr;
84         
85     ASSERT( p_pcr_data );
86     ASSERT( p_input );
87     ASSERT( p_es );
88
89     p_pcr = p_input->p_pcr;
90     
91     /* Convert the PCR in microseconde
92      * WARNING: do not remove the casts in the following calculation ! */
93     pcr_time  = ( (( (mtime_t)U32_AT((u32*)p_pcr_data) << 1 ) | ( p_pcr_data[4] >> 7 )) * 300 ) / 27;
94     sys_time  = mdate();
95     delta_pcr = sys_time - pcr_time;
96     
97     if( p_es->b_discontinuity ||
98         ( p_pcr->last_pcr != 0 && 
99               (    (p_pcr->last_pcr - pcr_time) > PCR_MAX_GAP
100                 || (p_pcr->last_pcr - pcr_time) < - PCR_MAX_GAP ) ) )
101     {
102         intf_DbgMsg("input debug: input_PcrReInit()\n");
103         input_PcrReInit(p_input);
104         p_pcr->i_synchro_state = SYNCHRO_REINIT;
105         p_es->b_discontinuity = 0;
106     }
107     p_pcr->last_pcr = pcr_time;
108
109     if( p_pcr->c_average_count == PCR_MAX_AVERAGE_COUNTER )
110     {
111         p_pcr->delta_pcr = 
112             ( delta_pcr + (p_pcr->delta_pcr * (PCR_MAX_AVERAGE_COUNTER-1)) )
113             / PCR_MAX_AVERAGE_COUNTER;
114     }
115     else
116     {
117         p_pcr->delta_pcr =
118             ( delta_pcr + (p_pcr->delta_pcr * p_pcr->c_average_count) )
119             / ( p_pcr->c_average_count + 1 );
120         p_pcr->c_average_count++;
121     }
122
123     if( p_pcr->i_synchro_state == SYNCHRO_NOT_STARTED )
124     {
125         p_pcr->i_synchro_state = SYNCHRO_START;
126     }
127 }
128
129 /******************************************************************************
130  * input_PcrClean : Clean PCR structures before dying
131  ******************************************************************************/
132 void input_PcrClean( input_thread_t *p_input )
133 {
134     ASSERT( p_input );
135
136     free( p_input->p_pcr );
137 }