diff --git a/src/chat/encryption/lime-x3dh-server-engine.cpp b/src/chat/encryption/lime-x3dh-server-engine.cpp
index 0df1c281168d78f3e9c950d07a54ca44af93d572..56be1e058349a498e6c0ca75764f1cd2bd0fbe5c 100644
--- a/src/chat/encryption/lime-x3dh-server-engine.cpp
+++ b/src/chat/encryption/lime-x3dh-server-engine.cpp
@@ -114,9 +114,16 @@ bool LimeX3dhUtils::isMessageEncrypted(const Content *internalContent) {
 	const ContentType & incomingContentType = internalContent->getContentType();
 	ContentType expectedContentType = ContentType::Encrypted;
 	
-	if (incomingContentType == expectedContentType && incomingContentType.getParameter("protocol").getValue() == "\"application/lime\""){
-		return true;
+	if (incomingContentType == expectedContentType){
+		string protocol = incomingContentType.getParameter("protocol").getValue();
+		if (protocol == "\"application/lime\""){
+			return true;
+		}else if (protocol.empty()){
+			lWarning() << "Accepting possible legacy lime message.";
+			return true;
+		}
 	}
+	
 	return false;
 }
 
diff --git a/src/conference/session/video-mixer.cpp b/src/conference/session/video-mixer.cpp
index da29299dc0339e908e66c6a6c22a2b48e358f9aa..69676e28143c60fdcd65262aa5463479b404ce30 100644
--- a/src/conference/session/video-mixer.cpp
+++ b/src/conference/session/video-mixer.cpp
@@ -38,11 +38,12 @@ MS2VideoMixer::MS2VideoMixer(MixerSession & session) : StreamMixer(session), MS2
 
 void MS2VideoMixer::connectEndpoint(Stream *vs, MSVideoEndpoint *endpoint, bool thumbnail){
 	ms_video_endpoint_set_user_data(endpoint, &vs->getGroup());
+	
 	if (thumbnail) {
-		lInfo() << "mix to all add endpoint to thumbnail";
+		lInfo() << *this << "Adding endpoint to thumbnail mixer.";
 		ms_video_conference_add_member(mConferenceThumbnail, endpoint);
 	} else {
-		lInfo() << "mix to all add endpoint to mConferenceMix";
+		lInfo() << *this << "Adding endpoint to main mixer.";
 		ms_video_conference_add_member(mConferenceMix, endpoint);
 	}
 }
@@ -58,6 +59,7 @@ void MS2VideoMixer::setFocus(StreamsGroup *sg){
 	// used by mConferenceMix
 	MSVideoEndpoint *ep = nullptr;
 	
+	lInfo() << *this << ": video focus requested for " << *sg; 
 	if (sg == nullptr){
 		ep = mMainLocalEndpoint;
 	}else{
@@ -72,15 +74,19 @@ void MS2VideoMixer::setFocus(StreamsGroup *sg){
 	}
 	if (ep){
 		ms_video_conference_set_focus(mConferenceMix, ep);
-	}else if (ms_video_conference_get_size(mConferenceMix) >= 2){
-		/* else this participant has no video, so set focus on a "no webcam" placeholder.
-		 * However, if there is one or two participants, don't do this and let the ms2 mixer cross the streams.
-		 */
-		MSVideoEndpoint *video_placeholder_ep = ms_video_conference_get_video_placeholder_member(mConferenceMix);
-		if (video_placeholder_ep) {
-			ms_video_conference_set_focus(mConferenceMix, video_placeholder_ep);
+	}else {
+		if (ms_video_conference_get_size(mConferenceMix) >= 2){
+			/* else this participant has no video, so set focus on a "no webcam" placeholder.
+			* However, if there is one or two participants, don't do this and let the ms2 mixer cross the streams.
+			*/
+			lInfo() << *this <<  "Showing video placeholder, participant has no video.";
+			MSVideoEndpoint *video_placeholder_ep = ms_video_conference_get_video_placeholder_member(mConferenceMix);
+			if (video_placeholder_ep) {
+				ms_video_conference_set_focus(mConferenceMix, video_placeholder_ep);
+			}
+		}else{
+			lInfo() << *this <<  "Not using video placeholder, participant count <= 2.";
 		}
-
 	}
 }
 
@@ -114,7 +120,7 @@ void MS2VideoMixer::createLocalMember(bool isThumbnail) {
 	
 	memset(&io, 0, sizeof(io));
 	
-	video_stream_enable_thumbnail(vs, isThumbnail);
+	video_stream_set_content(vs, isThumbnail ? MSVideoContentThumbnail : MSVideoContentDefault);
 	const LinphoneVideoDefinition *vdef = linphone_core_get_preferred_video_definition(mSession.getCCore());
 	pt = rtp_profile_get_payload(mLocalDummyProfile, sVP8PayloadTypeNumber);
 	pt->normal_bitrate =  outputBandwidth; /* Is it really needed ?*/
diff --git a/src/conference/session/video-stream.cpp b/src/conference/session/video-stream.cpp
index aed978dec2a4020e389549648eb94bf7a17aaac2..4faa9591731304a0756569797c61618548ec11e7 100644
--- a/src/conference/session/video-stream.cpp
+++ b/src/conference/session/video-stream.cpp
@@ -71,7 +71,20 @@ void MS2VideoStream::configure(const OfferAnswerContext &params) {
 	const auto & content = localDesc.getContent();
 	const auto & label = localDesc.getLabel();
 	if (mStream) {
-		video_stream_enable_thumbnail(mStream, (content.compare("thumbnail") == 0));
+		MSVideoContent mscontent = MSVideoContentDefault;
+		if (content == "thumbnail") {
+			mscontent = MSVideoContentThumbnail;
+		}else if (content == "speaker"){
+			mscontent = MSVideoContentSpeaker;
+		}
+		if (getVideoMixer() != nullptr && mscontent == MSVideoContentDefault
+			&& media_stream_get_direction(&mStream->ms) == MediaStreamSendRecv){
+			/* When handling a conference call, in absence of content attribute and if stream is sendrecv,
+			 * assume the target content is speaker (active speaker stream)*/
+			lInfo() << "No content given, assuming active speaker mode.";
+			mscontent = MSVideoContentSpeaker;
+		}
+		video_stream_set_content(mStream, mscontent);
 		if (!label.empty()) {
 			video_stream_set_label(mStream, label.c_str());
 		}
@@ -244,7 +257,7 @@ void MS2VideoStream::render(const OfferAnswerContext & ctx, CallSession::State t
 	}
 
 	bool basicChangesHandled = handleBasicChanges(ctx, targetState);
-	bool isThumbnail = (content.compare("thumbnail") == 0);
+	bool isThumbnail = (content == "thumbnail");
 
 	if (basicChangesHandled) {
 		bool muted = mMuted;
@@ -402,10 +415,7 @@ void MS2VideoStream::render(const OfferAnswerContext & ctx, CallSession::State t
 	else
 		video_stream_set_display_mode(mStream, stringToVideoDisplayMode(linphone_config_get_string(linphone_core_get_config(getCCore()), "video", "main_display_mode", "Hybrid")));
 
-	video_stream_enable_thumbnail(mStream, isThumbnail);
-	if (!label.empty()) {
-		video_stream_set_label(mStream, label.c_str());
-	}
+	configure(ctx);
 
 	if (getCCore()->video_conf.reuse_preview_source && source) {
 		lInfo() << "video_stream_start_with_source kept: " << source;
@@ -454,10 +464,15 @@ void MS2VideoStream::render(const OfferAnswerContext & ctx, CallSession::State t
 				io.input.type = MSResourceItc;
 				io.input.itc = itcFilter;
 				media_stream_set_max_network_bitrate(&mStream->ms, 80000);
-				if (vdef) {
-					MSVideoSize vsize = {160,120};
-					video_stream_set_sent_video_size(mStream, vsize);
-				}
+				
+				MSVideoSize vsize = {160,120};
+				video_stream_set_content(mStream, MSVideoContentThumbnail);
+				/* TODO The fps should be taken automatically from the main stream, however this is not implemented.
+				 * Meanwhile, force a medium 20 fps so that video encoder gets configured with realistic values.
+				 */
+				video_stream_set_fps(mStream, 20);
+				video_stream_set_sent_video_size(mStream, vsize);
+				
 				video_stream_start_from_io(mStream, videoProfile, dest.rtpAddr.c_str(), dest.rtpPort, dest.rtcpAddr.c_str(), dest.rtcpPort, usedPt, &io);
 			} else {
 				video_stream_start_from_io(mStream, videoProfile, dest.rtpAddr.c_str(), dest.rtpPort, dest.rtcpAddr.c_str(), dest.rtcpPort, usedPt, &io);
@@ -507,9 +522,8 @@ void MS2VideoStream::render(const OfferAnswerContext & ctx, CallSession::State t
 	}
 
 	if (videoMixer && (targetState == CallSession::State::StreamsRunning)){
-		const bool_t isRemote = ((!mStream->label && content.empty()) || !videoMixer->getVideoStream()) ? TRUE : (dir == MediaStreamSendOnly || videoMixer->getLocalParticipantLabel().compare(L_C_TO_STRING(mStream->label)) != 0);
-		mConferenceEndpoint = ms_video_endpoint_get_from_stream(mStream, isRemote);
-		videoMixer->connectEndpoint(this, mConferenceEndpoint, video_stream_thumbnail_enabled(mStream));
+		mConferenceEndpoint = ms_video_endpoint_get_from_stream(mStream, true);
+		videoMixer->connectEndpoint(this, mConferenceEndpoint, video_stream_get_content(mStream) == MSVideoContentThumbnail);
 	}
 }
 
diff --git a/tester/shared_tester_functions.cpp b/tester/shared_tester_functions.cpp
index d0f94058d5028a339726c7f061c52bf42386e4fe..fc2bccff5d55bb7710489260e135f809aabfb218 100644
--- a/tester/shared_tester_functions.cpp
+++ b/tester/shared_tester_functions.cpp
@@ -509,7 +509,7 @@ void _linphone_conference_video_change(bctbx_list_t *lcs, LinphoneCoreManager *m
 	linphone_core_enable_mic(mgr2->lc, FALSE);
 	linphone_core_enable_mic(mgr1->lc, TRUE);
 	wait_for_list(lcs, NULL, 0, 5000);
-	BC_ASSERT_FALSE(linphone_call_compare_video_color(call1, c3, MediaStreamSendRecv, ""));
+	BC_ASSERT_TRUE(linphone_call_compare_video_color(call1, c3, MediaStreamSendRecv, ""));
 	BC_ASSERT_FALSE(linphone_call_compare_video_color(call1, c1, MediaStreamSendRecv, ""));
 }