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
31439d7a
Commit
31439d7a
authored
Apr 25, 2007
by
Jean-Baptiste Kempf
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Jack patch by Jon Griffiths, fix crashes, improve debuging and use regexps.
parent
9397093e
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
114 additions
and
108 deletions
+114
-108
modules/audio_output/jack.c
modules/audio_output/jack.c
+114
-108
No files found.
modules/audio_output/jack.c
View file @
31439d7a
...
@@ -4,7 +4,7 @@
...
@@ -4,7 +4,7 @@
* Copyright (C) 2006 the VideoLAN team
* Copyright (C) 2006 the VideoLAN team
* $Id$
* $Id$
*
*
* Authors: Cyril Deguet <asmax
@
videolan.org>
* Authors: Cyril Deguet <asmax
_at_
videolan.org>
* Jon Griffiths <jon_p_griffiths _At_ yahoo _DOT_ com>
* Jon Griffiths <jon_p_griffiths _At_ yahoo _DOT_ com>
*
*
* This program is free software; you can redistribute it and/or modify
* This program is free software; you can redistribute it and/or modify
...
@@ -37,6 +37,8 @@
...
@@ -37,6 +37,8 @@
#include <jack/jack.h>
#include <jack/jack.h>
typedef
jack_default_audio_sample_t
jack_sample_t
;
/*****************************************************************************
/*****************************************************************************
* aout_sys_t: JACK audio output method descriptor
* aout_sys_t: JACK audio output method descriptor
*****************************************************************************
*****************************************************************************
...
@@ -47,6 +49,7 @@ struct aout_sys_t
...
@@ -47,6 +49,7 @@ struct aout_sys_t
{
{
jack_client_t
*
p_jack_client
;
jack_client_t
*
p_jack_client
;
jack_port_t
**
p_jack_ports
;
jack_port_t
**
p_jack_ports
;
jack_sample_t
**
p_jack_buffers
;
unsigned
int
i_channels
;
unsigned
int
i_channels
;
};
};
...
@@ -59,16 +62,16 @@ static void Play ( aout_instance_t * );
...
@@ -59,16 +62,16 @@ static void Play ( aout_instance_t * );
static
int
Process
(
jack_nframes_t
i_frames
,
void
*
p_arg
);
static
int
Process
(
jack_nframes_t
i_frames
,
void
*
p_arg
);
#define AUTO_CONNECT_OPTION "jack-auto-connect"
#define AUTO_CONNECT_OPTION "jack-auto-connect"
#define AUTO_CONNECT_TEXT N_("Automatically connect to
input device
s")
#define AUTO_CONNECT_TEXT N_("Automatically connect to
writable client
s")
#define AUTO_CONNECT_LONGTEXT N_( \
#define AUTO_CONNECT_LONGTEXT N_( \
"If enabled, this option will automatically connect output to the " \
"If enabled, this option will automatically connect
sound
output to the " \
"first
JACK inpu
ts found." )
"first
writable JACK clien
ts found." )
#define CONNECT_
MATCH_OPTION "jack-connect-match
"
#define CONNECT_
REGEX_OPTION "jack-connect-regex
"
#define CONNECT_
MATCH_TEXT N_("Connect to outputs beginning with
")
#define CONNECT_
REGEX_TEXT N_("Connect to clients matching
")
#define CONNECT_
MATCH
_LONGTEXT N_( \
#define CONNECT_
REGEX
_LONGTEXT N_( \
"If automatic connection is enabled, only JACK
inpu
ts whose names " \
"If automatic connection is enabled, only JACK
clien
ts whose names " \
"
begin with this prefix
will be considered for connection." )
"
match this regular expression
will be considered for connection." )
/*****************************************************************************
/*****************************************************************************
* Module descriptor
* Module descriptor
...
@@ -81,8 +84,8 @@ vlc_module_begin();
...
@@ -81,8 +84,8 @@ vlc_module_begin();
set_subcategory
(
SUBCAT_AUDIO_AOUT
);
set_subcategory
(
SUBCAT_AUDIO_AOUT
);
add_bool
(
AUTO_CONNECT_OPTION
,
0
,
NULL
,
AUTO_CONNECT_TEXT
,
add_bool
(
AUTO_CONNECT_OPTION
,
0
,
NULL
,
AUTO_CONNECT_TEXT
,
AUTO_CONNECT_LONGTEXT
,
VLC_TRUE
);
AUTO_CONNECT_LONGTEXT
,
VLC_TRUE
);
add_string
(
CONNECT_
MATCH_OPTION
,
NULL
,
NULL
,
CONNECT_MATCH
_TEXT
,
add_string
(
CONNECT_
REGEX_OPTION
,
NULL
,
NULL
,
CONNECT_REGEX
_TEXT
,
CONNECT_
MATCH
_LONGTEXT
,
VLC_TRUE
);
CONNECT_
REGEX
_LONGTEXT
,
VLC_TRUE
);
set_callbacks
(
Open
,
Close
);
set_callbacks
(
Open
,
Close
);
vlc_module_end
();
vlc_module_end
();
...
@@ -91,15 +94,15 @@ vlc_module_end();
...
@@ -91,15 +94,15 @@ vlc_module_end();
*****************************************************************************/
*****************************************************************************/
static
int
Open
(
vlc_object_t
*
p_this
)
static
int
Open
(
vlc_object_t
*
p_this
)
{
{
char
psz_name
[
32
];
aout_instance_t
*
p_aout
=
(
aout_instance_t
*
)
p_this
;
aout_instance_t
*
p_aout
=
(
aout_instance_t
*
)
p_this
;
struct
aout_sys_t
*
p_sys
=
NULL
;
struct
aout_sys_t
*
p_sys
=
NULL
;
char
**
pp_match_ports
=
NULL
;
char
*
psz_prefix
=
NULL
;
int
status
=
VLC_SUCCESS
;
int
status
=
VLC_SUCCESS
;
unsigned
int
i
;
unsigned
int
i
;
int
i_error
;
/* Allocate structure */
/* Allocate structure */
p_sys
=
malloc
(
sizeof
(
aout_sys_t
)
);
p_sys
=
calloc
(
1
,
sizeof
(
aout_sys_t
)
);
if
(
p_sys
==
NULL
)
if
(
p_sys
==
NULL
)
{
{
msg_Err
(
p_aout
,
"out of memory"
);
msg_Err
(
p_aout
,
"out of memory"
);
...
@@ -109,7 +112,9 @@ static int Open( vlc_object_t *p_this )
...
@@ -109,7 +112,9 @@ static int Open( vlc_object_t *p_this )
p_aout
->
output
.
p_sys
=
p_sys
;
p_aout
->
output
.
p_sys
=
p_sys
;
/* Connect to the JACK server */
/* Connect to the JACK server */
p_sys
->
p_jack_client
=
jack_client_new
(
"vlc"
);
snprintf
(
psz_name
,
sizeof
(
psz_name
),
"vlc_%d"
,
getpid
());
psz_name
[
sizeof
(
psz_name
)
-
1
]
=
'\0'
;
p_sys
->
p_jack_client
=
jack_client_new
(
psz_name
);
if
(
p_sys
->
p_jack_client
==
NULL
)
if
(
p_sys
->
p_jack_client
==
NULL
)
{
{
msg_Err
(
p_aout
,
"failed to connect to JACK server"
);
msg_Err
(
p_aout
,
"failed to connect to JACK server"
);
...
@@ -131,7 +136,8 @@ static int Open( vlc_object_t *p_this )
...
@@ -131,7 +136,8 @@ static int Open( vlc_object_t *p_this )
p_sys
->
i_channels
=
aout_FormatNbChannels
(
&
p_aout
->
output
.
output
);
p_sys
->
i_channels
=
aout_FormatNbChannels
(
&
p_aout
->
output
.
output
);
p_sys
->
p_jack_ports
=
malloc
(
p_sys
->
i_channels
*
sizeof
(
jack_port_t
*
)
);
p_sys
->
p_jack_ports
=
malloc
(
p_sys
->
i_channels
*
sizeof
(
jack_port_t
*
)
);
if
(
p_sys
->
p_jack_ports
==
NULL
)
if
(
p_sys
->
p_jack_ports
==
NULL
)
{
{
msg_Err
(
p_aout
,
"out of memory"
);
msg_Err
(
p_aout
,
"out of memory"
);
...
@@ -139,13 +145,22 @@ static int Open( vlc_object_t *p_this )
...
@@ -139,13 +145,22 @@ static int Open( vlc_object_t *p_this )
goto
error_out
;
goto
error_out
;
}
}
p_sys
->
p_jack_buffers
=
malloc
(
p_sys
->
i_channels
*
sizeof
(
jack_sample_t
*
)
);
if
(
p_sys
->
p_jack_buffers
==
NULL
)
{
msg_Err
(
p_aout
,
"out of memory"
);
status
=
VLC_ENOMEM
;
goto
error_out
;
}
/* Create the output ports */
/* Create the output ports */
for
(
i
=
0
;
i
<
p_sys
->
i_channels
;
i
++
)
for
(
i
=
0
;
i
<
p_sys
->
i_channels
;
i
++
)
{
{
char
p_name
[
32
]
;
snprintf
(
psz_name
,
sizeof
(
psz_name
),
"out_%d"
,
i
+
1
)
;
snprintf
(
p_name
,
32
,
"out_%d"
,
i
+
1
)
;
psz_name
[
sizeof
(
psz_name
)
-
1
]
=
'\0'
;
p_sys
->
p_jack_ports
[
i
]
=
jack_port_register
(
p_sys
->
p_jack_client
,
p_sys
->
p_jack_ports
[
i
]
=
jack_port_register
(
p_sys
->
p_jack_client
,
p_name
,
JACK_DEFAULT_AUDIO_TYPE
,
JackPortIsOutput
,
0
);
p
sz
_name
,
JACK_DEFAULT_AUDIO_TYPE
,
JackPortIsOutput
,
0
);
if
(
p_sys
->
p_jack_ports
[
i
]
==
NULL
)
if
(
p_sys
->
p_jack_ports
[
i
]
==
NULL
)
{
{
...
@@ -156,10 +171,10 @@ static int Open( vlc_object_t *p_this )
...
@@ -156,10 +171,10 @@ static int Open( vlc_object_t *p_this )
}
}
/* Tell the JACK server we are ready */
/* Tell the JACK server we are ready */
if
(
jack_activate
(
p_sys
->
p_jack_client
)
)
i_error
=
jack_activate
(
p_sys
->
p_jack_client
);
if
(
i_error
)
{
{
msg_Err
(
p_aout
,
"failed to activate JACK client"
);
msg_Err
(
p_aout
,
"failed to activate JACK client (error %d)"
,
i_error
);
jack_client_close
(
p_sys
->
p_jack_client
);
status
=
VLC_EGENERIC
;
status
=
VLC_EGENERIC
;
goto
error_out
;
goto
error_out
;
}
}
...
@@ -167,62 +182,29 @@ static int Open( vlc_object_t *p_this )
...
@@ -167,62 +182,29 @@ static int Open( vlc_object_t *p_this )
/* Auto connect ports if we were asked to */
/* Auto connect ports if we were asked to */
if
(
config_GetInt
(
p_aout
,
AUTO_CONNECT_OPTION
)
)
if
(
config_GetInt
(
p_aout
,
AUTO_CONNECT_OPTION
)
)
{
{
unsigned
int
i_in_ports
,
i_prefix_len
;
unsigned
int
i_in_ports
;
c
onst
char
**
pp_in_ports
;
c
har
*
psz_regex
=
config_GetPsz
(
p_aout
,
CONNECT_REGEX_OPTION
)
;
const
char
**
pp_in_ports
=
jack_get_ports
(
p_sys
->
p_jack_client
,
pp_in_ports
=
jack_get_ports
(
p_sys
->
p_jack_client
,
NULL
,
NULL
,
psz_regex
,
NULL
,
JackPortIsInput
);
JackPortIsInput
);
psz_prefix
=
config_GetPsz
(
p_aout
,
CONNECT_MATCH_OPTION
);
/* Count the number of returned ports */
i_prefix_len
=
psz_prefix
?
strlen
(
psz_prefix
)
:
0
;
/* Find JACK input ports to connect to */
i
=
0
;
i_in_ports
=
0
;
while
(
pp_in_ports
&&
pp_in_ports
[
i
]
)
{
if
(
!
psz_prefix
||
!
strncmp
(
psz_prefix
,
pp_in_ports
[
i
],
i_prefix_len
)
)
{
i_in_ports
++
;
/* Found one */
}
i
++
;
}
/* Connect the output ports to input ports */
if
(
i_in_ports
>
0
)
{
pp_match_ports
=
malloc
(
i_in_ports
*
sizeof
(
char
*
)
);
if
(
pp_match_ports
==
NULL
)
{
msg_Err
(
p_aout
,
"out of memory"
);
status
=
VLC_ENOMEM
;
goto
error_out
;
}
/* populate list of matching ports */
i
=
0
;
i_in_ports
=
0
;
i_in_ports
=
0
;
while
(
pp_in_ports
[
i
]
)
while
(
pp_in_ports
&&
pp_in_ports
[
i_in_ports
]
)
{
{
if
(
!
psz_prefix
||
i_in_ports
++
;
!
strncmp
(
psz_prefix
,
pp_in_ports
[
i
],
i_prefix_len
)
)
{
pp_match_ports
[
i_in_ports
]
=
pp_in_ports
[
i
];
i_in_ports
++
;
/* Found one */
}
i
++
;
}
}
/* Tie the output ports to JACK input ports */
/* Tie the output ports to JACK input ports */
for
(
i
=
0
;
i
<
p_sys
->
i_channels
;
i
++
)
for
(
i
=
0
;
i_in_ports
>
0
&&
i
<
p_sys
->
i_channels
;
i
++
)
{
{
const
char
*
psz_in
=
pp_match
_ports
[
i
%
i_in_ports
];
const
char
*
psz_in
=
pp_in
_ports
[
i
%
i_in_ports
];
const
char
*
psz_out
=
jack_port_name
(
p_sys
->
p_jack_ports
[
i
]
);
const
char
*
psz_out
=
jack_port_name
(
p_sys
->
p_jack_ports
[
i
]
);
if
(
jack_connect
(
p_sys
->
p_jack_client
,
psz_out
,
psz_in
)
)
i_error
=
jack_connect
(
p_sys
->
p_jack_client
,
psz_out
,
psz_in
);
if
(
i_error
)
{
{
msg_Err
(
p_aout
,
"failed to connect port %s to port %s
"
,
msg_Err
(
p_aout
,
"failed to connect port %s to port %s (error %d)
"
,
psz_out
,
psz_in
);
psz_out
,
psz_in
,
i_error
);
}
}
else
else
{
{
...
@@ -230,6 +212,9 @@ static int Open( vlc_object_t *p_this )
...
@@ -230,6 +212,9 @@ static int Open( vlc_object_t *p_this )
psz_out
,
psz_in
);
psz_out
,
psz_in
);
}
}
}
}
if
(
pp_in_ports
)
{
free
(
pp_in_ports
);
}
}
}
}
...
@@ -238,19 +223,22 @@ static int Open( vlc_object_t *p_this )
...
@@ -238,19 +223,22 @@ static int Open( vlc_object_t *p_this )
p_aout
->
output
.
i_nb_samples
,
p_aout
->
output
.
output
.
i_rate
);
p_aout
->
output
.
i_nb_samples
,
p_aout
->
output
.
output
.
i_rate
);
error_out:
error_out:
/* Clean up */
/* Clean up, if an error occurred */
if
(
psz_prefix
)
free
(
psz_prefix
);
if
(
pp_match_ports
)
free
(
pp_match_ports
);
if
(
status
!=
VLC_SUCCESS
&&
p_sys
!=
NULL
)
if
(
status
!=
VLC_SUCCESS
&&
p_sys
!=
NULL
)
{
{
if
(
p_sys
->
p_jack_ports
)
free
(
p_sys
->
p_jack_ports
);
if
(
p_sys
->
p_jack_client
)
if
(
p_sys
->
p_jack_client
)
{
jack_deactivate
(
p_sys
->
p_jack_client
);
jack_client_close
(
p_sys
->
p_jack_client
);
jack_client_close
(
p_sys
->
p_jack_client
);
}
if
(
p_sys
->
p_jack_ports
)
{
free
(
p_sys
->
p_jack_ports
);
}
if
(
p_sys
->
p_jack_buffers
)
{
free
(
p_sys
->
p_jack_buffers
);
}
free
(
p_sys
);
free
(
p_sys
);
}
}
return
status
;
return
status
;
...
@@ -262,36 +250,44 @@ error_out:
...
@@ -262,36 +250,44 @@ error_out:
*****************************************************************************/
*****************************************************************************/
int
Process
(
jack_nframes_t
i_frames
,
void
*
p_arg
)
int
Process
(
jack_nframes_t
i_frames
,
void
*
p_arg
)
{
{
aout_buffer_t
*
p_buffer
;
jack_default_audio_sample_t
*
p_jack_buffer
;
unsigned
int
i
,
j
,
i_nb_samples
=
0
;
unsigned
int
i
,
j
,
i_nb_samples
=
0
;
aout_instance_t
*
p_aout
=
(
aout_instance_t
*
)
p_arg
;
aout_instance_t
*
p_aout
=
(
aout_instance_t
*
)
p_arg
;
unsigned
int
i_nb_channels
=
p_aout
->
output
.
p_sys
->
i_channels
;
struct
aout_sys_t
*
p_sys
=
p_aout
->
output
.
p_sys
;
jack_sample_t
*
p_src
=
NULL
;
/* Get the next audio data buffer */
/* Get the next audio data buffer */
p_buffer
=
aout_FifoPop
(
p_aout
,
&
p_aout
->
output
.
fifo
);
aout_buffer_t
*
p_buffer
=
aout_FifoPop
(
p_aout
,
&
p_aout
->
output
.
fifo
);
if
(
p_buffer
!=
NULL
)
if
(
p_buffer
)
{
{
p_src
=
(
jack_sample_t
*
)
p_buffer
->
p_buffer
;
i_nb_samples
=
p_buffer
->
i_nb_samples
;
i_nb_samples
=
p_buffer
->
i_nb_samples
;
}
}
for
(
i
=
0
;
i
<
i_nb_channels
;
i
++
)
/* Get the JACK buffers to write to */
for
(
i
=
0
;
i
<
p_sys
->
i_channels
;
i
++
)
{
{
/* Get an output buffer from JACK */
p_sys
->
p_jack_buffers
[
i
]
=
jack_port_get_buffer
(
p_sys
->
p_jack_ports
[
i
],
p_jack_buffer
=
jack_port_get_buffer
(
i_frames
);
p_aout
->
output
.
p_sys
->
p_jack_ports
[
i
],
i_frames
);
}
/* Fill the buffer with
audio data */
/* Copy in the
audio data */
for
(
j
=
0
;
j
<
i_nb_samples
;
j
++
)
for
(
j
=
0
;
j
<
i_nb_samples
;
j
++
)
{
{
p_jack_buffer
[
j
]
=
((
float
*
)
p_buffer
->
p_buffer
)[
i_nb_channels
*
j
+
i
];
for
(
i
=
0
;
i
<
p_sys
->
i_channels
;
i
++
)
{
jack_sample_t
*
p_dst
=
p_sys
->
p_jack_buffers
[
i
];
p_dst
[
j
]
=
*
p_src
;
p_src
++
;
}
}
}
/* Fill any remaining buffer with silence */
if
(
i_nb_samples
<
i_frames
)
if
(
i_nb_samples
<
i_frames
)
{
{
memset
(
p_jack_buffer
+
i_nb_samples
,
0
,
for
(
i
=
0
;
i
<
p_sys
->
i_channels
;
i
++
)
sizeof
(
jack_default_audio_sample_t
)
*
{
(
i_frames
-
i_nb_samples
)
);
memset
(
p_sys
->
p_jack_buffers
[
i
]
+
i_nb_samples
,
0
,
sizeof
(
jack_sample_t
)
*
(
i_frames
-
i_nb_samples
)
);
}
}
}
}
...
@@ -299,7 +295,6 @@ int Process( jack_nframes_t i_frames, void *p_arg )
...
@@ -299,7 +295,6 @@ int Process( jack_nframes_t i_frames, void *p_arg )
{
{
aout_BufferFree
(
p_buffer
);
aout_BufferFree
(
p_buffer
);
}
}
return
0
;
return
0
;
}
}
...
@@ -317,11 +312,22 @@ static void Play( aout_instance_t *p_aout )
...
@@ -317,11 +312,22 @@ static void Play( aout_instance_t *p_aout )
*****************************************************************************/
*****************************************************************************/
static
void
Close
(
vlc_object_t
*
p_this
)
static
void
Close
(
vlc_object_t
*
p_this
)
{
{
int
i_error
;
aout_instance_t
*
p_aout
=
(
aout_instance_t
*
)
p_this
;
aout_instance_t
*
p_aout
=
(
aout_instance_t
*
)
p_this
;
struct
aout_sys_t
*
p_sys
=
p_aout
->
output
.
p_sys
;
struct
aout_sys_t
*
p_sys
=
p_aout
->
output
.
p_sys
;
i_error
=
jack_deactivate
(
p_sys
->
p_jack_client
);
if
(
i_error
)
{
msg_Err
(
p_aout
,
"jack_deactivate failed (error %d)"
,
i_error
);
}
i_error
=
jack_client_close
(
p_sys
->
p_jack_client
);
if
(
i_error
)
{
msg_Err
(
p_aout
,
"jack_client_close failed (error %d)"
,
i_error
);
}
free
(
p_sys
->
p_jack_ports
);
free
(
p_sys
->
p_jack_ports
);
jack_client_close
(
p_sys
->
p_jack_client
);
free
(
p_sys
->
p_jack_buffers
);
free
(
p_sys
);
free
(
p_sys
);
}
}
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