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
e73d940f
Commit
e73d940f
authored
Oct 12, 2010
by
Jean-Paul Saman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
audio_output: Modules.am: add amem audio memory output module
Build audio memory output module.
parent
f88ff9a9
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
648 additions
and
1 deletion
+648
-1
modules/audio_output/Modules.am
modules/audio_output/Modules.am
+3
-1
modules/audio_output/amem.c
modules/audio_output/amem.c
+645
-0
No files found.
modules/audio_output/Modules.am
View file @
e73d940f
...
...
@@ -9,8 +9,10 @@ SOURCES_auhal = auhal.c
SOURCES_jack = jack.c
SOURCES_pulse = pulse.c
SOURCES_audioqueue = audioqueue.c
SOURCES_amem = amem.c
libvlc_LTLIBRARIES += libaout_file_plugin.la
libvlc_LTLIBRARIES += libaout_file_plugin.la \
libamem_plugin.la
libalsa_plugin_la_SOURCES = alsa.c
libalsa_plugin_la_CFLAGS = $(AM_CFLAGS) $(ALSA_CFLAGS)
...
...
modules/audio_output/amem.c
0 → 100644
View file @
e73d940f
/*****************************************************************************
* amem.c: memory audio driver for vlc
*****************************************************************************
* Copyright (C) 2010 M2X BV
* $Id$
*
* Authors: Jean-Paul Saman <jpsaman@videolan.org>
*
* 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.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_codecs.h>
#include <vlc_es.h>
#include <vlc_aout.h>
#if defined(_WIN32_WINNT) || defined(WIN32)
# include <windows.h>
# include <conio.h>
# include <tchar.h>
//# include "windows_audio_common.h"
#else
# include <limits.h>
# include <errno.h>
# include <sys/types.h>
# include <sys/mman.h>
# include <sys/stat.h>
/* For mode constants */
# include <fcntl.h>
/* For O_* constants */
# include <semaphore.h>
#endif
#include <assert.h>
/*****************************************************************************
* Local prototypes
*****************************************************************************/
#define FRAME_SIZE 2048
/* Audio channels */
#define CHANNELS_MAX 6
static
const
int
pi_channels_maps
[
CHANNELS_MAX
+
1
]
=
{
0
,
AOUT_CHAN_CENTER
,
AOUT_CHAN_LEFT
|
AOUT_CHAN_RIGHT
,
AOUT_CHAN_CENTER
|
AOUT_CHAN_LEFT
|
AOUT_CHAN_RIGHT
,
AOUT_CHAN_LEFT
|
AOUT_CHAN_RIGHT
|
AOUT_CHAN_REARLEFT
|
AOUT_CHAN_REARRIGHT
,
AOUT_CHAN_LEFT
|
AOUT_CHAN_RIGHT
|
AOUT_CHAN_CENTER
|
AOUT_CHAN_REARLEFT
|
AOUT_CHAN_REARRIGHT
,
AOUT_CHAN_LEFT
|
AOUT_CHAN_RIGHT
|
AOUT_CHAN_CENTER
|
AOUT_CHAN_REARLEFT
|
AOUT_CHAN_REARRIGHT
|
AOUT_CHAN_LFE
};
/* Audio format */
static
const
char
*
const
format_list
[]
=
{
"u8"
,
"s8"
,
"u16"
,
"s16"
,
"u16_le"
,
"s16_le"
,
"u16_be"
,
"s16_be"
,
"fixed32"
,
"float32"
,
"spdif"
};
static
const
int
format_int
[]
=
{
VLC_CODEC_U8
,
VLC_CODEC_S8
,
VLC_CODEC_U16N
,
VLC_CODEC_S16N
,
VLC_CODEC_U16L
,
VLC_CODEC_S16L
,
VLC_CODEC_U16B
,
VLC_CODEC_S16B
,
VLC_CODEC_FI32
,
VLC_CODEC_FL32
,
VLC_CODEC_SPDIFL
};
/* Shared memory header structure */
typedef
struct
{
#if defined(_WIN32_WINNT) || defined(WIN32)
WAVEFORMATEX
wave
;
#else
vlc_sem_t
sem
;
vlc_fourcc_t
i_format
;
unsigned
int
i_rate
;
unsigned
int
i_bytes_per_frame
;
unsigned
int
i_frame_length
;
unsigned
i_bitspersample
;
unsigned
i_blockalign
;
uint8_t
i_channels
;
#endif
unsigned
int
i_read_samples
;
unsigned
int
i_write_samples
;
unsigned
int
i_max_samples
;
unsigned
int
i_nb_samples
;
void
*
samples
;
}
amem_shared_t
;
/* Private structure */
struct
aout_sys_t
{
char
*
psz_name
;
int
i_delay
;
#if defined(_WIN32_WINNT) || defined(WIN32)
HANDLE
handle
;
#else
int
shm_fd
;
#endif
amem_shared_t
*
header
;
};
static
int
Open
(
vlc_object_t
*
);
static
void
Close
(
vlc_object_t
*
);
static
void
Play
(
aout_instance_t
*
);
static
int
SetupSharedMem
(
aout_instance_t
*
);
static
void
ExitSharedMem
(
aout_instance_t
*
);
/*
* Shared Memory helpers
*/
#if defined(_WIN32_WINNT) || defined(WIN32)
/* FIXME: not tested yet */
static
int
amem_shmem_create
(
aout_instance_t
*
aout
,
ssize_t
len
)
{
aout_sys_t
*
sys
=
(
aout_sys_t
*
)
aout
->
output
.
p_sys
;
TCHAR
szName
[]
=
TEXT
(
sys
->
psz_name
);
sys
->
handle
=
CreateFileMapping
(
INVALID_HANDLE_VALUE
,
// use paging file
NULL
,
// default security
PAGE_READWRITE
,
// read/write access
0
,
// maximum object size (high-order DWORD)
len
,
// maximum object size (low-order DWORD)
szName
);
// name of mapping object
if
(
sys
->
handle
==
NULL
)
{
msg_Err
(
aout
,
"could not create file mapping object (%d)."
,
GetLastError
());
return
VLC_EGENERIC
;
}
/* Map shared buffer */
sys
->
header
=
(
amem_shared_t
*
)
MapViewOfFile
(
sys
->
handle
,
// handle to map object
FILE_MAP_ALL_ACCESS
,
// read/write permission
0
,
0
,
len
);
if
(
sys
->
header
==
NULL
)
{
msg_Err
(
aout
,
"could not map view of file (%d)."
,
GetLastError
());
CloseHandle
(
sys
->
handle
);
return
VLC_ENGERIC
;
}
sys
->
header
->
samples
=
sys
->
header
+
sizeof
(
amem_shared_t
);
return
VLC_SUCCESS
;
}
static
int
amem_shmem_open
(
aout_instance_t
*
aout
,
ssize_t
len
)
{
aout_sys_t
*
sys
=
(
aout_sys_t
*
)
aout
->
output
.
p_sys
;
TCHAR
szName
[]
=
TEXT
(
sys
->
psz_name
);
sys
->
handle
=
OpenFileMapping
(
FILE_MAP_ALL_ACCESS
,
// read/write access
FALSE
,
// do not inherit the name
szName
);
// name of mapping object
if
(
sys
->
handle
==
NULL
)
{
msg_Err
(
aout
,
"could not open file mapping object (%d)."
,
GetLastError
());
return
VLC_EGENERIC
;
}
sys
->
header
=
(
amem_shared_t
*
)
MapViewOfFile
(
handle
,
// handle to map object
FILE_MAP_ALL_ACCESS
,
// read/write permission
0
,
0
,
len
);
if
(
sys
->
header
==
NULL
)
{
msg_Err
(
aout
,
"could not map view of file (%d)."
,
GetLastError
());
CloseHandle
(
sys
->
handle
);
return
VLC_EGENERIC
;
}
sys
->
header
->
samples
=
sys
->
header
+
sizeof
(
amem_shared_t
);
/* FIXME: initialize semaphore */
return
VLC_SUCCESS
;
}
static
void
amem_shmem_close
(
aout_instance_t
*
aout
)
{
aout_sys_t
*
sys
=
(
aout_sys_t
*
)
aout
->
output
.
p_sys
;
/* FIXME: release semaphore */
UnmapViewOfFile
(
sys
->
header
);
CloseHandle
(
sys
->
handle
);
}
static
void
amem_shmem_header
(
aout_instance_t
*
aout
)
{
aout_sys_t
*
sys
=
(
aout_sys_t
*
)
aout
->
output
.
p_sys
;
vlc_sem_wait
(
&
sys
->
header
->
sem
);
/* Fill header struct */
uint16_t
tag
=
0
;
fourcc_to_wf_tag
(
aout
->
output
.
output
.
i_format
,
&
tag
);
sys
->
header
->
wave
.
wFormatTag
=
tag
;
sys
->
header
->
wave
.
nChannels
=
aout
->
output
.
output
.
i_channels
;
sys
->
header
->
wave
.
nSamplesPerSec
=
aout
->
output
.
output
.
i_rate
*
aout
->
output
.
i_nb_samples
;
//sys->header->wave.nAvgBytesPerSec = ;
sys
->
header
->
wave
.
nBlockAlign
=
aout
->
output
.
output
.
i_blockalign
;
sys
->
header
->
wave
.
wBitsPerSample
=
aout
->
output
.
output
.
i_bitspersample
;
sys
->
header
->
wave
.
cbSize
=
0
;
/* No additional format metadata */
sys
->
header
->
i_max_samples
=
aout
->
output
.
i_nb_samples
;
sys
->
header
->
i_nb_samples
=
0
;
msg_Info
(
aout
,
"samples %d, bits per sample %d"
,
aout
->
output
.
i_nb_samples
,
aout
->
output
.
output
.
i_bitspersample
);
/* FIXME: do not assume entire buffer is available */
memset
(
sys
->
header
->
samples
,
0
,
(
aout
->
output
.
i_nb_samples
*
aout
->
output
.
output
.
i_bitspersample
));
if
(
vlc_sem_post
(
&
sys
->
header
->
sem
)
<
0
)
msg_Err
(
aout
,
"failed unlocking semaphore (%m)"
);
}
static
void
amem_shmem_write
(
aout_instance_t
*
aout
,
aout_buffer_t
*
data
)
{
aout_sys_t
*
sys
=
(
aout_sys_t
*
)
aout
->
output
.
p_sys
;
/* FIXME: lock Semaphore */
/* FIXME: Do not assume we can fill entire buffer */
CopyMemory
((
PVOID
)
sys
->
header
->
samples
,
data
->
p_buffer
,
data
->
i_buffer
);
sys
->
header
->
i_nb_samples
=
p_buffer
->
i_buffer
/
(
sys
->
header
->
i_bitspersample
/
8
);
/* FIXME: unlock Semaphore */
}
#else
static
void
amem_sem_init
(
vlc_sem_t
*
sem
,
unsigned
value
)
{
if
(
unlikely
(
sem_init
(
sem
,
1
/* share between process*/
,
value
))
==
-
1
)
abort
();
}
static
int
amem_shmem_create
(
aout_instance_t
*
aout
,
ssize_t
len
)
{
aout_sys_t
*
sys
=
(
aout_sys_t
*
)
aout
->
output
.
p_sys
;
sys
->
shm_fd
=
shm_open
(
sys
->
psz_name
,
(
O_CREAT
|
O_EXCL
|
O_RDWR
),
(
S_IREAD
|
S_IWRITE
));
if
(
sys
->
shm_fd
<
0
)
{
msg_Err
(
aout
,
"could not open shared memory object (%m)"
);
return
VLC_EGENERIC
;
}
/* set correct maximum size */
if
(
ftruncate
(
sys
->
shm_fd
,
len
)
<
0
)
{
msg_Err
(
aout
,
"failed limiting shared memory size (%m)"
);
return
VLC_EGENERIC
;
}
/* mmap shared segment */
sys
->
header
=
mmap
(
0
,
len
,
(
PROT_READ
|
PROT_WRITE
),
MAP_SHARED
,
sys
->
shm_fd
,
0
);
if
(
sys
->
header
==
MAP_FAILED
)
{
msg_Err
(
aout
,
"could not mmap shared memory object (%m)"
);
return
VLC_EGENERIC
;
}
sys
->
header
->
samples
=
sys
->
header
+
sizeof
(
amem_shared_t
);
/* initialize unamed semaphore */
amem_sem_init
(
&
sys
->
header
->
sem
,
1
);
msg_Dbg
(
aout
,
"shared memory created"
);
return
VLC_SUCCESS
;
}
static
int
amem_shmem_open
(
aout_instance_t
*
aout
,
ssize_t
len
)
{
aout_sys_t
*
sys
=
(
aout_sys_t
*
)
aout
->
output
.
p_sys
;
sys
->
shm_fd
=
shm_open
(
sys
->
psz_name
,
O_RDWR
,
(
S_IREAD
|
S_IWRITE
));
if
(
sys
->
shm_fd
<
0
)
{
msg_Err
(
aout
,
"could not open shared memory object (%m)"
);
return
VLC_EGENERIC
;
}
/* set correct maximum size */
if
(
ftruncate
(
sys
->
shm_fd
,
len
)
<
0
)
{
msg_Err
(
aout
,
"failed limiting shared memory size (%m)"
);
return
VLC_EGENERIC
;
}
/* mmap shared segment */
sys
->
header
=
mmap
(
0
,
len
,
(
PROT_READ
|
PROT_WRITE
),
MAP_SHARED
,
sys
->
shm_fd
,
0
);
if
(
sys
->
header
==
MAP_FAILED
)
{
msg_Err
(
aout
,
"could not mmap shared memory object (%m)"
);
return
VLC_EGENERIC
;
}
sys
->
header
->
samples
=
sys
->
header
+
sizeof
(
amem_shared_t
);
msg_Dbg
(
aout
,
"shared memory opened"
);
return
VLC_SUCCESS
;
}
static
void
amem_shmem_close
(
aout_instance_t
*
aout
)
{
aout_sys_t
*
sys
=
(
aout_sys_t
*
)
aout
->
output
.
p_sys
;
vlc_sem_destroy
(
&
sys
->
header
->
sem
);
/* Determine shared memory size */
if
(
sys
->
header
!=
MAP_FAILED
)
{
ssize_t
len
=
sizeof
(
amem_shared_t
)
+
aout
->
output
.
i_nb_samples
*
aout
->
output
.
output
.
i_bitspersample
;
if
(
munmap
(
sys
->
header
,
len
)
<
0
)
{
msg_Err
(
aout
,
"failed unmapping shared memory (%m)"
);
}
}
close
(
sys
->
shm_fd
);
msg_Dbg
(
aout
,
"shared memory closed"
);
}
static
void
amem_shmem_header
(
aout_instance_t
*
aout
)
{
aout_sys_t
*
sys
=
(
aout_sys_t
*
)
aout
->
output
.
p_sys
;
amem_shared_t
*
header
=
sys
->
header
;
msg_Dbg
(
aout
,
"syncing shared header"
);
vlc_sem_wait
(
&
header
->
sem
);
/* Fill header struct */
header
->
i_format
=
aout
->
output
.
output
.
i_format
;
header
->
i_bitspersample
=
aout
->
output
.
output
.
i_bitspersample
;
header
->
i_bytes_per_frame
=
aout
->
output
.
output
.
i_bytes_per_frame
;
header
->
i_channels
=
aout
->
output
.
output
.
i_channels
;
header
->
i_frame_length
=
aout
->
output
.
output
.
i_frame_length
;
header
->
i_rate
=
aout
->
output
.
output
.
i_rate
;
header
->
i_blockalign
=
aout
->
output
.
output
.
i_blockalign
;
header
->
i_read_samples
=
0
;
header
->
i_write_samples
=
0
;
header
->
i_max_samples
=
aout
->
output
.
i_nb_samples
;
header
->
i_nb_samples
=
0
;
memset
(
header
->
samples
,
0
,
(
aout
->
output
.
i_nb_samples
*
aout
->
output
.
output
.
i_bitspersample
));
if
(
vlc_sem_post
(
&
header
->
sem
)
<
0
)
msg_Err
(
aout
,
"failed unlocking semaphore (%m)"
);
}
static
int
amem_shmem_write
(
aout_instance_t
*
aout
,
aout_buffer_t
*
p_buffer
)
{
aout_sys_t
*
sys
=
(
aout_sys_t
*
)
aout
->
output
.
p_sys
;
#if 0
int again = 0;
do
{
if (sem_trywait(&sys->header->sem) == 0)
break;
if (errno == EAGAIN)
again++;
if (again == 3)
{
msg_Err(aout, "Failed locking semaphore for writing");
return VLC_EGENERIC;
}
} while (again < 3);
#endif
vlc_sem_wait
(
&
sys
->
header
->
sem
);
/* FIXME: do not assume we can fill the entire buffer */
assert
(
p_buffer
->
i_nb_samples
<=
sys
->
header
->
i_max_samples
);
memcpy
(
sys
->
header
->
samples
,
p_buffer
->
p_buffer
,
p_buffer
->
i_buffer
);
sys
->
header
->
i_nb_samples
=
p_buffer
->
i_nb_samples
;
sys
->
header
->
i_write_samples
+=
p_buffer
->
i_nb_samples
;
if
(
vlc_sem_post
(
&
sys
->
header
->
sem
)
<
0
)
msg_Err
(
aout
,
"failed unlocking semaphore (%m)"
);
return
VLC_SUCCESS
;
}
#endif
/*****************************************************************************
* Module descriptor
*****************************************************************************/
#define ARATE_TEXT N_("Audio sample rate")
#define ARATE_LONGTEXT N_( \
"Sample rate of the audio stream (11250, 22500, 44100 or 48000).")
#define ACHANS_TEXT N_("Audio channels")
#define ACHANS_LONGTEXT N_( \
"Number of audio channels in the audio output." )
#define AFORMAT_TEXT N_("Output format")
#define AFORMAT_LONGTEXT N_( \
"One of \"u8\", \"s8\", \"u16\", \"s16\", " \
"\"u16_le\", \"s16_le\", \"u16_be\", \"s16_be\", \"fixed32\", " \
"\"float32\" or \"spdif\"")
#define ADELAY_TEXT N_("Output delay")
#define ADELAY_LONGTEXT N_( \
"Initial delay for audio output" )
#define ANAME_TEXT N_("Name to use (default /amem.shared)")
#define ANAME_LONGTEXT N_( \
"Name to use as identifier to the (named) shared memory" )
#define AMEM_CFG_PREFIX "amem-"
vlc_module_begin
()
set_description
(
N_
(
"Audio memory output"
))
set_shortname
(
N_
(
"Audio memory"
))
set_category
(
CAT_AUDIO
)
set_subcategory
(
SUBCAT_AUDIO_AOUT
)
set_capability
(
"audio output"
,
0
)
add_string
(
AMEM_CFG_PREFIX
"name"
,
"/amem.shared"
,
NULL
,
ANAME_TEXT
,
ANAME_LONGTEXT
,
true
)
add_string
(
AMEM_CFG_PREFIX
"format"
,
"s16"
,
NULL
,
AFORMAT_TEXT
,
AFORMAT_LONGTEXT
,
true
)
change_string_list
(
format_list
,
0
,
0
)
add_integer
(
AMEM_CFG_PREFIX
"channels"
,
2
,
NULL
,
ACHANS_TEXT
,
ACHANS_LONGTEXT
,
false
)
change_integer_range
(
0
,
CHANNELS_MAX
)
add_integer
(
AMEM_CFG_PREFIX
"samplerate"
,
44100
,
NULL
,
ARATE_TEXT
,
ARATE_LONGTEXT
,
true
)
add_integer
(
AMEM_CFG_PREFIX
"delay"
,
0
,
NULL
,
ADELAY_TEXT
,
ADELAY_TEXT
,
true
)
set_callbacks
(
Open
,
Close
)
vlc_module_end
()
/*****************************************************************************
* Open
*****************************************************************************/
static
int
Open
(
vlc_object_t
*
p_this
)
{
aout_instance_t
*
aout
=
(
aout_instance_t
*
)
p_this
;
aout_sys_t
*
sys
;
char
*
psz_format
;
const
char
*
const
*
ppsz_compare
=
format_list
;
int
i
=
0
;
/* */
aout
->
output
.
p_sys
=
sys
=
(
aout_sys_t
*
)
malloc
(
sizeof
(
aout_sys_t
));
if
(
sys
==
NULL
)
return
VLC_ENOMEM
;
/* */
sys
->
header
=
NULL
;
aout
->
output
.
pf_play
=
Play
;
/* Name to use */
sys
->
psz_name
=
var_CreateGetString
(
p_this
,
AMEM_CFG_PREFIX
"name"
);
/* Audio sample rate */
aout
->
output
.
output
.
i_rate
=
var_CreateGetInteger
(
p_this
,
AMEM_CFG_PREFIX
"samplerate"
);
/* Audio output delay */
sys
->
i_delay
=
var_CreateGetInteger
(
p_this
,
AMEM_CFG_PREFIX
"delay"
);
/* Audio format */
psz_format
=
var_CreateGetString
(
p_this
,
AMEM_CFG_PREFIX
"format"
);
while
(
*
ppsz_compare
!=
NULL
)
{
if
(
!
strncmp
(
*
ppsz_compare
,
psz_format
,
strlen
(
*
ppsz_compare
)))
{
break
;
}
ppsz_compare
++
;
i
++
;
}
if
(
*
ppsz_compare
==
NULL
)
{
msg_Err
(
aout
,
"cannot understand the format string (%s)"
,
psz_format
);
free
(
aout
->
output
.
p_sys
);
free
(
psz_format
);
return
VLC_EGENERIC
;
}
free
(
psz_format
);
aout
->
output
.
output
.
i_format
=
format_int
[
i
];
if
(
AOUT_FMT_NON_LINEAR
(
&
aout
->
output
.
output
))
{
aout
->
output
.
i_nb_samples
=
A52_FRAME_NB
;
aout
->
output
.
output
.
i_bytes_per_frame
=
AOUT_SPDIF_SIZE
;
aout
->
output
.
output
.
i_frame_length
=
A52_FRAME_NB
;
aout_VolumeNoneInit
(
aout
);
}
else
{
aout
->
output
.
i_nb_samples
=
FRAME_SIZE
;
aout_VolumeSoftInit
(
aout
);
}
/* Channels number */
int
i_channels
=
var_CreateGetInteger
(
p_this
,
AMEM_CFG_PREFIX
"channels"
);
if
((
i_channels
>
0
)
&&
(
i_channels
<=
CHANNELS_MAX
))
{
aout
->
output
.
output
.
i_physical_channels
=
pi_channels_maps
[
i_channels
];
}
/* Setup shared memory connection */
if
(
SetupSharedMem
(
aout
)
!=
VLC_SUCCESS
)
{
Close
(
p_this
);
return
VLC_EGENERIC
;
}
return
VLC_SUCCESS
;
}
/*****************************************************************************
* Close
*****************************************************************************/
static
void
Close
(
vlc_object_t
*
p_this
)
{
aout_instance_t
*
aout
=
(
aout_instance_t
*
)
p_this
;
ExitSharedMem
(
aout
);
free
(
aout
->
output
.
p_sys
->
psz_name
);
free
(
aout
->
output
.
p_sys
);
}
/*****************************************************************************
* Play
*****************************************************************************/
static
void
Play
(
aout_instance_t
*
aout
)
{
aout_buffer_t
*
p_buffer
;
p_buffer
=
aout_FifoPop
(
aout
,
&
aout
->
output
.
fifo
);
if
(
p_buffer
==
NULL
)
return
;
if
(
amem_shmem_write
(
aout
,
p_buffer
)
!=
VLC_SUCCESS
)
{
msg_Err
(
aout
,
"write error (%m)"
);
}
aout_BufferFree
(
p_buffer
);
}
/*****************************************************************************
* Shared Memory
*****************************************************************************/
static
int
SetupSharedMem
(
aout_instance_t
*
aout
)
{
aout_sys_t
*
sys
=
(
aout_sys_t
*
)
aout
->
output
.
p_sys
;
/* Determine shared memory size */
ssize_t
len
=
sizeof
(
amem_shared_t
)
+
aout
->
output
.
i_nb_samples
*
aout
->
output
.
output
.
i_bitspersample
;
if
(
*
sys
->
psz_name
!=
'/'
)
{
msg_Err
(
aout
,
"invalid shared segment name (does not begin with /)"
);
return
VLC_EGENERIC
;
}
if
(
strlen
(
sys
->
psz_name
)
>=
NAME_MAX
)
{
msg_Err
(
aout
,
"invalid shared segment name (string length >= %d)"
,
NAME_MAX
);
return
VLC_EGENERIC
;
}
if
(
amem_shmem_open
(
aout
,
len
)
!=
VLC_SUCCESS
)
return
VLC_EGENERIC
;
/* Fill header struct */
amem_shmem_header
(
aout
);
return
VLC_SUCCESS
;
}
static
void
ExitSharedMem
(
aout_instance_t
*
aout
)
{
amem_shmem_close
(
aout
);
}
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