Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
savoirfairelinux
jami-daemon
Commits
786cd2d1
Commit
786cd2d1
authored
Sep 01, 2011
by
Tristan Matthews
Browse files
* #6849: show error window if codecs are missing, instead of dying
parent
4b32b763
Changes
9
Hide whitespace changes
Inline
Side-by-side
daemon/src/audio/codecs/audiocodecfactory.cpp
View file @
786cd2d1
...
...
@@ -31,112 +31,110 @@
* as that of the covered work.
*/
#include
<iostream>
#include
<cstdlib>
#include
"audiocodecfactory.h"
#include
<cstdlib>
#include
<algorithm>
// for std::find
#include
"fileutils.h"
AudioCodecFactory
::
AudioCodecFactory
()
:
_CodecsMap
(),
_defaultCodecOrder
(),
_Cache
(),
_CodecInMemory
()
{
}
void
AudioCodecFactory
::
init
()
{
std
::
vector
<
sfl
::
Codec
*>
CodecDynamicList
=
scanCodecDirectory
();
if
(
CodecDynamicList
.
size
()
==
0
)
typedef
std
::
vector
<
sfl
::
Codec
*>
CodecVector
;
CodecVector
codecDynamicList
(
scanCodecDirectory
());
if
(
codecDynamicList
.
empty
())
_error
(
"Error - No codecs available"
);
for
(
size_t
i
=
0
;
i
<
CodecDynamicList
.
size
()
;
i
++
)
{
_CodecsMap
[
(
AudioCodecType
)
CodecDynamicList
[
i
]
->
getPayloadType
()
]
=
CodecDynamicList
[
i
];
_debug
(
"Loaded codec %s"
,
CodecDynamicList
[
i
]
->
getMimeSubtype
().
c_str
());
else
{
for
(
CodecVector
::
const_iterator
iter
=
codecDynamicList
.
begin
();
iter
!=
codecDynamicList
.
end
()
;
++
iter
)
{
codecsMap_
[
(
AudioCodecType
)
(
*
iter
)
->
getPayloadType
()
]
=
*
iter
;
_debug
(
"Loaded codec %s"
,
(
*
iter
)
->
getMimeSubtype
().
c_str
());
}
}
}
void
AudioCodecFactory
::
setDefaultOrder
()
{
_
defaultCodecOrder
.
clear
();
CodecsMap
::
iterator
iter
;
for
(
iter
=
_C
odecsMap
.
begin
();
iter
!=
_C
odecsMap
.
end
();
++
iter
)
_
defaultCodecOrder
.
push_back
(
iter
->
first
);
defaultCodecOrder
_
.
clear
();
CodecsMap
::
const_
iterator
iter
;
for
(
iter
=
c
odecsMap
_
.
begin
();
iter
!=
c
odecsMap
_
.
end
();
++
iter
)
defaultCodecOrder
_
.
push_back
(
iter
->
first
);
}
std
::
string
AudioCodecFactory
::
getCodecName
(
AudioCodecType
payload
)
{
CodecsMap
::
iterator
iter
=
_CodecsMap
.
find
(
payload
);
if
(
iter
!=
_CodecsMap
.
end
())
return
(
iter
->
second
->
getMimeSubtype
());
CodecsMap
::
const_iterator
iter
=
codecsMap_
.
find
(
payload
);
return
""
;
if
(
iter
!=
codecsMap_
.
end
())
return
iter
->
second
->
getMimeSubtype
();
else
return
""
;
}
sfl
::
Codec
*
AudioCodecFactory
::
getCodec
(
AudioCodecType
payload
)
{
CodecsMap
::
iterator
iter
=
_C
odecsMap
.
find
(
payload
);
CodecsMap
::
const_
iterator
iter
=
c
odecsMap
_
.
find
(
payload
);
if
(
iter
!=
_C
odecsMap
.
end
())
if
(
iter
!=
c
odecsMap
_
.
end
())
return
iter
->
second
;
_error
(
"CodecDescriptor: cannot find codec %i"
,
payload
);
return
NULL
;
else
{
_error
(
"CodecDescriptor: cannot find codec %i"
,
payload
);
return
NULL
;
}
}
double
AudioCodecFactory
::
getBitRate
(
AudioCodecType
payload
)
{
CodecsMap
::
iterator
iter
=
_C
odecsMap
.
find
(
payload
);
CodecsMap
::
const_
iterator
iter
=
c
odecsMap
_
.
find
(
payload
);
if
(
iter
!=
_C
odecsMap
.
end
())
return
(
iter
->
second
->
getBitRate
()
)
;
return
0.0
;
if
(
iter
!=
c
odecsMap
_
.
end
())
return
iter
->
second
->
getBitRate
();
else
return
0.0
;
}
int
AudioCodecFactory
::
getSampleRate
(
AudioCodecType
payload
)
const
{
CodecsMap
::
const_iterator
iter
=
_C
odecsMap
.
find
(
payload
);
CodecsMap
::
const_iterator
iter
=
c
odecsMap
_
.
find
(
payload
);
if
(
iter
!=
_C
odecsMap
.
end
())
if
(
iter
!=
c
odecsMap
_
.
end
())
return
iter
->
second
->
getClockRate
();
return
0
;
else
return
0
;
}
void
AudioCodecFactory
::
saveActiveCodecs
(
const
std
::
vector
<
std
::
string
>&
list
)
{
_
defaultCodecOrder
.
clear
();
defaultCodecOrder
_
.
clear
();
// list contains the ordered payload of active codecs picked by the user
// we used the CodecOrder vector to save the order.
for
(
s
ize_t
i
=
0
;
i
<
list
.
size
();
i
++
)
{
int
payload
=
std
::
atoi
(
list
[
i
].
data
());
for
(
s
td
::
vector
<
std
::
string
>::
const_iterator
iter
=
list
.
begin
();
iter
!=
list
.
end
();
++
iter
)
{
int
payload
=
std
::
atoi
(
iter
->
c_str
());
if
(
isCodecLoaded
(
payload
))
_
defaultCodecOrder
.
push_back
(
(
AudioCodecType
)
payload
);
defaultCodecOrder
_
.
push_back
(
(
AudioCodecType
)
payload
);
}
}
void
AudioCodecFactory
::
deleteHandlePointer
(
void
)
AudioCodecFactory
::
deleteHandlePointer
(
)
{
for
(
std
::
vector
<
CodecHandlePointer
>::
const_iterator
iter
=
_C
odecInMemory
.
begin
();
iter
!=
_C
odecInMemory
.
end
();
++
iter
)
c
odecInMemory
_
.
begin
();
iter
!=
c
odecInMemory
_
.
end
();
++
iter
)
unloadCodec
(
*
iter
);
_C
odecInMemory
.
clear
();
c
odecInMemory
_
.
clear
();
}
std
::
vector
<
sfl
::
Codec
*>
AudioCodecFactory
::
scanCodecDirectory
(
void
)
std
::
vector
<
sfl
::
Codec
*>
AudioCodecFactory
::
scanCodecDirectory
(
)
{
std
::
vector
<
sfl
::
Codec
*>
codecs
;
std
::
vector
<
std
::
string
>
dirToScan
;
dirToScan
.
push_back
(
std
::
string
(
HOMEDIR
)
+
DIR_SEPARATOR_STR
"."
PROGDIR
"/"
);
dirToScan
.
push_back
(
CODECS_DIR
"/"
);
dirToScan
.
push_back
(
std
::
string
(
HOMEDIR
)
+
DIR_SEPARATOR_STR
"."
PROGDIR
"/"
);
dirToScan
.
push_back
(
CODECS_DIR
"/"
);
const
char
*
envDir
=
getenv
(
"CODECS_PATH"
);
if
(
envDir
)
dirToScan
.
push_back
(
std
::
string
(
envDir
)
+
DIR_SEPARATOR_STR
);
...
...
@@ -162,7 +160,7 @@ std::vector<sfl::Codec*> AudioCodecFactory::scanCodecDirectory (void)
sfl
::
Codec
*
audioCodec
=
loadCodec
(
dirStr
+
file
);
if
(
audioCodec
)
{
codecs
.
push_back
(
audioCodec
);
_
Cache
.
push_back
(
file
);
lib
Cache
_
.
push_back
(
file
);
}
}
}
...
...
@@ -173,12 +171,12 @@ std::vector<sfl::Codec*> AudioCodecFactory::scanCodecDirectory (void)
return
codecs
;
}
sfl
::
Codec
*
AudioCodecFactory
::
loadCodec
(
std
::
string
path
)
sfl
::
Codec
*
AudioCodecFactory
::
loadCodec
(
const
std
::
string
&
path
)
{
void
*
codecHandle
=
dlopen
(
path
.
c_str
()
,
RTLD_LAZY
);
if
(
!
codecHandle
)
{
_error
(
"%s
\n
"
,
dlerror
());
return
NULL
;
_error
(
"%s
\n
"
,
dlerror
());
return
NULL
;
}
dlerror
();
...
...
@@ -186,13 +184,13 @@ sfl::Codec* AudioCodecFactory::loadCodec (std::string path)
create_t
*
createCodec
=
(
create_t
*
)
dlsym
(
codecHandle
,
"create"
);
char
*
error
=
dlerror
();
if
(
error
)
{
_error
(
"%s
\n
"
,
error
);
return
NULL
;
_error
(
"%s
\n
"
,
error
);
return
NULL
;
}
sfl
::
Codec
*
a
=
createCodec
();
_C
odecInMemory
.
push_back
(
CodecHandlePointer
(
a
,
codecHandle
));
c
odecInMemory
_
.
push_back
(
CodecHandlePointer
(
a
,
codecHandle
));
return
a
;
}
...
...
@@ -204,8 +202,8 @@ void AudioCodecFactory::unloadCodec (CodecHandlePointer p)
char
*
error
=
dlerror
();
if
(
error
)
{
_error
(
"%s
\n
"
,
error
);
return
;
_error
(
"%s
\n
"
,
error
);
return
;
}
destroyCodec
(
p
.
first
);
...
...
@@ -217,34 +215,22 @@ sfl::Codec* AudioCodecFactory::instantiateCodec (AudioCodecType payload)
{
std
::
vector
<
CodecHandlePointer
>::
iterator
iter
;
for
(
iter
=
_C
odecInMemory
.
begin
();
iter
!=
_C
odecInMemory
.
end
();
++
iter
)
{
for
(
iter
=
c
odecInMemory
_
.
begin
();
iter
!=
c
odecInMemory
_
.
end
();
++
iter
)
{
if
(
iter
->
first
->
getPayloadType
()
==
payload
)
{
create_t
*
createCodec
=
(
create_t
*
)
dlsym
(
iter
->
second
,
"create"
);
char
*
error
=
dlerror
();
if
(
error
)
_error
(
"%s
\n
"
,
error
);
_error
(
"%s
\n
"
,
error
);
else
return
createCodec
();
return
createCodec
();
}
}
return
NULL
;
}
sfl
::
Codec
*
AudioCodecFactory
::
getFirstCodecAvailable
(
void
)
{
CodecsMap
::
iterator
iter
=
_CodecsMap
.
begin
();
if
(
iter
!=
_CodecsMap
.
end
())
return
iter
->
second
;
else
return
NULL
;
}
bool
AudioCodecFactory
::
seemsValid
(
std
::
string
lib
)
bool
AudioCodecFactory
::
seemsValid
(
const
std
::
string
&
lib
)
{
// The name of the shared library seems valid <==> it looks like libcodec_xxx.so
// We check this
...
...
@@ -280,24 +266,20 @@ bool AudioCodecFactory::seemsValid (std::string lib)
if
(
lib
.
substr
(
lib
.
length
()
-
suffix
.
length
()
,
suffix
.
length
())
==
suffix
)
return
true
;
return
false
;
return
false
;
}
bool
AudioCodecFactory
::
alreadyInCache
(
std
::
string
lib
)
AudioCodecFactory
::
alreadyInCache
(
const
std
::
string
&
lib
)
{
for
(
size_t
i
=
0
;
i
<
_Cache
.
size
()
;
i
++
)
if
(
_Cache
[
i
]
==
lib
)
return
true
;
return
false
;
return
std
::
find
(
libCache_
.
begin
(),
libCache_
.
end
(),
lib
)
!=
libCache_
.
end
();
}
bool
AudioCodecFactory
::
isCodecLoaded
(
int
payload
)
{
CodecsMap
::
iterator
iter
;
for
(
iter
=
_C
odecsMap
.
begin
();
iter
!=
_C
odecsMap
.
end
();
++
iter
)
if
(
iter
->
first
==
payload
)
CodecsMap
::
const_
iterator
iter
;
for
(
iter
=
c
odecsMap
_
.
begin
();
iter
!=
c
odecsMap
_
.
end
();
++
iter
)
if
(
iter
->
first
==
payload
)
return
true
;
return
false
;
...
...
@@ -309,17 +291,17 @@ std::vector <std::string> AudioCodecFactory::getCodecSpecifications (const int32
std
::
stringstream
ss
;
// Add the name of the codec
v
.
push_back
(
getCodecName
(
(
AudioCodecType
)
payload
));
v
.
push_back
(
getCodecName
(
static_cast
<
AudioCodecType
>
(
payload
))
)
;
// Add the sample rate
ss
<<
getSampleRate
(
(
AudioCodecType
)
payload
);
v
.
push_back
(
(
ss
.
str
())
.
data
())
;
ss
.
str
(
""
);
ss
<<
getSampleRate
(
static_cast
<
AudioCodecType
>
(
payload
)
)
;
v
.
push_back
(
ss
.
str
());
ss
.
str
(
""
);
// Add the bit rate
ss
<<
getBitRate
(
(
AudioCodecType
)
payload
);
v
.
push_back
(
(
ss
.
str
())
.
data
())
;
ss
.
str
(
""
);
ss
<<
getBitRate
(
static_cast
<
AudioCodecType
>
(
payload
)
)
;
v
.
push_back
(
ss
.
str
());
ss
.
str
(
""
);
return
v
;
}
daemon/src/audio/codecs/audiocodecfactory.h
View file @
786cd2d1
...
...
@@ -40,30 +40,23 @@
#include
"global.h"
#include
"audiocodec.h"
/** Enable us to keep the handle pointer on the codec dynamicaly loaded so that we could destroy when we dont need it anymore */
typedef
std
::
pair
<
sfl
::
Codec
*
,
void
*>
CodecHandlePointer
;
/** Maps a pointer on an audiocodec object to a payload */
typedef
std
::
map
<
AudioCodecType
,
sfl
::
Codec
*>
CodecsMap
;
/*
* @file codecdescriptor.h
* @brief Handle audio codecs, load them in memory
*/
/** Maps a pointer on an audiocodec object to a payload */
typedef
std
::
map
<
AudioCodecType
,
sfl
::
Codec
*>
CodecsMap
;
class
AudioCodecFactory
{
public:
/**
* Constructor
*/
AudioCodecFactory
();
/**
* Accessor to data structures
* @return CodecsMap& The available codec
*/
const
CodecsMap
&
getCodecsMap
()
const
{
return
_C
odecsMap
;
return
c
odecsMap
_
;
}
/**
...
...
@@ -117,13 +110,6 @@ class AudioCodecFactory
*/
void
deleteHandlePointer
(
void
);
/**
* Get the first element of the CodecsMap struct.
* i.e the one with the lowest payload
* @return AudioCodec The pointer on the codec object
*/
sfl
::
Codec
*
getFirstCodecAvailable
(
void
);
/**
* Instantiate a codec, used in AudioRTP to get an instance of Codec per call
* @param CodecHandlePointer The map containing the pointer on the object and the pointer on the handle function
...
...
@@ -147,20 +133,23 @@ class AudioCodecFactory
bool
isCodecLoaded
(
int
payload
);
private:
/** Enable us to keep the handle pointer on the codec dynamicaly loaded so that we could destroy when we dont need it anymore */
typedef
std
::
pair
<
sfl
::
Codec
*
,
void
*>
CodecHandlePointer
;
/**
* Scan the installation directory ( --prefix configure option )
* And load the dynamic library
* @return std::vector<AudioCodec*> The list of the codec object successfully loaded in memory
*/
std
::
vector
<
sfl
::
Codec
*>
scanCodecDirectory
(
void
);
std
::
vector
<
sfl
::
Codec
*>
scanCodecDirectory
();
/**
* Load a codec
* @param std::string The path of the shared ( dynamic ) library.
* @return AudioCodec* the pointer of the object loaded.
*/
sfl
::
Codec
*
loadCodec
(
std
::
string
);
sfl
::
Codec
*
loadCodec
(
const
std
::
string
&
path
);
/**
* Unload a codec
...
...
@@ -174,7 +163,7 @@ class AudioCodecFactory
* @return bool True if the file name begins with libcodec_ and ends with .so
* false otherwise
*/
bool
seemsValid
(
std
::
string
);
static
bool
seemsValid
(
const
std
::
string
&
lib
);
/**
* Check if the codecs shared library has already been scanned during the session
...
...
@@ -183,28 +172,28 @@ class AudioCodecFactory
* @return bool True if the codecs has been scanned
* false otherwise
*/
bool
alreadyInCache
(
std
::
string
);
bool
alreadyInCache
(
const
std
::
string
&
lib
);
/**
* Map the payload of a codec and the object associated ( AudioCodec * )
*/
CodecsMap
_C
odecsMap
;
CodecsMap
c
odecsMap
_
;
/**
* Vector containing a default order for the codecs
*/
CodecOrder
_
defaultCodecOrder
;
CodecOrder
defaultCodecOrder
_
;
/**
* Vector containing the complete name of the codec shared library scanned
*/
std
::
vector
<
std
::
string
>
_
Cache
;
std
::
vector
<
std
::
string
>
lib
Cache
_
;
/**
* Vector containing pairs
* Pair between pointer on function handle and pointer on audiocodec object
*/
std
::
vector
<
CodecHandlePointer
>
_C
odecInMemory
;
std
::
vector
<
CodecHandlePointer
>
c
odecInMemory
_
;
};
#endif // __CODEC_DESCRIPTOR_H__
daemon/src/dbus/configurationmanager.cpp
View file @
786cd2d1
...
...
@@ -173,6 +173,9 @@ std::vector<std::string> ConfigurationManager::getAudioCodecList (void)
list
.
push_back
(
ss
.
str
());
}
if
(
list
.
empty
())
errorAlert
(
CODECS_NOT_LOADED
);
return
list
;
}
...
...
@@ -189,7 +192,10 @@ std::vector<std::string> ConfigurationManager::getSupportedTlsMethod (void)
std
::
vector
<
std
::
string
>
ConfigurationManager
::
getAudioCodecDetails
(
const
int32_t
&
payload
)
{
return
Manager
::
instance
().
getAudioCodecFactory
().
getCodecSpecifications
(
payload
);
std
::
vector
<
std
::
string
>
result
(
Manager
::
instance
().
getAudioCodecFactory
().
getCodecSpecifications
(
payload
));
if
(
result
.
empty
())
errorAlert
(
CODECS_NOT_LOADED
);
return
result
;
}
std
::
vector
<
std
::
string
>
ConfigurationManager
::
getActiveAudioCodecList
(
const
std
::
string
&
accountID
)
...
...
daemon/src/global.h
View file @
786cd2d1
...
...
@@ -113,10 +113,11 @@ static const SOUND_FORMAT INT32 = 0x8;
#define NOTIFY_ALL TRUE_STR
/** Desktop notification level 0: never notify */
// Error codes for error handling
#define NO_ERROR 0x0000
/** No error - Everything alright */
#define ALSA_CAPTURE_DEVICE 0x0001
/** Error while opening capture device */
#define ALSA_PLAYBACK_DEVICE 0x0010
/** Error while opening playback device */
#define PULSEAUDIO_NOT_RUNNING 0x0100
/** Pulseaudio is not running */
#define NO_ERROR 0x0000
/** No error - Everything alright */
#define ALSA_CAPTURE_DEVICE 0x0001
/** Error while opening capture device */
#define ALSA_PLAYBACK_DEVICE 0x0010
/** Error while opening playback device */
#define PULSEAUDIO_NOT_RUNNING 0x0100
/** Pulseaudio is not running */
#define CODECS_NOT_LOADED 0x1000
/** Codecs not found */
#define ALSA 0
#define PULSEAUDIO 1
...
...
daemon/src/managerimpl.cpp
View file @
786cd2d1
...
...
@@ -2294,11 +2294,6 @@ int32_t ManagerImpl::getAudioManager (void) const
}
void
ManagerImpl
::
notifyErrClient
(
int32_t
errCode
)
{
_dbus
.
getConfigurationManager
()
->
errorAlert
(
errCode
);
}
int
ManagerImpl
::
getAudioDeviceIndex
(
const
std
::
string
&
name
)
{
int
soundCardIndex
=
0
;
...
...
daemon/src/managerimpl.h
View file @
786cd2d1
...
...
@@ -756,13 +756,6 @@ class ManagerImpl
*/
std
::
vector
<
::
std
::
string
>
getActiveCodecList
(
void
)
const
;
/*
* Notify the client that an error occured
* @param errCode The error code. Could be: ALSA_CAPTURE_ERROR
* ALSA_PLAYBACK_ERROR
*/
void
notifyErrClient
(
int32_t
errCode
);
/**
* Retrieve in the configuration tree the value of a parameter in a specific section
* @param section The section to look in
...
...
gnome/src/codeclist.c
View file @
786cd2d1
...
...
@@ -87,12 +87,8 @@ void codec_capabilities_load (void)
}
// If we didn't load any codecs, problem ...
if
(
g_queue_get_length
(
codecsCapabilities
)
==
0
)
{
// Error message
if
(
g_queue_get_length
(
codecsCapabilities
)
==
0
)
ERROR
(
"No audio codecs found"
);
dbus_unregister
(
getpid
());
exit
(
1
);
}
}
void
account_create_codec_list
(
account_t
**
acc
)
...
...
gnome/src/dbus/dbus.c
View file @
786cd2d1
...
...
@@ -514,6 +514,9 @@ error_alert (DBusGProxy *proxy UNUSED, int err, void * foo UNUSED)
case
PULSEAUDIO_NOT_RUNNING
:
msg
=
_
(
"Pulseaudio notification
\n\n
Pulseaudio is not running"
);
break
;
case
CODECS_NOT_LOADED
:
msg
=
_
(
"Codecs notification
\n\n
Codecs not found"
);
break
;
default:
return
;
}
...
...
gnome/src/sflphone_const.h
View file @
786cd2d1
...
...
@@ -127,11 +127,13 @@
#define SHORTCUT_TOGGLEHOLD "toggleHold"
/** Error while opening capture device */
#define ALSA_CAPTURE_DEVICE 0x0001
#define ALSA_CAPTURE_DEVICE
0x0001
/** Error while opening playback device */
#define ALSA_PLAYBACK_DEVICE
0x0010
#define ALSA_PLAYBACK_DEVICE 0x0010
/** Error pulseaudio */
#define PULSEAUDIO_NOT_RUNNING 0x0100
#define PULSEAUDIO_NOT_RUNNING 0x0100
/** Error codecs not loaded */
#define CODECS_NOT_LOADED 0x1000
/** Tone to play when no voice mails */
#define TONE_WITHOUT_MESSAGE 0
...
...
Write
Preview
Supports
Markdown
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