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
c086f181
Commit
c086f181
authored
Apr 16, 2012
by
Rémi Denis-Courmont
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
move aout_Packet out of the core and deprecate it
And do the same with aout_Fifo since only aout_Packet uses it.
parent
2eab05e3
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
394 additions
and
398 deletions
+394
-398
include/vlc_aout.h
include/vlc_aout.h
+6
-6
modules/audio_output/Modules.am
modules/audio_output/Modules.am
+7
-7
modules/audio_output/packet.c
modules/audio_output/packet.c
+381
-0
src/audio_output/aout_internal.h
src/audio_output/aout_internal.h
+0
-8
src/audio_output/common.c
src/audio_output/common.c
+0
-113
src/audio_output/output.c
src/audio_output/output.c
+0
-258
src/libvlccore.sym
src/libvlccore.sym
+0
-6
No files found.
include/vlc_aout.h
View file @
c086f181
...
@@ -251,14 +251,14 @@ typedef struct
...
@@ -251,14 +251,14 @@ typedef struct
bool
starving
;
/**< Whether currently starving (to limit error messages) */
bool
starving
;
/**< Whether currently starving (to limit error messages) */
}
aout_packet_t
;
}
aout_packet_t
;
VLC_
API
void
aout_PacketInit
(
audio_output_t
*
,
aout_packet_t
*
,
unsigned
);
VLC_
DEPRECATED
void
aout_PacketInit
(
audio_output_t
*
,
aout_packet_t
*
,
unsigned
);
VLC_
API
void
aout_PacketDestroy
(
audio_output_t
*
);
VLC_
DEPRECATED
void
aout_PacketDestroy
(
audio_output_t
*
);
VLC_
API
void
aout_PacketPlay
(
audio_output_t
*
,
block_t
*
);
VLC_
DEPRECATED
void
aout_PacketPlay
(
audio_output_t
*
,
block_t
*
);
VLC_
API
void
aout_PacketPause
(
audio_output_t
*
,
bool
,
mtime_t
);
VLC_
DEPRECATED
void
aout_PacketPause
(
audio_output_t
*
,
bool
,
mtime_t
);
VLC_
API
void
aout_PacketFlush
(
audio_output_t
*
,
bool
);
VLC_
DEPRECATED
void
aout_PacketFlush
(
audio_output_t
*
,
bool
);
VLC_
API
block_t
*
aout_PacketNext
(
audio_output_t
*
,
mtime_t
)
VLC_USED
;
VLC_
DEPRECATED
block_t
*
aout_PacketNext
(
audio_output_t
*
,
mtime_t
)
VLC_USED
;
#endif
/* VLC_AOUT_H */
#endif
/* VLC_AOUT_H */
modules/audio_output/Modules.am
View file @
c086f181
SOURCES_aout_directx = directx.c windows_audio_common.h
SOURCES_aout_directx = directx.c windows_audio_common.h
packet.c
SOURCES_aout_file = file.c
SOURCES_aout_file = file.c
SOURCES_waveout = waveout.c windows_audio_common.h
SOURCES_waveout = waveout.c windows_audio_common.h
packet.c
SOURCES_auhal = auhal.c
SOURCES_auhal = auhal.c
packet.c
SOURCES_jack = jack.c
SOURCES_jack = jack.c
packet.c
SOURCES_audioqueue = audioqueue.c
SOURCES_audioqueue = audioqueue.c
packet.c
SOURCES_opensles_android = opensles_android.c
SOURCES_opensles_android = opensles_android.c
libadummy_plugin_la_SOURCES = adummy.c
libadummy_plugin_la_SOURCES = adummy.c
...
@@ -21,7 +21,7 @@ libvlc_LTLIBRARIES += \
...
@@ -21,7 +21,7 @@ libvlc_LTLIBRARIES += \
libamem_plugin.la \
libamem_plugin.la \
libaout_file_plugin.la
libaout_file_plugin.la
liboss_plugin_la_SOURCES = oss.c
liboss_plugin_la_SOURCES = oss.c
packet.c
liboss_plugin_la_CFLAGS = $(AM_CFLAGS)
liboss_plugin_la_CFLAGS = $(AM_CFLAGS)
liboss_plugin_la_LIBADD = $(AM_LIBADD) $(OSS_LIBS)
liboss_plugin_la_LIBADD = $(AM_LIBADD) $(OSS_LIBS)
liboss_plugin_la_DEPENDENCIES =
liboss_plugin_la_DEPENDENCIES =
...
@@ -45,7 +45,7 @@ if HAVE_PULSE
...
@@ -45,7 +45,7 @@ if HAVE_PULSE
libvlc_LTLIBRARIES += libpulse_plugin.la
libvlc_LTLIBRARIES += libpulse_plugin.la
endif
endif
libkai_plugin_la_SOURCES = kai.c
libkai_plugin_la_SOURCES = kai.c
packet.c
libkai_plugin_la_CFLAGS = $(AM_CFLAGS)
libkai_plugin_la_CFLAGS = $(AM_CFLAGS)
libkai_plugin_la_LIBADD = $(AM_LIBADD) $(KAI_LIBS)
libkai_plugin_la_LIBADD = $(AM_LIBADD) $(KAI_LIBS)
libkai_plugin_la_DEPENDENCIES =
libkai_plugin_la_DEPENDENCIES =
...
...
modules/audio_output/packet.c
0 → 100644
View file @
c086f181
/*****************************************************************************
* packet.c : helper for legacy audio output plugins
*****************************************************************************
* Copyright (C) 2002-2012 VLC authors and VideoLAN
*
* 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.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <assert.h>
#include <vlc_common.h>
#include <vlc_aout.h>
/**
* Initializes the members of a FIFO.
*/
static
void
aout_FifoInit
(
aout_fifo_t
*
p_fifo
,
uint32_t
i_rate
)
{
assert
(
i_rate
!=
0
);
p_fifo
->
p_first
=
NULL
;
p_fifo
->
pp_last
=
&
p_fifo
->
p_first
;
date_Init
(
&
p_fifo
->
end_date
,
i_rate
,
1
);
date_Set
(
&
p_fifo
->
end_date
,
VLC_TS_INVALID
);
}
/**
* Pushes a packet into the FIFO.
*/
static
void
aout_FifoPush
(
aout_fifo_t
*
p_fifo
,
aout_buffer_t
*
p_buffer
)
{
*
p_fifo
->
pp_last
=
p_buffer
;
p_fifo
->
pp_last
=
&
p_buffer
->
p_next
;
*
p_fifo
->
pp_last
=
NULL
;
/* Enforce the continuity of the stream. */
if
(
date_Get
(
&
p_fifo
->
end_date
)
!=
VLC_TS_INVALID
)
{
p_buffer
->
i_pts
=
date_Get
(
&
p_fifo
->
end_date
);
p_buffer
->
i_length
=
date_Increment
(
&
p_fifo
->
end_date
,
p_buffer
->
i_nb_samples
);
p_buffer
->
i_length
-=
p_buffer
->
i_pts
;
}
else
{
date_Set
(
&
p_fifo
->
end_date
,
p_buffer
->
i_pts
+
p_buffer
->
i_length
);
}
}
/**
* Trashes all buffers.
*/
static
void
aout_FifoReset
(
aout_fifo_t
*
p_fifo
)
{
aout_buffer_t
*
p_buffer
;
date_Set
(
&
p_fifo
->
end_date
,
VLC_TS_INVALID
);
p_buffer
=
p_fifo
->
p_first
;
while
(
p_buffer
!=
NULL
)
{
aout_buffer_t
*
p_next
=
p_buffer
->
p_next
;
aout_BufferFree
(
p_buffer
);
p_buffer
=
p_next
;
}
p_fifo
->
p_first
=
NULL
;
p_fifo
->
pp_last
=
&
p_fifo
->
p_first
;
}
/**
* Move forwards or backwards all dates in the FIFO.
*/
static
void
aout_FifoMoveDates
(
aout_fifo_t
*
fifo
,
mtime_t
difference
)
{
if
(
date_Get
(
&
fifo
->
end_date
)
==
VLC_TS_INVALID
)
{
assert
(
fifo
->
p_first
==
NULL
);
return
;
}
date_Move
(
&
fifo
->
end_date
,
difference
);
for
(
block_t
*
block
=
fifo
->
p_first
;
block
!=
NULL
;
block
=
block
->
p_next
)
block
->
i_pts
+=
difference
;
}
/**
* Gets the next buffer out of the FIFO
*/
static
aout_buffer_t
*
aout_FifoPop
(
aout_fifo_t
*
p_fifo
)
{
aout_buffer_t
*
p_buffer
=
p_fifo
->
p_first
;
if
(
p_buffer
!=
NULL
)
{
p_fifo
->
p_first
=
p_buffer
->
p_next
;
if
(
p_fifo
->
p_first
==
NULL
)
p_fifo
->
pp_last
=
&
p_fifo
->
p_first
;
}
return
p_buffer
;
}
/**
* Destroys a FIFO and its buffers
*/
static
void
aout_FifoDestroy
(
aout_fifo_t
*
p_fifo
)
{
aout_buffer_t
*
p_buffer
;
p_buffer
=
p_fifo
->
p_first
;
while
(
p_buffer
!=
NULL
)
{
aout_buffer_t
*
p_next
=
p_buffer
->
p_next
;
aout_BufferFree
(
p_buffer
);
p_buffer
=
p_next
;
}
p_fifo
->
p_first
=
NULL
;
p_fifo
->
pp_last
=
&
p_fifo
->
p_first
;
}
static
inline
aout_packet_t
*
aout_packet
(
audio_output_t
*
aout
)
{
return
(
aout_packet_t
*
)(
aout
->
sys
);
}
void
aout_PacketInit
(
audio_output_t
*
aout
,
aout_packet_t
*
p
,
unsigned
samples
)
{
assert
(
p
==
aout_packet
(
aout
));
vlc_mutex_init
(
&
p
->
lock
);
aout_FifoInit
(
&
p
->
partial
,
aout
->
format
.
i_rate
);
aout_FifoInit
(
&
p
->
fifo
,
aout
->
format
.
i_rate
);
p
->
pause_date
=
VLC_TS_INVALID
;
p
->
time_report
=
VLC_TS_INVALID
;
p
->
samples
=
samples
;
p
->
starving
=
true
;
}
void
aout_PacketDestroy
(
audio_output_t
*
aout
)
{
aout_packet_t
*
p
=
aout_packet
(
aout
);
aout_FifoDestroy
(
&
p
->
partial
);
aout_FifoDestroy
(
&
p
->
fifo
);
vlc_mutex_destroy
(
&
p
->
lock
);
}
static
block_t
*
aout_OutputSlice
(
audio_output_t
*
);
void
aout_PacketPlay
(
audio_output_t
*
aout
,
block_t
*
block
)
{
aout_packet_t
*
p
=
aout_packet
(
aout
);
mtime_t
time_report
;
vlc_mutex_lock
(
&
p
->
lock
);
aout_FifoPush
(
&
p
->
partial
,
block
);
while
((
block
=
aout_OutputSlice
(
aout
))
!=
NULL
)
aout_FifoPush
(
&
p
->
fifo
,
block
);
time_report
=
p
->
time_report
;
p
->
time_report
=
VLC_TS_INVALID
;
vlc_mutex_unlock
(
&
p
->
lock
);
if
(
time_report
!=
VLC_TS_INVALID
)
aout_TimeReport
(
aout
,
mdate
()
-
time_report
);
}
void
aout_PacketPause
(
audio_output_t
*
aout
,
bool
pause
,
mtime_t
date
)
{
aout_packet_t
*
p
=
aout_packet
(
aout
);
if
(
pause
)
{
assert
(
p
->
pause_date
==
VLC_TS_INVALID
);
p
->
pause_date
=
date
;
}
else
{
assert
(
p
->
pause_date
!=
VLC_TS_INVALID
);
mtime_t
duration
=
date
-
p
->
pause_date
;
p
->
pause_date
=
VLC_TS_INVALID
;
vlc_mutex_lock
(
&
p
->
lock
);
aout_FifoMoveDates
(
&
p
->
partial
,
duration
);
aout_FifoMoveDates
(
&
p
->
fifo
,
duration
);
vlc_mutex_unlock
(
&
p
->
lock
);
}
}
void
aout_PacketFlush
(
audio_output_t
*
aout
,
bool
drain
)
{
aout_packet_t
*
p
=
aout_packet
(
aout
);
vlc_mutex_lock
(
&
p
->
lock
);
aout_FifoReset
(
&
p
->
partial
);
aout_FifoReset
(
&
p
->
fifo
);
vlc_mutex_unlock
(
&
p
->
lock
);
(
void
)
drain
;
/* TODO */
}
/**
* Rearranges audio blocks in correct number of samples.
* @note (FIXME) This is left here for historical reasons. It belongs in the
* output code. Besides, this operation should be avoided if possible.
*/
static
block_t
*
aout_OutputSlice
(
audio_output_t
*
p_aout
)
{
aout_packet_t
*
p
=
aout_packet
(
p_aout
);
aout_fifo_t
*
p_fifo
=
&
p
->
partial
;
const
unsigned
samples
=
p
->
samples
;
assert
(
samples
>
0
);
/* Retrieve the date of the next buffer. */
date_t
exact_start_date
=
p
->
fifo
.
end_date
;
mtime_t
start_date
=
date_Get
(
&
exact_start_date
);
/* Check if there is enough data to slice a new buffer. */
aout_buffer_t
*
p_buffer
=
p_fifo
->
p_first
;
if
(
p_buffer
==
NULL
)
return
NULL
;
/* Find the earliest start date available. */
if
(
start_date
==
VLC_TS_INVALID
)
{
start_date
=
p_buffer
->
i_pts
;
date_Set
(
&
exact_start_date
,
start_date
);
}
/* Compute the end date for the new buffer. */
mtime_t
end_date
=
date_Increment
(
&
exact_start_date
,
samples
);
/* Check that we have enough samples (TODO merge with next loop). */
for
(
unsigned
available
=
0
;
available
<
samples
;
)
{
p_buffer
=
p_buffer
->
p_next
;
if
(
p_buffer
==
NULL
)
return
NULL
;
available
+=
p_buffer
->
i_nb_samples
;
}
if
(
AOUT_FMT_LINEAR
(
&
p_aout
->
format
)
)
{
const
unsigned
framesize
=
p_aout
->
format
.
i_bytes_per_frame
;
/* Build packet with adequate number of samples */
unsigned
needed
=
samples
*
framesize
;
p_buffer
=
block_Alloc
(
needed
);
if
(
unlikely
(
p_buffer
==
NULL
)
)
/* XXX: should free input buffers */
return
NULL
;
p_buffer
->
i_nb_samples
=
samples
;
for
(
uint8_t
*
p_out
=
p_buffer
->
p_buffer
;
needed
>
0
;
)
{
aout_buffer_t
*
p_inbuf
=
p_fifo
->
p_first
;
if
(
unlikely
(
p_inbuf
==
NULL
)
)
{
msg_Err
(
p_aout
,
"packetization error"
);
vlc_memset
(
p_out
,
0
,
needed
);
break
;
}
const
uint8_t
*
p_in
=
p_inbuf
->
p_buffer
;
size_t
avail
=
p_inbuf
->
i_nb_samples
*
framesize
;
if
(
avail
>
needed
)
{
vlc_memcpy
(
p_out
,
p_in
,
needed
);
p_fifo
->
p_first
->
p_buffer
+=
needed
;
p_fifo
->
p_first
->
i_buffer
-=
needed
;
needed
/=
framesize
;
p_fifo
->
p_first
->
i_nb_samples
-=
needed
;
mtime_t
t
=
needed
*
CLOCK_FREQ
/
p_aout
->
format
.
i_rate
;
p_fifo
->
p_first
->
i_pts
+=
t
;
p_fifo
->
p_first
->
i_length
-=
t
;
break
;
}
vlc_memcpy
(
p_out
,
p_in
,
avail
);
needed
-=
avail
;
p_out
+=
avail
;
/* Next buffer */
aout_BufferFree
(
aout_FifoPop
(
p_fifo
)
);
}
}
else
p_buffer
=
aout_FifoPop
(
p_fifo
);
p_buffer
->
i_pts
=
start_date
;
p_buffer
->
i_length
=
end_date
-
start_date
;
return
p_buffer
;
}
/**
* Dequeues the next audio packet (a.k.a. audio fragment).
* The audio output plugin must first call aout_PacketPlay() to queue the
* decoded audio samples. Typically, audio_output_t.pf_play is set to, or calls
* aout_PacketPlay().
* @note This function is considered legacy. Please do not use this function in
* new audio output plugins.
* @param p_aout audio output instance
* @param start_date expected PTS of the audio packet
*/
block_t
*
aout_PacketNext
(
audio_output_t
*
p_aout
,
mtime_t
start_date
)
{
aout_packet_t
*
p
=
aout_packet
(
p_aout
);
aout_fifo_t
*
p_fifo
=
&
p
->
fifo
;
block_t
*
p_buffer
;
const
bool
b_can_sleek
=
!
AOUT_FMT_LINEAR
(
&
p_aout
->
format
);
const
mtime_t
now
=
mdate
();
const
mtime_t
threshold
=
(
b_can_sleek
?
start_date
:
now
)
-
AOUT_MAX_PTS_DELAY
;
vlc_mutex_lock
(
&
p
->
lock
);
if
(
p
->
pause_date
!=
VLC_TS_INVALID
)
goto
out
;
/* paused: do not dequeue buffers */
for
(;;)
{
p_buffer
=
p_fifo
->
p_first
;
if
(
p_buffer
==
NULL
)
goto
out
;
/* nothing to play */
if
(
p_buffer
->
i_pts
>=
threshold
)
break
;
/* Drop the audio sample if the audio output is really late.
* In the case of b_can_sleek, we don't use a resampler so we need to
* be a lot more severe. */
msg_Dbg
(
p_aout
,
"audio output is too slow (%"
PRId64
" us): "
" trashing %"
PRId64
" us"
,
threshold
-
p_buffer
->
i_pts
,
p_buffer
->
i_length
);
block_Release
(
aout_FifoPop
(
p_fifo
));
}
mtime_t
delta
=
start_date
-
p_buffer
->
i_pts
;
/* This assumes that all buffers have the same duration. This is true
* since aout_PacketPlay() (aout_OutputSlice()) is used. */
if
(
0
>=
delta
+
p_buffer
->
i_length
)
{
if
(
!
p
->
starving
)
{
msg_Dbg
(
p_aout
,
"audio output is starving (%"
PRId64
"), "
"playing silence"
,
delta
);
p
->
starving
=
true
;
}
goto
out
;
/* nothing to play _yet_ */
}
p
->
starving
=
false
;
p_buffer
=
aout_FifoPop
(
p_fifo
);
if
(
!
b_can_sleek
&&
(
delta
<
-
AOUT_MAX_PTS_ADVANCE
||
AOUT_MAX_PTS_DELAY
<
delta
))
{
msg_Warn
(
p_aout
,
"audio output out of sync, "
"adjusting dates (%"
PRId64
" us)"
,
delta
);
aout_FifoMoveDates
(
&
p
->
partial
,
delta
);
aout_FifoMoveDates
(
p_fifo
,
delta
);
p
->
time_report
=
delta
;
}
vlc_mutex_unlock
(
&
p
->
lock
);
return
p_buffer
;
out:
vlc_mutex_unlock
(
&
p
->
lock
);
return
NULL
;
}
src/audio_output/aout_internal.h
View file @
c086f181
...
@@ -172,14 +172,6 @@ audio_output_t *aout_New (vlc_object_t *);
...
@@ -172,14 +172,6 @@ audio_output_t *aout_New (vlc_object_t *);
#define aout_New(a) aout_New(VLC_OBJECT(a))
#define aout_New(a) aout_New(VLC_OBJECT(a))
void
aout_Destroy
(
audio_output_t
*
);
void
aout_Destroy
(
audio_output_t
*
);
void
aout_FifoInit
(
vlc_object_t
*
,
aout_fifo_t
*
,
uint32_t
);
mtime_t
aout_FifoFirstDate
(
const
aout_fifo_t
*
)
VLC_USED
;
#define aout_FifoInit(o, f, r) aout_FifoInit(VLC_OBJECT(o), f, r)
void
aout_FifoPush
(
aout_fifo_t
*
,
aout_buffer_t
*
);
aout_buffer_t
*
aout_FifoPop
(
aout_fifo_t
*
p_fifo
)
VLC_USED
;
void
aout_FifoReset
(
aout_fifo_t
*
);
void
aout_FifoMoveDates
(
aout_fifo_t
*
,
mtime_t
);
void
aout_FifoDestroy
(
aout_fifo_t
*
p_fifo
);
void
aout_FormatsPrint
(
vlc_object_t
*
,
const
char
*
,
void
aout_FormatsPrint
(
vlc_object_t
*
,
const
char
*
,
const
audio_sample_format_t
*
,
const
audio_sample_format_t
*
,
const
audio_sample_format_t
*
);
const
audio_sample_format_t
*
);
...
...
src/audio_output/common.c
View file @
c086f181
...
@@ -435,119 +435,6 @@ void aout_FormatsPrint( vlc_object_t *obj, const char * psz_text,
...
@@ -435,119 +435,6 @@ void aout_FormatsPrint( vlc_object_t *obj, const char * psz_text,
aout_FormatPrintChannels
(
p_format2
)
);
aout_FormatPrintChannels
(
p_format2
)
);
}
}
/*
* FIFO management (internal) - please understand that solving race conditions
* is _your_ job, ie. in the audio output you should own the mixer lock
* before calling any of these functions.
*/
#undef aout_FifoInit
/*****************************************************************************
* aout_FifoInit : initialize the members of a FIFO
*****************************************************************************/
void
aout_FifoInit
(
vlc_object_t
*
obj
,
aout_fifo_t
*
p_fifo
,
uint32_t
i_rate
)
{
if
(
unlikely
(
i_rate
==
0
)
)
msg_Err
(
obj
,
"initialising fifo with zero divider"
);
p_fifo
->
p_first
=
NULL
;
p_fifo
->
pp_last
=
&
p_fifo
->
p_first
;
date_Init
(
&
p_fifo
->
end_date
,
i_rate
,
1
);
date_Set
(
&
p_fifo
->
end_date
,
VLC_TS_INVALID
);
}
/*****************************************************************************
* aout_FifoPush : push a packet into the FIFO
*****************************************************************************/
void
aout_FifoPush
(
aout_fifo_t
*
p_fifo
,
aout_buffer_t
*
p_buffer
)
{
*
p_fifo
->
pp_last
=
p_buffer
;
p_fifo
->
pp_last
=
&
p_buffer
->
p_next
;
*
p_fifo
->
pp_last
=
NULL
;
/* Enforce the continuity of the stream. */
if
(
date_Get
(
&
p_fifo
->
end_date
)
!=
VLC_TS_INVALID
)
{
p_buffer
->
i_pts
=
date_Get
(
&
p_fifo
->
end_date
);
p_buffer
->
i_length
=
date_Increment
(
&
p_fifo
->
end_date
,
p_buffer
->
i_nb_samples
);
p_buffer
->
i_length
-=
p_buffer
->
i_pts
;
}
else
{
date_Set
(
&
p_fifo
->
end_date
,
p_buffer
->
i_pts
+
p_buffer
->
i_length
);
}
}
/*****************************************************************************
* aout_FifoReset: trash all buffers
*****************************************************************************/
void
aout_FifoReset
(
aout_fifo_t
*
p_fifo
)
{
aout_buffer_t
*
p_buffer
;
date_Set
(
&
p_fifo
->
end_date
,
VLC_TS_INVALID
);
p_buffer
=
p_fifo
->
p_first
;
while
(
p_buffer
!=
NULL
)
{
aout_buffer_t
*
p_next
=
p_buffer
->
p_next
;
aout_BufferFree
(
p_buffer
);
p_buffer
=
p_next
;
}
p_fifo
->
p_first
=
NULL
;
p_fifo
->
pp_last
=
&
p_fifo
->
p_first
;
}
/*****************************************************************************
* aout_FifoMoveDates : Move forwards or backwards all dates in the FIFO
*****************************************************************************/
void
aout_FifoMoveDates
(
aout_fifo_t
*
fifo
,
mtime_t
difference
)
{
if
(
date_Get
(
&
fifo
->
end_date
)
==
VLC_TS_INVALID
)
{
assert
(
fifo
->
p_first
==
NULL
);
return
;
}
date_Move
(
&
fifo
->
end_date
,
difference
);
for
(
block_t
*
block
=
fifo
->
p_first
;
block
!=
NULL
;
block
=
block
->
p_next
)
block
->
i_pts
+=
difference
;
}
/*****************************************************************************
* aout_FifoPop : get the next buffer out of the FIFO
*****************************************************************************/
aout_buffer_t
*
aout_FifoPop
(
aout_fifo_t
*
p_fifo
)
{
aout_buffer_t
*
p_buffer
=
p_fifo
->
p_first
;
if
(
p_buffer
!=
NULL
)
{
p_fifo
->
p_first
=
p_buffer
->
p_next
;
if
(
p_fifo
->
p_first
==
NULL
)
p_fifo
->
pp_last
=
&
p_fifo
->
p_first
;
}
return
p_buffer
;
}
/*****************************************************************************
* aout_FifoDestroy : destroy a FIFO and its buffers
*****************************************************************************/
void
aout_FifoDestroy
(
aout_fifo_t
*
p_fifo
)
{
aout_buffer_t
*
p_buffer
;
p_buffer
=
p_fifo
->
p_first
;
while
(
p_buffer
!=
NULL
)
{
aout_buffer_t
*
p_next
=
p_buffer
->
p_next
;
aout_BufferFree
(
p_buffer
);
p_buffer
=
p_next
;
}
p_fifo
->
p_first
=
NULL
;
p_fifo
->
pp_last
=
&
p_fifo
->
p_first
;
}
/*****************************************************************************
/*****************************************************************************
* aout_CheckChannelReorder : Check if we need to do some channel re-ordering
* aout_CheckChannelReorder : Check if we need to do some channel re-ordering
*****************************************************************************/
*****************************************************************************/
...
...
src/audio_output/output.c
View file @
c086f181
...
@@ -30,7 +30,6 @@
...
@@ -30,7 +30,6 @@
#include <math.h>
#include <math.h>
#include <assert.h>
#include <vlc_common.h>
#include <vlc_common.h>
#include <vlc_aout.h>
#include <vlc_aout.h>
#include <vlc_aout_intf.h>
#include <vlc_aout_intf.h>
...
@@ -366,260 +365,3 @@ void aout_VolumeHardSet (audio_output_t *aout, float volume, bool mute)
...
@@ -366,260 +365,3 @@ void aout_VolumeHardSet (audio_output_t *aout, float volume, bool mute)
var_SetBool
(
aout
,
"mute"
,
mute
);
var_SetBool
(
aout
,
"mute"
,
mute
);
var_TriggerCallback
(
aout
,
"intf-change"
);
var_TriggerCallback
(
aout
,
"intf-change"
);
}
}
/*** Packet-oriented audio output support ***/
static
inline
aout_packet_t
*
aout_packet
(
audio_output_t
*
aout
)
{
return
(
aout_packet_t
*
)(
aout
->
sys
);
}
void
aout_PacketInit
(
audio_output_t
*
aout
,
aout_packet_t
*
p
,
unsigned
samples
)
{
assert
(
p
==
aout_packet
(
aout
));
vlc_mutex_init
(
&
p
->
lock
);
aout_FifoInit
(
aout
,
&
p
->
partial
,
aout
->
format
.
i_rate
);
aout_FifoInit
(
aout
,
&
p
->
fifo
,
aout
->
format
.
i_rate
);
p
->
pause_date
=
VLC_TS_INVALID
;
p
->
time_report
=
VLC_TS_INVALID
;
p
->
samples
=
samples
;
p
->
starving
=
true
;
}
void
aout_PacketDestroy
(
audio_output_t
*
aout
)
{
aout_packet_t
*
p
=
aout_packet
(
aout
);
aout_FifoDestroy
(
&
p
->
partial
);
aout_FifoDestroy
(
&
p
->
fifo
);
vlc_mutex_destroy
(
&
p
->
lock
);
}
static
block_t
*
aout_OutputSlice
(
audio_output_t
*
);
void
aout_PacketPlay
(
audio_output_t
*
aout
,
block_t
*
block
)
{
aout_packet_t
*
p
=
aout_packet
(
aout
);
mtime_t
time_report
;
vlc_mutex_lock
(
&
p
->
lock
);
aout_FifoPush
(
&
p
->
partial
,
block
);
while
((
block
=
aout_OutputSlice
(
aout
))
!=
NULL
)
aout_FifoPush
(
&
p
->
fifo
,
block
);
time_report
=
p
->
time_report
;
p
->
time_report
=
VLC_TS_INVALID
;
vlc_mutex_unlock
(
&
p
->
lock
);
if
(
time_report
!=
VLC_TS_INVALID
)
aout_TimeReport
(
aout
,
mdate
()
-
time_report
);
}
void
aout_PacketPause
(
audio_output_t
*
aout
,
bool
pause
,
mtime_t
date
)
{
aout_packet_t
*
p
=
aout_packet
(
aout
);
if
(
pause
)
{
assert
(
p
->
pause_date
==
VLC_TS_INVALID
);
p
->
pause_date
=
date
;
}
else
{
assert
(
p
->
pause_date
!=
VLC_TS_INVALID
);
mtime_t
duration
=
date
-
p
->
pause_date
;
p
->
pause_date
=
VLC_TS_INVALID
;
vlc_mutex_lock
(
&
p
->
lock
);
aout_FifoMoveDates
(
&
p
->
partial
,
duration
);
aout_FifoMoveDates
(
&
p
->
fifo
,
duration
);
vlc_mutex_unlock
(
&
p
->
lock
);
}
}
void
aout_PacketFlush
(
audio_output_t
*
aout
,
bool
drain
)
{
aout_packet_t
*
p
=
aout_packet
(
aout
);
vlc_mutex_lock
(
&
p
->
lock
);
aout_FifoReset
(
&
p
->
partial
);
aout_FifoReset
(
&
p
->
fifo
);
vlc_mutex_unlock
(
&
p
->
lock
);
(
void
)
drain
;
/* TODO */
}
/**
* Rearranges audio blocks in correct number of samples.
* @note (FIXME) This is left here for historical reasons. It belongs in the
* output code. Besides, this operation should be avoided if possible.
*/
static
block_t
*
aout_OutputSlice
(
audio_output_t
*
p_aout
)
{
aout_packet_t
*
p
=
aout_packet
(
p_aout
);
aout_fifo_t
*
p_fifo
=
&
p
->
partial
;
const
unsigned
samples
=
p
->
samples
;
assert
(
samples
>
0
);
vlc_assert_locked
(
&
p
->
lock
);
/* Retrieve the date of the next buffer. */
date_t
exact_start_date
=
p
->
fifo
.
end_date
;
mtime_t
start_date
=
date_Get
(
&
exact_start_date
);
/* See if we have enough data to prepare a new buffer for the audio output. */
aout_buffer_t
*
p_buffer
=
p_fifo
->
p_first
;
if
(
p_buffer
==
NULL
)
return
NULL
;
/* Find the earliest start date available. */
if
(
start_date
==
VLC_TS_INVALID
)
{
start_date
=
p_buffer
->
i_pts
;
date_Set
(
&
exact_start_date
,
start_date
);
}
/* Compute the end date for the new buffer. */
mtime_t
end_date
=
date_Increment
(
&
exact_start_date
,
samples
);
/* Check that we have enough samples (TODO merge with next loop). */
for
(
unsigned
available
=
0
;
available
<
samples
;
)
{
p_buffer
=
p_buffer
->
p_next
;
if
(
p_buffer
==
NULL
)
return
NULL
;
available
+=
p_buffer
->
i_nb_samples
;
}
if
(
AOUT_FMT_LINEAR
(
&
p_aout
->
format
)
)
{
const
unsigned
framesize
=
p_aout
->
format
.
i_bytes_per_frame
;
/* Build packet with adequate number of samples */
unsigned
needed
=
samples
*
framesize
;
p_buffer
=
block_Alloc
(
needed
);
if
(
unlikely
(
p_buffer
==
NULL
)
)
/* XXX: should free input buffers */
return
NULL
;
p_buffer
->
i_nb_samples
=
samples
;
for
(
uint8_t
*
p_out
=
p_buffer
->
p_buffer
;
needed
>
0
;
)
{
aout_buffer_t
*
p_inbuf
=
p_fifo
->
p_first
;
if
(
unlikely
(
p_inbuf
==
NULL
)
)
{
msg_Err
(
p_aout
,
"packetization error"
);
vlc_memset
(
p_out
,
0
,
needed
);
break
;
}
const
uint8_t
*
p_in
=
p_inbuf
->
p_buffer
;
size_t
avail
=
p_inbuf
->
i_nb_samples
*
framesize
;
if
(
avail
>
needed
)
{
vlc_memcpy
(
p_out
,
p_in
,
needed
);
p_fifo
->
p_first
->
p_buffer
+=
needed
;
p_fifo
->
p_first
->
i_buffer
-=
needed
;
needed
/=
framesize
;
p_fifo
->
p_first
->
i_nb_samples
-=
needed
;
mtime_t
t
=
needed
*
CLOCK_FREQ
/
p_aout
->
format
.
i_rate
;
p_fifo
->
p_first
->
i_pts
+=
t
;
p_fifo
->
p_first
->
i_length
-=
t
;
break
;
}
vlc_memcpy
(
p_out
,
p_in
,
avail
);
needed
-=
avail
;
p_out
+=
avail
;
/* Next buffer */
aout_BufferFree
(
aout_FifoPop
(
p_fifo
)
);
}
}
else
p_buffer
=
aout_FifoPop
(
p_fifo
);
p_buffer
->
i_pts
=
start_date
;
p_buffer
->
i_length
=
end_date
-
start_date
;
return
p_buffer
;
}
/**
* Dequeues the next audio packet (a.k.a. audio fragment).
* The audio output plugin must first call aout_PacketPlay() to queue the
* decoded audio samples. Typically, audio_output_t.pf_play is set to, or calls
* aout_PacketPlay().
* @note This function is considered legacy. Please do not use this function in
* new audio output plugins.
* @param p_aout audio output instance
* @param start_date expected PTS of the audio packet
*/
block_t
*
aout_PacketNext
(
audio_output_t
*
p_aout
,
mtime_t
start_date
)
{
aout_packet_t
*
p
=
aout_packet
(
p_aout
);
aout_fifo_t
*
p_fifo
=
&
p
->
fifo
;
block_t
*
p_buffer
;
const
bool
b_can_sleek
=
!
AOUT_FMT_LINEAR
(
&
p_aout
->
format
);
const
mtime_t
now
=
mdate
();
const
mtime_t
threshold
=
(
b_can_sleek
?
start_date
:
now
)
-
AOUT_MAX_PTS_DELAY
;
vlc_mutex_lock
(
&
p
->
lock
);
if
(
p
->
pause_date
!=
VLC_TS_INVALID
)
goto
out
;
/* paused: do not dequeue buffers */
for
(;;)
{
p_buffer
=
p_fifo
->
p_first
;
if
(
p_buffer
==
NULL
)
goto
out
;
/* nothing to play */
if
(
p_buffer
->
i_pts
>=
threshold
)
break
;
/* Drop the audio sample if the audio output is really late.
* In the case of b_can_sleek, we don't use a resampler so we need to
* be a lot more severe. */
msg_Dbg
(
p_aout
,
"audio output is too slow (%"
PRId64
" us): "
" trashing %"
PRId64
" us"
,
threshold
-
p_buffer
->
i_pts
,
p_buffer
->
i_length
);
block_Release
(
aout_FifoPop
(
p_fifo
));
}
mtime_t
delta
=
start_date
-
p_buffer
->
i_pts
;
/* This assumes that all buffers have the same duration. This is true
* since aout_PacketPlay() (aout_OutputSlice()) is used. */
if
(
0
>=
delta
+
p_buffer
->
i_length
)
{
if
(
!
p
->
starving
)
{
msg_Dbg
(
p_aout
,
"audio output is starving (%"
PRId64
"), "
"playing silence"
,
delta
);
p
->
starving
=
true
;
}
goto
out
;
/* nothing to play _yet_ */
}
p
->
starving
=
false
;
p_buffer
=
aout_FifoPop
(
p_fifo
);
if
(
!
b_can_sleek
&&
(
delta
<
-
AOUT_MAX_PTS_ADVANCE
||
AOUT_MAX_PTS_DELAY
<
delta
))
{
msg_Warn
(
p_aout
,
"audio output out of sync, "
"adjusting dates (%"
PRId64
" us)"
,
delta
);
aout_FifoMoveDates
(
&
p
->
partial
,
delta
);
aout_FifoMoveDates
(
p_fifo
,
delta
);
p
->
time_report
=
delta
;
}
vlc_mutex_unlock
(
&
p
->
lock
);
return
p_buffer
;
out:
vlc_mutex_unlock
(
&
p
->
lock
);
return
NULL
;
}
src/libvlccore.sym
View file @
c086f181
...
@@ -14,12 +14,6 @@ aout_FormatPrintChannels
...
@@ -14,12 +14,6 @@ aout_FormatPrintChannels
aout_MixerDelete
aout_MixerDelete
aout_MixerNew
aout_MixerNew
aout_MixerRun
aout_MixerRun
aout_PacketInit
aout_PacketDestroy
aout_PacketPlay
aout_PacketPause
aout_PacketFlush
aout_PacketNext
aout_VolumeGet
aout_VolumeGet
aout_VolumeSet
aout_VolumeSet
aout_VolumeUp
aout_VolumeUp
...
...
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