Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-2-2
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-2-2
Commits
386288d6
Commit
386288d6
authored
Oct 24, 2009
by
Rémi Denis-Courmont
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ALSA: vlc_thread_create -> vlc_clone
parent
19eb1b45
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
60 additions
and
41 deletions
+60
-41
modules/audio_output/alsa.c
modules/audio_output/alsa.c
+60
-41
No files found.
modules/audio_output/alsa.c
View file @
386288d6
...
@@ -66,6 +66,7 @@ struct aout_sys_t
...
@@ -66,6 +66,7 @@ struct aout_sys_t
bool
b_playing
;
/* playing status */
bool
b_playing
;
/* playing status */
mtime_t
start_date
;
mtime_t
start_date
;
vlc_thread_t
thread
;
vlc_mutex_t
lock
;
vlc_mutex_t
lock
;
vlc_cond_t
wait
;
vlc_cond_t
wait
;
};
};
...
@@ -92,7 +93,7 @@ struct aout_sys_t
...
@@ -92,7 +93,7 @@ struct aout_sys_t
static
int
Open
(
vlc_object_t
*
);
static
int
Open
(
vlc_object_t
*
);
static
void
Close
(
vlc_object_t
*
);
static
void
Close
(
vlc_object_t
*
);
static
void
Play
(
aout_instance_t
*
);
static
void
Play
(
aout_instance_t
*
);
static
void
*
ALSAThread
(
v
lc_object_t
*
);
static
void
*
ALSAThread
(
v
oid
*
);
static
void
ALSAFill
(
aout_instance_t
*
);
static
void
ALSAFill
(
aout_instance_t
*
);
static
int
FindDevicesCallback
(
vlc_object_t
*
p_this
,
char
const
*
psz_name
,
static
int
FindDevicesCallback
(
vlc_object_t
*
p_this
,
char
const
*
psz_name
,
vlc_value_t
newval
,
vlc_value_t
oldval
,
void
*
p_unused
);
vlc_value_t
newval
,
vlc_value_t
oldval
,
void
*
p_unused
);
...
@@ -661,8 +662,8 @@ static int Open( vlc_object_t *p_this )
...
@@ -661,8 +662,8 @@ static int Open( vlc_object_t *p_this )
#endif
#endif
/* Create ALSA thread and wait for its readiness. */
/* Create ALSA thread and wait for its readiness. */
if
(
vlc_
thread_create
(
p_aout
,
"aout"
,
ALSAThread
,
if
(
vlc_
clone
(
&
p_sys
->
thread
,
ALSAThread
,
p_aout
,
VLC_THREAD_PRIORITY_OUTPUT
)
)
VLC_THREAD_PRIORITY_OUTPUT
)
)
{
{
msg_Err
(
p_aout
,
"cannot create ALSA thread (%m)"
);
msg_Err
(
p_aout
,
"cannot create ALSA thread (%m)"
);
goto
error
;
goto
error
;
...
@@ -709,7 +710,8 @@ static void Close( vlc_object_t *p_this )
...
@@ -709,7 +710,8 @@ static void Close( vlc_object_t *p_this )
int
i_snd_rc
;
int
i_snd_rc
;
/* Make sure that the thread will stop once it is waken up */
/* Make sure that the thread will stop once it is waken up */
vlc_object_kill
(
p_aout
);
vlc_cancel
(
p_sys
->
thread
);
vlc_join
(
p_sys
->
thread
,
NULL
);
/* make sure the audio output thread is waken up */
/* make sure the audio output thread is waken up */
vlc_mutex_lock
(
&
p_aout
->
output
.
p_sys
->
lock
);
vlc_mutex_lock
(
&
p_aout
->
output
.
p_sys
->
lock
);
...
@@ -717,9 +719,6 @@ static void Close( vlc_object_t *p_this )
...
@@ -717,9 +719,6 @@ static void Close( vlc_object_t *p_this )
vlc_mutex_unlock
(
&
p_aout
->
output
.
p_sys
->
lock
);
vlc_mutex_unlock
(
&
p_aout
->
output
.
p_sys
->
lock
);
/* */
/* */
vlc_thread_join
(
p_aout
);
p_aout
->
b_die
=
false
;
i_snd_rc
=
snd_pcm_close
(
p_sys
->
p_snd_pcm
);
i_snd_rc
=
snd_pcm_close
(
p_sys
->
p_snd_pcm
);
if
(
i_snd_rc
>
0
)
if
(
i_snd_rc
>
0
)
...
@@ -735,35 +734,34 @@ static void Close( vlc_object_t *p_this )
...
@@ -735,35 +734,34 @@ static void Close( vlc_object_t *p_this )
free
(
p_sys
);
free
(
p_sys
);
}
}
static
void
pcm_drop
(
void
*
pcm
)
{
snd_pcm_drop
(
pcm
);
}
/*****************************************************************************
/*****************************************************************************
* ALSAThread: asynchronous thread used to DMA the data to the device
* ALSAThread: asynchronous thread used to DMA the data to the device
*****************************************************************************/
*****************************************************************************/
static
void
*
ALSAThread
(
v
lc_object_t
*
p_this
)
static
void
*
ALSAThread
(
v
oid
*
data
)
{
{
aout_instance_t
*
p_aout
=
(
aout_instance_t
*
)
p_this
;
aout_instance_t
*
p_aout
=
data
;
struct
aout_sys_t
*
p_sys
=
p_aout
->
output
.
p_sys
;
struct
aout_sys_t
*
p_sys
=
p_aout
->
output
.
p_sys
;
int
canc
=
vlc_savecancel
();
/* Wait for the exact time to start playing (avoids resampling) */
/* Wait for the exact time to start playing (avoids resampling) */
vlc_mutex_lock
(
&
p_sys
->
lock
);
vlc_mutex_lock
(
&
p_sys
->
lock
);
while
(
!
p_sys
->
start_date
&&
vlc_object_alive
(
p_aout
)
)
mutex_cleanup_push
(
&
p_sys
->
lock
);
while
(
!
p_sys
->
start_date
)
vlc_cond_wait
(
&
p_sys
->
wait
,
&
p_sys
->
lock
);
vlc_cond_wait
(
&
p_sys
->
wait
,
&
p_sys
->
lock
);
vlc_mutex_unlock
(
&
p_sys
->
lock
);
vlc_cleanup_run
();
if
(
!
vlc_object_alive
(
p_aout
)
)
goto
cleanup
;
mwait
(
p_sys
->
start_date
-
AOUT_PTS_TOLERANCE
/
4
);
mwait
(
p_sys
->
start_date
-
AOUT_PTS_TOLERANCE
/
4
);
while
(
vlc_object_alive
(
p_aout
)
)
vlc_cleanup_push
(
pcm_drop
,
p_sys
->
p_snd_pcm
);
{
for
(;;)
ALSAFill
(
p_aout
);
ALSAFill
(
p_aout
);
}
cleanup:
assert
(
0
);
snd_pcm_drop
(
p_sys
->
p_snd_pcm
);
vlc_cleanup_pop
();
vlc_restorecancel
(
canc
);
return
NULL
;
}
}
/*****************************************************************************
/*****************************************************************************
...
@@ -772,16 +770,17 @@ cleanup:
...
@@ -772,16 +770,17 @@ cleanup:
static
void
ALSAFill
(
aout_instance_t
*
p_aout
)
static
void
ALSAFill
(
aout_instance_t
*
p_aout
)
{
{
struct
aout_sys_t
*
p_sys
=
p_aout
->
output
.
p_sys
;
struct
aout_sys_t
*
p_sys
=
p_aout
->
output
.
p_sys
;
aout_buffer_t
*
p_buffer
;
snd_pcm_t
*
p_pcm
=
p_sys
->
p_snd_pcm
;
snd_pcm_status_t
*
p_status
;
snd_pcm_status_t
*
p_status
;
int
i_snd_rc
;
int
i_snd_rc
;
mtime_t
next_date
;
mtime_t
next_date
;
int
canc
=
vlc_savecancel
();
/* Fill in the buffer until space or audio output buffer shortage */
/* Fill in the buffer until space or audio output buffer shortage */
/* Get the status */
/* Get the status */
snd_pcm_status_alloca
(
&
p_status
);
snd_pcm_status_alloca
(
&
p_status
);
i_snd_rc
=
snd_pcm_status
(
p_
sys
->
p_snd_
pcm
,
p_status
);
i_snd_rc
=
snd_pcm_status
(
p_pcm
,
p_status
);
if
(
i_snd_rc
<
0
)
if
(
i_snd_rc
<
0
)
{
{
msg_Err
(
p_aout
,
"cannot get device status"
);
msg_Err
(
p_aout
,
"cannot get device status"
);
...
@@ -792,8 +791,7 @@ static void ALSAFill( aout_instance_t * p_aout )
...
@@ -792,8 +791,7 @@ static void ALSAFill( aout_instance_t * p_aout )
if
(
snd_pcm_status_get_state
(
p_status
)
==
SND_PCM_STATE_XRUN
)
if
(
snd_pcm_status_get_state
(
p_status
)
==
SND_PCM_STATE_XRUN
)
{
{
/* Prepare the device */
/* Prepare the device */
i_snd_rc
=
snd_pcm_prepare
(
p_sys
->
p_snd_pcm
);
i_snd_rc
=
snd_pcm_prepare
(
p_pcm
);
if
(
i_snd_rc
)
if
(
i_snd_rc
)
{
{
msg_Err
(
p_aout
,
"cannot recover from buffer underrun"
);
msg_Err
(
p_aout
,
"cannot recover from buffer underrun"
);
...
@@ -803,7 +801,7 @@ static void ALSAFill( aout_instance_t * p_aout )
...
@@ -803,7 +801,7 @@ static void ALSAFill( aout_instance_t * p_aout )
msg_Dbg
(
p_aout
,
"recovered from buffer underrun"
);
msg_Dbg
(
p_aout
,
"recovered from buffer underrun"
);
/* Get the new status */
/* Get the new status */
i_snd_rc
=
snd_pcm_status
(
p_
sys
->
p_snd_
pcm
,
p_status
);
i_snd_rc
=
snd_pcm_status
(
p_pcm
,
p_status
);
if
(
i_snd_rc
<
0
)
if
(
i_snd_rc
<
0
)
{
{
msg_Err
(
p_aout
,
"cannot get device status after recovery"
);
msg_Err
(
p_aout
,
"cannot get device status after recovery"
);
...
@@ -818,10 +816,10 @@ static void ALSAFill( aout_instance_t * p_aout )
...
@@ -818,10 +816,10 @@ static void ALSAFill( aout_instance_t * p_aout )
/* Here the device should be in RUNNING state, p_status is valid. */
/* Here the device should be in RUNNING state, p_status is valid. */
snd_pcm_sframes_t
delay
=
snd_pcm_status_get_delay
(
p_status
);
snd_pcm_sframes_t
delay
=
snd_pcm_status_get_delay
(
p_status
);
if
(
delay
==
0
)
/* workaround buggy alsa drivers */
if
(
delay
==
0
)
/* workaround buggy alsa drivers */
if
(
snd_pcm_delay
(
p_
sys
->
p_snd_
pcm
,
&
delay
)
<
0
)
if
(
snd_pcm_delay
(
p_pcm
,
&
delay
)
<
0
)
delay
=
0
;
/* FIXME: use a positive minimal delay */
delay
=
0
;
/* FIXME: use a positive minimal delay */
size_t
i_bytes
=
snd_pcm_frames_to_bytes
(
p_
sys
->
p_snd_
pcm
,
delay
);
size_t
i_bytes
=
snd_pcm_frames_to_bytes
(
p_pcm
,
delay
);
mtime_t
delay_us
=
CLOCK_FREQ
*
i_bytes
mtime_t
delay_us
=
CLOCK_FREQ
*
i_bytes
/
p_aout
->
output
.
output
.
i_bytes_per_frame
/
p_aout
->
output
.
output
.
i_bytes_per_frame
/
p_aout
->
output
.
output
.
i_rate
/
p_aout
->
output
.
output
.
i_rate
...
@@ -842,7 +840,7 @@ static void ALSAFill( aout_instance_t * p_aout )
...
@@ -842,7 +840,7 @@ static void ALSAFill( aout_instance_t * p_aout )
next_date
=
mdate
()
+
delay_us
;
next_date
=
mdate
()
+
delay_us
;
}
}
p_buffer
=
aout_OutputNextBuffer
(
p_aout
,
next_date
,
block_t
*
p_buffer
=
aout_OutputNextBuffer
(
p_aout
,
next_date
,
(
p_aout
->
output
.
output
.
i_format
==
VLC_CODEC_SPDIFL
)
);
(
p_aout
->
output
.
output
.
i_format
==
VLC_CODEC_SPDIFL
)
);
/* Audio output buffer shortage -> stop the fill process and wait */
/* Audio output buffer shortage -> stop the fill process and wait */
...
@@ -851,37 +849,58 @@ static void ALSAFill( aout_instance_t * p_aout )
...
@@ -851,37 +849,58 @@ static void ALSAFill( aout_instance_t * p_aout )
for
(;;)
for
(;;)
{
{
i_snd_rc
=
snd_pcm_writei
(
p_sys
->
p_snd_pcm
,
p_buffer
->
p_buffer
,
int
n
=
snd_pcm_poll_descriptors_count
(
p_pcm
);
p_buffer
->
i_nb_samples
);
struct
pollfd
ufd
[
n
];
if
(
i_snd_rc
!=
-
ESTRPIPE
)
unsigned
short
revents
;
break
;
snd_pcm_poll_descriptors
(
p_pcm
,
ufd
,
n
);
do
{
vlc_restorecancel
(
canc
);
poll
(
ufd
,
n
,
-
1
);
canc
=
vlc_savecancel
();
snd_pcm_poll_descriptors_revents
(
p_pcm
,
ufd
,
n
,
&
revents
);
}
while
(
!
revents
);
if
(
revents
&
POLLOUT
)
{
i_snd_rc
=
snd_pcm_writei
(
p_pcm
,
p_buffer
->
p_buffer
,
p_buffer
->
i_nb_samples
);
if
(
i_snd_rc
!=
-
ESTRPIPE
)
break
;
}
/* a suspend event occurred
/* a suspend event occurred
* (stream is suspended and waiting for an application recovery) */
* (stream is suspended and waiting for an application recovery) */
msg_Dbg
(
p_aout
,
"entering in suspend mode, trying to resume..."
);
msg_Dbg
(
p_aout
,
"entering in suspend mode, trying to resume..."
);
while
(
vlc_object_alive
(
p_aout
)
&&
vlc_object_alive
(
p_aout
->
p_libvlc
)
&&
while
(
(
i_snd_rc
=
snd_pcm_resume
(
p_pcm
)
)
==
-
EAGAIN
)
(
i_snd_rc
=
snd_pcm_resume
(
p_sys
->
p_snd_pcm
)
)
==
-
EAGAIN
)
{
{
msleep
(
1000000
);
vlc_restorecancel
(
canc
);
msleep
(
CLOCK_FREQ
);
/* device still suspended, wait... */
canc
=
vlc_savecancel
();
}
}
if
(
i_snd_rc
<
0
)
if
(
i_snd_rc
<
0
)
/* Device does not supp
ro
t resuming, restart it */
/* Device does not supp
or
t resuming, restart it */
i_snd_rc
=
snd_pcm_prepare
(
p_
sys
->
p_snd_
pcm
);
i_snd_rc
=
snd_pcm_prepare
(
p_pcm
);
}
}
if
(
i_snd_rc
<
0
)
if
(
i_snd_rc
<
0
)
msg_Err
(
p_aout
,
"cannot write: %s"
,
snd_strerror
(
i_snd_rc
)
);
msg_Err
(
p_aout
,
"cannot write: %s"
,
snd_strerror
(
i_snd_rc
)
);
aout_BufferFree
(
p_buffer
);
vlc_restorecancel
(
canc
);
block_Release
(
p_buffer
);
return
;
return
;
error:
error:
if
(
i_snd_rc
<
0
)
if
(
i_snd_rc
<
0
)
msg_Err
(
p_aout
,
"ALSA error: %s"
,
snd_strerror
(
i_snd_rc
)
);
msg_Err
(
p_aout
,
"ALSA error: %s"
,
snd_strerror
(
i_snd_rc
)
);
msleep
(
p_sys
->
i_period_time
>>
1
);
vlc_restorecancel
(
canc
);
msleep
(
p_sys
->
i_period_time
/
2
);
}
}
static
void
GetDevicesForCard
(
module_config_t
*
p_item
,
int
i_card
);
static
void
GetDevicesForCard
(
module_config_t
*
p_item
,
int
i_card
);
...
...
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