Commit 43131a72 authored by Sylvain Berfini's avatar Sylvain Berfini 🎩

Auto resize Android video preview is enabled & is an instance of TextureView

parent aa4e84ab
......@@ -5033,6 +5033,14 @@ void linphone_core_migrate_logs_from_rc_to_db(LinphoneCore *lc) {
* Video related functions *
******************************************************************************/
void linphone_core_resize_video_preview(LinphoneCore *lc, int width, int height) {
bool_t auto_camera_preview_resize = !!lp_config_get_int(lc->config, "video", "auto_resize_preview_to_keep_ratio", 0);
if (!auto_camera_preview_resize) return;
bctbx_message("Resizing video preview to: %ix%i", width, height);
#ifdef VIDEO_ENABLED
getPlatformHelpers(lc)->resizeVideoPreview(width, height);
#endif
}
#ifdef VIDEO_ENABLED
static void video_filter_callback(void *userdata, struct _MSFilter *f, unsigned int id, void *arg) {
......@@ -5051,6 +5059,13 @@ static void video_filter_callback(void *userdata, struct _MSFilter *f, unsigned
}
break;
}
case MS_CAMERA_PREVIEW_SIZE_CHANGED: {
MSVideoSize size = *(MSVideoSize *)arg;
bctbx_message("Camera preview size changed: %ix%i", size.width, size.height);
LinphoneCore *lc = (LinphoneCore *)userdata;
linphone_core_resize_video_preview(lc, size.width, size.height);
break;
}
}
}
#endif
......@@ -5109,7 +5124,7 @@ static void toggle_video_preview(LinphoneCore *lc, bool_t val){
}
if (lc->preview_window_id != NULL) {
video_preview_set_native_window_id(lc->previewstream, lc->preview_window_id);
}
}
video_preview_set_fps(lc->previewstream, linphone_core_get_preferred_framerate(lc));
if (linphone_core_qrcode_video_preview_enabled(lc)) {
video_preview_enable_qrcode(lc->previewstream, TRUE);
......@@ -5121,9 +5136,13 @@ static void toggle_video_preview(LinphoneCore *lc, bool_t val){
if (video_preview_qrcode_enabled(lc->previewstream)) {
ms_filter_add_notify_callback(lc->previewstream->qrcode, video_filter_callback, lc, TRUE);
}
MSVideoSize size = video_preview_get_current_size(lc->previewstream);
linphone_core_resize_video_preview(lc, size.width, size.height);
ms_filter_add_notify_callback(lc->previewstream->source, video_filter_callback, lc, TRUE);
}
} else {
if (lc->previewstream != NULL) {
ms_filter_remove_notify_callback(lc->previewstream->source, video_filter_callback, lc);
video_preview_stop(lc->previewstream);
lc->previewstream = NULL;
}
......
......@@ -614,6 +614,7 @@ void _linphone_core_set_log_handler(OrtpLogFunc logfunc);
void _linphone_core_set_native_preview_window_id(LinphoneCore *lc, void *id);
void _linphone_core_set_native_video_window_id(LinphoneCore *lc, void *id);
void linphone_core_resize_video_preview(LinphoneCore *lc, int width, int height);
LinphoneAccountCreatorCbs * linphone_account_creator_cbs_new(void);
void linphone_account_creator_set_current_callbacks(LinphoneAccountCreator *creator, LinphoneAccountCreatorCbs *cbs);
......
......@@ -3040,6 +3040,18 @@ void MediaSessionPrivate::startTextStream () {
lInfo() << "No valid text stream defined";
}
static void video_filter_callback(void *userdata, struct _MSFilter *f, unsigned int id, void *arg) {
switch(id) {
case MS_CAMERA_PREVIEW_SIZE_CHANGED: {
MSVideoSize size = *(MSVideoSize *)arg;
bctbx_message("Camera preview size changed: %ix%i", size.width, size.height);
LinphoneCore *lc = (LinphoneCore *)userdata;
linphone_core_resize_video_preview(lc, size.width, size.height);
break;
}
}
}
void MediaSessionPrivate::startVideoStream (CallSession::State targetState) {
#ifdef VIDEO_ENABLED
L_Q();
......@@ -3156,6 +3168,11 @@ void MediaSessionPrivate::startVideoStream (CallSession::State targetState) {
usedPt, &io);
}
}
MSVideoSize size = video_preview_get_current_size(videoStream);
linphone_core_resize_video_preview(q->getCore()->getCCore(), size.width, size.height);
ms_filter_add_notify_callback(videoStream->source, video_filter_callback, q->getCore()->getCCore(), FALSE);
ms_media_stream_sessions_set_encryption_mandatory(&videoStream->ms.sessions, isEncryptionMandatory());
if (listener)
listener->onResetFirstVideoFrameDecoded(q->getSharedFromThis());
......@@ -4548,6 +4565,7 @@ LinphoneStatus MediaSession::update (const MediaSessionParams *msp, const string
video_stream_change_camera(d->videoStream, getCore()->getCCore()->video_conf.device);
else
video_stream_update_video_params(d->videoStream);
linphone_core_resize_video_preview(getCore()->getCCore(), vsize.width, vsize.height);
}
#endif
}
......
......@@ -53,6 +53,7 @@ public:
void setVideoPreviewWindow (void *windowId) override;
void setVideoWindow (void *windowId) override;
void resizeVideoPreview (int width, int height) override;
bool isNetworkReachable () override;
void onWifiOnlyEnabled (bool enabled) override;
......@@ -87,6 +88,7 @@ private:
jmethodID mGetNativeLibraryDirId = nullptr;
jmethodID mSetNativeVideoWindowId = nullptr;
jmethodID mSetNativePreviewVideoWindowId = nullptr;
jmethodID mResizeVideoPreview = nullptr;
jmethodID mOnLinphoneCoreStartId = nullptr;
jmethodID mOnLinphoneCoreStopId = nullptr;
jmethodID mOnWifiOnlyEnabledId = nullptr;
......@@ -140,6 +142,7 @@ AndroidPlatformHelpers::AndroidPlatformHelpers (std::shared_ptr<LinphonePrivate:
mGetNativeLibraryDirId = getMethodId(env, klass, "getNativeLibraryDir", "()Ljava/lang/String;");
mSetNativeVideoWindowId = getMethodId(env, klass, "setVideoRenderingView", "(Ljava/lang/Object;)V");
mSetNativePreviewVideoWindowId = getMethodId(env, klass, "setVideoPreviewView", "(Ljava/lang/Object;)V");
mResizeVideoPreview = getMethodId(env, klass, "resizeVideoPreview", "(II)V");
mOnLinphoneCoreStartId = getMethodId(env, klass, "onLinphoneCoreStart", "(Z)V");
mOnLinphoneCoreStopId = getMethodId(env, klass, "onLinphoneCoreStop", "()V");
mOnWifiOnlyEnabledId = getMethodId(env, klass, "onWifiOnlyEnabled", "(Z)V");
......@@ -275,6 +278,16 @@ void AndroidPlatformHelpers::setVideoWindow (void *windowId) {
}
}
void AndroidPlatformHelpers::resizeVideoPreview (int width, int height) {
JNIEnv *env = ms_get_jni_env();
if (env && mJavaHelper) {
string displayFilter = L_C_TO_STRING(linphone_core_get_video_display_filter(getCore()->getCCore()));
if ((displayFilter.empty() || displayFilter == "MSAndroidTextureDisplay")) {
env->CallVoidMethod(mJavaHelper, mResizeVideoPreview, width, height);
}
}
}
// -----------------------------------------------------------------------------
bool AndroidPlatformHelpers::isNetworkReachable() {
......
......@@ -68,6 +68,7 @@ public:
void setVideoPreviewWindow (void *windowId) override {}
string getDownloadPath () override {return Utils::getEmptyConstRefObject<string>();}
void setVideoWindow (void *windowId) override {}
void resizeVideoPreview (int width, int height) override {}
bool isNetworkReachable () override;
void onWifiOnlyEnabled (bool enabled) override;
......
......@@ -94,6 +94,7 @@ void GenericPlatformHelpers::setVideoPreviewWindow (void *windowId) {}
void GenericPlatformHelpers::setVideoWindow (void *windowId) {}
void GenericPlatformHelpers::resizeVideoPreview (int width, int height) {}
bool GenericPlatformHelpers::isNetworkReachable () {
return mNetworkReachable;
......
......@@ -63,6 +63,7 @@ public:
virtual void setVideoPreviewWindow (void *windowId) = 0;
virtual std::string getDownloadPath () = 0;
virtual void setVideoWindow (void *windowId) = 0;
virtual void resizeVideoPreview (int width, int height) = 0;
// This method shall retrieve DNS server list from the platform and assign it to the core.
virtual bool isNetworkReachable () = 0;
......@@ -111,6 +112,7 @@ public:
void setVideoPreviewWindow (void *windowId) override;
void setVideoWindow (void *windowId) override;
void resizeVideoPreview (int width, int height) override;
bool isNetworkReachable () override;
void onWifiOnlyEnabled (bool enabled) override;
......
......@@ -50,6 +50,7 @@ import android.os.PowerManager.WakeLock;
import android.os.Build;
import android.view.Surface;
import android.view.TextureView;
import android.view.ViewGroup;
import java.lang.Runnable;
import java.net.InetAddress;
......@@ -83,6 +84,7 @@ public class AndroidPlatformHelper {
private String mUserCertificatePath;
private Surface mSurface;
private SurfaceTexture mSurfaceTexture;
private TextureView mPreviewTextureView;
private boolean mDozeModeEnabled;
private BroadcastReceiver mDozeReceiver;
private IntentFilter mDozeIntentFilter;
......@@ -358,8 +360,9 @@ public class AndroidPlatformHelper {
"or enable compatibility mode by setting displaytype=MSAndroidOpenGLDisplay in the [video] section your linphonerc factory configuration file" +
"so you can keep using your existing application code for managing video views.");
}
TextureView textureView = (TextureView)view;
textureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
mPreviewTextureView = (TextureView)view;
ViewGroup.LayoutParams lp = mPreviewTextureView.getLayoutParams();
mPreviewTextureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
Log.i("[Platform Helper] Preview window surface is available");
......@@ -368,13 +371,14 @@ public class AndroidPlatformHelper {
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
Log.i("[Platform Helper] Preview window surface is no longer available");
setNativePreviewWindowId(mNativePtr, null);
mPreviewTextureView = null;
return false;
}
......@@ -383,9 +387,9 @@ public class AndroidPlatformHelper {
}
});
if (textureView.isAvailable()) {
if (mPreviewTextureView.isAvailable()) {
Log.i("[Platform Helper] Preview window surface is available");
setNativePreviewWindowId(mNativePtr, textureView.getSurfaceTexture());
setNativePreviewWindowId(mNativePtr, mPreviewTextureView.getSurfaceTexture());
}
}
......@@ -434,6 +438,61 @@ public class AndroidPlatformHelper {
}
}
public synchronized void resizeVideoPreview(int width, int height) {
if (mPreviewTextureView != null) {
Log.i("[Platform Helper] Video preview size is now: " + width + "x" + height);
ViewGroup.LayoutParams lp = mPreviewTextureView.getLayoutParams();
Log.i("[Platform Helper] Preview layout params are: " + lp.width + ", " + lp.height);
int maxWidth, maxHeight;
if (lp.width == ViewGroup.LayoutParams.MATCH_PARENT) {
maxWidth = mPreviewTextureView.getWidth();
} else if (lp.width == ViewGroup.LayoutParams.WRAP_CONTENT) {
maxWidth = width;
} else {
maxWidth = lp.width;
}
if (lp.height == ViewGroup.LayoutParams.MATCH_PARENT) {
maxHeight = mPreviewTextureView.getHeight();
} else if (lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
maxHeight = height;
} else {
maxHeight = lp.height;
}
Log.i("[Platform Helper] Preview max width: " + maxWidth + ", max height: " + maxHeight);
// A MATCH_PARENT will take over a WRAP_CONTENT or a fixed size and maintain ratio
if (lp.width == ViewGroup.LayoutParams.MATCH_PARENT && lp.height != ViewGroup.LayoutParams.MATCH_PARENT) {
lp.width = maxWidth;
lp.height = height * maxWidth / width;
} else if (lp.height == ViewGroup.LayoutParams.MATCH_PARENT && lp.width != ViewGroup.LayoutParams.MATCH_PARENT) {
lp.height = maxHeight;
lp.width = width * maxHeight / height;
}
// A WRAP_CONTENT won't be used if a fixed size is given for the other constraint
else if (lp.width == ViewGroup.LayoutParams.WRAP_CONTENT && lp.height != ViewGroup.LayoutParams.WRAP_CONTENT) {
lp.height = maxHeight;
lp.width = width * maxHeight / height;
} else if (lp.height == ViewGroup.LayoutParams.WRAP_CONTENT && lp.width != ViewGroup.LayoutParams.WRAP_CONTENT) {
lp.width = maxWidth;
lp.height = height * maxWidth / width;
} else {
if (width < height) {
lp.width = maxWidth;
lp.height = height * maxWidth / width;
} else {
lp.height = maxHeight;
lp.width = width * maxHeight / height;
}
}
Log.i("[Platform Helper] Preview layout params updated to: " + lp.width + ", " + lp.height);
mPreviewTextureView.setLayoutParams(lp);
} else {
Log.w("[Platform Helper] Couldn't resize video preview to: " + width + "x" + height + ", no texture view found");
}
}
public synchronized Handler getHandler() {
return mMainHandler;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment