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
5138b463
Commit
5138b463
authored
Nov 11, 2012
by
Rémi Denis-Courmont
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
aout: inline synchronization code into dec.c
parent
c96fa88a
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
162 additions
and
297 deletions
+162
-297
po/POTFILES.in
po/POTFILES.in
+0
-1
src/Makefile.am
src/Makefile.am
+0
-1
src/audio_output/aout_internal.h
src/audio_output/aout_internal.h
+4
-17
src/audio_output/dec.c
src/audio_output/dec.c
+158
-53
src/audio_output/input.c
src/audio_output/input.c
+0
-223
src/audio_output/output.c
src/audio_output/output.c
+0
-2
No files found.
po/POTFILES.in
View file @
5138b463
...
@@ -66,7 +66,6 @@ src/audio_output/aout_internal.h
...
@@ -66,7 +66,6 @@ src/audio_output/aout_internal.h
src/audio_output/common.c
src/audio_output/common.c
src/audio_output/dec.c
src/audio_output/dec.c
src/audio_output/filters.c
src/audio_output/filters.c
src/audio_output/input.c
src/audio_output/output.c
src/audio_output/output.c
src/config/chain.c
src/config/chain.c
src/config/cmdline.c
src/config/cmdline.c
...
...
src/Makefile.am
View file @
5138b463
...
@@ -413,7 +413,6 @@ SOURCES_libvlc_common = \
...
@@ -413,7 +413,6 @@ SOURCES_libvlc_common = \
audio_output/common.c
\
audio_output/common.c
\
audio_output/dec.c
\
audio_output/dec.c
\
audio_output/filters.c
\
audio_output/filters.c
\
audio_output/input.c
\
audio_output/output.c
\
audio_output/output.c
\
audio_output/volume.c
\
audio_output/volume.c
\
network/getaddrinfo.c
\
network/getaddrinfo.c
\
...
...
src/audio_output/aout_internal.h
View file @
5138b463
...
@@ -46,26 +46,17 @@ typedef struct
...
@@ -46,26 +46,17 @@ typedef struct
typedef
struct
aout_volume
aout_volume_t
;
typedef
struct
aout_volume
aout_volume_t
;
/** an input stream for the audio output */
struct
aout_input_t
{
int
i_resampling_type
;
int
i_resamp_start_drift
;
/* */
int
i_buffer_lost
;
};
typedef
struct
typedef
struct
{
{
vlc_mutex_t
lock
;
vlc_mutex_t
lock
;
module_t
*
module
;
/**< Output plugin (or NULL if inactive) */
module_t
*
module
;
/**< Output plugin (or NULL if inactive) */
aout_input_t
*
input
;
aout_volume_t
*
volume
;
aout_volume_t
*
volume
;
struct
struct
{
{
date_t
date
;
date_t
date
;
int
resamp_type
;
int
resamp_start_drift
;
}
sync
;
}
sync
;
audio_sample_format_t
input_format
;
audio_sample_format_t
input_format
;
...
@@ -84,6 +75,8 @@ typedef struct
...
@@ -84,6 +75,8 @@ typedef struct
aout_request_vout_t
request_vout
;
aout_request_vout_t
request_vout
;
bool
recycle_vout
;
bool
recycle_vout
;
unsigned
buffers_lost
;
vlc_atomic_t
restart
;
vlc_atomic_t
restart
;
}
aout_owner_t
;
}
aout_owner_t
;
...
@@ -102,12 +95,6 @@ static inline aout_owner_t *aout_owner (audio_output_t *aout)
...
@@ -102,12 +95,6 @@ static inline aout_owner_t *aout_owner (audio_output_t *aout)
* Prototypes
* Prototypes
*****************************************************************************/
*****************************************************************************/
/* From input.c : */
aout_input_t
*
aout_InputNew
(
void
);
void
aout_InputDelete
(
aout_input_t
*
);
block_t
*
aout_InputPlay
(
audio_output_t
*
p_aout
,
aout_input_t
*
p_input
,
block_t
*
p_buffer
,
int
i_input_rate
,
date_t
*
);
/* From filters.c : */
/* From filters.c : */
int
aout_FiltersPipelineCreate
(
vlc_object_t
*
,
filter_t
**
,
unsigned
*
,
int
aout_FiltersPipelineCreate
(
vlc_object_t
*
,
filter_t
**
,
unsigned
*
,
unsigned
,
const
audio_sample_format_t
*
,
const
audio_sample_format_t
*
);
unsigned
,
const
audio_sample_format_t
*
,
const
audio_sample_format_t
*
);
...
...
src/audio_output/dec.c
View file @
5138b463
...
@@ -95,9 +95,10 @@ error:
...
@@ -95,9 +95,10 @@ error:
date_Init
(
&
owner
->
sync
.
date
,
owner
->
mixer_format
.
i_rate
,
1
);
date_Init
(
&
owner
->
sync
.
date
,
owner
->
mixer_format
.
i_rate
,
1
);
date_Set
(
&
owner
->
sync
.
date
,
VLC_TS_INVALID
);
date_Set
(
&
owner
->
sync
.
date
,
VLC_TS_INVALID
);
owner
->
sync
.
resamp_type
=
AOUT_RESAMPLING_NONE
;
owner
->
buffers_lost
=
0
;
assert
(
owner
->
input
==
NULL
);
owner
->
input
=
aout_InputNew
();
aout_unlock
(
p_aout
);
aout_unlock
(
p_aout
);
return
ret
;
return
ret
;
}
}
...
@@ -108,14 +109,8 @@ error:
...
@@ -108,14 +109,8 @@ error:
void
aout_DecDelete
(
audio_output_t
*
p_aout
)
void
aout_DecDelete
(
audio_output_t
*
p_aout
)
{
{
aout_owner_t
*
owner
=
aout_owner
(
p_aout
);
aout_owner_t
*
owner
=
aout_owner
(
p_aout
);
aout_input_t
*
input
;
aout_lock
(
p_aout
);
aout_lock
(
p_aout
);
/* Remove the input. */
input
=
owner
->
input
;
aout_InputDelete
(
input
);
owner
->
input
=
NULL
;
aout_FiltersDelete
(
p_aout
);
aout_FiltersDelete
(
p_aout
);
aout_OutputDelete
(
p_aout
);
aout_OutputDelete
(
p_aout
);
aout_volume_Delete
(
owner
->
volume
);
aout_volume_Delete
(
owner
->
volume
);
...
@@ -127,7 +122,7 @@ void aout_DecDelete (audio_output_t *p_aout)
...
@@ -127,7 +122,7 @@ void aout_DecDelete (audio_output_t *p_aout)
#define AOUT_RESTART_OUTPUT 1
#define AOUT_RESTART_OUTPUT 1
#define AOUT_RESTART_INPUT 2
#define AOUT_RESTART_INPUT 2
static
void
aout_CheckRestart
(
audio_output_t
*
aout
)
static
int
aout_CheckRestart
(
audio_output_t
*
aout
)
{
{
aout_owner_t
*
owner
=
aout_owner
(
aout
);
aout_owner_t
*
owner
=
aout_owner
(
aout
);
...
@@ -135,15 +130,12 @@ static void aout_CheckRestart (audio_output_t *aout)
...
@@ -135,15 +130,12 @@ static void aout_CheckRestart (audio_output_t *aout)
int
restart
=
vlc_atomic_swap
(
&
owner
->
restart
,
0
);
int
restart
=
vlc_atomic_swap
(
&
owner
->
restart
,
0
);
if
(
likely
(
restart
==
0
))
if
(
likely
(
restart
==
0
))
return
;
return
0
;
assert
(
restart
&
AOUT_RESTART_INPUT
);
assert
(
restart
&
AOUT_RESTART_INPUT
);
const
aout_request_vout_t
request_vout
=
owner
->
request_vout
;
const
aout_request_vout_t
request_vout
=
owner
->
request_vout
;
aout_InputDelete
(
owner
->
input
);
owner
->
input
=
NULL
;
aout_FiltersDelete
(
aout
);
aout_FiltersDelete
(
aout
);
/* Reinitializes the output */
/* Reinitializes the output */
...
@@ -151,16 +143,18 @@ static void aout_CheckRestart (audio_output_t *aout)
...
@@ -151,16 +143,18 @@ static void aout_CheckRestart (audio_output_t *aout)
{
{
aout_OutputDelete
(
aout
);
aout_OutputDelete
(
aout
);
if
(
aout_OutputNew
(
aout
,
&
owner
->
input_format
))
if
(
aout_OutputNew
(
aout
,
&
owner
->
input_format
))
{
abort
();
/* FIXME we are officially screwed */
aout_volume_Delete
(
owner
->
volume
);
return
;
/* we are officially screwed */
}
aout_volume_SetFormat
(
owner
->
volume
,
owner
->
mixer_format
.
i_format
);
aout_volume_SetFormat
(
owner
->
volume
,
owner
->
mixer_format
.
i_format
);
}
}
owner
->
sync
.
resamp_type
=
AOUT_RESAMPLING_NONE
;
if
(
aout_FiltersNew
(
aout
,
&
owner
->
input_format
,
&
owner
->
mixer_format
,
if
(
aout_FiltersNew
(
aout
,
&
owner
->
input_format
,
&
owner
->
mixer_format
,
&
request_vout
)
==
0
)
&
request_vout
))
owner
->
input
=
aout_InputNew
();
{
abort
();
/* FIXME */
}
return
0
;
}
}
/**
/**
...
@@ -235,64 +229,175 @@ void aout_DecDeleteBuffer (audio_output_t *aout, block_t *block)
...
@@ -235,64 +229,175 @@ void aout_DecDeleteBuffer (audio_output_t *aout, block_t *block)
block_Release
(
block
);
block_Release
(
block
);
}
}
static
void
aout_StopResampling
(
audio_output_t
*
aout
)
{
aout_owner_t
*
owner
=
aout_owner
(
aout
);
owner
->
sync
.
resamp_type
=
AOUT_RESAMPLING_NONE
;
aout_FiltersAdjustResampling
(
aout
,
0
);
}
/*****************************************************************************
/*****************************************************************************
* aout_DecPlay : filter & mix the decoded buffer
* aout_DecPlay : filter & mix the decoded buffer
*****************************************************************************/
*****************************************************************************/
int
aout_DecPlay
(
audio_output_t
*
p_aout
,
block_t
*
p_buffer
,
int
i_
input_rate
)
int
aout_DecPlay
(
audio_output_t
*
aout
,
block_t
*
block
,
int
input_rate
)
{
{
aout_owner_t
*
owner
=
aout_owner
(
p_aout
);
aout_owner_t
*
owner
=
aout_owner
(
aout
);
aout_input_t
*
input
;
assert
(
i_input_rate
>=
INPUT_RATE_DEFAULT
/
AOUT_MAX_INPUT_RATE
&&
assert
(
input_rate
>=
INPUT_RATE_DEFAULT
/
AOUT_MAX_INPUT_RATE
);
i_input_rate
<=
INPUT_RATE_DEFAULT
*
AOUT_MAX_INPUT_RATE
);
assert
(
input_rate
<=
INPUT_RATE_DEFAULT
*
AOUT_MAX_INPUT_RATE
);
assert
(
p_buffer
->
i_pts
>
0
);
assert
(
block
->
i_pts
>=
VLC_TS_0
);
p_buffer
->
i_length
=
(
mtime_t
)
p_buffer
->
i_nb_samples
*
1000000
block
->
i_length
=
CLOCK_FREQ
*
block
->
i_nb_samples
/
owner
->
input_format
.
i_rate
;
/
owner
->
input_format
.
i_rate
;
aout_lock
(
p_aout
);
aout_lock
(
aout
);
aout_CheckRestart
(
p_aout
);
if
(
unlikely
(
aout_CheckRestart
(
aout
)))
goto
drop
;
/* Pipeline is unrecoverably broken :-( */
/* We don't care if someone changes the start date behind our back after
* this. We'll deal with that when pushing the buffer, and compensate
* with the next incoming buffer. */
mtime_t
start_date
=
date_Get
(
&
owner
->
sync
.
date
);
const
mtime_t
now
=
mdate
();
if
(
start_date
!=
VLC_TS_INVALID
&&
start_date
<
now
)
{
/* The decoder is _very_ late. This can only happen if the user
* pauses the stream (or if the decoder is buggy, which cannot
* happen :). */
msg_Warn
(
aout
,
"computed PTS is out of range (%"
PRId64
"), "
"clearing out"
,
now
-
start_date
);
aout_OutputFlush
(
aout
,
false
);
if
(
owner
->
sync
.
resamp_type
!=
AOUT_RESAMPLING_NONE
)
msg_Warn
(
aout
,
"timing screwed, stopping resampling"
);
aout_StopResampling
(
aout
);
block
->
i_flags
|=
BLOCK_FLAG_DISCONTINUITY
;
start_date
=
VLC_TS_INVALID
;
}
if
(
block
->
i_pts
<
now
+
AOUT_MIN_PREPARE_TIME
)
{
/* The decoder gives us f*cked up PTS. It's its business, but we
* can't present it anyway, so drop the buffer. */
msg_Warn
(
aout
,
"PTS is out of range (%"
PRId64
"), dropping buffer"
,
now
-
block
->
i_pts
);
aout_StopResampling
(
aout
);
goto
drop
;
}
input
=
owner
->
input
;
/* If the audio drift is too big then it's not worth trying to resample
if
(
unlikely
(
input
==
NULL
))
/* can happen due to restart */
* the audio. */
if
(
start_date
==
VLC_TS_INVALID
)
{
{
aout_unlock
(
p_aout
);
start_date
=
block
->
i_pts
;
block_Release
(
p_buffer
);
date_Set
(
&
owner
->
sync
.
date
,
start_date
);
return
-
1
;
}
}
/* Input */
mtime_t
drift
=
start_date
-
block
->
i_pts
;
p_buffer
=
aout_InputPlay
(
p_aout
,
input
,
p_buffer
,
i_input_rate
,
if
(
drift
<
-
input_rate
*
3
*
AOUT_MAX_PTS_ADVANCE
/
INPUT_RATE_DEFAULT
)
&
owner
->
sync
.
date
);
if
(
p_buffer
!=
NULL
)
{
{
date_Increment
(
&
owner
->
sync
.
date
,
p_buffer
->
i_nb_samples
);
msg_Warn
(
aout
,
"buffer way too early (%"
PRId64
"), clearing queue"
,
drift
);
aout_OutputFlush
(
aout
,
false
);
if
(
owner
->
sync
.
resamp_type
!=
AOUT_RESAMPLING_NONE
)
msg_Warn
(
aout
,
"timing screwed, stopping resampling"
);
aout_StopResampling
(
aout
);
block
->
i_flags
|=
BLOCK_FLAG_DISCONTINUITY
;
start_date
=
block
->
i_pts
;
date_Set
(
&
owner
->
sync
.
date
,
start_date
);
drift
=
0
;
}
else
if
(
drift
>
+
input_rate
*
3
*
AOUT_MAX_PTS_DELAY
/
INPUT_RATE_DEFAULT
)
{
msg_Warn
(
aout
,
"buffer way too late (%"
PRId64
"), dropping buffer"
,
drift
);
goto
drop
;
}
/* Mixer */
block
=
aout_FiltersPlay
(
aout
,
block
,
input_rate
);
aout_volume_Amplify
(
owner
->
volume
,
p_buffer
);
if
(
block
==
NULL
)
{
owner
->
buffers_lost
++
;
goto
out
;
}
/* Output */
/* Adjust the resampler if needed.
aout_OutputPlay
(
p_aout
,
p_buffer
);
* We first need to calculate the output rate of this resampler. */
if
((
owner
->
sync
.
resamp_type
==
AOUT_RESAMPLING_NONE
)
&&
(
drift
<
-
AOUT_MAX_PTS_ADVANCE
||
drift
>
+
AOUT_MAX_PTS_DELAY
))
{
/* Can happen in several circumstances :
* 1. A problem at the input (clock drift)
* 2. A small pause triggered by the user
* 3. Some delay in the output stage, causing a loss of lip
* synchronization
* Solution : resample the buffer to avoid a scratch.
*/
owner
->
sync
.
resamp_start_drift
=
(
int
)
-
drift
;
owner
->
sync
.
resamp_type
=
(
drift
<
0
)
?
AOUT_RESAMPLING_DOWN
:
AOUT_RESAMPLING_UP
;
msg_Warn
(
aout
,
(
drift
<
0
)
?
"buffer too early (%"
PRId64
"), down-sampling"
:
"buffer too late (%"
PRId64
"), up-sampling"
,
drift
);
}
if
(
owner
->
sync
.
resamp_type
!=
AOUT_RESAMPLING_NONE
)
{
/* Resampling has been triggered previously (because of dates
* mismatch). We want the resampling to happen progressively so
* it isn't too audible to the listener. */
const
int
adjust
=
(
owner
->
sync
.
resamp_type
==
AOUT_RESAMPLING_UP
)
?
+
2
:
-
2
;
/* Check if everything is back to normal, then stop resampling. */
if
(
!
aout_FiltersAdjustResampling
(
aout
,
adjust
))
{
owner
->
sync
.
resamp_type
=
AOUT_RESAMPLING_NONE
;
msg_Warn
(
aout
,
"resampling stopped (drift: %"
PRIi64
")"
,
block
->
i_pts
-
start_date
);
}
else
if
(
abs
((
int
)(
block
->
i_pts
-
start_date
))
<
abs
(
owner
->
sync
.
resamp_start_drift
)
/
2
)
{
/* If we reduced the drift from half, then it is time to switch
* back the resampling direction. */
if
(
owner
->
sync
.
resamp_type
==
AOUT_RESAMPLING_UP
)
owner
->
sync
.
resamp_type
=
AOUT_RESAMPLING_DOWN
;
else
owner
->
sync
.
resamp_type
=
AOUT_RESAMPLING_UP
;
owner
->
sync
.
resamp_start_drift
=
0
;
}
else
if
(
owner
->
sync
.
resamp_start_drift
&&
(
abs
((
int
)(
block
->
i_pts
-
start_date
))
>
abs
(
owner
->
sync
.
resamp_start_drift
)
*
3
/
2
))
{
/* If the drift is increasing and not decreasing, than something
* is bad. We'd better stop the resampling right now. */
msg_Warn
(
aout
,
"timing screwed, stopping resampling"
);
aout_StopResampling
(
aout
);
block
->
i_flags
|=
BLOCK_FLAG_DISCONTINUITY
;
}
}
}
aout_unlock
(
p_aout
);
block
->
i_pts
=
start_date
;
date_Increment
(
&
owner
->
sync
.
date
,
block
->
i_nb_samples
);
/* Software volume */
aout_volume_Amplify
(
owner
->
volume
,
block
);
/* Output */
aout_OutputPlay
(
aout
,
block
);
out:
aout_unlock
(
aout
);
return
0
;
return
0
;
drop:
block_Release
(
block
);
owner
->
buffers_lost
++
;
goto
out
;
}
}
int
aout_DecGetResetLost
(
audio_output_t
*
aout
)
int
aout_DecGetResetLost
(
audio_output_t
*
aout
)
{
{
aout_owner_t
*
owner
=
aout_owner
(
aout
);
aout_owner_t
*
owner
=
aout_owner
(
aout
);
aout_input_t
*
input
=
owner
->
input
;
unsigned
val
;
int
val
;
aout_lock
(
aout
);
aout_lock
(
aout
);
if
(
likely
(
input
!=
NULL
))
val
=
owner
->
buffers_lost
;
{
owner
->
buffers_lost
=
0
;
val
=
input
->
i_buffer_lost
;
input
->
i_buffer_lost
=
0
;
}
else
val
=
0
;
/* if aout_CheckRestart() failed */
aout_unlock
(
aout
);
aout_unlock
(
aout
);
return
val
;
return
val
;
...
...
src/audio_output/input.c
deleted
100644 → 0
View file @
c96fa88a
/*****************************************************************************
* input.c : internal management of input streams for the audio output
*****************************************************************************
* Copyright (C) 2002-2007 VLC authors and VideoLAN
* $Id$
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc_common.h>
#include <vlc_input.h>
#include <vlc_aout.h>
#include <libvlc.h>
#include "aout_internal.h"
static
void
inputDrop
(
aout_input_t
*
,
block_t
*
);
static
void
inputResamplingStop
(
audio_output_t
*
,
aout_input_t
*
);
/*****************************************************************************
* aout_InputNew : allocate a new input and rework the filter pipeline
*****************************************************************************/
aout_input_t
*
aout_InputNew
(
void
)
{
aout_input_t
*
p_input
=
xmalloc
(
sizeof
(
*
p_input
));
p_input
->
i_resampling_type
=
AOUT_RESAMPLING_NONE
;
p_input
->
i_buffer_lost
=
0
;
return
p_input
;
}
/*****************************************************************************
* aout_InputDelete : delete an input
*****************************************************************************
* This function must be entered with the mixer lock.
*****************************************************************************/
void
aout_InputDelete
(
aout_input_t
*
p_input
)
{
free
(
p_input
);
}
/*****************************************************************************
* aout_InputPlay : play a buffer
*****************************************************************************
* This function must be entered with the input lock.
*****************************************************************************/
block_t
*
aout_InputPlay
(
audio_output_t
*
p_aout
,
aout_input_t
*
p_input
,
block_t
*
p_buffer
,
int
i_input_rate
,
date_t
*
date
)
{
mtime_t
start_date
;
aout_assert_locked
(
p_aout
);
mtime_t
now
=
mdate
();
/* We don't care if someone changes the start date behind our back after
* this. We'll deal with that when pushing the buffer, and compensate
* with the next incoming buffer. */
start_date
=
date_Get
(
date
);
if
(
start_date
!=
VLC_TS_INVALID
&&
start_date
<
now
)
{
/* The decoder is _very_ late. This can only happen if the user
* pauses the stream (or if the decoder is buggy, which cannot
* happen :). */
msg_Warn
(
p_aout
,
"computed PTS is out of range (%"
PRId64
"), "
"clearing out"
,
now
-
start_date
);
aout_OutputFlush
(
p_aout
,
false
);
if
(
p_input
->
i_resampling_type
!=
AOUT_RESAMPLING_NONE
)
msg_Warn
(
p_aout
,
"timing screwed, stopping resampling"
);
inputResamplingStop
(
p_aout
,
p_input
);
p_buffer
->
i_flags
|=
BLOCK_FLAG_DISCONTINUITY
;
start_date
=
VLC_TS_INVALID
;
}
if
(
p_buffer
->
i_pts
<
now
+
AOUT_MIN_PREPARE_TIME
)
{
/* The decoder gives us f*cked up PTS. It's its business, but we
* can't present it anyway, so drop the buffer. */
msg_Warn
(
p_aout
,
"PTS is out of range (%"
PRId64
"), dropping buffer"
,
now
-
p_buffer
->
i_pts
);
inputDrop
(
p_input
,
p_buffer
);
inputResamplingStop
(
p_aout
,
p_input
);
return
NULL
;
}
/* If the audio drift is too big then it's not worth trying to resample
* the audio. */
if
(
start_date
==
VLC_TS_INVALID
)
{
start_date
=
p_buffer
->
i_pts
;
date_Set
(
date
,
start_date
);
}
mtime_t
drift
=
start_date
-
p_buffer
->
i_pts
;
if
(
drift
<
-
i_input_rate
*
3
*
AOUT_MAX_PTS_ADVANCE
/
INPUT_RATE_DEFAULT
)
{
msg_Warn
(
p_aout
,
"buffer way too early (%"
PRId64
"), clearing queue"
,
drift
);
aout_OutputFlush
(
p_aout
,
false
);
if
(
p_input
->
i_resampling_type
!=
AOUT_RESAMPLING_NONE
)
msg_Warn
(
p_aout
,
"timing screwed, stopping resampling"
);
inputResamplingStop
(
p_aout
,
p_input
);
p_buffer
->
i_flags
|=
BLOCK_FLAG_DISCONTINUITY
;
start_date
=
p_buffer
->
i_pts
;
date_Set
(
date
,
start_date
);
drift
=
0
;
}
else
if
(
drift
>
+
i_input_rate
*
3
*
AOUT_MAX_PTS_DELAY
/
INPUT_RATE_DEFAULT
)
{
msg_Warn
(
p_aout
,
"buffer way too late (%"
PRId64
"), dropping buffer"
,
drift
);
inputDrop
(
p_input
,
p_buffer
);
return
NULL
;
}
p_buffer
=
aout_FiltersPlay
(
p_aout
,
p_buffer
,
i_input_rate
);
if
(
!
p_buffer
)
return
NULL
;
/* Run the resampler if needed.
* We first need to calculate the output rate of this resampler. */
if
(
(
p_input
->
i_resampling_type
==
AOUT_RESAMPLING_NONE
)
&&
(
drift
<
-
AOUT_MAX_PTS_ADVANCE
||
drift
>
+
AOUT_MAX_PTS_DELAY
)
)
{
/* Can happen in several circumstances :
* 1. A problem at the input (clock drift)
* 2. A small pause triggered by the user
* 3. Some delay in the output stage, causing a loss of lip
* synchronization
* Solution : resample the buffer to avoid a scratch.
*/
p_input
->
i_resamp_start_drift
=
(
int
)
-
drift
;
p_input
->
i_resampling_type
=
(
drift
<
0
)
?
AOUT_RESAMPLING_DOWN
:
AOUT_RESAMPLING_UP
;
msg_Warn
(
p_aout
,
(
drift
<
0
)
?
"buffer too early (%"
PRId64
"), down-sampling"
:
"buffer too late (%"
PRId64
"), up-sampling"
,
drift
);
}
if
(
p_input
->
i_resampling_type
!=
AOUT_RESAMPLING_NONE
)
{
/* Resampling has been triggered previously (because of dates
* mismatch). We want the resampling to happen progressively so
* it isn't too audible to the listener. */
const
int
adjust
=
(
p_input
->
i_resampling_type
==
AOUT_RESAMPLING_UP
)
?
+
2
:
-
2
;
/* Check if everything is back to normal, in which case we can stop the
* resampling */
if
(
!
aout_FiltersAdjustResampling
(
p_aout
,
adjust
)
)
{
p_input
->
i_resampling_type
=
AOUT_RESAMPLING_NONE
;
msg_Warn
(
p_aout
,
"resampling stopped (drift: %"
PRIi64
")"
,
p_buffer
->
i_pts
-
start_date
);
}
else
if
(
abs
(
(
int
)(
p_buffer
->
i_pts
-
start_date
)
)
<
abs
(
p_input
->
i_resamp_start_drift
)
/
2
)
{
/* if we reduced the drift from half, then it is time to switch
* back the resampling direction. */
if
(
p_input
->
i_resampling_type
==
AOUT_RESAMPLING_UP
)
p_input
->
i_resampling_type
=
AOUT_RESAMPLING_DOWN
;
else
p_input
->
i_resampling_type
=
AOUT_RESAMPLING_UP
;
p_input
->
i_resamp_start_drift
=
0
;
}
else
if
(
p_input
->
i_resamp_start_drift
&&
(
abs
(
(
int
)(
p_buffer
->
i_pts
-
start_date
)
)
>
abs
(
p_input
->
i_resamp_start_drift
)
*
3
/
2
)
)
{
/* If the drift is increasing and not decreasing, than something
* is bad. We'd better stop the resampling right now. */
msg_Warn
(
p_aout
,
"timing screwed, stopping resampling"
);
inputResamplingStop
(
p_aout
,
p_input
);
p_buffer
->
i_flags
|=
BLOCK_FLAG_DISCONTINUITY
;
}
}
p_buffer
->
i_pts
=
start_date
;
return
p_buffer
;
}
/*****************************************************************************
* static functions
*****************************************************************************/
static
void
inputDrop
(
aout_input_t
*
p_input
,
block_t
*
p_buffer
)
{
block_Release
(
p_buffer
);
p_input
->
i_buffer_lost
++
;
}
static
void
inputResamplingStop
(
audio_output_t
*
p_aout
,
aout_input_t
*
p_input
)
{
p_input
->
i_resampling_type
=
AOUT_RESAMPLING_NONE
;
aout_FiltersAdjustResampling
(
p_aout
,
0
);
}
src/audio_output/output.c
View file @
5138b463
...
@@ -96,8 +96,6 @@ audio_output_t *aout_New (vlc_object_t *parent)
...
@@ -96,8 +96,6 @@ audio_output_t *aout_New (vlc_object_t *parent)
vlc_mutex_init
(
&
owner
->
lock
);
vlc_mutex_init
(
&
owner
->
lock
);
vlc_object_set_destructor
(
aout
,
aout_Destructor
);
vlc_object_set_destructor
(
aout
,
aout_Destructor
);
owner
->
input
=
NULL
;
/* Audio output module callbacks */
/* Audio output module callbacks */
var_Create
(
aout
,
"volume"
,
VLC_VAR_FLOAT
);
var_Create
(
aout
,
"volume"
,
VLC_VAR_FLOAT
);
var_AddCallback
(
aout
,
"volume"
,
var_Copy
,
parent
);
var_AddCallback
(
aout
,
"volume"
,
var_Copy
,
parent
);
...
...
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