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