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
b5615ec0
Commit
b5615ec0
authored
Oct 27, 2008
by
Antoine Cellerier
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Split Alsa access module from v4l2.
parent
50ddca67
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
608 additions
and
0 deletions
+608
-0
configure.ac
configure.ac
+2
-0
modules/access/Modules.am
modules/access/Modules.am
+1
-0
modules/access/alsa.c
modules/access/alsa.c
+605
-0
No files found.
configure.ac
View file @
b5615ec0
...
...
@@ -4642,6 +4642,8 @@ then
AC_DEFINE(HAVE_ALSA_NEW_API, 1, Define if ALSA is at least rc4))
VLC_ADD_PLUGIN([alsa])
VLC_ADD_LIBS([alsa],[-lasound -lm -ldl])
VLC_ADD_PLUGIN([access_alsa])
VLC_ADD_LIBS([access_alsa],[-lasound -lm -ldl])
else
if test "${enable_alsa}" = "yes"; then
AC_MSG_ERROR([Could not find ALSA development headers])
...
...
modules/access/Modules.am
View file @
b5615ec0
...
...
@@ -37,6 +37,7 @@ SOURCES_cdda = \
vcd/cdrom_internals.h \
$(NULL)
SOURCES_access_jack = jack.c
SOURCES_access_alsa = alsa.c
libvlc_LTLIBRARIES += \
libaccess_file_plugin.la \
...
...
modules/access/alsa.c
0 → 100644
View file @
b5615ec0
/*****************************************************************************
* alsa.c : Alsa input module for vlc
*****************************************************************************
* Copyright (C) 2002-2009 the VideoLAN team
* $Id$
*
* Authors: Benjamin Pracht <bigben at videolan dot org>
* Richard Hosking <richard at hovis dot net>
* Antoine Cellerier <dionoea at videolan d.t org>
* Dennis Lou <dlou99 at yahoo dot com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 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 General Public License for more details.
*
* You should have received a copy of the GNU 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.
*****************************************************************************/
/*
* ALSA support based on parts of
* http://www.equalarea.com/paul/alsa-audio.html
* and hints taken from alsa-utils (aplay/arecord)
* http://www.alsa-project.org
*/
/*****************************************************************************
* Preamble
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_access.h>
#include <vlc_demux.h>
#include <vlc_input.h>
#include <vlc_vout.h>
#include <ctype.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/soundcard.h>
#define ALSA_PCM_NEW_HW_PARAMS_API
#define ALSA_PCM_NEW_SW_PARAMS_API
#include <alsa/asoundlib.h>
#include <poll.h>
/*****************************************************************************
* Module descriptior
*****************************************************************************/
static
int
DemuxOpen
(
vlc_object_t
*
);
static
void
DemuxClose
(
vlc_object_t
*
);
#define STEREO_TEXT N_( "Stereo" )
#define STEREO_LONGTEXT N_( \
"Capture the audio stream in stereo." )
#define SAMPLERATE_TEXT N_( "Samplerate" )
#define SAMPLERATE_LONGTEXT N_( \
"Samplerate of the captured audio stream, in Hz (eg: 11025, 22050, 44100, 48000)" )
#define CACHING_TEXT N_("Caching value in ms")
#define CACHING_LONGTEXT N_( \
"Caching value for Alsa captures. This " \
"value should be set in milliseconds." )
#define ALSA_DEFAULT "hw"
#define CFG_PREFIX "alsa-"
vlc_module_begin
();
set_shortname
(
N_
(
"Alsa"
)
);
set_description
(
N_
(
"Alsa audio capture input"
)
);
set_category
(
CAT_INPUT
);
set_subcategory
(
SUBCAT_INPUT_ACCESS
);
add_shortcut
(
"alsa"
);
set_capability
(
"access_demux"
,
10
);
set_callbacks
(
DemuxOpen
,
DemuxClose
);
add_bool
(
CFG_PREFIX
"stereo"
,
true
,
NULL
,
STEREO_TEXT
,
STEREO_LONGTEXT
,
true
);
add_integer
(
CFG_PREFIX
"samplerate"
,
48000
,
NULL
,
SAMPLERATE_TEXT
,
SAMPLERATE_LONGTEXT
,
true
);
add_integer
(
CFG_PREFIX
"caching"
,
DEFAULT_PTS_DELAY
/
1000
,
NULL
,
CACHING_TEXT
,
CACHING_LONGTEXT
,
true
);
vlc_module_end
();
/*****************************************************************************
* Access: local prototypes
*****************************************************************************/
static
int
DemuxControl
(
demux_t
*
,
int
,
va_list
);
static
int
Demux
(
demux_t
*
);
static
block_t
*
GrabAudio
(
demux_t
*
p_demux
);
static
int
OpenAudioDev
(
vlc_object_t
*
,
demux_sys_t
*
);
static
bool
ProbeAudioDevAlsa
(
vlc_object_t
*
,
const
char
*
psz_device
);
struct
demux_sys_t
{
const
char
*
psz_device
;
/* Alsa device from MRL */
int
i_fd_audio
;
/* Audio */
int
i_pts
;
unsigned
int
i_sample_rate
;
bool
b_stereo
;
size_t
i_audio_max_frame_size
;
block_t
*
p_block_audio
;
es_out_id_t
*
p_es_audio
;
int
i_audio_method
;
/* ALSA Audio */
snd_pcm_t
*
p_alsa_pcm
;
size_t
i_alsa_frame_size
;
int
i_alsa_chunk_size
;
};
static
int
FindMainDevice
(
vlc_object_t
*
p_this
,
demux_sys_t
*
p_sys
)
{
msg_Dbg
(
p_this
,
"opening device '%s'"
,
p_sys
->
psz_device
);
if
(
ProbeAudioDevAlsa
(
p_this
,
p_sys
->
psz_device
)
)
{
msg_Dbg
(
p_this
,
"'%s' is an audio device"
,
p_sys
->
psz_device
);
p_sys
->
i_fd_audio
=
OpenAudioDev
(
p_this
,
p_sys
);
}
if
(
p_sys
->
i_fd_audio
<
0
)
return
VLC_EGENERIC
;
return
VLC_SUCCESS
;
}
/*****************************************************************************
* DemuxOpen: opens alsa device, access_demux callback
*****************************************************************************
*
* url: <alsa device>::::
*
*****************************************************************************/
static
int
DemuxOpen
(
vlc_object_t
*
p_this
)
{
demux_t
*
p_demux
=
(
demux_t
*
)
p_this
;
demux_sys_t
*
p_sys
;
/* Only when selected */
if
(
*
p_demux
->
psz_access
==
'\0'
)
return
VLC_EGENERIC
;
/* Set up p_demux */
p_demux
->
pf_control
=
DemuxControl
;
p_demux
->
pf_demux
=
Demux
;
p_demux
->
info
.
i_update
=
0
;
p_demux
->
info
.
i_title
=
0
;
p_demux
->
info
.
i_seekpoint
=
0
;
p_demux
->
p_sys
=
p_sys
=
calloc
(
1
,
sizeof
(
demux_sys_t
)
);
if
(
p_sys
==
NULL
)
return
VLC_ENOMEM
;
p_sys
->
i_sample_rate
=
var_CreateGetInteger
(
p_demux
,
CFG_PREFIX
"samplerate"
);
p_sys
->
b_stereo
=
var_CreateGetBool
(
p_demux
,
CFG_PREFIX
"stereo"
);
p_sys
->
i_pts
=
var_CreateGetInteger
(
p_demux
,
CFG_PREFIX
"caching"
);
p_sys
->
psz_device
=
NULL
;
p_sys
->
i_fd_audio
=
-
1
;
p_sys
->
p_es_audio
=
NULL
;
p_sys
->
p_block_audio
=
NULL
;
if
(
p_demux
->
psz_path
&&
*
p_demux
->
psz_path
)
p_sys
->
psz_device
=
p_demux
->
psz_path
;
else
p_sys
->
psz_device
=
ALSA_DEFAULT
;
msg_Err
(
p_this
,
"Device is %s"
,
p_sys
->
psz_device
);
if
(
FindMainDevice
(
p_this
,
p_sys
)
!=
VLC_SUCCESS
)
{
DemuxClose
(
p_this
);
return
VLC_EGENERIC
;
}
return
VLC_SUCCESS
;
}
/*****************************************************************************
* Close: close device, free resources
*****************************************************************************/
static
void
DemuxClose
(
vlc_object_t
*
p_this
)
{
demux_t
*
p_demux
=
(
demux_t
*
)
p_this
;
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
if
(
p_sys
->
p_alsa_pcm
)
{
snd_pcm_close
(
p_sys
->
p_alsa_pcm
);
p_sys
->
i_fd_audio
=
-
1
;
}
if
(
p_sys
->
i_fd_audio
>=
0
)
close
(
p_sys
->
i_fd_audio
);
if
(
p_sys
->
p_block_audio
)
block_Release
(
p_sys
->
p_block_audio
);
free
(
p_sys
);
}
/*****************************************************************************
* DemuxControl:
*****************************************************************************/
static
int
DemuxControl
(
demux_t
*
p_demux
,
int
i_query
,
va_list
args
)
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
bool
*
pb
;
int64_t
*
pi64
;
switch
(
i_query
)
{
/* Special for access_demux */
case
DEMUX_CAN_PAUSE
:
case
DEMUX_CAN_SEEK
:
case
DEMUX_SET_PAUSE_STATE
:
case
DEMUX_CAN_CONTROL_PACE
:
pb
=
(
bool
*
)
va_arg
(
args
,
bool
*
);
*
pb
=
false
;
return
VLC_SUCCESS
;
case
DEMUX_GET_PTS_DELAY
:
pi64
=
(
int64_t
*
)
va_arg
(
args
,
int64_t
*
);
*
pi64
=
(
int64_t
)
p_sys
->
i_pts
*
1000
;
return
VLC_SUCCESS
;
case
DEMUX_GET_TIME
:
pi64
=
(
int64_t
*
)
va_arg
(
args
,
int64_t
*
);
*
pi64
=
mdate
();
return
VLC_SUCCESS
;
/* TODO implement others */
default:
return
VLC_EGENERIC
;
}
return
VLC_EGENERIC
;
}
/*****************************************************************************
* Demux: Processes the audio frame
*****************************************************************************/
static
int
Demux
(
demux_t
*
p_demux
)
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
struct
pollfd
fd
;
fd
.
fd
=
p_sys
->
i_fd_audio
;
fd
.
events
=
POLLIN
|
POLLPRI
;
fd
.
revents
=
0
;
/* Wait for data */
if
(
poll
(
&
fd
,
1
,
500
)
)
/* Timeout after 0.5 seconds since I don't know if pf_demux can be blocking. */
{
if
(
fd
.
revents
&
(
POLLIN
|
POLLPRI
)
)
{
block_t
*
p_block
=
GrabAudio
(
p_demux
);
if
(
p_block
)
{
es_out_Control
(
p_demux
->
out
,
ES_OUT_SET_PCR
,
p_block
->
i_pts
);
es_out_Send
(
p_demux
->
out
,
p_sys
->
p_es_audio
,
p_block
);
}
}
}
return
1
;
}
/*****************************************************************************
* GrabAudio: Grab an audio frame
*****************************************************************************/
static
block_t
*
GrabAudio
(
demux_t
*
p_demux
)
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
int
i_read
=
0
,
i_correct
;
block_t
*
p_block
;
printf
(
"%s %d
\n
"
,
__func__
,
__LINE__
);
if
(
p_sys
->
p_block_audio
)
p_block
=
p_sys
->
p_block_audio
;
else
p_block
=
block_New
(
p_demux
,
p_sys
->
i_audio_max_frame_size
);
if
(
!
p_block
)
{
msg_Warn
(
p_demux
,
"cannot get block"
);
return
0
;
}
p_sys
->
p_block_audio
=
p_block
;
/* ALSA */
i_read
=
snd_pcm_readi
(
p_sys
->
p_alsa_pcm
,
p_block
->
p_buffer
,
p_sys
->
i_alsa_chunk_size
);
if
(
i_read
<=
0
)
{
int
i_resume
;
switch
(
i_read
)
{
case
-
EAGAIN
:
break
;
case
-
EPIPE
:
/* xrun */
snd_pcm_prepare
(
p_sys
->
p_alsa_pcm
);
break
;
case
-
ESTRPIPE
:
/* suspend */
i_resume
=
snd_pcm_resume
(
p_sys
->
p_alsa_pcm
);
if
(
i_resume
<
0
&&
i_resume
!=
-
EAGAIN
)
snd_pcm_prepare
(
p_sys
->
p_alsa_pcm
);
break
;
default:
msg_Err
(
p_demux
,
"Failed to read alsa frame (%s)"
,
snd_strerror
(
i_read
)
);
return
0
;
}
}
else
{
/* convert from frames to bytes */
i_read
*=
p_sys
->
i_alsa_frame_size
;
}
if
(
i_read
<=
0
)
return
0
;
p_block
->
i_buffer
=
i_read
;
p_sys
->
p_block_audio
=
0
;
/* Correct the date because of kernel buffering */
i_correct
=
i_read
;
/* ALSA */
int
i_err
;
snd_pcm_sframes_t
delay
=
0
;
if
(
(
i_err
=
snd_pcm_delay
(
p_sys
->
p_alsa_pcm
,
&
delay
)
)
>=
0
)
{
size_t
i_correction_delta
=
delay
*
p_sys
->
i_alsa_frame_size
;
/* Test for overrun */
if
(
i_correction_delta
>
p_sys
->
i_audio_max_frame_size
)
{
msg_Warn
(
p_demux
,
"ALSA read overrun (%zu > %zu)"
,
i_correction_delta
,
p_sys
->
i_audio_max_frame_size
);
i_correction_delta
=
p_sys
->
i_audio_max_frame_size
;
snd_pcm_prepare
(
p_sys
->
p_alsa_pcm
);
}
i_correct
+=
i_correction_delta
;
}
else
{
/* delay failed so reset */
msg_Warn
(
p_demux
,
"ALSA snd_pcm_delay failed (%s)"
,
snd_strerror
(
i_err
)
);
snd_pcm_prepare
(
p_sys
->
p_alsa_pcm
);
}
/* Timestamp */
p_block
->
i_pts
=
p_block
->
i_dts
=
mdate
()
-
INT64_C
(
1000000
)
*
(
mtime_t
)
i_correct
/
2
/
(
p_sys
->
b_stereo
?
2
:
1
)
/
p_sys
->
i_sample_rate
;
return
p_block
;
}
/*****************************************************************************
* OpenAudioDev: open and set up the audio device and probe for capabilities
*****************************************************************************/
static
int
OpenAudioDevAlsa
(
vlc_object_t
*
p_this
,
demux_sys_t
*
p_sys
)
{
const
char
*
psz_device
=
p_sys
->
psz_device
;
p_sys
->
p_alsa_pcm
=
NULL
;
snd_pcm_hw_params_t
*
p_hw_params
=
NULL
;
snd_pcm_uframes_t
buffer_size
;
snd_pcm_uframes_t
chunk_size
;
/* ALSA */
int
i_err
;
if
(
(
i_err
=
snd_pcm_open
(
&
p_sys
->
p_alsa_pcm
,
psz_device
,
SND_PCM_STREAM_CAPTURE
,
SND_PCM_NONBLOCK
)
)
<
0
)
{
msg_Err
(
p_this
,
"Cannot open ALSA audio device %s (%s)"
,
psz_device
,
snd_strerror
(
i_err
)
);
goto
adev_fail
;
}
if
(
(
i_err
=
snd_pcm_nonblock
(
p_sys
->
p_alsa_pcm
,
1
)
)
<
0
)
{
msg_Err
(
p_this
,
"Cannot set ALSA nonblock (%s)"
,
snd_strerror
(
i_err
)
);
goto
adev_fail
;
}
/* Begin setting hardware parameters */
if
(
(
i_err
=
snd_pcm_hw_params_malloc
(
&
p_hw_params
)
)
<
0
)
{
msg_Err
(
p_this
,
"ALSA: cannot allocate hardware parameter structure (%s)"
,
snd_strerror
(
i_err
)
);
goto
adev_fail
;
}
if
(
(
i_err
=
snd_pcm_hw_params_any
(
p_sys
->
p_alsa_pcm
,
p_hw_params
)
)
<
0
)
{
msg_Err
(
p_this
,
"ALSA: cannot initialize hardware parameter structure (%s)"
,
snd_strerror
(
i_err
)
);
goto
adev_fail
;
}
/* Set Interleaved access */
if
(
(
i_err
=
snd_pcm_hw_params_set_access
(
p_sys
->
p_alsa_pcm
,
p_hw_params
,
SND_PCM_ACCESS_RW_INTERLEAVED
)
)
<
0
)
{
msg_Err
(
p_this
,
"ALSA: cannot set access type (%s)"
,
snd_strerror
(
i_err
)
);
goto
adev_fail
;
}
/* Set 16 bit little endian */
if
(
(
i_err
=
snd_pcm_hw_params_set_format
(
p_sys
->
p_alsa_pcm
,
p_hw_params
,
SND_PCM_FORMAT_S16_LE
)
)
<
0
)
{
msg_Err
(
p_this
,
"ALSA: cannot set sample format (%s)"
,
snd_strerror
(
i_err
)
);
goto
adev_fail
;
}
/* Set sample rate */
#ifdef HAVE_ALSA_NEW_API
i_err
=
snd_pcm_hw_params_set_rate_near
(
p_sys
->
p_alsa_pcm
,
p_hw_params
,
&
p_sys
->
i_sample_rate
,
NULL
);
#else
i_err
=
snd_pcm_hw_params_set_rate_near
(
p_sys
->
p_alsa_pcm
,
p_hw_params
,
p_sys
->
i_sample_rate
,
NULL
);
#endif
if
(
i_err
<
0
)
{
msg_Err
(
p_this
,
"ALSA: cannot set sample rate (%s)"
,
snd_strerror
(
i_err
)
);
goto
adev_fail
;
}
/* Set channels */
unsigned
int
channels
=
p_sys
->
b_stereo
?
2
:
1
;
if
(
(
i_err
=
snd_pcm_hw_params_set_channels
(
p_sys
->
p_alsa_pcm
,
p_hw_params
,
channels
)
)
<
0
)
{
channels
=
(
channels
==
1
)
?
2
:
1
;
msg_Warn
(
p_this
,
"ALSA: cannot set channel count (%s). "
"Trying with channels=%d"
,
snd_strerror
(
i_err
),
channels
);
if
(
(
i_err
=
snd_pcm_hw_params_set_channels
(
p_sys
->
p_alsa_pcm
,
p_hw_params
,
channels
)
)
<
0
)
{
msg_Err
(
p_this
,
"ALSA: cannot set channel count (%s)"
,
snd_strerror
(
i_err
)
);
goto
adev_fail
;
}
p_sys
->
b_stereo
=
(
channels
==
2
);
}
/* Set metrics for buffer calculations later */
unsigned
int
buffer_time
;
if
(
(
i_err
=
snd_pcm_hw_params_get_buffer_time_max
(
p_hw_params
,
&
buffer_time
,
0
)
)
<
0
)
{
msg_Err
(
p_this
,
"ALSA: cannot get buffer time max (%s)"
,
snd_strerror
(
i_err
)
);
goto
adev_fail
;
}
if
(
buffer_time
>
500000
)
buffer_time
=
500000
;
/* Set period time */
unsigned
int
period_time
=
buffer_time
/
4
;
#ifdef HAVE_ALSA_NEW_API
i_err
=
snd_pcm_hw_params_set_period_time_near
(
p_sys
->
p_alsa_pcm
,
p_hw_params
,
&
period_time
,
0
);
#else
i_err
=
snd_pcm_hw_params_set_period_time_near
(
p_sys
->
p_alsa_pcm
,
p_hw_params
,
period_time
,
0
);
#endif
if
(
i_err
<
0
)
{
msg_Err
(
p_this
,
"ALSA: cannot set period time (%s)"
,
snd_strerror
(
i_err
)
);
goto
adev_fail
;
}
/* Set buffer time */
#ifdef HAVE_ALSA_NEW_API
i_err
=
snd_pcm_hw_params_set_buffer_time_near
(
p_sys
->
p_alsa_pcm
,
p_hw_params
,
&
buffer_time
,
0
);
#else
i_err
=
snd_pcm_hw_params_set_buffer_time_near
(
p_sys
->
p_alsa_pcm
,
p_hw_params
,
buffer_time
,
0
);
#endif
if
(
i_err
<
0
)
{
msg_Err
(
p_this
,
"ALSA: cannot set buffer time (%s)"
,
snd_strerror
(
i_err
)
);
goto
adev_fail
;
}
/* Apply new hardware parameters */
if
(
(
i_err
=
snd_pcm_hw_params
(
p_sys
->
p_alsa_pcm
,
p_hw_params
)
)
<
0
)
{
msg_Err
(
p_this
,
"ALSA: cannot set hw parameters (%s)"
,
snd_strerror
(
i_err
)
);
goto
adev_fail
;
}
/* Get various buffer metrics */
snd_pcm_hw_params_get_period_size
(
p_hw_params
,
&
chunk_size
,
0
);
snd_pcm_hw_params_get_buffer_size
(
p_hw_params
,
&
buffer_size
);
if
(
chunk_size
==
buffer_size
)
{
msg_Err
(
p_this
,
"ALSA: period cannot equal buffer size (%lu == %lu)"
,
chunk_size
,
buffer_size
);
goto
adev_fail
;
}
int
bits_per_sample
=
snd_pcm_format_physical_width
(
SND_PCM_FORMAT_S16_LE
);
int
bits_per_frame
=
bits_per_sample
*
channels
;
p_sys
->
i_alsa_chunk_size
=
chunk_size
;
p_sys
->
i_alsa_frame_size
=
bits_per_frame
/
8
;
p_sys
->
i_audio_max_frame_size
=
chunk_size
*
bits_per_frame
/
8
;
snd_pcm_hw_params_free
(
p_hw_params
);
p_hw_params
=
NULL
;
/* Prep device */
if
(
(
i_err
=
snd_pcm_prepare
(
p_sys
->
p_alsa_pcm
)
)
<
0
)
{
msg_Err
(
p_this
,
"ALSA: cannot prepare audio interface for use (%s)"
,
snd_strerror
(
i_err
)
);
goto
adev_fail
;
}
if
(
!
p_sys
->
psz_device
)
p_sys
->
psz_device
=
strdup
(
ALSA_DEFAULT
);
/* Return a fake handle so other tests work */
return
1
;
adev_fail:
if
(
p_hw_params
)
snd_pcm_hw_params_free
(
p_hw_params
);
if
(
p_sys
->
p_alsa_pcm
)
snd_pcm_close
(
p_sys
->
p_alsa_pcm
);
return
-
1
;
}
static
int
OpenAudioDev
(
vlc_object_t
*
p_this
,
demux_sys_t
*
p_sys
)
{
int
i_fd
=
OpenAudioDevAlsa
(
p_this
,
p_sys
);
if
(
i_fd
<
0
)
return
i_fd
;
msg_Dbg
(
p_this
,
"opened adev=`%s' %s %dHz"
,
p_sys
->
psz_device
,
p_sys
->
b_stereo
?
"stereo"
:
"mono"
,
p_sys
->
i_sample_rate
);
es_format_t
fmt
;
es_format_Init
(
&
fmt
,
AUDIO_ES
,
VLC_FOURCC
(
'a'
,
'r'
,
'a'
,
'w'
)
);
fmt
.
audio
.
i_channels
=
p_sys
->
b_stereo
?
2
:
1
;
fmt
.
audio
.
i_rate
=
p_sys
->
i_sample_rate
;
fmt
.
audio
.
i_bitspersample
=
16
;
fmt
.
audio
.
i_blockalign
=
fmt
.
audio
.
i_channels
*
fmt
.
audio
.
i_bitspersample
/
8
;
fmt
.
i_bitrate
=
fmt
.
audio
.
i_channels
*
fmt
.
audio
.
i_rate
*
fmt
.
audio
.
i_bitspersample
;
msg_Dbg
(
p_this
,
"new audio es %d channels %dHz"
,
fmt
.
audio
.
i_channels
,
fmt
.
audio
.
i_rate
);
demux_t
*
p_demux
=
(
demux_t
*
)
p_this
;
p_sys
->
p_es_audio
=
es_out_Add
(
p_demux
->
out
,
&
fmt
);
return
i_fd
;
}
/*****************************************************************************
* ProbeAudioDevAlsa: probe audio for capabilities
*****************************************************************************/
static
bool
ProbeAudioDevAlsa
(
vlc_object_t
*
p_this
,
const
char
*
psz_device
)
{
int
i_err
;
snd_pcm_t
*
p_alsa_pcm
;
if
(
(
i_err
=
snd_pcm_open
(
&
p_alsa_pcm
,
psz_device
,
SND_PCM_STREAM_CAPTURE
,
SND_PCM_NONBLOCK
)
)
<
0
)
{
msg_Err
(
p_this
,
"cannot open device %s for ALSA audio (%s)"
,
psz_device
,
snd_strerror
(
i_err
)
);
return
false
;
}
snd_pcm_close
(
p_alsa_pcm
);
return
true
;
}
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