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
ff85edc6
Commit
ff85edc6
authored
Feb 07, 2001
by
Christophe Massiot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
* Centralized clock management, preparing for stream navigation ;
* Fixed a bug in the management of the first video PTS.
parent
422bd79f
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
215 additions
and
168 deletions
+215
-168
include/input_ext-intf.h
include/input_ext-intf.h
+3
-2
src/input/input.h
src/input/input.h
+10
-5
src/input/input_clock.c
src/input/input_clock.c
+168
-4
src/input/input_programs.c
src/input/input_programs.c
+7
-9
src/input/input_ps.c
src/input/input_ps.c
+2
-1
src/input/mpeg_system.c
src/input/mpeg_system.c
+15
-144
src/misc/modules.c
src/misc/modules.c
+2
-2
src/video_parser/video_parser.c
src/video_parser/video_parser.c
+8
-1
No files found.
include/input_ext-intf.h
View file @
ff85edc6
...
@@ -4,7 +4,7 @@
...
@@ -4,7 +4,7 @@
* control the pace of reading.
* control the pace of reading.
*****************************************************************************
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* Copyright (C) 1999, 2000 VideoLAN
* $Id: input_ext-intf.h,v 1.1
1 2001/01/30 05:48:23 sam
Exp $
* $Id: input_ext-intf.h,v 1.1
2 2001/02/07 15:32:25 massiot
Exp $
*
*
* Authors:
* Authors:
*
*
...
@@ -110,7 +110,8 @@ typedef struct pgrm_descriptor_s
...
@@ -110,7 +110,8 @@ typedef struct pgrm_descriptor_s
/* Synchronization information */
/* Synchronization information */
mtime_t
delta_cr
;
mtime_t
delta_cr
;
mtime_t
cr_ref
,
sysdate_ref
;
mtime_t
cr_ref
,
sysdate_ref
;
mtime_t
last_cr
;
mtime_t
last_cr
;
/* reference to detect unexpected stream
* discontinuities */
count_t
c_average_count
;
count_t
c_average_count
;
/* counter used to compute dynamic average values */
/* counter used to compute dynamic average values */
int
i_synchro_state
;
int
i_synchro_state
;
...
...
src/input/input.h
View file @
ff85edc6
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* input.h: structures of the input not exported to other modules
* input.h: structures of the input not exported to other modules
*****************************************************************************
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* Copyright (C) 1999, 2000 VideoLAN
* $Id: input.h,v 1.1
2 2001/01/24 19:05:5
5 massiot Exp $
* $Id: input.h,v 1.1
3 2001/02/07 15:32:2
5 massiot Exp $
*
*
* Authors:
* Authors:
*
*
...
@@ -30,7 +30,7 @@
...
@@ -30,7 +30,7 @@
* Ethernet MTU is 1500 bytes, so in a UDP *
* Ethernet MTU is 1500 bytes, so in a UDP *
* packet we can put : 1500/188 = 7 TS *
* packet we can put : 1500/188 = 7 TS *
* packets. Have a nice day and merry Xmas. */
* packets. Have a nice day and merry Xmas. */
#define PADDING_PACKET_SIZE 1
00
/* Size of the NULL packet inserted in case
#define PADDING_PACKET_SIZE 1
88
/* Size of the NULL packet inserted in case
* of data loss (this should be < 188). */
* of data loss (this should be < 188). */
/*****************************************************************************
/*****************************************************************************
...
@@ -78,7 +78,7 @@ void NextDataPacket ( struct bit_stream_s * );
...
@@ -78,7 +78,7 @@ void NextDataPacket ( struct bit_stream_s * );
/*****************************************************************************
/*****************************************************************************
* Prototypes from input_programs.c
* Prototypes from input_programs.c
*****************************************************************************/
*****************************************************************************/
void
input_InitStream
(
struct
input_thread_s
*
,
size_t
);
int
input_InitStream
(
struct
input_thread_s
*
,
size_t
);
void
input_EndStream
(
struct
input_thread_s
*
);
void
input_EndStream
(
struct
input_thread_s
*
);
struct
pgrm_descriptor_s
*
input_FindProgram
(
struct
input_thread_s
*
,
u16
);
struct
pgrm_descriptor_s
*
input_FindProgram
(
struct
input_thread_s
*
,
u16
);
struct
pgrm_descriptor_s
*
input_AddProgram
(
struct
input_thread_s
*
,
struct
pgrm_descriptor_s
*
input_AddProgram
(
struct
input_thread_s
*
,
...
@@ -103,10 +103,15 @@ void input_DecodePES( struct decoder_fifo_s *, struct pes_packet_s * );
...
@@ -103,10 +103,15 @@ void input_DecodePES( struct decoder_fifo_s *, struct pes_packet_s * );
/*****************************************************************************
/*****************************************************************************
* Prototypes from input_clock.c
* Prototypes from input_clock.c
*****************************************************************************/
*****************************************************************************/
mtime_t
input_ClockToSysdate
(
struct
input_thread_s
*
,
struct
pgrm_descriptor_s
*
,
mtime_t
);
void
input_ClockNewRef
(
struct
input_thread_s
*
,
void
input_ClockNewRef
(
struct
input_thread_s
*
,
struct
pgrm_descriptor_s
*
,
mtime_t
);
struct
pgrm_descriptor_s
*
,
mtime_t
);
void
input_EscapeDiscontinuity
(
struct
input_thread_s
*
,
struct
pgrm_descriptor_s
*
);
void
input_ClockInit
(
struct
pgrm_descriptor_s
*
);
void
input_ClockManageRef
(
struct
input_thread_s
*
,
struct
pgrm_descriptor_s
*
,
mtime_t
);
mtime_t
input_ClockGetTS
(
struct
input_thread_s
*
,
struct
pgrm_descriptor_s
*
,
mtime_t
);
/*****************************************************************************
/*****************************************************************************
* Create a NULL packet for padding in case of a data loss
* Create a NULL packet for padding in case of a data loss
...
...
src/input/input_clock.c
View file @
ff85edc6
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* input_clock.c: Clock/System date conversions, stream management
* input_clock.c: Clock/System date conversions, stream management
*****************************************************************************
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* Copyright (C) 1999, 2000 VideoLAN
* $Id: input_clock.c,v 1.
1 2001/01/24 19:05:55
massiot Exp $
* $Id: input_clock.c,v 1.
2 2001/02/07 15:32:26
massiot Exp $
*
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
*
...
@@ -38,10 +38,50 @@
...
@@ -38,10 +38,50 @@
#include "input.h"
#include "input.h"
/*
* DISCUSSION : SYNCHRONIZATION METHOD
*
* In some cases we can impose the pace of reading (when reading from a
* file or a pipe), and for the synchronization we simply sleep() until
* it is time to deliver the packet to the decoders. When reading from
* the network, we must be read at the same pace as the server writes,
* otherwise the kernel's buffer will trash packets. The risk is now to
* overflow the input buffers in case the server goes too fast, that is
* why we do these calculations :
*
* We compute a mean for the pcr because we want to eliminate the
* network jitter and keep the low frequency variations. The mean 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 decode (or trash) 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_ClockToSysdate: converts a movie clock to system date
*
Constants
*****************************************************************************/
*****************************************************************************/
mtime_t
input_ClockToSysdate
(
input_thread_t
*
p_input
,
/* Maximum number of samples used to compute the dynamic average value.
* We use the following formula :
* new_average = (old_average * c_average + new_sample_value) / (c_average +1) */
#define CR_MAX_AVERAGE_COUNTER 40
/* Maximum gap allowed between two CRs. */
#define CR_MAX_GAP 1000000
/*****************************************************************************
* ClockToSysdate: converts a movie clock to system date
*****************************************************************************/
static
mtime_t
ClockToSysdate
(
input_thread_t
*
p_input
,
pgrm_descriptor_t
*
p_pgrm
,
mtime_t
i_clock
)
pgrm_descriptor_t
*
p_pgrm
,
mtime_t
i_clock
)
{
{
mtime_t
i_sysdate
=
0
;
mtime_t
i_sysdate
=
0
;
...
@@ -59,6 +99,19 @@ mtime_t input_ClockToSysdate( input_thread_t * p_input,
...
@@ -59,6 +99,19 @@ mtime_t input_ClockToSysdate( input_thread_t * p_input,
return
(
i_sysdate
);
return
(
i_sysdate
);
}
}
/*****************************************************************************
* ClockCurrent: converts current system date to clock units
*****************************************************************************
* Caution : the synchro state must be SYNCHRO_OK for this to operate.
*****************************************************************************/
static
mtime_t
ClockCurrent
(
input_thread_t
*
p_input
,
pgrm_descriptor_t
*
p_pgrm
)
{
return
(
(
mdate
()
-
p_pgrm
->
sysdate_ref
)
*
27
*
DEFAULT_RATE
/
p_input
->
stream
.
control
.
i_rate
/
300
+
p_pgrm
->
cr_ref
);
}
/*****************************************************************************
/*****************************************************************************
* input_ClockNewRef: writes a new clock reference
* input_ClockNewRef: writes a new clock reference
*****************************************************************************/
*****************************************************************************/
...
@@ -69,3 +122,114 @@ void input_ClockNewRef( input_thread_t * p_input, pgrm_descriptor_t * p_pgrm,
...
@@ -69,3 +122,114 @@ void input_ClockNewRef( input_thread_t * p_input, pgrm_descriptor_t * p_pgrm,
p_pgrm
->
sysdate_ref
=
mdate
();
p_pgrm
->
sysdate_ref
=
mdate
();
}
}
/*****************************************************************************
* input_EscapeDiscontinuity: send a NULL packet to the decoders
*****************************************************************************/
void
input_EscapeDiscontinuity
(
input_thread_t
*
p_input
,
pgrm_descriptor_t
*
p_pgrm
)
{
int
i_es
;
for
(
i_es
=
0
;
i_es
<
p_pgrm
->
i_es_number
;
i_es
++
)
{
es_descriptor_t
*
p_es
=
p_pgrm
->
pp_es
[
i_es
];
if
(
p_es
->
p_decoder_fifo
!=
NULL
)
{
input_NullPacket
(
p_input
,
p_es
);
}
}
}
/*****************************************************************************
* input_ClockInit: reinitializes the clock reference after a stream
* discontinuity
*****************************************************************************/
void
input_ClockInit
(
pgrm_descriptor_t
*
p_pgrm
)
{
p_pgrm
->
last_cr
=
0
;
p_pgrm
->
cr_ref
=
0
;
p_pgrm
->
sysdate_ref
=
0
;
p_pgrm
->
delta_cr
=
0
;
p_pgrm
->
c_average_count
=
0
;
}
/*****************************************************************************
* input_ClockManageRef: manages a clock reference
*****************************************************************************/
void
input_ClockManageRef
(
input_thread_t
*
p_input
,
pgrm_descriptor_t
*
p_pgrm
,
mtime_t
i_clock
)
{
if
(
p_pgrm
->
i_synchro_state
!=
SYNCHRO_OK
)
{
/* Feed synchro with a new reference point. */
input_ClockNewRef
(
p_input
,
p_pgrm
,
i_clock
);
p_pgrm
->
i_synchro_state
=
SYNCHRO_OK
;
}
else
{
if
(
p_pgrm
->
last_cr
!=
0
&&
(
(
p_pgrm
->
last_cr
-
i_clock
)
>
CR_MAX_GAP
||
(
p_pgrm
->
last_cr
-
i_clock
)
<
-
CR_MAX_GAP
)
)
{
/* Stream discontinuity, for which we haven't received a
* warning from the stream control facilities (dd-edited
* stream ?). */
intf_WarnMsg
(
3
,
"Clock gap, unexpected stream discontinuity"
);
input_ClockInit
(
p_pgrm
);
p_pgrm
->
i_synchro_state
=
SYNCHRO_START
;
input_EscapeDiscontinuity
(
p_input
,
p_pgrm
);
}
p_pgrm
->
last_cr
=
i_clock
;
if
(
p_input
->
stream
.
b_pace_control
&&
p_input
->
stream
.
pp_programs
[
0
]
==
p_pgrm
)
{
/* Wait a while before delivering the packets to the decoder.
* In case of multiple programs, we arbitrarily follow the
* clock of the first program. */
mwait
(
ClockToSysdate
(
p_input
,
p_pgrm
,
i_clock
)
);
}
else
{
/* Smooth clock reference variations. */
mtime_t
i_extrapoled_clock
=
ClockCurrent
(
p_input
,
p_pgrm
);
/* Bresenham algorithm to smooth variations. */
if
(
p_pgrm
->
c_average_count
==
CR_MAX_AVERAGE_COUNTER
)
{
p_pgrm
->
delta_cr
=
(
p_pgrm
->
delta_cr
*
(
CR_MAX_AVERAGE_COUNTER
-
1
)
+
i_extrapoled_clock
)
/
CR_MAX_AVERAGE_COUNTER
;
}
else
{
p_pgrm
->
delta_cr
=
(
p_pgrm
->
delta_cr
*
p_pgrm
->
c_average_count
+
i_extrapoled_clock
)
/
(
p_pgrm
->
c_average_count
+
1
);
p_pgrm
->
c_average_count
++
;
}
}
}
}
/*****************************************************************************
* input_ClockGetTS: manages a PTS or DTS
*****************************************************************************/
mtime_t
input_ClockGetTS
(
input_thread_t
*
p_input
,
pgrm_descriptor_t
*
p_pgrm
,
mtime_t
i_ts
)
{
if
(
p_pgrm
->
i_synchro_state
==
SYNCHRO_OK
)
{
return
(
ClockToSysdate
(
p_input
,
p_pgrm
,
i_ts
+
p_pgrm
->
delta_cr
)
+
DEFAULT_PTS_DELAY
);
}
else
{
return
0
;
}
}
src/input/input_programs.c
View file @
ff85edc6
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* input_programs.c: es_descriptor_t, pgrm_descriptor_t management
* input_programs.c: es_descriptor_t, pgrm_descriptor_t management
*****************************************************************************
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* Copyright (C) 1999, 2000 VideoLAN
* $Id: input_programs.c,v 1.2
7 2001/01/24 19:05:55
massiot Exp $
* $Id: input_programs.c,v 1.2
8 2001/02/07 15:32:26
massiot Exp $
*
*
* Authors:
* Authors:
*
*
...
@@ -51,7 +51,7 @@
...
@@ -51,7 +51,7 @@
/*****************************************************************************
/*****************************************************************************
* input_InitStream: init the stream descriptor of the given input
* input_InitStream: init the stream descriptor of the given input
*****************************************************************************/
*****************************************************************************/
void
input_InitStream
(
input_thread_t
*
p_input
,
size_t
i_data_len
)
int
input_InitStream
(
input_thread_t
*
p_input
,
size_t
i_data_len
)
{
{
p_input
->
stream
.
i_stream_id
=
0
;
p_input
->
stream
.
i_stream_id
=
0
;
p_input
->
stream
.
pp_es
=
NULL
;
p_input
->
stream
.
pp_es
=
NULL
;
...
@@ -63,11 +63,12 @@ void input_InitStream( input_thread_t * p_input, size_t i_data_len )
...
@@ -63,11 +63,12 @@ void input_InitStream( input_thread_t * p_input, size_t i_data_len )
if
(
(
p_input
->
stream
.
p_demux_data
=
malloc
(
i_data_len
))
==
NULL
)
if
(
(
p_input
->
stream
.
p_demux_data
=
malloc
(
i_data_len
))
==
NULL
)
{
{
intf_ErrMsg
(
"Unable to allocate memory in input_InitStream"
);
intf_ErrMsg
(
"Unable to allocate memory in input_InitStream"
);
/* FIXME : find a way to tell if failed */
return
1
;
return
;
}
}
memset
(
p_input
->
stream
.
p_demux_data
,
0
,
i_data_len
);
memset
(
p_input
->
stream
.
p_demux_data
,
0
,
i_data_len
);
}
}
return
0
;
}
}
/*****************************************************************************
/*****************************************************************************
...
@@ -147,11 +148,8 @@ pgrm_descriptor_t * input_AddProgram( input_thread_t * p_input,
...
@@ -147,11 +148,8 @@ pgrm_descriptor_t * input_AddProgram( input_thread_t * p_input,
p_input
->
stream
.
pp_programs
[
i_pgrm_index
]
->
i_es_number
=
0
;
p_input
->
stream
.
pp_programs
[
i_pgrm_index
]
->
i_es_number
=
0
;
p_input
->
stream
.
pp_programs
[
i_pgrm_index
]
->
pp_es
=
NULL
;
p_input
->
stream
.
pp_programs
[
i_pgrm_index
]
->
pp_es
=
NULL
;
p_input
->
stream
.
pp_programs
[
i_pgrm_index
]
->
delta_cr
=
0
;
input_ClockInit
(
p_input
->
stream
.
pp_programs
[
i_pgrm_index
]
);
p_input
->
stream
.
pp_programs
[
i_pgrm_index
]
->
cr_ref
=
0
;
p_input
->
stream
.
pp_programs
[
i_pgrm_index
]
->
sysdate_ref
=
0
;
p_input
->
stream
.
pp_programs
[
i_pgrm_index
]
->
last_cr
=
0
;
p_input
->
stream
.
pp_programs
[
i_pgrm_index
]
->
c_average_count
=
0
;
p_input
->
stream
.
pp_programs
[
i_pgrm_index
]
->
i_synchro_state
p_input
->
stream
.
pp_programs
[
i_pgrm_index
]
->
i_synchro_state
=
SYNCHRO_START
;
=
SYNCHRO_START
;
p_input
->
stream
.
pp_programs
[
i_pgrm_index
]
->
b_discontinuity
=
0
;
p_input
->
stream
.
pp_programs
[
i_pgrm_index
]
->
b_discontinuity
=
0
;
...
...
src/input/input_ps.c
View file @
ff85edc6
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* input_ps.c: PS demux and packet management
* input_ps.c: PS demux and packet management
*****************************************************************************
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
* Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: input_ps.c,v 1.2
1 2001/01/30 05:48:23 sam
Exp $
* $Id: input_ps.c,v 1.2
2 2001/02/07 15:32:26 massiot
Exp $
*
*
* Authors:
* Authors:
*
*
...
@@ -103,6 +103,7 @@ static void PSInit( input_thread_t * p_input )
...
@@ -103,6 +103,7 @@ static void PSInit( input_thread_t * p_input )
}
}
fseek
(
p_method
->
stream
,
0
,
SEEK_SET
);
fseek
(
p_method
->
stream
,
0
,
SEEK_SET
);
/* FIXME : detect if InitStream failed */
input_InitStream
(
p_input
,
sizeof
(
stream_ps_data_t
)
);
input_InitStream
(
p_input
,
sizeof
(
stream_ps_data_t
)
);
input_AddProgram
(
p_input
,
0
,
sizeof
(
stream_ps_data_t
)
);
input_AddProgram
(
p_input
,
0
,
sizeof
(
stream_ps_data_t
)
);
...
...
src/input/mpeg_system.c
View file @
ff85edc6
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* mpeg_system.c: TS, PS and PES management
* mpeg_system.c: TS, PS and PES management
*****************************************************************************
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
* Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: mpeg_system.c,v 1.2
8 2001/01/30 05:48:23 sam
Exp $
* $Id: mpeg_system.c,v 1.2
9 2001/02/07 15:32:26 massiot
Exp $
*
*
* Authors:
* Authors:
*
*
...
@@ -217,11 +217,10 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
...
@@ -217,11 +217,10 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
p_pes
=
NULL
;
p_pes
=
NULL
;
return
;
return
;
}
}
p_pes
->
i_pts
=
input_Clock
ToSysdate
(
p_input
,
p_es
->
p_pgrm
,
p_pes
->
i_pts
=
input_Clock
GetTS
(
p_input
,
p_es
->
p_pgrm
,
(
((
mtime_t
)(
p_full_header
[
2
]
&
0x0E
)
<<
29
)
|
(
((
mtime_t
)(
p_full_header
[
2
]
&
0x0E
)
<<
29
)
|
(((
mtime_t
)
U16_AT
(
p_full_header
+
3
)
<<
14
)
-
(
1
<<
14
))
|
(((
mtime_t
)
U16_AT
(
p_full_header
+
3
)
<<
14
)
-
(
1
<<
14
))
|
((
mtime_t
)
U16_AT
(
p_full_header
+
5
)
>>
1
)
)
)
((
mtime_t
)
U16_AT
(
p_full_header
+
5
)
>>
1
)
)
);
+
DEFAULT_PTS_DELAY
;
if
(
b_has_dts
)
if
(
b_has_dts
)
{
{
...
@@ -235,13 +234,11 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
...
@@ -235,13 +234,11 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
p_pes
=
NULL
;
p_pes
=
NULL
;
return
;
return
;
}
}
p_pes
->
i_dts
=
input_ClockToSysdate
(
p_input
,
p_pes
->
i_dts
=
input_ClockGetTS
(
p_input
,
p_es
->
p_pgrm
,
p_es
->
p_pgrm
,
(
((
mtime_t
)(
p_full_header
[
7
]
&
0x0E
)
<<
29
)
|
(
((
mtime_t
)(
p_full_header
[
7
]
&
0x0E
)
<<
29
)
|
(((
mtime_t
)
U16_AT
(
p_full_header
+
8
)
<<
14
)
(((
mtime_t
)
U16_AT
(
p_full_header
+
8
)
<<
14
)
-
(
1
<<
14
))
|
-
(
1
<<
14
))
|
((
mtime_t
)
U16_AT
(
p_full_header
+
10
)
>>
1
)
)
)
((
mtime_t
)
U16_AT
(
p_full_header
+
10
)
>>
1
)
)
);
+
DEFAULT_PTS_DELAY
;
}
}
}
}
}
}
...
@@ -313,11 +310,10 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
...
@@ -313,11 +310,10 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
return
;
return
;
}
}
p_pes
->
i_pts
=
input_Clock
ToSysdate
(
p_input
,
p_es
->
p_pgrm
,
p_pes
->
i_pts
=
input_Clock
GetTS
(
p_input
,
p_es
->
p_pgrm
,
(
((
mtime_t
)(
p_ts
[
0
]
&
0x0E
)
<<
29
)
|
(
((
mtime_t
)(
p_ts
[
0
]
&
0x0E
)
<<
29
)
|
(((
mtime_t
)
U16_AT
(
p_ts
+
1
)
<<
14
)
-
(
1
<<
14
))
|
(((
mtime_t
)
U16_AT
(
p_ts
+
1
)
<<
14
)
-
(
1
<<
14
))
|
((
mtime_t
)
U16_AT
(
p_ts
+
3
)
>>
1
)
)
)
((
mtime_t
)
U16_AT
(
p_ts
+
3
)
>>
1
)
)
);
+
DEFAULT_PTS_DELAY
;
if
(
b_has_dts
)
if
(
b_has_dts
)
{
{
...
@@ -332,12 +328,11 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
...
@@ -332,12 +328,11 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
return
;
return
;
}
}
p_pes
->
i_dts
=
input_Clock
ToSysdate
(
p_input
,
p_pes
->
i_dts
=
input_Clock
GetTS
(
p_input
,
p_es
->
p_pgrm
,
p_es
->
p_pgrm
,
(
((
mtime_t
)(
p_ts
[
0
]
&
0x0E
)
<<
29
)
|
(
((
mtime_t
)(
p_ts
[
0
]
&
0x0E
)
<<
29
)
|
(((
mtime_t
)
U16_AT
(
p_ts
+
1
)
<<
14
)
-
(
1
<<
14
))
|
(((
mtime_t
)
U16_AT
(
p_ts
+
1
)
<<
14
)
-
(
1
<<
14
))
|
((
mtime_t
)
U16_AT
(
p_ts
+
3
)
>>
1
)
)
)
((
mtime_t
)
U16_AT
(
p_ts
+
3
)
>>
1
)
)
);
+
DEFAULT_PTS_DELAY
;
}
}
}
}
}
}
...
@@ -491,132 +486,6 @@ void input_GatherPES( input_thread_t * p_input, data_packet_t * p_data,
...
@@ -491,132 +486,6 @@ void input_GatherPES( input_thread_t * p_input, data_packet_t * p_data,
}
}
/*
* Pace control
*/
/*
* DISCUSSION : SYNCHRONIZATION METHOD
*
* In some cases we can impose the pace of reading (when reading from a
* file or a pipe), and for the synchronization we simply sleep() until
* it is time to deliver the packet to the decoders. When reading from
* the network, we must be read at the same pace as the server writes,
* otherwise the kernel's buffer will trash packets. The risk is now to
* overflow the input buffers in case the server goes too fast, that is
* why we do these calculations :
*
* 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 decode (or trash) 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.
*/
/*****************************************************************************
* Constants
*****************************************************************************/
/* Maximum number of samples used to compute the dynamic average value,
* it is also the maximum of c_average_count in pgrm_ts_data_t.
* We use the following formula :
* new_average = (old_average * c_average + new_sample_value) / (c_average +1) */
#define CR_MAX_AVERAGE_COUNTER 40
/* Maximum gap allowed between two CRs. */
#define CR_MAX_GAP 1000000
/*****************************************************************************
* CRReInit : Reinitialize the clock reference
*****************************************************************************/
static
void
CRReInit
(
pgrm_descriptor_t
*
p_pgrm
)
{
p_pgrm
->
delta_cr
=
0
;
p_pgrm
->
last_cr
=
0
;
p_pgrm
->
c_average_count
=
0
;
}
/* FIXME: find a better name */
/*****************************************************************************
* CRDecode : Decode a clock reference
*****************************************************************************/
static
void
CRDecode
(
input_thread_t
*
p_input
,
pgrm_descriptor_t
*
p_pgrm
,
mtime_t
cr_time
)
{
if
(
p_pgrm
->
i_synchro_state
!=
SYNCHRO_OK
)
{
input_ClockNewRef
(
p_input
,
p_pgrm
,
cr_time
);
p_pgrm
->
i_synchro_state
=
SYNCHRO_OK
;
}
else
{
if
(
p_pgrm
->
b_discontinuity
||
(
p_pgrm
->
last_cr
!=
0
&&
(
(
p_pgrm
->
last_cr
-
cr_time
)
>
CR_MAX_GAP
||
(
p_pgrm
->
last_cr
-
cr_time
)
<
-
CR_MAX_GAP
)
)
)
{
#if 0
/* This code is deprecated */
int i_es;
/* Stream discontinuity. */
intf_WarnMsg( 3, "CR re-initialiazed" );
CRReInit( p_pgrm );
p_pgrm->i_synchro_state = SYNCHRO_REINIT;
p_pgrm->b_discontinuity = 0;
/* Warn all the elementary streams */
for( i_es = 0; i_es < p_pgrm->i_es_number; i_es++ )
{
p_pgrm->pp_es[i_es]->b_discontinuity = 1;
}
#endif
}
p_pgrm
->
last_cr
=
cr_time
;
if
(
p_input
->
stream
.
b_pace_control
)
{
/* Wait a while before delivering the packets to the decoder. */
mwait
(
input_ClockToSysdate
(
p_input
,
p_pgrm
,
cr_time
)
);
}
else
{
#if 0
/* This code is deprecated, too */
mtime_t sys_time, delta_cr;
sys_time = mdate();
delta_cr = sys_time - cr_time;
if( p_pgrm->c_average_count == CR_MAX_AVERAGE_COUNTER )
{
p_pgrm->delta_cr = ( delta_cr + (p_pgrm->delta_cr
* (CR_MAX_AVERAGE_COUNTER - 1)) )
/ CR_MAX_AVERAGE_COUNTER;
}
else
{
p_pgrm->delta_cr = ( delta_cr + (p_pgrm->delta_cr
* p_pgrm->c_average_count) )
/ ( p_pgrm->c_average_count + 1 );
p_pgrm->c_average_count++;
}
#endif
}
}
}
/*
/*
* PS Demultiplexing
* PS Demultiplexing
*/
*/
...
@@ -939,7 +808,7 @@ void input_DemuxPS( input_thread_t * p_input, data_packet_t * p_data )
...
@@ -939,7 +808,7 @@ void input_DemuxPS( input_thread_t * p_input, data_packet_t * p_data )
}
}
/* Call the pace control. */
/* Call the pace control. */
//intf_Msg("+%lld", scr_time);
//intf_Msg("+%lld", scr_time);
CRDecode
(
p_input
,
p_input
->
stream
.
pp_programs
[
0
],
input_ClockManageRef
(
p_input
,
p_input
->
stream
.
pp_programs
[
0
],
scr_time
);
scr_time
);
b_trash
=
1
;
b_trash
=
1
;
}
}
...
@@ -1111,7 +980,8 @@ void input_DemuxTS( input_thread_t * p_input, data_packet_t * p_data )
...
@@ -1111,7 +980,8 @@ void input_DemuxTS( input_thread_t * p_input, data_packet_t * p_data )
(
(
mtime_t
)
U32_AT
((
u32
*
)
&
p
[
6
])
<<
1
)
(
(
mtime_t
)
U32_AT
((
u32
*
)
&
p
[
6
])
<<
1
)
|
(
p
[
10
]
>>
7
);
|
(
p
[
10
]
>>
7
);
/* Call the pace control. */
/* Call the pace control. */
CRDecode
(
p_input
,
p_es
->
p_pgrm
,
pcr_time
);
input_ClockManageRef
(
p_input
,
p_es
->
p_pgrm
,
pcr_time
);
}
}
}
/* PCR ? */
}
/* PCR ? */
}
/* valid TS adaptation field ? */
}
/* valid TS adaptation field ? */
...
@@ -1184,6 +1054,7 @@ void input_DemuxTS( input_thread_t * p_input, data_packet_t * p_data )
...
@@ -1184,6 +1054,7 @@ void input_DemuxTS( input_thread_t * p_input, data_packet_t * p_data )
{
{
/* The payload contains PSI tables */
/* The payload contains PSI tables */
#if 0
#if 0
/* FIXME ! write the PSI decoder :p */
input_DemuxPSI( p_input, p_data, p_es,
input_DemuxPSI( p_input, p_data, p_es,
b_unit_start, b_lost );
b_unit_start, b_lost );
#endif
#endif
...
...
src/misc/modules.c
View file @
ff85edc6
...
@@ -224,7 +224,7 @@ void module_ManageBank( module_bank_t * p_bank )
...
@@ -224,7 +224,7 @@ void module_ManageBank( module_bank_t * p_bank )
}
}
else
else
{
{
intf_
DbgMsg
(
"module: hiding unused module `%s'"
,
intf_
WarnMsg
(
1
,
"module: hiding unused module `%s'"
,
p_module
->
psz_name
);
p_module
->
psz_name
);
HideModule
(
p_module
);
HideModule
(
p_module
);
}
}
...
...
src/video_parser/video_parser.c
View file @
ff85edc6
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* video_parser.c : video parser thread
* video_parser.c : video parser thread
*****************************************************************************
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* Copyright (C) 1999, 2000 VideoLAN
* $Id: video_parser.c,v 1.7
0 2001/01/24 19:05:55
massiot Exp $
* $Id: video_parser.c,v 1.7
1 2001/02/07 15:32:26
massiot Exp $
*
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Samuel Hocevar <sam@via.ecp.fr>
* Samuel Hocevar <sam@via.ecp.fr>
...
@@ -225,6 +225,13 @@ static int InitThread( vpar_thread_t *p_vpar )
...
@@ -225,6 +225,13 @@ static int InitThread( vpar_thread_t *p_vpar )
p_vpar
->
bit_stream
.
pf_bitstream_callback
=
BitstreamCallback
;
p_vpar
->
bit_stream
.
pf_bitstream_callback
=
BitstreamCallback
;
p_vpar
->
bit_stream
.
p_callback_arg
=
(
void
*
)
p_vpar
;
p_vpar
->
bit_stream
.
p_callback_arg
=
(
void
*
)
p_vpar
;
/* InitBitstream has normally begun to read a PES packet, get its
* PTS/DTS */
if
(
!
p_vpar
->
p_fifo
->
b_die
)
{
BitstreamCallback
(
&
p_vpar
->
bit_stream
,
1
);
}
/* Initialize parsing data */
/* Initialize parsing data */
p_vpar
->
sequence
.
p_forward
=
NULL
;
p_vpar
->
sequence
.
p_forward
=
NULL
;
p_vpar
->
sequence
.
p_backward
=
NULL
;
p_vpar
->
sequence
.
p_backward
=
NULL
;
...
...
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