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
51c132ff
Commit
51c132ff
authored
Sep 09, 2013
by
Guillaume Roguez
Browse files
Merge branch 'video_mixing'
parents
34ace3a7
eca34446
Changes
42
Hide whitespace changes
Inline
Side-by-side
daemon/.gitignore
View file @
51c132ff
build-aux/
aclocal.m4
build-aux
...
...
daemon/src/Makefile.am
View file @
51c132ff
...
...
@@ -86,6 +86,8 @@ libsflphone_la_SOURCES = conference.cpp \
fileutils.cpp
\
scoped_lock.cpp
\
scoped_lock.h
\
sflthread.cpp
\
sflthread.h
\
conference.h
\
voiplink.h
\
preferences.h
\
...
...
daemon/src/client/dbus/video_controls.cpp
View file @
51c132ff
...
...
@@ -32,7 +32,7 @@
#include
"video_controls.h"
#include
"video/libav_utils.h"
#include
"video/video_
preview
.h"
#include
"video/video_
camera
.h"
#include
"account.h"
#include
"logger.h"
#include
"manager.h"
...
...
@@ -42,7 +42,9 @@ const char * const SERVER_PATH = "/org/sflphone/SFLphone/VideoControls";
}
VideoControls
::
VideoControls
(
DBus
::
Connection
&
connection
)
:
DBus
::
ObjectAdaptor
(
connection
,
SERVER_PATH
),
preview_
(),
videoPreference_
()
DBus
::
ObjectAdaptor
(
connection
,
SERVER_PATH
)
,
videoPreview_
()
,
videoPreference_
()
{
// initialize libav libraries
libav_utils
::
sfl_avcodec_init
();
...
...
@@ -157,7 +159,7 @@ VideoControls::getSettings() {
void
VideoControls
::
startPreview
()
{
if
(
p
review_
.
get
())
{
if
(
videoP
review_
.
get
())
{
ERROR
(
"Video preview was already started!"
);
return
;
}
...
...
@@ -166,24 +168,29 @@ VideoControls::startPreview()
using
std
::
string
;
map
<
string
,
string
>
args
(
videoPreference_
.
getSettings
());
p
review_
.
reset
(
new
sfl_video
::
Video
Preview
(
args
));
videoP
review_
.
reset
(
new
sfl_video
::
Video
Camera
(
args
));
}
void
VideoControls
::
stopPreview
()
{
if
(
p
review_
.
get
())
{
if
(
videoP
review_
.
get
())
{
DEBUG
(
"Stopping video preview"
);
p
review_
.
reset
();
videoP
review_
.
reset
();
}
else
{
WARN
(
"Video preview was already stopped"
);
}
}
sfl_video
::
VideoSource
*
VideoControls
::
getVideoPreview
()
{
return
videoPreview_
.
get
();
}
bool
VideoControls
::
hasPreviewStarted
()
{
return
p
review_
.
get
()
!=
0
;
return
videoP
review_
.
get
()
!=
0
;
}
std
::
string
...
...
daemon/src/client/video_controls.h
View file @
51c132ff
...
...
@@ -55,18 +55,18 @@
#endif // HAVE_DBUS
#include
<
tr1/
memory>
// for shared_ptr
#include
<memory>
// for shared_ptr
#include
"video/video_preferences.h"
namespace
sfl_video
{
class
Video
Preview
;
class
Video
Source
;
}
class
VideoControls
:
public
org
::
sflphone
::
SFLphone
::
VideoControls_adaptor
,
public
DBus
::
IntrospectableAdaptor
,
public
DBus
::
ObjectAdaptor
{
private:
std
::
tr1
::
shared_ptr
<
sfl_video
::
Video
Preview
>
p
review_
;
std
::
shared_ptr
<
sfl_video
::
Video
Source
>
videoP
review_
;
VideoPreference
videoPreference_
;
public:
...
...
@@ -126,6 +126,7 @@ class VideoControls : public org::sflphone::SFLphone::VideoControls_adaptor,
void
startPreview
();
void
stopPreview
();
bool
hasPreviewStarted
();
sfl_video
::
VideoSource
*
getVideoPreview
();
};
#endif // VIDEO_CONTROLS_H_
daemon/src/conference.cpp
View file @
51c132ff
...
...
@@ -36,12 +36,30 @@
#include
"audio/audiolayer.h"
#include
"audio/mainbuffer.h"
#ifdef SFL_VIDEO
#include
"client/video_controls.h"
#include
"video/video_camera.h"
#endif
Conference
::
Conference
()
:
id_
(
Manager
::
instance
().
getNewCallID
())
,
confState_
(
ACTIVE_ATTACHED
)
,
participants_
()
#ifdef SFL_VIDEO
,
videoMixer_
()
#endif
{
Recordable
::
initRecFilename
(
id_
);
#ifdef SFL_VIDEO
sfl_video
::
VideoCamera
*
camera
=
static_cast
<
sfl_video
::
VideoCamera
*>
(
Manager
::
instance
().
getVideoControls
()
->
getVideoPreview
());
if
(
camera
)
{
videoMixer_
.
addSource
(
camera
);
camera
->
setMixer
(
&
videoMixer_
);
}
#endif
}
Conference
::
ConferenceState
Conference
::
getState
()
const
...
...
@@ -127,3 +145,9 @@ std::string Conference::getConfID() const {
return
id_
;
}
#ifdef SFL_VIDEO
sfl_video
::
VideoMixer
*
Conference
::
getVideoMixer
()
{
return
&
videoMixer_
;
}
#endif
daemon/src/conference.h
View file @
51c132ff
...
...
@@ -30,11 +30,19 @@
#ifndef CONFERENCE_H
#define CONFERENCE_H
#ifdef HAVE_CONFIG_H
#include
"config.h"
#endif
#include
<set>
#include
<string>
#include
"audio/recordable.h"
#ifdef SFL_VIDEO
#include
"video/video_mixer.h"
#endif
typedef
std
::
set
<
std
::
string
>
ParticipantSet
;
class
Conference
:
public
Recordable
{
...
...
@@ -90,10 +98,19 @@ class Conference : public Recordable {
* Start/stop recording toggle
*/
virtual
bool
toggleRecording
();
#ifdef SFL_VIDEO
sfl_video
::
VideoMixer
*
getVideoMixer
();
#endif
private:
std
::
string
id_
;
ConferenceState
confState_
;
ParticipantSet
participants_
;
#ifdef SFL_VIDEO
sfl_video
::
VideoMixer
videoMixer_
;
#endif
};
#endif
daemon/src/managerimpl.cpp
View file @
51c132ff
...
...
@@ -95,7 +95,8 @@
ManagerImpl
::
ManagerImpl
()
:
preferences
(),
voipPreferences
(),
hookPreference
(),
audioPreference
(),
shortcutPreferences
(),
hasTriedToRegister_
(
false
),
audioCodecFactory
(),
client_
(),
config_
(),
hasTriedToRegister_
(
false
),
audioCodecFactory
(),
client_
(),
config_
(),
currentCallId_
(),
currentCallMutex_
(),
audiodriver_
(
0
),
dtmfKey_
(),
toneMutex_
(),
telephoneTone_
(),
audiofile_
(),
audioLayerMutex_
(),
waitingCalls_
(),
waitingCallsMutex_
(),
path_
(),
...
...
daemon/src/
video/packet_handle
.cpp
→
daemon/src/
sflthread
.cpp
View file @
51c132ff
/*
* Copyright (C) 2011-2013 Savoir-Faire Linux Inc.
* Author: Tristan Matthews <tristan.matthews@savoirfairelinux.com>
* Copyright (C) 2013 Savoir-Faire Linux Inc.
*
* Author: Guillaume Roguez <Guillaume.Roguez@savoirfairelinux.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
...
...
@@ -28,15 +29,65 @@
* as that of the covered work.
*/
#include
"packet_handle.h"
// libav includes
extern
"C"
{
#include
<libavformat/avformat.h>
#include
"sflthread.h"
#include
"logger.h"
#define set_false_atomic(x) static_cast<void>(__sync_fetch_and_and(x, false))
void
*
SFLThread
::
run_
(
void
*
data
)
{
SFLThread
*
obj
=
static_cast
<
SFLThread
*>
(
data
);
obj
->
mainloop_
();
return
nullptr
;
}
void
SFLThread
::
mainloop_
()
{
if
(
setup
())
{
while
(
running_
)
process
();
cleanup
();
}
else
ERROR
(
"setup failed"
);
}
SFLThread
::
SFLThread
()
:
thread_
(),
running_
(
false
)
{}
SFLThread
::~
SFLThread
()
{
if
(
isRunning
())
{
stop
();
join
();
}
}
void
SFLThread
::
start
()
{
if
(
!
running_
)
{
running_
=
true
;
pthread_create
(
&
thread_
,
NULL
,
&
run_
,
this
);
}
}
void
SFLThread
::
stop
()
{
set_false_atomic
(
&
running_
);
}
PacketHandle
::
PacketHandle
(
AVPacket
&
inpacket
)
:
inpacket_
(
inpacket
)
{}
void
SFLThread
::
join
()
{
if
(
thread_
)
pthread_join
(
thread_
,
NULL
);
}
void
SFLThread
::
exit
()
{
stop
();
pthread_exit
(
NULL
);
}
PacketHandle
::~
PacketHandle
()
bool
SFLThread
::
isRunning
()
{
av_free_packet
(
&
inpacket_
)
;
return
running_
;
}
daemon/src/
video/video_preview
.h
→
daemon/src/
sflthread
.h
View file @
51c132ff
/*
* Copyright (C) 2011-2013 Savoir-Faire Linux Inc.
* Author: Tristan Matthews <tristan.matthews@savoirfairelinux.com>
* Copyright (C) 2013 Savoir-Faire Linux Inc.
*
* Author: Guillaume Roguez <Guillaume.Roguez@savoirfairelinux.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
...
...
@@ -28,26 +29,34 @@
* as that of the covered work.
*/
#ifndef __VIDEO_PREVIEW_H__
#define __VIDEO_PREVIEW_H__
#ifndef __SFLTHREAD_H__
#define __SFLTHREAD_H__
#include
<pthread.h>
class
SFLThread
{
public:
SFLThread
();
virtual
~
SFLThread
();
#include
<tr1/memory>
#include
<string>
#include
<map>
void
start
();
void
stop
();
void
join
();
bool
isRunning
();
namespace
sfl_video
{
protected:
virtual
bool
setup
()
{
return
true
;
};
virtual
void
process
()
{};
virtual
void
cleanup
()
{};
class
VideoReceiveThread
;
void
exit
()
;
class
VideoPreview
{
public:
VideoPreview
(
const
std
::
map
<
std
::
string
,
std
::
string
>
&
args
);
~
VideoPreview
()
;
private:
static
void
*
run_
(
void
*
);
void
mainloop_
(
);
pthread_t
thread_
;
private:
std
::
map
<
std
::
string
,
std
::
string
>
args_
;
std
::
tr1
::
shared_ptr
<
VideoReceiveThread
>
receiveThread_
;
bool
running_
;
};
}
#endif // __
VIDEO_PREVIEW
_H__
#endif // __
SFLTHREAD
_H__
daemon/src/sip/sipvoiplink.cpp
View file @
51c132ff
...
...
@@ -1914,7 +1914,6 @@ void sdp_media_update_cb(pjsip_inv_session *inv, pj_status_t status)
call
->
getAudioRtp
().
setDtmfPayloadType
(
sdpSession
->
getTelephoneEventType
());
#ifdef SFL_VIDEO
Manager
::
instance
().
getVideoControls
()
->
stopPreview
();
call
->
getVideoRtp
().
updateSDP
(
*
call
->
getLocalSDP
());
call
->
getVideoRtp
().
updateDestination
(
call
->
getLocalSDP
()
->
getRemoteIP
(),
call
->
getLocalSDP
()
->
getRemoteVideoPort
());
call
->
getVideoRtp
().
start
(
call
->
getLocalSDP
()
->
getLocalVideoPort
());
...
...
daemon/src/video/Makefile.am
View file @
51c132ff
...
...
@@ -3,15 +3,23 @@ include $(top_srcdir)/globals.mak
SUBDIRS
=
test
noinst_LTLIBRARIES
=
libvideo.la
libvideo_la_SOURCES
=
libav_utils.cpp libav_utils.h video_rtp_session.cpp
\
video_rtp_session.h video_send_thread.h video_send_thread.cpp
\
video_receive_thread.h video_receive_thread.cpp
\
video_preview.h video_preview.cpp video_v4l2.cpp
\
video_v4l2_list.cpp video_v4l2.h video_v4l2_list.h
\
video_preferences.h video_preferences.cpp
\
packet_handle.h packet_handle.cpp check.h shm_header.h
\
shm_sink.cpp shm_sink.h video_provider.h
\
socket_pair.cpp socket_pair.h
libvideo_la_SOURCES
=
\
video_v4l2.cpp
\
video_v4l2_list.cpp video_v4l2.h video_v4l2_list.h
\
video_preferences.cpp video_preferences.h
\
video_base.cpp video_base.h
\
video_scaler.cpp video_scaler.h
\
video_decoder.cpp video_decoder.h
\
video_encoder.cpp video_encoder.h
\
video_mixer.cpp video_mixer.h
\
socket_pair.cpp socket_pair.h
\
shm_sink.cpp shm_sink.h
\
video_camera.cpp video_camera.h
\
video_receive_thread.cpp video_receive_thread.h
\
video_send_thread.cpp video_send_thread.h
\
video_rtp_session.cpp video_rtp_session.h
\
check.h shm_header.h video_provider.h
\
libav_utils.cpp libav_utils.h libav_deps.h
libvideo_la_LIBADD
=
@LIBAVCODEC_LIBS@ @LIBAVFORMAT_LIBS@ @LIBAVDEVICE_LIBS@ @LIBSWSCALE_LIBS@ @LIBAVUTIL_LIBS@ @UDEV_LIBS@
...
...
daemon/src/video/check.h
View file @
51c132ff
...
...
@@ -32,13 +32,16 @@
#define CHECK_H_
#include
"logger.h"
#include
"sflthread.h"
// cast to void to avoid compiler warnings about unused return values
#define set_false_atomic(x) static_cast<void>(__sync_fetch_and_and(x, false))
#define set_true_atomic(x) static_cast<void>(__sync_fetch_and_or(x, true))
#define atomic_increment(x) static_cast<void>(__sync_fetch_and_add(x, 1))
#define atomic_decrement(x) static_cast<void>(__sync_fetch_and_sub(x, 1))
// If condition A is false, print the error message in M and exit thread
#define EXIT_IF_FAIL(A, M, ...) if (!(A)) { ERROR(M, ##__VA_ARGS__); set_false_atomic(&threadRunning_); pthread_exit(NULL); }
#define EXIT_IF_FAIL(A, M, ...) if (!(A)) { \
ERROR(M, ##__VA_ARGS__); this->exit(); }
#endif // CHECK_H_
daemon/src/video/libav_deps.h
0 → 100644
View file @
51c132ff
/*
* Copyright (C) 2013 Savoir-Faire Linux Inc.
* Author: Guillaume Roguez <Guillaume.Roguez@savoirfairelinux.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 3 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.
*
* Additional permission under GNU GPL version 3 section 7:
*
* If you modify this program, or any covered work, by linking or
* combining it with the OpenSSL project's OpenSSL library (or a
* modified version of that library), containing parts covered by the
* terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
* grants you additional permission to convey the resulting work.
* Corresponding Source for a non-source form of such a combination
* shall include the source code for the parts of OpenSSL used as well
* as that of the covered work.
*/
#ifndef __LIBAV_DEPS_H__
#define __LIBAV_DEPS_H__
extern
"C"
{
#include
<libavcodec/avcodec.h>
#include
<libavformat/avformat.h>
#include
<libavdevice/avdevice.h>
#include
<libswscale/swscale.h>
#include
<libavutil/opt.h>
}
#include
"libav_utils.h"
/* LIBAVFORMAT_VERSION_CHECK checks for the right version of libav and FFmpeg
* a is the major version
* b and c the minor and micro versions of libav
* d and e the minor and micro versions of FFmpeg */
#define LIBAVFORMAT_VERSION_CHECK( a, b, c, d, e ) \
( (LIBAVFORMAT_VERSION_MICRO < 100 && LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT( a, b, c ) ) || \
(LIBAVFORMAT_VERSION_MICRO >= 100 && LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT( a, d, e ) ) )
#define HAVE_SDP_CUSTOM_IO LIBAVFORMAT_VERSION_CHECK(54,20,3,59,103)
#if (LIBAVUTIL_VERSION_MAJOR < 53) && !defined(FF_API_PIX_FMT)
#define AVPixelFormat PixelFormat
#endif
#if (LIBAVCODEC_VERSION_MAJOR < 54) \
|| ((LIBAVCODEC_VERSION_MAJOR == 54) && (LIBAVCODEC_VERSION_MINOR < 28))
#define avcodec_free_frame(x) av_freep(x)
#endif
#endif // __LIBAV_DEPS_H__
daemon/src/video/libav_utils.cpp
View file @
51c132ff
...
...
@@ -2,6 +2,7 @@
* Copyright (C) 2004-2013 Savoir-Faire Linux Inc.
* Author: Tristan Matthews <tristan.matthews@savoirfairelinux.com>
* Author: Luca Barbato <lu_zero@gentoo.org>
* Author: Guillaume Roguez <Guillaume.Roguez@savoirfairelinux.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
...
...
@@ -29,18 +30,15 @@
* as that of the covered work.
*/
#include
"libav_utils.h"
#include
"libav_deps.h"
#include
"video_base.h"
#include
"logger.h"
#include
<vector>
#include
<algorithm>
#include
<string>
#include
<iostream>
#include
"logger.h"
extern
"C"
{
#include
<libavcodec/avcodec.h>
#include
<libavformat/avformat.h>
#include
<libavdevice/avdevice.h>
}
namespace
{
using
std
::
string
;
...
...
@@ -174,4 +172,29 @@ getDefaultCodecs()
return
result
;
}
int
libav_pixel_format
(
int
fmt
)
{
switch
(
fmt
)
{
case
VIDEO_PIXFMT_BGRA
:
return
PIX_FMT_BGRA
;
case
VIDEO_PIXFMT_YUV420P
:
return
PIX_FMT_YUV420P
;
}
return
fmt
;
}
int
sfl_pixel_format
(
int
fmt
)
{
switch
(
fmt
)
{
case
PIX_FMT_YUV420P
:
return
VIDEO_PIXFMT_YUV420P
;
}
return
fmt
;
}
void
sfl_url_split
(
const
char
*
url
,
char
*
hostname
,
size_t
hostname_size
,
int
*
port
,
char
*
path
,
size_t
path_size
)
{
av_url_split
(
NULL
,
0
,
NULL
,
0
,
hostname
,
hostname_size
,
port
,
path
,
path_size
,
url
);
}
}
// end namespace libav_utils
daemon/src/video/libav_utils.h
View file @
51c132ff
...
...
@@ -35,20 +35,25 @@
#include
<map>
#include
<string>
namespace
libav_utils
{
void
sfl_avcodec_init
();
void
sfl_avcodec_init
();
int
libav_pixel_format
(
int
fmt
);
int
sfl_pixel_format
(
int
fmt
);
std
::
map
<
std
::
string
,
std
::
string
>
encodersMap
();
std
::
map
<
std
::
string
,
std
::
string
>
encodersMap
();
std
::
vector
<
std
::
string
>
getVideoCodecList
();
std
::
vector
<
std
::
string
>
getVideoCodecList
();
std
::
vector
<
std
::
map
<
std
::
string
,
std
::
string
>
>
getDefaultCodecs
();
std
::
vector
<
std
::
map
<
std
::
string
,
std
::
string
>
>
getDefaultCodecs
();
const
char
*
const
DEFAULT_H264_PROFILE_LEVEL_ID
=
"profile-level-id=428014"
;
const
char
*
const
MAX_H264_PROFILE_LEVEL_ID
=
"profile-level-id=640034"
;
void
sfl_url_split
(
const
char
*
url
,
char
*
hostname
,
size_t
hostname_size
,
int
*
port
,
char
*
path
,
size_t
path_size
);
}
#endif // __LIBAV_UTILS_H__
daemon/src/video/shm_sink.cpp
View file @
51c132ff
...
...
@@ -62,8 +62,7 @@ SHMSink::~SHMSink()
stop
();
}
bool
SHMSink
::
start
()
bool
SHMSink
::
start
()
{
if
(
fd_
!=
-
1
)
{
ERROR
(
"fd must be -1"
);
...
...
@@ -123,8 +122,7 @@ SHMSink::start()
return
true
;
}
bool
SHMSink
::
stop
()
bool
SHMSink
::
stop
()
{
if
(
fd_
>=
0
)
close
(
fd_
);
...
...
@@ -143,8 +141,7 @@ SHMSink::stop()
return
true
;
}
bool
SHMSink
::
resize_area
(
size_t
desired_length
)
bool
SHMSink
::
resize_area
(
size_t
desired_length
)
{
if
(
desired_length
<=
shm_area_len_
)
return
true
;
...
...
daemon/src/video/socket_pair.cpp
View file @
51c132ff
...
...
@@ -30,9 +30,12 @@
* as that of the covered work.
*/
#include
"libav_deps.h"
#include
"socket_pair.h"
#include
"scoped_lock.h"
#include
"libav_utils.h"
#include
"logger.h"
#include
<cstring>
#include
<stdexcept>
#include
<unistd.h>
...
...
@@ -42,11 +45,6 @@
#include
<netdb.h>
extern
"C"
{
#include
<libavutil/avstring.h>
#include
<libavformat/avformat.h>
}
namespace
{
int
ff_network_wait_fd
(
int
fd
)
...
...
@@ -54,16 +52,16 @@ int ff_network_wait_fd(int fd)
struct
pollfd
p
=
{
fd
,
POLLOUT
,
0
};
int
ret
;
ret
=
poll
(
&
p
,
1
,
100
);
return
ret
<
0
?
errno
:
p
.
revents
&
(
POLLOUT
|
POLLERR
|
POLLHUP
)
?
0
:
AVERROR
(
EAGAIN
)
;
return
ret
<
0
?
errno
:
p
.
revents
&
(
POLLOUT
|
POLLERR
|
POLLHUP
)
?
0
:
-
EAGAIN
;
}
struct
addrinfo
*
udp_resolve_host