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
f999f1dd
Commit
f999f1dd
authored
Dec 20, 2012
by
Rafaël Carré
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
opensles: move code from Start/Stop to Open/Close
These objects do not depend on the audio format
parent
0e1c348b
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
213 additions
and
192 deletions
+213
-192
modules/audio_output/opensles_android.c
modules/audio_output/opensles_android.c
+213
-192
No files found.
modules/audio_output/opensles_android.c
View file @
f999f1dd
...
...
@@ -41,6 +41,17 @@
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>
#define CHECK_OPENSL_ERROR( msg ) \
if( unlikely( result != SL_RESULT_SUCCESS ) ) \
{ \
msg_Err( aout, msg" (%lu)", result ); \
goto error; \
}
typedef
SLresult
(
*
slCreateEngine_t
)(
SLObjectItf
*
,
SLuint32
,
const
SLEngineOption
*
,
SLuint32
,
const
SLInterfaceID
*
,
const
SLboolean
*
);
#define Destroy(a) (*a)->Destroy(a);
#define SetPlayState(a, b) (*a)->SetPlayState(a, b)
#define RegisterCallback(a, b, c) (*a)->RegisterCallback(a, b, c)
...
...
@@ -69,7 +80,7 @@ struct aout_sys_t
SLAndroidSimpleBufferQueueItf
playerBufferQueue
;
SLObjectItf
playerObject
;
SLVolumeItf
volumeItf
;
SLEngineItf
engineEngine
;
SLPlayItf
playerPlay
;
vlc_mutex_t
lock
;
...
...
@@ -86,13 +97,21 @@ struct aout_sys_t
block_t
**
pp_buffer_last
;
void
*
p_so_handle
;
slCreateEngine_t
slCreateEnginePtr
;
SLInterfaceID
SL_IID_ENGINE
;
SLInterfaceID
SL_IID_ANDROIDSIMPLEBUFFERQUEUE
;
SLInterfaceID
SL_IID_VOLUME
;
SLInterfaceID
SL_IID_PLAY
;
audio_sample_format_t
format
;
};
/*****************************************************************************
* Local prototypes.
*****************************************************************************/
static
int
Open
(
vlc_object_t
*
);
static
int
Open
(
vlc_object_t
*
);
static
void
Close
(
vlc_object_t
*
);
/*****************************************************************************
* Module descriptor
...
...
@@ -106,56 +125,41 @@ vlc_module_begin ()
set_capability
(
"audio output"
,
170
)
add_shortcut
(
"opensles"
,
"android"
)
set_callbacks
(
Open
,
NULL
)
set_callbacks
(
Open
,
Close
)
vlc_module_end
()
static
void
Clean
(
aout_sys_t
*
p_sys
)
{
if
(
p_sys
->
playerObject
)
Destroy
(
p_sys
->
playerObject
);
if
(
p_sys
->
outputMixObject
)
Destroy
(
p_sys
->
outputMixObject
);
if
(
p_sys
->
engineObject
)
Destroy
(
p_sys
->
engineObject
);
if
(
p_sys
->
p_so_handle
)
dlclose
(
p_sys
->
p_so_handle
);
free
(
p_sys
);
}
static
void
Flush
(
audio_output_t
*
p_aout
,
bool
drain
)
static
void
Flush
(
audio_output_t
*
aout
,
bool
drain
)
{
aout_sys_t
*
p_sys
=
p_
aout
->
sys
;
aout_sys_t
*
sys
=
aout
->
sys
;
if
(
drain
)
{
mtime_t
delay
;
vlc_mutex_lock
(
&
p_
sys
->
lock
);
delay
=
p_
sys
->
length
;
vlc_mutex_unlock
(
&
p_
sys
->
lock
);
vlc_mutex_lock
(
&
sys
->
lock
);
delay
=
sys
->
length
;
vlc_mutex_unlock
(
&
sys
->
lock
);
msleep
(
delay
);
}
else
{
vlc_mutex_lock
(
&
p_
sys
->
lock
);
SetPlayState
(
p_
sys
->
playerPlay
,
SL_PLAYSTATE_STOPPED
);
Clear
(
p_
sys
->
playerBufferQueue
);
SetPlayState
(
p_
sys
->
playerPlay
,
SL_PLAYSTATE_PLAYING
);
vlc_mutex_lock
(
&
sys
->
lock
);
SetPlayState
(
sys
->
playerPlay
,
SL_PLAYSTATE_STOPPED
);
Clear
(
sys
->
playerBufferQueue
);
SetPlayState
(
sys
->
playerPlay
,
SL_PLAYSTATE_PLAYING
);
p_
sys
->
length
=
0
;
p_
sys
->
buffers
=
0
;
sys
->
length
=
0
;
sys
->
buffers
=
0
;
/* release audio data not yet written to opensles */
block_ChainRelease
(
p_
sys
->
p_buffer_chain
);
p_
sys
->
p_buffer_chain
=
NULL
;
p_sys
->
pp_buffer_last
=
&
p_
sys
->
p_buffer_chain
;
block_ChainRelease
(
sys
->
p_buffer_chain
);
sys
->
p_buffer_chain
=
NULL
;
sys
->
pp_buffer_last
=
&
sys
->
p_buffer_chain
;
/* release audio data written to opensles, but not yet
* played on hardware */
block_ChainRelease
(
p_
sys
->
p_chain
);
p_
sys
->
p_chain
=
NULL
;
p_sys
->
pp_last
=
&
p_
sys
->
p_chain
;
block_ChainRelease
(
sys
->
p_chain
);
sys
->
p_chain
=
NULL
;
sys
->
pp_last
=
&
sys
->
p_chain
;
vlc_mutex_unlock
(
&
p_
sys
->
lock
);
vlc_mutex_unlock
(
&
sys
->
lock
);
}
}
...
...
@@ -181,26 +185,26 @@ static int MuteSet(audio_output_t *aout, bool mute)
return
(
r
==
SL_RESULT_SUCCESS
)
?
0
:
-
1
;
}
static
void
Pause
(
audio_output_t
*
p_
aout
,
bool
pause
,
mtime_t
date
)
static
void
Pause
(
audio_output_t
*
aout
,
bool
pause
,
mtime_t
date
)
{
(
void
)
date
;
aout_sys_t
*
p_sys
=
p_
aout
->
sys
;
SetPlayState
(
p_
sys
->
playerPlay
,
aout_sys_t
*
sys
=
aout
->
sys
;
SetPlayState
(
sys
->
playerPlay
,
pause
?
SL_PLAYSTATE_PAUSED
:
SL_PLAYSTATE_PLAYING
);
}
static
int
TimeGet
(
audio_output_t
*
p_
aout
,
mtime_t
*
restrict
drift
)
static
int
TimeGet
(
audio_output_t
*
aout
,
mtime_t
*
restrict
drift
)
{
aout_sys_t
*
p_sys
=
p_
aout
->
sys
;
aout_sys_t
*
sys
=
aout
->
sys
;
vlc_mutex_lock
(
&
p_
sys
->
lock
);
mtime_t
delay
=
p_
sys
->
length
;
vlc_mutex_unlock
(
&
p_
sys
->
lock
);
vlc_mutex_lock
(
&
sys
->
lock
);
mtime_t
delay
=
sys
->
length
;
vlc_mutex_unlock
(
&
sys
->
lock
);
SLAndroidSimpleBufferQueueState
st
;
SLresult
res
=
GetState
(
p_
sys
->
playerBufferQueue
,
&
st
);
SLresult
res
=
GetState
(
sys
->
playerBufferQueue
,
&
st
);
if
(
unlikely
(
res
!=
SL_RESULT_SUCCESS
))
{
msg_Err
(
p_
aout
,
"Could not query buffer queue state in TimeGet (%lu)"
,
res
);
msg_Err
(
aout
,
"Could not query buffer queue state in TimeGet (%lu)"
,
res
);
return
-
1
;
}
...
...
@@ -211,52 +215,52 @@ static int TimeGet(audio_output_t* p_aout, mtime_t* restrict drift)
return
0
;
}
static
int
WriteBuffer
(
audio_output_t
*
p_
aout
)
static
int
WriteBuffer
(
audio_output_t
*
aout
)
{
aout_sys_t
*
p_sys
=
p_
aout
->
sys
;
aout_sys_t
*
sys
=
aout
->
sys
;
block_t
*
b
=
p_
sys
->
p_buffer_chain
;
block_t
*
b
=
sys
->
p_buffer_chain
;
if
(
!
b
)
return
false
;
if
(
!
b
->
i_length
)
b
->
i_length
=
(
mtime_t
)(
b
->
i_buffer
/
2
/
p_sys
->
format
.
i_channels
)
*
CLOCK_FREQ
/
p_
sys
->
format
.
i_rate
;
b
->
i_length
=
(
mtime_t
)(
b
->
i_buffer
/
2
/
sys
->
format
.
i_channels
)
*
CLOCK_FREQ
/
sys
->
format
.
i_rate
;
/* If something bad happens, we must remove this buffer from the FIFO */
block_t
**
pp_last_saved
=
p_
sys
->
pp_last
;
block_t
**
pp_last_saved
=
sys
->
pp_last
;
block_t
*
p_last_saved
=
*
pp_last_saved
;
block_t
*
next_saved
=
b
->
p_next
;
b
->
p_next
=
NULL
;
/* Put this block in the list of audio already written to opensles */
block_ChainLastAppend
(
&
p_
sys
->
pp_last
,
b
);
block_ChainLastAppend
(
&
sys
->
pp_last
,
b
);
mtime_t
len
=
b
->
i_length
;
p_
sys
->
length
+=
len
;
sys
->
length
+=
len
;
block_t
*
next
=
b
->
p_next
;
vlc_mutex_unlock
(
&
p_
sys
->
lock
);
SLresult
r
=
Enqueue
(
p_
sys
->
playerBufferQueue
,
b
->
p_buffer
,
b
->
i_buffer
);
vlc_mutex_lock
(
&
p_
sys
->
lock
);
vlc_mutex_unlock
(
&
sys
->
lock
);
SLresult
r
=
Enqueue
(
sys
->
playerBufferQueue
,
b
->
p_buffer
,
b
->
i_buffer
);
vlc_mutex_lock
(
&
sys
->
lock
);
if
(
r
==
SL_RESULT_SUCCESS
)
{
/* Remove that block from the list of audio not yet written */
p_
sys
->
buffers
++
;
p_
sys
->
p_buffer_chain
=
next
;
if
(
!
p_
sys
->
p_buffer_chain
)
p_sys
->
pp_buffer_last
=
&
p_
sys
->
p_buffer_chain
;
sys
->
buffers
++
;
sys
->
p_buffer_chain
=
next
;
if
(
!
sys
->
p_buffer_chain
)
sys
->
pp_buffer_last
=
&
sys
->
p_buffer_chain
;
}
else
{
/* Remove that block from the list of audio already written */
msg_Err
(
p_
aout
,
"error %lu when writing %d bytes, %d/255 buffers occupied %s"
,
r
,
b
->
i_buffer
,
p_
sys
->
buffers
,
msg_Err
(
aout
,
"error %lu when writing %d bytes, %d/255 buffers occupied %s"
,
r
,
b
->
i_buffer
,
sys
->
buffers
,
(
r
==
SL_RESULT_BUFFER_INSUFFICIENT
)
?
" (buffer insufficient)"
:
""
);
p_
sys
->
pp_last
=
pp_last_saved
;
sys
->
pp_last
=
pp_last_saved
;
*
pp_last_saved
=
p_last_saved
;
b
->
p_next
=
next_saved
;
p_
sys
->
length
-=
len
;
sys
->
length
-=
len
;
next
=
NULL
;
/* We'll try again next time */
}
...
...
@@ -266,123 +270,63 @@ static int WriteBuffer(audio_output_t *p_aout)
/*****************************************************************************
* Play: play a sound
*****************************************************************************/
static
void
Play
(
audio_output_t
*
p_
aout
,
block_t
*
p_buffer
)
static
void
Play
(
audio_output_t
*
aout
,
block_t
*
p_buffer
)
{
aout_sys_t
*
p_sys
=
p_
aout
->
sys
;
aout_sys_t
*
sys
=
aout
->
sys
;
p_buffer
->
p_next
=
NULL
;
/* Make sur our linked list doesn't use old references */
vlc_mutex_lock
(
&
p_
sys
->
lock
);
block_ChainLastAppend
(
&
p_
sys
->
pp_buffer_last
,
p_buffer
);
while
(
WriteBuffer
(
p_
aout
))
vlc_mutex_lock
(
&
sys
->
lock
);
block_ChainLastAppend
(
&
sys
->
pp_buffer_last
,
p_buffer
);
while
(
WriteBuffer
(
aout
))
;
vlc_mutex_unlock
(
&
p_
sys
->
lock
);
vlc_mutex_unlock
(
&
sys
->
lock
);
}
static
void
PlayedCallback
(
SLAndroidSimpleBufferQueueItf
caller
,
void
*
pContext
)
{
(
void
)
caller
;
block_t
*
p_block
;
audio_output_t
*
p_
aout
=
pContext
;
aout_sys_t
*
p_sys
=
p_
aout
->
sys
;
audio_output_t
*
aout
=
pContext
;
aout_sys_t
*
sys
=
aout
->
sys
;
assert
(
caller
==
p_
sys
->
playerBufferQueue
);
assert
(
caller
==
sys
->
playerBufferQueue
);
vlc_mutex_lock
(
&
p_
sys
->
lock
);
p_
sys
->
buffers
--
;
vlc_mutex_lock
(
&
sys
->
lock
);
sys
->
buffers
--
;
p_block
=
p_
sys
->
p_chain
;
p_block
=
sys
->
p_chain
;
assert
(
p_block
);
p_sys
->
p_chain
=
p_
sys
->
p_chain
->
p_next
;
sys
->
p_chain
=
sys
->
p_chain
->
p_next
;
/* if we exhausted our fifo, we must reset the pointer to the last
* appended block */
if
(
!
p_
sys
->
p_chain
)
p_sys
->
pp_last
=
&
p_
sys
->
p_chain
;
if
(
!
sys
->
p_chain
)
sys
->
pp_last
=
&
sys
->
p_chain
;
p_
sys
->
length
-=
p_block
->
i_length
;
sys
->
length
-=
p_block
->
i_length
;
vlc_mutex_unlock
(
&
p_
sys
->
lock
);
vlc_mutex_unlock
(
&
sys
->
lock
);
block_Release
(
p_block
);
}
/*****************************************************************************
*
Open
*
*****************************************************************************/
static
int
Start
(
audio_output_t
*
p_aout
,
audio_sample_format_t
*
restrict
fmt
)
static
void
Clean
(
aout_sys_t
*
sys
)
{
SLresult
result
;
SLEngineItf
engineEngine
;
/* Allocate structure */
p_aout
->
sys
=
calloc
(
1
,
sizeof
(
aout_sys_t
)
);
if
(
unlikely
(
p_aout
->
sys
==
NULL
)
)
return
VLC_ENOMEM
;
aout_sys_t
*
p_sys
=
p_aout
->
sys
;
//Acquiring LibOpenSLES symbols :
p_sys
->
p_so_handle
=
dlopen
(
"libOpenSLES.so"
,
RTLD_NOW
);
if
(
p_sys
->
p_so_handle
==
NULL
)
{
msg_Err
(
p_aout
,
"Failed to load libOpenSLES"
);
goto
error
;
}
typedef
SLresult
(
*
slCreateEngine_t
)(
SLObjectItf
*
,
SLuint32
,
const
SLEngineOption
*
,
SLuint32
,
const
SLInterfaceID
*
,
const
SLboolean
*
);
slCreateEngine_t
slCreateEnginePtr
=
NULL
;
SLInterfaceID
*
SL_IID_ENGINE
;
SLInterfaceID
*
SL_IID_ANDROIDSIMPLEBUFFERQUEUE
;
SLInterfaceID
*
SL_IID_VOLUME
;
SLInterfaceID
*
SL_IID_PLAY
;
#define OPENSL_DLSYM( dest, handle, name ) \
dest = dlsym( handle, name ); \
if( dest == NULL ) \
{ \
msg_Err( p_aout, "Failed to load symbol %s", name ); \
goto error; \
}
OPENSL_DLSYM
(
slCreateEnginePtr
,
p_sys
->
p_so_handle
,
"slCreateEngine"
);
OPENSL_DLSYM
(
SL_IID_ANDROIDSIMPLEBUFFERQUEUE
,
p_sys
->
p_so_handle
,
"SL_IID_ANDROIDSIMPLEBUFFERQUEUE"
);
OPENSL_DLSYM
(
SL_IID_ENGINE
,
p_sys
->
p_so_handle
,
"SL_IID_ENGINE"
);
OPENSL_DLSYM
(
SL_IID_PLAY
,
p_sys
->
p_so_handle
,
"SL_IID_PLAY"
);
OPENSL_DLSYM
(
SL_IID_VOLUME
,
p_sys
->
p_so_handle
,
"SL_IID_VOLUME"
);
#define CHECK_OPENSL_ERROR( msg ) \
if( unlikely( result != SL_RESULT_SUCCESS ) ) \
{ \
msg_Err( p_aout, msg" (%lu)", result ); \
goto error; \
}
// create engine
result
=
slCreateEnginePtr
(
&
p_sys
->
engineObject
,
0
,
NULL
,
0
,
NULL
,
NULL
);
CHECK_OPENSL_ERROR
(
"Failed to create engine"
);
// realize the engine in synchronous mode
result
=
Realize
(
p_sys
->
engineObject
,
SL_BOOLEAN_FALSE
);
CHECK_OPENSL_ERROR
(
"Failed to realize engine"
);
// get the engine interface, needed to create other objects
result
=
GetInterface
(
p_sys
->
engineObject
,
*
SL_IID_ENGINE
,
&
engineEngine
);
CHECK_OPENSL_ERROR
(
"Failed to get the engine interface"
);
// create output mix, with environmental reverb specified as a non-required interface
const
SLInterfaceID
ids1
[]
=
{
*
SL_IID_VOLUME
};
const
SLboolean
req1
[]
=
{
SL_BOOLEAN_FALSE
};
result
=
CreateOutputMix
(
engineEngine
,
&
p_sys
->
outputMixObject
,
1
,
ids1
,
req1
);
CHECK_OPENSL_ERROR
(
"Failed to create output mix"
);
if
(
sys
->
playerObject
)
Destroy
(
sys
->
playerObject
);
if
(
sys
->
outputMixObject
)
Destroy
(
sys
->
outputMixObject
);
if
(
sys
->
engineObject
)
Destroy
(
sys
->
engineObject
);
}
// realize the output mix in synchronous mode
result
=
Realize
(
p_sys
->
outputMixObject
,
SL_BOOLEAN_FALSE
);
CHECK_OPENSL_ERROR
(
"Failed to realize output mix"
)
;
static
int
Start
(
audio_output_t
*
aout
,
audio_sample_format_t
*
restrict
fmt
)
{
SLresult
result
;
aout_sys_t
*
sys
=
aout
->
sys
;
// configure audio source - this defines the number of samples you can enqueue.
SLDataLocator_AndroidSimpleBufferQueue
loc_bufq
=
{
...
...
@@ -404,89 +348,166 @@ static int Start( audio_output_t *p_aout, audio_sample_format_t *restrict fmt )
// configure audio sink
SLDataLocator_OutputMix
loc_outmix
=
{
SL_DATALOCATOR_OUTPUTMIX
,
p_
sys
->
outputMixObject
sys
->
outputMixObject
};
SLDataSink
audioSnk
=
{
&
loc_outmix
,
NULL
};
//create audio player
const
SLInterfaceID
ids2
[]
=
{
*
SL_IID_ANDROIDSIMPLEBUFFERQUEUE
,
*
SL_IID_VOLUME
};
const
SLInterfaceID
ids2
[]
=
{
sys
->
SL_IID_ANDROIDSIMPLEBUFFERQUEUE
,
sys
->
SL_IID_VOLUME
};
static
const
SLboolean
req2
[]
=
{
SL_BOOLEAN_TRUE
,
SL_BOOLEAN_TRUE
};
result
=
CreateAudioPlayer
(
engineEngine
,
&
p_
sys
->
playerObject
,
&
audioSrc
,
result
=
CreateAudioPlayer
(
sys
->
engineEngine
,
&
sys
->
playerObject
,
&
audioSrc
,
&
audioSnk
,
sizeof
(
ids2
)
/
sizeof
(
*
ids2
),
ids2
,
req2
);
CHECK_OPENSL_ERROR
(
"Failed to create audio player"
);
result
=
Realize
(
p_
sys
->
playerObject
,
SL_BOOLEAN_FALSE
);
result
=
Realize
(
sys
->
playerObject
,
SL_BOOLEAN_FALSE
);
CHECK_OPENSL_ERROR
(
"Failed to realize player object."
);
result
=
GetInterface
(
p_sys
->
playerObject
,
*
SL_IID_PLAY
,
&
p_
sys
->
playerPlay
);
result
=
GetInterface
(
sys
->
playerObject
,
sys
->
SL_IID_PLAY
,
&
sys
->
playerPlay
);
CHECK_OPENSL_ERROR
(
"Failed to get player interface."
);
result
=
GetInterface
(
p_sys
->
playerObject
,
*
SL_IID_VOLUME
,
&
p_
sys
->
volumeItf
);
result
=
GetInterface
(
sys
->
playerObject
,
sys
->
SL_IID_VOLUME
,
&
sys
->
volumeItf
);
CHECK_OPENSL_ERROR
(
"failed to get volume interface."
);
result
=
GetInterface
(
p_sys
->
playerObject
,
*
SL_IID_ANDROIDSIMPLEBUFFERQUEUE
,
&
p_
sys
->
playerBufferQueue
);
result
=
GetInterface
(
sys
->
playerObject
,
sys
->
SL_IID_ANDROIDSIMPLEBUFFERQUEUE
,
&
sys
->
playerBufferQueue
);
CHECK_OPENSL_ERROR
(
"Failed to get buff queue interface"
);
result
=
RegisterCallback
(
p_
sys
->
playerBufferQueue
,
PlayedCallback
,
(
void
*
)
p_
aout
);
result
=
RegisterCallback
(
sys
->
playerBufferQueue
,
PlayedCallback
,
(
void
*
)
aout
);
CHECK_OPENSL_ERROR
(
"Failed to register buff queue callback."
);
// set the player's state to playing
result
=
SetPlayState
(
p_
sys
->
playerPlay
,
SL_PLAYSTATE_PLAYING
);
result
=
SetPlayState
(
sys
->
playerPlay
,
SL_PLAYSTATE_PLAYING
);
CHECK_OPENSL_ERROR
(
"Failed to switch to playing state"
);
vlc_mutex_init
(
&
p_sys
->
lock
);
p_sys
->
p_chain
=
NULL
;
p_sys
->
pp_last
=
&
p_sys
->
p_chain
;
p_sys
->
p_buffer_chain
=
NULL
;
p_sys
->
pp_buffer_last
=
&
p_sys
->
p_buffer_chain
;
sys
->
p_chain
=
NULL
;
sys
->
pp_last
=
&
sys
->
p_chain
;
sys
->
p_buffer_chain
=
NULL
;
sys
->
pp_buffer_last
=
&
sys
->
p_buffer_chain
;
// we want 16bit signed data native endian.
fmt
->
i_format
=
VLC_CODEC_S16N
;
fmt
->
i_physical_channels
=
AOUT_CHAN_LEFT
|
AOUT_CHAN_RIGHT
;
p_aout
->
play
=
Play
;
p_aout
->
pause
=
Pause
;
p_aout
->
flush
=
Flush
;
p_aout
->
mute_set
=
MuteSet
;
p_aout
->
volume_set
=
VolumeSet
;
SetPositionUpdatePeriod
(
p_
sys
->
playerPlay
,
AOUT_MIN_PREPARE_TIME
*
1000
/
CLOCK_FREQ
);
SetPositionUpdatePeriod
(
sys
->
playerPlay
,
AOUT_MIN_PREPARE_TIME
*
1000
/
CLOCK_FREQ
);
aout_FormatPrepare
(
fmt
);
p_
sys
->
format
=
*
fmt
;
sys
->
format
=
*
fmt
;
return
VLC_SUCCESS
;
error:
Clean
(
p_sys
);
Clean
(
sys
);
return
VLC_EGENERIC
;
}
static
void
Stop
(
audio_output_t
*
aout
)
{
aout_sys_t
*
sys
=
aout
->
sys
;
SetPlayState
(
sys
->
playerPlay
,
SL_PLAYSTATE_STOPPED
);
//Flush remaining buffers if any.
Clear
(
sys
->
playerBufferQueue
);
block_ChainRelease
(
sys
->
p_chain
);
block_ChainRelease
(
sys
->
p_buffer_chain
);
}
/*****************************************************************************
*
Close
*
*****************************************************************************/
static
void
Stop
(
audio_output_t
*
p_aout
)
static
void
Close
(
vlc_object_t
*
obj
)
{
aout_sys_t
*
p_sys
=
p_aout
->
sys
;
audio_output_t
*
aout
=
(
audio_output_t
*
)
obj
;
aout_sys_t
*
sys
=
aout
->
sys
;
SetPlayState
(
p_sys
->
playerPlay
,
SL_PLAYSTATE_STOPPED
);
//Flush remaining buffers if any.
Clear
(
p_sys
->
playerBufferQueue
);
block_ChainRelease
(
p_sys
->
p_chain
);
block_ChainRelease
(
p_sys
->
p_buffer_chain
);
vlc_mutex_destroy
(
&
p_sys
->
lock
);
Clean
(
p_sys
);
Clean
(
sys
);
dlclose
(
sys
->
p_so_handle
);
vlc_mutex_destroy
(
&
sys
->
lock
);
free
(
sys
);
}
static
int
Open
(
vlc_object_t
*
obj
)
{
audio_output_t
*
aout
=
(
audio_output_t
*
)
obj
;
aout_sys_t
*
sys
;
SLresult
result
;
aout
->
sys
=
sys
=
calloc
(
1
,
sizeof
(
*
sys
));
if
(
unlikely
(
sys
==
NULL
))
return
VLC_ENOMEM
;
sys
->
p_so_handle
=
dlopen
(
"libOpenSLES.so"
,
RTLD_NOW
);
if
(
sys
->
p_so_handle
==
NULL
)
{
msg_Err
(
aout
,
"Failed to load libOpenSLES"
);
goto
error
;
}
sys
->
slCreateEnginePtr
=
dlsym
(
sys
->
p_so_handle
,
"slCreateEngine"
);
if
(
unlikely
(
sys
->
slCreateEnginePtr
==
NULL
))
{
msg_Err
(
aout
,
"Failed to load symbol slCreateEngine"
);
goto
error
;
}
#define OPENSL_DLSYM(dest, name) \
do { \
const SLInterfaceID *sym = dlsym(sys->p_so_handle, "SL_IID_"name); \
if (unlikely(sym == NULL)) \
{ \
msg_Err(aout, "Failed to load symbol SL_IID_"name); \
goto error; \
} \
sys->dest = *sym; \
} while(0)
OPENSL_DLSYM
(
SL_IID_ANDROIDSIMPLEBUFFERQUEUE
,
"ANDROIDSIMPLEBUFFERQUEUE"
);
OPENSL_DLSYM
(
SL_IID_ENGINE
,
"ENGINE"
);
OPENSL_DLSYM
(
SL_IID_PLAY
,
"PLAY"
);
OPENSL_DLSYM
(
SL_IID_VOLUME
,
"VOLUME"
);
#undef OPENSL_DLSYM
// create engine
result
=
sys
->
slCreateEnginePtr
(
&
sys
->
engineObject
,
0
,
NULL
,
0
,
NULL
,
NULL
);
CHECK_OPENSL_ERROR
(
"Failed to create engine"
);
// realize the engine in synchronous mode
result
=
Realize
(
sys
->
engineObject
,
SL_BOOLEAN_FALSE
);
CHECK_OPENSL_ERROR
(
"Failed to realize engine"
);
// get the engine interface, needed to create other objects
result
=
GetInterface
(
sys
->
engineObject
,
sys
->
SL_IID_ENGINE
,
&
sys
->
engineEngine
);
CHECK_OPENSL_ERROR
(
"Failed to get the engine interface"
);
// create output mix, with environmental reverb specified as a non-required interface
const
SLInterfaceID
ids1
[]
=
{
sys
->
SL_IID_VOLUME
};
const
SLboolean
req1
[]
=
{
SL_BOOLEAN_FALSE
};
result
=
CreateOutputMix
(
sys
->
engineEngine
,
&
sys
->
outputMixObject
,
1
,
ids1
,
req1
);
CHECK_OPENSL_ERROR
(
"Failed to create output mix"
);
// realize the output mix in synchronous mode
result
=
Realize
(
sys
->
outputMixObject
,
SL_BOOLEAN_FALSE
);
CHECK_OPENSL_ERROR
(
"Failed to realize output mix"
);
vlc_mutex_init
(
&
sys
->
lock
);
aout
->
start
=
Start
;
aout
->
stop
=
Stop
;
aout
->
time_get
=
TimeGet
;
aout
->
play
=
Play
;
aout
->
pause
=
Pause
;
aout
->
flush
=
Flush
;
aout
->
mute_set
=
MuteSet
;
aout
->
volume_set
=
VolumeSet
;
/* FIXME: set volume/mute here */
aout
->
start
=
Start
;
aout
->
stop
=
Stop
;
aout
->
time_get
=
TimeGet
;
return
VLC_SUCCESS
;
error:
Clean
(
sys
);
if
(
sys
->
p_so_handle
)
dlclose
(
sys
->
p_so_handle
);
free
(
sys
);
return
VLC_EGENERIC
;
}
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