Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc
Commits
5fc945b6
Commit
5fc945b6
authored
Jan 07, 2000
by
Jean-Marc Dressler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refonte de la synchro qui devrait eliminer les problemes rencontres
lors des changements de flux.
parent
5671a4b5
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
87 additions
and
106 deletions
+87
-106
include/input.h
include/input.h
+5
-13
include/input_pcr.h
include/input_pcr.h
+6
-1
src/input/input.c
src/input/input.c
+27
-16
src/input/input_pcr.c
src/input/input_pcr.c
+49
-76
No files found.
include/input.h
View file @
5fc945b6
...
@@ -207,23 +207,15 @@ typedef struct
...
@@ -207,23 +207,15 @@ typedef struct
typedef
struct
pcr_descriptor_struct
typedef
struct
pcr_descriptor_struct
{
{
vlc_mutex_t
lock
;
/* pcr modification lock */
/* system_date = PTS_date + delta_pcr + delta_absolute */
mtime_t
delta_pcr
;
mtime_t
delta_absolute
;
mtime_t
delta_clock
;
mtime_t
delta_decode
;
/* represents decoder_time - pcr_time in usecondes */
mtime_t
last_pcr
;
mtime_t
last_pcr
;
count_t
c_average
;
u32
i_synchro_state
;
count_t
c_average_count
;
/* counter used to compute dynamic average values */
/* counter used to compute dynamic average values */
count_t
c_pts
;
#ifdef STATS
/* Stats */
count_t
c_average_jitter
;
mtime_t
max_jitter
;
/* the evalueted maximum jitter */
mtime_t
average_jitter
;
/* the evalueted average jitter */
count_t
c_pcr
;
/* the number of PCR which have been decoded */
#endif
}
pcr_descriptor_t
;
}
pcr_descriptor_t
;
/******************************************************************************
/******************************************************************************
...
...
include/input_pcr.h
View file @
5fc945b6
...
@@ -9,9 +9,14 @@
...
@@ -9,9 +9,14 @@
* new_average = (old_average * c_average + new_sample_value) / (c_average +1) */
* new_average = (old_average * c_average + new_sample_value) / (c_average +1) */
#define PCR_MAX_AVERAGE_COUNTER 40
#define PCR_MAX_AVERAGE_COUNTER 40
/* Maximum
allowed gap
between two PCRs. */
/* Maximum
gap allowed
between two PCRs. */
#define PCR_MAX_GAP 1000000
#define PCR_MAX_GAP 1000000
/* synchro states */
#define SYNCHRO_NOT_STARTED 1
#define SYNCHRO_START 2
#define SYNCHRO_REINIT 3
/******************************************************************************
/******************************************************************************
* Prototypes
* Prototypes
******************************************************************************/
******************************************************************************/
...
...
src/input/input.c
View file @
5fc945b6
...
@@ -915,27 +915,38 @@ static __inline__ void input_DemuxPES( input_thread_t *p_input,
...
@@ -915,27 +915,38 @@ static __inline__ void input_DemuxPES( input_thread_t *p_input,
pcr_descriptor_t
*
p_pcr
;
pcr_descriptor_t
*
p_pcr
;
p_pcr
=
p_input
->
p_pcr
;
p_pcr
=
p_input
->
p_pcr
;
vlc_mutex_lock
(
&
p_pcr
->
lock
);
if
(
p_pcr
->
delta_clock
==
0
)
p_pes
->
i_pts
=
(
((
mtime_t
)(
p_pes
->
p_pes_header
[
9
]
&
0x0E
)
<<
29
)
|
(((
mtime_t
)
U16_AT
(
p_pes
->
p_pes_header
+
10
)
<<
14
)
-
(
1
<<
14
))
|
((
mtime_t
)
U16_AT
(
p_pes
->
p_pes_header
+
12
)
>>
1
)
)
*
300
;
p_pes
->
i_pts
/=
27
;
if
(
p_pcr
->
i_synchro_state
)
{
{
p_pes
->
b_has_pts
=
0
;
switch
(
p_pcr
->
i_synchro_state
)
{
case
SYNCHRO_NOT_STARTED
:
p_pes
->
b_has_pts
=
0
;
break
;
case
SYNCHRO_START
:
p_pes
->
i_pts
+=
p_pcr
->
delta_pcr
;
p_pcr
->
delta_absolute
=
mdate
()
-
p_pes
->
i_pts
+
500000
;
p_pes
->
i_pts
+=
p_pcr
->
delta_absolute
;
p_pcr
->
i_synchro_state
=
0
;
break
;
case
SYNCHRO_REINIT
:
/* We skip a PES */
p_pes
->
b_has_pts
=
0
;
p_pcr
->
i_synchro_state
=
SYNCHRO_START
;
break
;
}
}
}
else
else
{
{
p_pes
->
i_pts
=
(
((
mtime_t
)(
p_pes
->
p_pes_header
[
9
]
&
0x0E
)
<<
29
)
|
p_pes
->
i_pts
+=
p_pcr
->
delta_pcr
+
p_pcr
->
delta_absolute
;
(((
mtime_t
)
U16_AT
(
p_pes
->
p_pes_header
+
10
)
<<
14
)
-
(
1
<<
14
))
|
((
mtime_t
)
U16_AT
(
p_pes
->
p_pes_header
+
12
)
>>
1
)
);
p_pes
->
i_pts
*=
300
;
p_pes
->
i_pts
/=
27
;
p_pes
->
i_pts
+=
p_pcr
->
delta_clock
;
if
(
p_pcr
->
c_pts
==
0
)
{
p_pcr
->
delta_decode
=
mdate
()
-
p_pes
->
i_pts
+
500000
;
}
p_pes
->
i_pts
+=
p_pcr
->
delta_decode
;
p_pcr
->
c_pts
+=
1
;
}
}
vlc_mutex_unlock
(
&
p_pcr
->
lock
);
}
}
break
;
break
;
}
}
...
...
src/input/input_pcr.c
View file @
5fc945b6
...
@@ -22,25 +22,38 @@
...
@@ -22,25 +22,38 @@
#include "intf_msg.h"
#include "intf_msg.h"
#include "input_pcr.h"
#include "input_pcr.h"
/* Note:
*
* SYNCHRONIZATION METHOD
*
* We compute an average for the pcr because we want to eliminate the
* network jitter and keep the low frequency variations. The average is
* in fact a low pass filter and the jitter is a high frequency signal
* that is why it is eliminated by the filter/average.
*
* The low frequency variations enable us to synchronize the client clock
* with the server clock because they represent the time variation between
* the 2 clocks. Those variations (ie the filtered pcr) are used to compute
* the presentation dates for the audio and video frames. With those dates
* we can decoding (or trashing) the MPEG2 stream at "exactly" the same rate
* as it is sent by the server and so we keep the synchronization between
* the server and the client.
*
* It is a very important matter if you want to avoid underflow or overflow
* in all the FIFOs, but it may be not enough.
*
*/
/******************************************************************************
/******************************************************************************
* input_PcrReInit : Reinitialize the pcr_descriptor
* input_PcrReInit : Reinitialize the pcr_descriptor
******************************************************************************/
******************************************************************************/
void
input_PcrReInit
(
input_thread_t
*
p_input
)
void
input_PcrReInit
(
input_thread_t
*
p_input
)
{
{
ASSERT
(
p_input
);
ASSERT
(
p_input
);
p_input
->
p_pcr
->
delta_clock
=
0
;
p_input
->
p_pcr
->
c_average
=
0
;
p_input
->
p_pcr
->
c_pts
=
0
;
p_input
->
p_pcr
->
last_pcr
=
0
;
#ifdef STATS
p_input
->
p_pcr
->
delta_pcr
=
0
;
p_input
->
p_pcr
->
c_average_jitter
=
0
;
p_input
->
p_pcr
->
last_pcr
=
0
;
p_input
->
p_pcr
->
c_pcr
=
0
;
p_input
->
p_pcr
->
c_average_count
=
0
;
p_input
->
p_pcr
->
max_jitter
=
0
;
/* For the printf in input_PcrDecode() (for debug purpose only) */
printf
(
"
\n
"
);
#endif
}
}
/******************************************************************************
/******************************************************************************
...
@@ -48,14 +61,14 @@ void input_PcrReInit( input_thread_t *p_input )
...
@@ -48,14 +61,14 @@ void input_PcrReInit( input_thread_t *p_input )
******************************************************************************/
******************************************************************************/
int
input_PcrInit
(
input_thread_t
*
p_input
)
int
input_PcrInit
(
input_thread_t
*
p_input
)
{
{
ASSERT
(
p_input
);
ASSERT
(
p_input
);
if
(
(
p_input
->
p_pcr
=
malloc
(
sizeof
(
pcr_descriptor_t
)))
==
NULL
)
if
(
(
p_input
->
p_pcr
=
malloc
(
sizeof
(
pcr_descriptor_t
)))
==
NULL
)
{
{
return
(
-
1
);
return
(
-
1
);
}
}
vlc_mutex_init
(
&
p_input
->
p_pcr
->
lock
);
input_PcrReInit
(
p_input
);
input_PcrReInit
(
p_input
);
p_input
->
p_pcr
->
i_synchro_state
=
SYNCHRO_NOT_STARTED
;
return
(
0
);
return
(
0
);
}
}
...
@@ -66,91 +79,51 @@ int input_PcrInit( input_thread_t *p_input )
...
@@ -66,91 +79,51 @@ int input_PcrInit( input_thread_t *p_input )
void
input_PcrDecode
(
input_thread_t
*
p_input
,
es_descriptor_t
*
p_es
,
void
input_PcrDecode
(
input_thread_t
*
p_input
,
es_descriptor_t
*
p_es
,
u8
*
p_pcr_data
)
u8
*
p_pcr_data
)
{
{
mtime_t
pcr_time
,
sys_time
,
delta_
clock
;
mtime_t
pcr_time
,
sys_time
,
delta_
pcr
;
pcr_descriptor_t
*
p_pcr
;
pcr_descriptor_t
*
p_pcr
;
ASSERT
(
p_pcr_data
);
ASSERT
(
p_pcr_data
);
ASSERT
(
p_input
);
ASSERT
(
p_input
);
ASSERT
(
p_es
);
ASSERT
(
p_es
);
p_pcr
=
p_input
->
p_pcr
;
p_pcr
=
p_input
->
p_pcr
;
/*
Express
the PCR in microseconde
/*
Convert
the PCR in microseconde
* WARNING: do not remove the casts in the following calculation ! */
* WARNING: do not remove the casts in the following calculation ! */
pcr_time
=
(
((
(
mtime_t
)
U32_AT
((
u32
*
)
p_pcr_data
)
<<
1
)
|
(
p_pcr_data
[
4
]
>>
7
))
*
300
)
/
27
;
pcr_time
=
(
((
(
mtime_t
)
U32_AT
((
u32
*
)
p_pcr_data
)
<<
1
)
|
(
p_pcr_data
[
4
]
>>
7
))
*
300
)
/
27
;
sys_time
=
mdate
();
sys_time
=
mdate
();
delta_clock
=
sys_time
-
pcr_time
;
delta_pcr
=
sys_time
-
pcr_time
;
vlc_mutex_lock
(
&
p_pcr
->
lock
);
if
(
p_es
->
b_discontinuity
||
if
(
p_es
->
b_discontinuity
||
(
p_pcr
->
last_pcr
!=
0
&&
(
p_pcr
->
last_pcr
!=
0
&&
(
(
p_pcr
->
last_pcr
-
pcr_time
)
>
PCR_MAX_GAP
(
(
p_pcr
->
last_pcr
-
pcr_time
)
>
PCR_MAX_GAP
||
(
p_pcr
->
last_pcr
-
pcr_time
)
<
-
PCR_MAX_GAP
)
)
)
||
(
p_pcr
->
last_pcr
-
pcr_time
)
<
-
PCR_MAX_GAP
)
)
)
{
{
intf_DbgMsg
(
"input debug: input_PcrReInit()
\n
"
);
intf_DbgMsg
(
"input debug: input_PcrReInit()
\n
"
);
input_PcrReInit
(
p_input
);
input_PcrReInit
(
p_input
);
p_pcr
->
i_synchro_state
=
SYNCHRO_REINIT
;
p_es
->
b_discontinuity
=
0
;
p_es
->
b_discontinuity
=
0
;
}
}
p_pcr
->
last_pcr
=
pcr_time
;
p_pcr
->
last_pcr
=
pcr_time
;
if
(
p_pcr
->
c_average
==
PCR_MAX_AVERAGE_COUNTER
)
if
(
p_pcr
->
c_average
_count
==
PCR_MAX_AVERAGE_COUNTER
)
{
{
p_pcr
->
delta_clock
=
(
delta_clock
+
(
p_pcr
->
delta_clock
*
(
PCR_MAX_AVERAGE_COUNTER
-
1
)))
p_pcr
->
delta_pcr
=
/
PCR_MAX_AVERAGE_COUNTER
;
(
delta_pcr
+
(
p_pcr
->
delta_pcr
*
(
PCR_MAX_AVERAGE_COUNTER
-
1
))
)
/
PCR_MAX_AVERAGE_COUNTER
;
}
}
else
else
{
{
p_pcr
->
delta_clock
=
(
delta_clock
+
(
p_pcr
->
delta_clock
*
p_pcr
->
c_average
))
p_pcr
->
delta_pcr
=
/
(
p_pcr
->
c_average
+
1
);
(
delta_pcr
+
(
p_pcr
->
delta_pcr
*
p_pcr
->
c_average_count
)
)
p_pcr
->
c_average
++
;
/
(
p_pcr
->
c_average_count
+
1
);
p_pcr
->
c_average_count
++
;
}
}
vlc_mutex_unlock
(
&
p_pcr
->
lock
);
if
(
p_pcr
->
i_synchro_state
==
SYNCHRO_NOT_STARTED
)
#ifdef STATS
{
{
mtime_t
jitter
;
p_pcr
->
i_synchro_state
=
SYNCHRO_START
;
jitter
=
delta_clock
-
p_pcr
->
delta_clock
;
/* Compute the maximum jitter */
if
(
jitter
<
0
)
{
if
(
(
p_pcr
->
max_jitter
<=
0
&&
p_pcr
->
max_jitter
>=
jitter
)
||
(
p_pcr
->
max_jitter
>=
0
&&
p_pcr
->
max_jitter
<=
-
jitter
))
{
p_pcr
->
max_jitter
=
jitter
;
}
}
else
{
if
(
(
p_pcr
->
max_jitter
<=
0
&&
-
p_pcr
->
max_jitter
<=
jitter
)
||
(
p_pcr
->
max_jitter
>=
0
&&
p_pcr
->
max_jitter
<=
jitter
))
{
p_pcr
->
max_jitter
=
jitter
;
}
}
/* Compute the average jitter */
if
(
p_pcr
->
c_average_jitter
==
PCR_MAX_AVERAGE_COUNTER
)
{
p_pcr
->
average_jitter
=
(
jitter
+
(
p_pcr
->
average_jitter
*
(
PCR_MAX_AVERAGE_COUNTER
-
1
)))
/
PCR_MAX_AVERAGE_COUNTER
;
}
else
{
p_pcr
->
average_jitter
=
(
jitter
+
(
p_pcr
->
average_jitter
*
p_pcr
->
c_average_jitter
))
/
(
p_pcr
->
c_average
+
1
);
p_pcr
->
c_average_jitter
++
;
}
printf
(
"delta: % 13Ld, max_jitter: % 9Ld, av. jitter: % 6Ld, PCR %6ld
\r
"
,
p_pcr
->
delta_clock
,
p_pcr
->
max_jitter
,
p_pcr
->
average_jitter
,
p_pcr
->
c_pcr
);
fflush
(
stdout
);
p_pcr
->
c_pcr
++
;
}
}
#endif
}
}
/******************************************************************************
/******************************************************************************
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment