diff --git a/daemon/src/dbus/video_controls-introspec.xml b/daemon/src/dbus/video_controls-introspec.xml index 518b6a8b169490e513c2e752592274a877f5872d..72b676456413cbd1761f1513f488dcbd2f351068 100644 --- a/daemon/src/dbus/video_controls-introspec.xml +++ b/daemon/src/dbus/video_controls-introspec.xml @@ -126,8 +126,11 @@ <tp:docstring>Signal triggered by changes in the detected v4l2 devices, e.g. a camera being unplugged.</tp:docstring> </signal> - <signal name="startedEvent" tp:name-for-bindings="startedEvent"> + <signal name="startedDecoding" tp:name-for-bindings="startedDecoding"> <tp:docstring>Signal triggered when video is available in a shared memory buffer.</tp:docstring> + <arg type="s" name="id"> + <tp:docstring>The ID of the call associated with the video, or "local" in the case of local video</tp:docstring> + </arg> <arg type="s" name="shmPath"> <tp:docstring>The path of the newly created shared memory</tp:docstring> </arg> @@ -139,9 +142,14 @@ </arg> </signal> - <signal name="stoppedEvent" tp:name-for-bindings="stoppedEvent"> + <signal name="stoppedDecoding" tp:name-for-bindings="stoppedDecoding"> <tp:docstring>Signal triggered when video is no longer available in a shared memory buffer.</tp:docstring> - <arg type="s" name="shmPath"></arg> + <arg type="s" name="id"> + <tp:docstring>The ID of the call associated with the video, or "local" in the case of local video</tp:docstring> + </arg> + <arg type="s" name="shmPath"> + <tp:docstring>The path of the newly created shared memory</tp:docstring> + </arg> </signal> <method name="getCurrentCodecName" tp:name-for-bindings="getCurrentCodecName"> diff --git a/daemon/src/sip/sipcall.cpp b/daemon/src/sip/sipcall.cpp index 0ea0d48ba6ad0fbfbe7166b301f6bc833b280fc2..34c56000ec714e3798516e088fae61dcc6e5a0c5 100644 --- a/daemon/src/sip/sipcall.cpp +++ b/daemon/src/sip/sipcall.cpp @@ -49,7 +49,8 @@ SIPCall::SIPCall(const std::string& id, Call::CallType type, , inv(NULL) , audiortp_(this) #ifdef SFL_VIDEO - , videortp_(Manager::instance().getDbusManager()->getVideoControls()->getSettings()) + // The ID is used to associate video streams to calls + , videortp_(id, Manager::instance().getDbusManager()->getVideoControls()->getSettings()) #endif , pool_(pj_pool_create(&caching_pool->factory, id.c_str(), INITIAL_SIZE, INCREMENT_SIZE, NULL)) , local_sdp_(new Sdp(pool_)) diff --git a/daemon/src/video/test/test_video_rtp.cpp b/daemon/src/video/test/test_video_rtp.cpp index e113c7750bf36db4d17c28470a11c8b456d6463d..0cfaec39ec3e31a536d66f89f73df33e5e35113a 100644 --- a/daemon/src/video/test/test_video_rtp.cpp +++ b/daemon/src/video/test/test_video_rtp.cpp @@ -39,7 +39,7 @@ int main () { VideoPreference preference; - sfl_video::VideoRtpSession session(preference.getSettings()); + sfl_video::VideoRtpSession session("test", preference.getSettings()); session.start(); sleep(10); session.stop(); diff --git a/daemon/src/video/video_preview.cpp b/daemon/src/video/video_preview.cpp index 849a65ac577a9e7ea0686ffb904180b95119ee14..114bd73512629b102a4a73c5465adb2779a092ca 100644 --- a/daemon/src/video/video_preview.cpp +++ b/daemon/src/video/video_preview.cpp @@ -41,7 +41,8 @@ namespace sfl_video { VideoPreview::VideoPreview(const std::map<std::string, std::string> &args) : args_(args), receiveThread_() { - receiveThread_.reset(new VideoReceiveThread(args_)); + const char * const LOCAL_ID = "local"; + receiveThread_.reset(new VideoReceiveThread(LOCAL_ID, args_)); receiveThread_->start(); } diff --git a/daemon/src/video/video_receive_thread.cpp b/daemon/src/video/video_receive_thread.cpp index d40f7c12bc2fcee74763e3fd7d0f7764fe79df22..71d6e2d350f97f6ce2fafad6b03b062b861819a3 100644 --- a/daemon/src/video/video_receive_thread.cpp +++ b/daemon/src/video/video_receive_thread.cpp @@ -182,7 +182,7 @@ void VideoReceiveThread::setup() bufferSize_ = getBufferSize(dstWidth_, dstHeight_, VIDEO_RGB_FORMAT); EXIT_IF_FAIL(sink_.start(), "Cannot start shared memory sink"); - Manager::instance().getVideoControls()->startedEvent(sink_.openedName(), dstWidth_, dstHeight_); + Manager::instance().getVideoControls()->startedDecoding(id_, sink_.openedName(), dstWidth_, dstHeight_); } void VideoReceiveThread::createScalingContext() @@ -196,11 +196,11 @@ void VideoReceiveThread::createScalingContext() EXIT_IF_FAIL(imgConvertCtx_, "Cannot init the conversion context!"); } -VideoReceiveThread::VideoReceiveThread(const std::map<string, string> &args) : +VideoReceiveThread::VideoReceiveThread(const std::string &id, const std::map<string, string> &args) : args_(args), frameNumber_(0), decoderCtx_(0), rawFrame_(0), scaledPicture_(0), streamIndex_(-1), inputCtx_(0), imgConvertCtx_(0), dstWidth_(0), dstHeight_(0), sink_(), receiving_(false), sdpFilename_(), - bufferSize_(0) + bufferSize_(0), id_(id) {} /// Copies and scales our rendered frame to the buffer pointed to by data @@ -236,6 +236,7 @@ void VideoReceiveThread::run() ERROR("Couldn't read frame : %s\n", strerror(ret)); break; } + // Guarantee that we free the packet every iteration PacketHandle inpacket_handle(inpacket); // is this a packet from the video stream? @@ -255,7 +256,7 @@ void VideoReceiveThread::run() VideoReceiveThread::~VideoReceiveThread() { - Manager::instance().getVideoControls()->stoppedEvent(sink_.openedName()); + Manager::instance().getVideoControls()->stoppedDecoding(id_, sink_.openedName()); receiving_ = false; ost::Thread::terminate(); diff --git a/daemon/src/video/video_receive_thread.h b/daemon/src/video/video_receive_thread.h index e82064bd99bc00c5adfac899551128a4707a1dd2..272953c2e7b1e1821b3d9dab8d72ddd263608651 100644 --- a/daemon/src/video/video_receive_thread.h +++ b/daemon/src/video/video_receive_thread.h @@ -70,13 +70,14 @@ class VideoReceiveThread : public ost::Thread { bool receiving_; std::string sdpFilename_; size_t bufferSize_; + const std::string id_; void setup(); void createScalingContext(); void loadSDP(); void fill_buffer(void *data); public: - VideoReceiveThread(const std::map<std::string, std::string> &args); + VideoReceiveThread(const std::string &id, const std::map<std::string, std::string> &args); virtual ~VideoReceiveThread(); virtual void run(); }; diff --git a/daemon/src/video/video_rtp_session.cpp b/daemon/src/video/video_rtp_session.cpp index 5f92ae7ae590ad08301d3cc4a96a53d749bf5e0e..e6e72958fe8256ce108a60cfd797338113b7192f 100644 --- a/daemon/src/video/video_rtp_session.cpp +++ b/daemon/src/video/video_rtp_session.cpp @@ -44,9 +44,9 @@ namespace sfl_video { using std::map; using std::string; -VideoRtpSession::VideoRtpSession(const map<string, string> &txArgs) : +VideoRtpSession::VideoRtpSession(const string &callID, const map<string, string> &txArgs) : sendThread_(), receiveThread_(), txArgs_(txArgs), - rxArgs_(), sending_(false), receiving_(false) + rxArgs_(), sending_(false), receiving_(false), callID_(callID) { // FIXME: bitrate must be configurable txArgs_["bitrate"] = "500000"; @@ -142,7 +142,7 @@ void VideoRtpSession::start() if (receiving_) { if (receiveThread_.get()) WARN("Restarting video receiver"); - receiveThread_.reset(new VideoReceiveThread(rxArgs_)); + receiveThread_.reset(new VideoReceiveThread(callID_, rxArgs_)); receiveThread_->start(); } else diff --git a/daemon/src/video/video_rtp_session.h b/daemon/src/video/video_rtp_session.h index bca21a05189aceddc92ce7ba758465853ebf572e..8b4dcf3d22ecdbe49d82bde3e4b7bc2b7f0ed8ea 100644 --- a/daemon/src/video/video_rtp_session.h +++ b/daemon/src/video/video_rtp_session.h @@ -44,8 +44,8 @@ class VideoReceiveThread; class VideoRtpSession { public: - VideoRtpSession(const std::map<std::string, std::string> &txArgs); - + VideoRtpSession(const std::string &callID, + const std::map<std::string, std::string> &txArgs); void start(); void stop(); void updateDestination(const std::string &destination, @@ -59,6 +59,7 @@ class VideoRtpSession { std::map<std::string, std::string> rxArgs_; bool sending_; bool receiving_; + const std::string callID_; }; } diff --git a/gnome/src/dbus/dbus.c b/gnome/src/dbus/dbus.c index 58b45a26d62c8c90c0fe011f7da5441e9271ca2d..2b742f1c7415d576ace7d8a451466f0123613e35 100644 --- a/gnome/src/dbus/dbus.c +++ b/gnome/src/dbus/dbus.c @@ -735,16 +735,16 @@ gboolean dbus_connect(GError **error) g_cclosure_user_marshal_VOID__STRING_STRING_BOOL, G_TYPE_NONE, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_INVALID); - /* Register STRING STRING INT Marshaller */ - dbus_g_object_register_marshaller( - g_cclosure_user_marshal_VOID__STRING_STRING_INT, G_TYPE_NONE, - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INVALID); - /* Register STRING STRING STRING Marshaller */ dbus_g_object_register_marshaller( g_cclosure_user_marshal_VOID__STRING_STRING_STRING, G_TYPE_NONE, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID); + /* Register STRING STRING INT INT Marshaller */ + dbus_g_object_register_marshaller( + g_cclosure_user_marshal_VOID__STRING_STRING_INT_INT, G_TYPE_NONE, + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT, G_TYPE_INVALID); + DEBUG("Adding callmanager Dbus signals"); /* Incoming call */ @@ -892,7 +892,6 @@ gboolean dbus_connect(GError **error) const gchar *videocontrols_interface = "org.sflphone.SFLphone.VideoControls"; video_proxy = dbus_g_proxy_new_for_name(connection, dbus_message_bus_name, videocontrols_object_instance, videocontrols_interface); - g_assert(video_proxy != NULL); if (video_proxy == NULL) { ERROR("Error: Failed to connect to %s", videocontrols_object_instance); return FALSE; @@ -902,16 +901,16 @@ gboolean dbus_connect(GError **error) dbus_g_proxy_connect_signal(video_proxy, "deviceEvent", G_CALLBACK(video_device_event_cb), NULL, NULL); - dbus_g_proxy_add_signal(video_proxy, "startedEvent", G_TYPE_STRING, - G_TYPE_INT, G_TYPE_INT, G_TYPE_INVALID); - dbus_g_proxy_connect_signal(video_proxy, "startedEvent", - G_CALLBACK(started_video_event_cb), NULL, + dbus_g_proxy_add_signal(video_proxy, "startedDecoding", G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT, G_TYPE_INVALID); + dbus_g_proxy_connect_signal(video_proxy, "startedDecoding", + G_CALLBACK(started_decoding_video_cb), NULL, NULL); - dbus_g_proxy_add_signal(video_proxy, "stoppedEvent", - G_TYPE_STRING, G_TYPE_INVALID); - dbus_g_proxy_connect_signal(video_proxy, "stoppedEvent", - G_CALLBACK(stopped_video_event_cb), + dbus_g_proxy_add_signal(video_proxy, "stoppedDecoding", + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID); + dbus_g_proxy_connect_signal(video_proxy, "stoppedDecoding", + G_CALLBACK(stopped_decoding_video_cb), NULL, NULL); #endif diff --git a/gnome/src/dbus/marshaller.list b/gnome/src/dbus/marshaller.list index 72ef972346614b38037512b173f31c31aa9d1883..f8df0b825f09af1c4ca17498a97fbf6591645f9f 100644 --- a/gnome/src/dbus/marshaller.list +++ b/gnome/src/dbus/marshaller.list @@ -6,5 +6,5 @@ VOID:STRING,DOUBLE VOID:STRING,STRING VOID:STRING,INT,INT VOID:STRING,STRING,BOOL -VOID:STRING,STRING,INT VOID:STRING,STRING,STRING +VOID:STRING,STRING,INT,INT diff --git a/gnome/src/dbus/video_controls-introspec.xml b/gnome/src/dbus/video_controls-introspec.xml index 518b6a8b169490e513c2e752592274a877f5872d..72b676456413cbd1761f1513f488dcbd2f351068 100644 --- a/gnome/src/dbus/video_controls-introspec.xml +++ b/gnome/src/dbus/video_controls-introspec.xml @@ -126,8 +126,11 @@ <tp:docstring>Signal triggered by changes in the detected v4l2 devices, e.g. a camera being unplugged.</tp:docstring> </signal> - <signal name="startedEvent" tp:name-for-bindings="startedEvent"> + <signal name="startedDecoding" tp:name-for-bindings="startedDecoding"> <tp:docstring>Signal triggered when video is available in a shared memory buffer.</tp:docstring> + <arg type="s" name="id"> + <tp:docstring>The ID of the call associated with the video, or "local" in the case of local video</tp:docstring> + </arg> <arg type="s" name="shmPath"> <tp:docstring>The path of the newly created shared memory</tp:docstring> </arg> @@ -139,9 +142,14 @@ </arg> </signal> - <signal name="stoppedEvent" tp:name-for-bindings="stoppedEvent"> + <signal name="stoppedDecoding" tp:name-for-bindings="stoppedDecoding"> <tp:docstring>Signal triggered when video is no longer available in a shared memory buffer.</tp:docstring> - <arg type="s" name="shmPath"></arg> + <arg type="s" name="id"> + <tp:docstring>The ID of the call associated with the video, or "local" in the case of local video</tp:docstring> + </arg> + <arg type="s" name="shmPath"> + <tp:docstring>The path of the newly created shared memory</tp:docstring> + </arg> </signal> <method name="getCurrentCodecName" tp:name-for-bindings="getCurrentCodecName"> diff --git a/gnome/src/video/video_renderer.c b/gnome/src/video/video_renderer.c index 60843bc82546e0a81d9a16963bc2b5f71e2b1119..f52ffeb29a834c36d7b5b250783930f21ec18782 100644 --- a/gnome/src/video/video_renderer.c +++ b/gnome/src/video/video_renderer.c @@ -477,9 +477,9 @@ try_clutter_init() #undef PRINT_ERR } -void started_video_event_cb(DBusGProxy *proxy UNUSED, gchar *shm_path, - gint width, gint height, - GError *error UNUSED, gpointer userdata UNUSED) +void started_decoding_video_cb(DBusGProxy *proxy UNUSED, + gchar *id, gchar *shm_path, gint width, gint height, + GError *error UNUSED, gpointer userdata UNUSED) { if (!video_window) { video_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); @@ -529,9 +529,9 @@ void started_video_event_cb(DBusGProxy *proxy UNUSED, gchar *shm_path, } void -stopped_video_event_cb(DBusGProxy *proxy UNUSED, gchar *shm_path, GError *error UNUSED, gpointer userdata UNUSED) +stopped_decoding_video_cb(DBusGProxy *proxy UNUSED, gchar *id, gchar *shm_path, GError *error UNUSED, gpointer userdata UNUSED) { - DEBUG("Video stopped for shm:%s", shm_path); + DEBUG("Video stopped for id %s, shm path %s", id, shm_path); if (video_renderer_global) { if (video_window) { diff --git a/gnome/src/video/video_renderer.h b/gnome/src/video/video_renderer.h index b210657c48730815e3fdd437405fe25c2eea8fa6..77c79c37cd21952e1028cb148bd21acde689ac1a 100644 --- a/gnome/src/video/video_renderer.h +++ b/gnome/src/video/video_renderer.h @@ -69,10 +69,11 @@ video_renderer_run(VideoRenderer *self); void video_renderer_stop(VideoRenderer *self); -void started_video_event_cb(DBusGProxy *proxy, gchar *shm_path, - gint width, gint height, GError *error, - gpointer userdata); -void stopped_video_event_cb(DBusGProxy *proxy, gchar *shm_path, GError *error, gpointer userdata); +void started_decoding_video_cb(DBusGProxy *proxy, gchar *id, gchar *shm_path, + gint width, gint height, GError *error, + gpointer userdata); +void stopped_decoding_video_cb(DBusGProxy *proxy, gchar *id, gchar *shm_path, + GError *error, gpointer userdata); /* Try to init the gtk clutter backend, returns TRUE on success, FALSE otherwise */ gboolean try_clutter_init();