Commit c1635a66 authored by Erwan Croze's avatar Erwan Croze 👋🏻

Implementing Qrcode callback on the preview stream

parent 0945515d
......@@ -48,6 +48,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "mediastreamer2/msjpegwriter.h"
#include "mediastreamer2/msogl.h"
#include "mediastreamer2/msvolume.h"
#include "mediastreamer2/msqrcodereader.h"
#include "bctoolbox/charconv.h"
#include "chat/chat-room/client-group-chat-room-p.h"
......@@ -447,6 +448,14 @@ void linphone_core_cbs_set_chat_room_state_changed (LinphoneCoreCbs *cbs, Linpho
cbs->vtable->chat_room_state_changed = cb;
}
LinphoneCoreCbsQrcodeFoundedCb linphone_core_cbs_get_qrcode_founded(LinphoneCoreCbs *cbs) {
return cbs->vtable->qrcode_founded;
}
void linphone_core_cbs_set_qrcode_founded(LinphoneCoreCbs *cbs, LinphoneCoreCbsQrcodeFoundedCb cb) {
cbs->vtable->qrcode_founded = cb;
}
void linphone_core_cbs_set_ec_calibration_result(LinphoneCoreCbs *cbs, LinphoneCoreCbsEcCalibrationResultCb cb) {
cbs->vtable->ec_calibration_result = cb;
}
......@@ -3129,15 +3138,15 @@ static void monitor_network_state(LinphoneCore *lc, time_t curtime){
bool_t new_status=lc->network_last_status;
char newip[LINPHONE_IPADDR_SIZE];
/* only do the network up checking every five seconds */
// only do the network up checking every five seconds
if (lc->network_last_check==0 || (curtime-lc->network_last_check)>=5){
linphone_core_get_local_ip(lc,AF_UNSPEC,NULL,newip);
if (strcmp(newip,"::1")!=0 && strcmp(newip,"127.0.0.1")!=0){
new_status=TRUE;
}else new_status=FALSE; /*no network*/
}else new_status=FALSE; //no network
if (new_status==lc->network_last_status && new_status==TRUE && strcmp(newip,lc->localip)!=0){
/*IP address change detected*/
//IP address change detected
ms_message("IP address change detected.");
set_network_reachable(lc,FALSE,curtime);
lc->network_last_status=FALSE;
......@@ -4791,11 +4800,22 @@ void linphone_core_migrate_logs_from_rc_to_db(LinphoneCore *lc) {
* Video related functions *
******************************************************************************/
#ifdef VIDEO_ENABLED
static void snapshot_taken(void *userdata, struct _MSFilter *f, unsigned int id, void *arg) {
if (id == MS_JPEG_WRITER_SNAPSHOT_TAKEN) {
LinphoneCore *lc = (LinphoneCore *)userdata;
linphone_core_enable_video_preview(lc, FALSE);
static void video_filter_callback(void *userdata, struct _MSFilter *f, unsigned int id, void *arg) {
switch(id) {
case MS_JPEG_WRITER_SNAPSHOT_TAKEN: {
LinphoneCore *lc = (LinphoneCore *)userdata;
linphone_core_enable_video_preview(lc, FALSE);
break;
}
case MS_QRCODE_READER_QRCODE_FOUND: {
LinphoneCore *lc = (LinphoneCore *)userdata;
if (linphone_core_cbs_get_qrcode_founded(linphone_core_get_current_callbacks(lc)) != NULL) {
linphone_core_notify_qrcode_founded(lc, (const char*)arg);
}
break;
}
}
}
#endif
......@@ -4818,7 +4838,7 @@ LinphoneStatus linphone_core_take_preview_snapshot(LinphoneCore *lc, const char
lc->previewstream->ms.factory = lc->factory;
linphone_core_enable_video_preview(lc, TRUE);
ms_filter_add_notify_callback(lc->previewstream->local_jpegwriter, snapshot_taken, lc, TRUE);
ms_filter_add_notify_callback(lc->previewstream->local_jpegwriter, video_filter_callback, lc, TRUE);
ms_filter_call_method(lc->previewstream->local_jpegwriter, MS_JPEG_WRITER_TAKE_SNAPSHOT, (void*)file);
} else {
ms_filter_call_method(lc->previewstream->local_jpegwriter, MS_JPEG_WRITER_TAKE_SNAPSHOT, (void*)file);
......@@ -4848,7 +4868,11 @@ 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);
video_preview_start(lc->previewstream,lc->video_conf.device);
if (video_preview_qrcode_enabled(lc->previewstream))
ms_filter_add_notify_callback(lc->previewstream->qrcode, video_filter_callback, lc, TRUE);
}
}else{
if (lc->previewstream!=NULL){
......@@ -5023,6 +5047,16 @@ bool_t linphone_core_video_preview_enabled(const LinphoneCore *lc){
return lc->video_conf.show_local;
}
void linphone_core_enable_qrcode_video_preview(LinphoneCore *lc, bool_t val) {
lc->video_conf.qrcode_decoder=val;
if (linphone_core_ready(lc))
lp_config_set_int(lc->config,"video","qrcode_decoder",val);
}
bool_t linphone_core_qrcode_video_preview_enabled(const LinphoneCore *lc) {
return lc->video_conf.qrcode_decoder;
}
void linphone_core_enable_self_view(LinphoneCore *lc, bool_t val){
#ifdef VIDEO_ENABLED
LinphoneCall *call=linphone_core_get_current_call (lc);
......
......@@ -510,7 +510,7 @@ void linphone_core_notify_friend_list_removed(LinphoneCore *lc, LinphoneFriendLi
void linphone_core_notify_call_created(LinphoneCore *lc, LinphoneCall *call);
void linphone_core_notify_version_update_check_result_received(LinphoneCore *lc, LinphoneVersionUpdateCheckResult result, const char *version, const char *url);
void linphone_core_notify_chat_room_state_changed (LinphoneCore *lc, LinphoneChatRoom *cr, LinphoneChatRoomState state);
void linphone_core_notify_qrcode_founded(LinphoneCore *lc, const char *result);
void linphone_core_notify_ec_calibration_result(LinphoneCore *lc, LinphoneEcCalibratorStatus status, int delay_ms);
void linphone_core_notify_ec_calibration_audio_init(LinphoneCore *lc);
void linphone_core_notify_ec_calibration_audio_uninit(LinphoneCore *lc);
......
......@@ -326,6 +326,7 @@ struct video_config{
float fps;
bool_t capture;
bool_t show_local;
bool_t qrcode_decoder;
bool_t display;
bool_t selfview; /*during calls*/
bool_t reuse_preview_source;
......
......@@ -298,6 +298,11 @@ void linphone_core_notify_chat_room_state_changed (LinphoneCore *lc, LinphoneCha
cleanup_dead_vtable_refs(lc);
}
void linphone_core_notify_qrcode_founded(LinphoneCore *lc, const char *result) {
NOTIFY_IF_EXIST(qrcode_founded, lc, result);
cleanup_dead_vtable_refs(lc);
}
void linphone_core_notify_ec_calibration_result(LinphoneCore *lc, LinphoneEcCalibratorStatus status, int delay_ms) {
NOTIFY_IF_EXIST(ec_calibration_result, lc, status, delay_ms);
cleanup_dead_vtable_refs(lc);
......
......@@ -405,6 +405,13 @@ typedef void (*LinphoneCoreCbsVersionUpdateCheckResultReceivedCb) (LinphoneCore
*/
typedef void (*LinphoneCoreCbsChatRoomStateChangedCb) (LinphoneCore *lc, LinphoneChatRoom *cr, LinphoneChatRoomState state);
/**
* Callback prototype telling the result of decoded qrcode
* @param[in] lc LinphoneCore object
* @param[in] result The result of the decoded qrcode
*/
typedef void (*LinphoneCoreCbsQrcodeFoundedCb)(LinphoneCore *lc, const char *result);
/**
* @}
**/
......
......@@ -194,6 +194,7 @@ typedef struct _LinphoneCoreVTable{
LinphoneCoreCbsCallCreatedCb call_created;
LinphoneCoreCbsVersionUpdateCheckResultReceivedCb version_update_check_result_received;
LinphoneCoreCbsChatRoomStateChangedCb chat_room_state_changed;
LinphoneCoreCbsQrcodeFoundedCb qrcode_founded;
LinphoneCoreCbsEcCalibrationResultCb ec_calibration_result;
LinphoneCoreCbsEcCalibrationAudioInitCb ec_calibration_audio_init;
LinphoneCoreCbsEcCalibrationAudioUninitCb ec_calibration_audio_uninit;
......@@ -687,6 +688,20 @@ LINPHONE_PUBLIC LinphoneCoreCbsChatRoomStateChangedCb linphone_core_cbs_get_chat
*/
LINPHONE_PUBLIC void linphone_core_cbs_set_chat_room_state_changed (LinphoneCoreCbs *cbs, LinphoneCoreCbsChatRoomStateChangedCb cb);
/**
* Get the qrcode founded callback.
* @param[in] cbs LinphoneCoreCbs object
* @return The current callback
*/
LINPHONE_PUBLIC LinphoneCoreCbsQrcodeFoundedCb linphone_core_cbs_get_qrcode_founded(LinphoneCoreCbs *cbs);
/**
* Set the qrcode found callback.
* @param[in] cbs LinphoneCoreCbs object
* @param[in] cb The callback to use
**/
LINPHONE_PUBLIC void linphone_core_cbs_set_qrcode_founded(LinphoneCoreCbs *cbs, LinphoneCoreCbsQrcodeFoundedCb cb);
/**
* @brief Sets a callback to call each time the echo-canceler calibration is completed.
*/
......@@ -3606,6 +3621,22 @@ LINPHONE_PUBLIC void linphone_core_enable_video_preview(LinphoneCore *lc, bool_t
**/
LINPHONE_PUBLIC bool_t linphone_core_video_preview_enabled(const LinphoneCore *lc);
/**
* Controls QRCode enablement.
* @param[in] lc LinphoneCore object
* @param[in] val A boolean value telling whether the QRCode is enabled in the preview.
* @ingroup media_parameters
**/
LINPHONE_PUBLIC void linphone_core_enable_qrcode_video_preview(LinphoneCore *lc, bool_t val);
/**
* Tells whether QRCode is enabled in the preview.
* @param[in] lc LinphoneCore object
* @return A boolean value telling whether QRCode is enabled in the preview.
* @ingroup media_parameters
**/
LINPHONE_PUBLIC bool_t linphone_core_qrcode_video_preview_enabled(const LinphoneCore *lc);
/**
* Take a photo of currently from capture device and write it into a jpeg file.
* Note that the snapshot is asynchronous, an application shall not assume that the file is created when the function returns.
......
......@@ -139,6 +139,7 @@ set(RC_FILES
set(IMAGE_FILES
images/linphone.svg
images/linphonesiteqr.jpg
images/nowebcamCIF.jpg
images/nowebcamVGA.jpg
)
......
......@@ -128,6 +128,7 @@ extern bool_t liblinphone_tester_keep_uuid;
extern bool_t liblinphone_tester_tls_support_disabled;
extern const MSAudioDiffParams audio_cmp_params;
extern const char *liblinphone_tester_mire_id;
extern const char *liblinphone_tester_static_image_id;
extern bool_t liblinphonetester_ipv6;
extern bool_t liblinphonetester_show_account_manager_logs;
......
......@@ -51,6 +51,7 @@ int liblinphonetester_transport_timeout = 9000; /*milliseconds. it is set to suc
Thanks to the timeout, it will fallback to IPv4*/
const char *liblinphone_tester_mire_id="Mire: Mire (synthetic moving picture)";
const char *liblinphone_tester_static_image_id="StaticImage: Static picture";
static void network_reachable(LinphoneCore *lc, bool_t reachable) {
stats* counters;
......
......@@ -23,6 +23,8 @@
#include "tester_utils.h"
#include "linphone/lpconfig.h"
#include <mediastreamer2/msqrcodereader.h>
static void enable_disable_camera_after_camera_switches(void) {
LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
......@@ -61,8 +63,60 @@ static void enable_disable_camera_after_camera_switches(void) {
linphone_core_manager_destroy(pauline);
}
typedef struct struct_qrcode_callback_data {
int qrcode_found;
char *text;
}qrcode_callback_data;
static void qrcode_found_cb(LinphoneCore *lc, const char *result) {
LinphoneCoreCbs *cbs = linphone_core_get_current_callbacks(lc);
qrcode_callback_data *found = (qrcode_callback_data *)linphone_core_cbs_get_user_data(cbs);
found->qrcode_found = TRUE;
if (result) {
if (found->text) ms_free(found->text);
found->text = ms_strdup(result);
}
}
static void decode_qrcode_from_nowebcam(void) {
qrcode_callback_data qrcode_data;
char *qrcode_image;
LinphoneCoreManager* lcm = linphone_core_manager_create("empty_rc");
LinphoneCoreCbs* cbs = NULL;
qrcode_data.qrcode_found = FALSE;
qrcode_data.text = NULL;
linphone_core_manager_start(lcm, FALSE);
qrcode_image = bc_tester_res("images/linphonesiteqr.jpg");
linphone_core_set_video_device(lcm->lc, liblinphone_tester_static_image_id);
linphone_core_set_static_picture(lcm->lc, qrcode_image);
linphone_core_enable_qrcode_video_preview(lcm->lc, TRUE);
cbs = linphone_core_get_current_callbacks(lcm->lc);
linphone_core_cbs_set_qrcode_founded(cbs, qrcode_found_cb);
linphone_core_cbs_set_user_data(cbs, &qrcode_data);
linphone_core_enable_video_preview(lcm->lc, TRUE);
BC_ASSERT_TRUE(wait_for_until(lcm->lc, NULL, &qrcode_data.qrcode_found, TRUE, 3000));
if (qrcode_data.qrcode_found) {
if (BC_ASSERT_PTR_NOT_NULL(qrcode_data.text)) {
ms_message("QRCode decode: %s", qrcode_data.text);
BC_ASSERT_STRING_EQUAL(qrcode_data.text, "https://www.linphone.org/");
}
}
if (qrcode_data.text) ms_free(qrcode_data.text);
if (qrcode_image) ms_free(qrcode_image);
linphone_core_enable_video_preview(lcm->lc, FALSE);
linphone_core_manager_destroy(lcm);
}
test_t video_tests[] = {
TEST_NO_TAG("Enable/disable camera after camera switches", enable_disable_camera_after_camera_switches)
TEST_NO_TAG("Enable/disable camera after camera switches", enable_disable_camera_after_camera_switches),
TEST_NO_TAG("Decode QRCode", decode_qrcode_from_nowebcam)
};
test_suite_t video_test_suite = {
......
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