├── .gitignore ├── .gitattributes ├── src ├── apps │ ├── pi │ │ ├── .gitignore │ │ └── Makefile │ ├── linux │ │ ├── .gitignore │ │ └── Makefile │ └── win │ │ ├── cam2web.rc │ │ ├── Icons │ │ ├── user.ico │ │ ├── about.ico │ │ ├── access.ico │ │ ├── admin.ico │ │ ├── cam2web.ico │ │ ├── family.ico │ │ ├── folder.ico │ │ ├── password.ico │ │ ├── settings.ico │ │ ├── cam2web_red.ico │ │ ├── cam2web_green.ico │ │ ├── cam2web_orange.ico │ │ ├── camera_active_red.ico │ │ ├── camera_active_blue.ico │ │ ├── camera_active_green.ico │ │ └── camera_active_orange.ico │ │ ├── .gitignore │ │ ├── SettingsDialog.hpp │ │ ├── AccessRightsDialog.hpp │ │ ├── EditAuthDomainDialog.hpp │ │ ├── cam2web.sln │ │ ├── EditUserDialog.hpp │ │ ├── Tools.hpp │ │ ├── UiTools.hpp │ │ ├── resource.h │ │ ├── EditAuthDomainDialog.cpp │ │ ├── AppConfig.hpp │ │ ├── Tools.cpp │ │ └── EditUserDialog.cpp ├── tools │ └── web2h │ │ └── make │ │ ├── gcc │ │ ├── .gitignore │ │ └── Makefile │ │ └── msvc │ │ ├── .gitignore │ │ ├── web2h.vcxproj.filters │ │ ├── web2h.sln │ │ └── web2h.vcxproj ├── web │ ├── cam2web.png │ ├── cam2web_white.png │ ├── cameraproperties.js │ ├── styles.css │ ├── camera.js │ ├── admin.html │ ├── index.html │ └── cameraproperties.html └── core │ ├── IObjectConfigurator.hpp │ ├── XInterfaces.hpp │ ├── XStringTools.hpp │ ├── cameras │ ├── DirectShow │ │ ├── XDeviceName.cpp │ │ ├── XDeviceCapabilities.cpp │ │ ├── XDevicePinInfo.cpp │ │ ├── XDeviceName.hpp │ │ ├── XDeviceCapabilities.hpp │ │ ├── XDevicePinInfo.hpp │ │ ├── XLocalVideoDeviceConfig.hpp │ │ └── XLocalVideoDevice.hpp │ ├── V4L2 │ │ ├── XV4LCameraConfig.hpp │ │ ├── XV4LCamera.hpp │ │ └── XV4LCameraConfig.cpp │ └── RaspiCam │ │ ├── XRaspiCameraConfig.hpp │ │ └── XRaspiCamera.hpp │ ├── XObjectConfigurationSerializer.hpp │ ├── XSimpleJsonParser.hpp │ ├── XError.cpp │ ├── XManualResetEvent.hpp │ ├── IVideoSource.hpp │ ├── XImageDrawing.hpp │ ├── XObjectConfigurationRequestHandler.hpp │ ├── XJpegEncoder.hpp │ ├── XVideoSourceToWeb.hpp │ ├── IObjectInformation.hpp │ ├── XStringTools.cpp │ ├── XVideoFrameDecorator.hpp │ ├── XError.hpp │ ├── IVideoSourceListener.hpp │ ├── XManualResetEvent.cpp │ ├── XImage.hpp │ ├── XVideoFrameDecorator.cpp │ ├── XObjectConfigurationSerializer.cpp │ ├── XImage.cpp │ ├── XJpegEncoder.cpp │ └── XWebServer.hpp ├── externals ├── jquery │ └── ReadMe.txt ├── libjpeg-turbo │ ├── lib-win │ │ ├── 64 │ │ │ └── turbojpeg-static.lib │ │ └── turbojpeg-static.lib │ ├── ReadMe.txt │ └── include │ │ └── jconfig.h ├── mongoose │ ├── ReadMe.txt │ ├── CONTRIBUTING.md │ ├── LICENSE │ └── README.md └── DirectShow │ ├── ReadMe.txt │ └── qedit.h ├── images ├── cam2web.png ├── win_main.png ├── win_settings.png └── win_access_rights.png ├── README.md ├── CustomWebUi.md ├── Building.md ├── Release notes.txt ├── Running.md └── WebAPI.md /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | externals/* linguist-vendored -------------------------------------------------------------------------------- /src/apps/pi/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | cam2web 3 | 4 | -------------------------------------------------------------------------------- /src/apps/linux/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | cam2web 3 | 4 | -------------------------------------------------------------------------------- /src/tools/web2h/make/gcc/.gitignore: -------------------------------------------------------------------------------- 1 | web2h 2 | *.o 3 | 4 | -------------------------------------------------------------------------------- /externals/jquery/ReadMe.txt: -------------------------------------------------------------------------------- 1 | jQuery 1.11.1 2 | jQuery Mobile 1.4.2 3 | -------------------------------------------------------------------------------- /images/cam2web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvsandbox/cam2web/HEAD/images/cam2web.png -------------------------------------------------------------------------------- /images/win_main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvsandbox/cam2web/HEAD/images/win_main.png -------------------------------------------------------------------------------- /src/tools/web2h/make/msvc/.gitignore: -------------------------------------------------------------------------------- 1 | Debug 2 | Release 3 | *.sdf 4 | *.suo 5 | *.VC.db 6 | -------------------------------------------------------------------------------- /src/web/cam2web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvsandbox/cam2web/HEAD/src/web/cam2web.png -------------------------------------------------------------------------------- /images/win_settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvsandbox/cam2web/HEAD/images/win_settings.png -------------------------------------------------------------------------------- /src/apps/win/cam2web.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvsandbox/cam2web/HEAD/src/apps/win/cam2web.rc -------------------------------------------------------------------------------- /src/web/cam2web_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvsandbox/cam2web/HEAD/src/web/cam2web_white.png -------------------------------------------------------------------------------- /src/apps/win/Icons/user.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvsandbox/cam2web/HEAD/src/apps/win/Icons/user.ico -------------------------------------------------------------------------------- /images/win_access_rights.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvsandbox/cam2web/HEAD/images/win_access_rights.png -------------------------------------------------------------------------------- /src/apps/win/Icons/about.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvsandbox/cam2web/HEAD/src/apps/win/Icons/about.ico -------------------------------------------------------------------------------- /src/apps/win/Icons/access.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvsandbox/cam2web/HEAD/src/apps/win/Icons/access.ico -------------------------------------------------------------------------------- /src/apps/win/Icons/admin.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvsandbox/cam2web/HEAD/src/apps/win/Icons/admin.ico -------------------------------------------------------------------------------- /src/apps/win/Icons/cam2web.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvsandbox/cam2web/HEAD/src/apps/win/Icons/cam2web.ico -------------------------------------------------------------------------------- /src/apps/win/Icons/family.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvsandbox/cam2web/HEAD/src/apps/win/Icons/family.ico -------------------------------------------------------------------------------- /src/apps/win/Icons/folder.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvsandbox/cam2web/HEAD/src/apps/win/Icons/folder.ico -------------------------------------------------------------------------------- /src/apps/win/Icons/password.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvsandbox/cam2web/HEAD/src/apps/win/Icons/password.ico -------------------------------------------------------------------------------- /src/apps/win/Icons/settings.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvsandbox/cam2web/HEAD/src/apps/win/Icons/settings.ico -------------------------------------------------------------------------------- /src/apps/win/Icons/cam2web_red.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvsandbox/cam2web/HEAD/src/apps/win/Icons/cam2web_red.ico -------------------------------------------------------------------------------- /src/apps/win/.gitignore: -------------------------------------------------------------------------------- 1 | Debug 2 | Release 3 | *.sdf 4 | *.suo 5 | *.opensdf 6 | *.vcxproj.user 7 | *.VC.db 8 | *.VC.opendb 9 | -------------------------------------------------------------------------------- /src/apps/win/Icons/cam2web_green.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvsandbox/cam2web/HEAD/src/apps/win/Icons/cam2web_green.ico -------------------------------------------------------------------------------- /src/apps/win/Icons/cam2web_orange.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvsandbox/cam2web/HEAD/src/apps/win/Icons/cam2web_orange.ico -------------------------------------------------------------------------------- /src/apps/win/Icons/camera_active_red.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvsandbox/cam2web/HEAD/src/apps/win/Icons/camera_active_red.ico -------------------------------------------------------------------------------- /src/apps/win/Icons/camera_active_blue.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvsandbox/cam2web/HEAD/src/apps/win/Icons/camera_active_blue.ico -------------------------------------------------------------------------------- /src/apps/win/Icons/camera_active_green.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvsandbox/cam2web/HEAD/src/apps/win/Icons/camera_active_green.ico -------------------------------------------------------------------------------- /src/apps/win/Icons/camera_active_orange.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvsandbox/cam2web/HEAD/src/apps/win/Icons/camera_active_orange.ico -------------------------------------------------------------------------------- /externals/libjpeg-turbo/lib-win/turbojpeg-static.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvsandbox/cam2web/HEAD/externals/libjpeg-turbo/lib-win/turbojpeg-static.lib -------------------------------------------------------------------------------- /externals/libjpeg-turbo/lib-win/64/turbojpeg-static.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvsandbox/cam2web/HEAD/externals/libjpeg-turbo/lib-win/64/turbojpeg-static.lib -------------------------------------------------------------------------------- /externals/mongoose/ReadMe.txt: -------------------------------------------------------------------------------- 1 | The folder contains source code of Mongoose web server, used by the project. 2 | 3 | Version as of 2017-02-06 4 | Latest commit: d39969d1e6168ea373e07456c557909744e57ee2 5 | 6 | https://github.com/cesanta/mongoose 7 | -------------------------------------------------------------------------------- /src/tools/web2h/make/msvc/web2h.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /externals/DirectShow/ReadMe.txt: -------------------------------------------------------------------------------- 1 | The folder contains "qedit.h" file to make MSVC happy when building DirectShow related project. 2 | The file is no longer part of Windows SDK, so needs to be obtained from other sources (like older 3 | DirectX SDK). 4 | 5 | The file come from the link below: 6 | http://social.msdn.microsoft.com/Forums/en-US/windowsdirectshowdevelopment/thread/2ab5c212-5824-419d-b5d9-7f5db82f57cd 7 | -------------------------------------------------------------------------------- /externals/mongoose/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | People who have agreed to the 2 | [Cesanta CLA](https://docs.cesanta.com/contributors_la.shtml) 3 | can make contributions. Note that the CLA isn't a copyright 4 | _assigment_ but rather a copyright _license_. 5 | You retain the copyright on your contributions. 6 | 7 | We follow the Google C/C++ style guide: https://google.github.io/styleguide/cppguide.html 8 | We'd appreciate if your contribution follows the same style guide. 9 | -------------------------------------------------------------------------------- /externals/libjpeg-turbo/ReadMe.txt: -------------------------------------------------------------------------------- 1 | The folder contains build of the libjpeg-turbo library, MSVC 2015. 2 | 3 | MSVC solution files were generated using CMake command below. 4 | 5 | 32 bit 6 | cmake -G "Visual Studio 14 2015" -D ENABLE_SHARED:BOOL=ON -D WITH_ARITH_DEC:BOOL=ON -D WITH_ARITH_ENC:BOOL=ON -D WITH_JPEG7:BOOL=ON -D WITH_JPEG8:BOOL=ON -D WITH_MEM_SRCDST:BOOL=ON -D WITH_SIMD:BOOL=ON -D WITH_TURBOJPEG:BOOL=ON ../ 7 | 8 | 64 bit 9 | cmake -G "Visual Studio 14 2015 Win64" -D ENABLE_SHARED:BOOL=ON -D WITH_ARITH_DEC:BOOL=ON -D WITH_ARITH_ENC:BOOL=ON -D WITH_JPEG7:BOOL=ON -D WITH_JPEG8:BOOL=ON -D WITH_MEM_SRCDST:BOOL=ON -D WITH_SIMD:BOOL=ON -D WITH_TURBOJPEG:BOOL=ON ../ 10 | 11 | 12 | Version 2.0.4 (2019-12-31) 13 | https://github.com/libjpeg-turbo/libjpeg-turbo 14 | -------------------------------------------------------------------------------- /externals/mongoose/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2004-2013 Sergey Lyubka 2 | Copyright (c) 2013-2016 Cesanta Software Limited 3 | All rights reserved 4 | 5 | This software is dual-licensed: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License version 2 as 7 | published by the Free Software Foundation. For the terms of this 8 | license, see . 9 | 10 | You are free to use this software under the terms of the GNU General 11 | Public License, but WITHOUT ANY WARRANTY; without even the implied 12 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 | See the GNU General Public License for more details. 14 | 15 | Alternatively, you can license this software under a commercial 16 | license, as set out in . 17 | -------------------------------------------------------------------------------- /src/tools/web2h/make/msvc/web2h.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio 14 3 | VisualStudioVersion = 14.0.25420.1 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "web2h", "web2h.vcxproj", "{FA0B8656-7FBF-439A-995B-60000AFD32F0}" 6 | EndProject 7 | Global 8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 9 | Debug|Win32 = Debug|Win32 10 | Release|Win32 = Release|Win32 11 | EndGlobalSection 12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 13 | {FA0B8656-7FBF-439A-995B-60000AFD32F0}.Debug|Win32.ActiveCfg = Debug|Win32 14 | {FA0B8656-7FBF-439A-995B-60000AFD32F0}.Debug|Win32.Build.0 = Debug|Win32 15 | {FA0B8656-7FBF-439A-995B-60000AFD32F0}.Release|Win32.ActiveCfg = Release|Win32 16 | {FA0B8656-7FBF-439A-995B-60000AFD32F0}.Release|Win32.Build.0 = Release|Win32 17 | EndGlobalSection 18 | GlobalSection(SolutionProperties) = preSolution 19 | HideSolutionNode = FALSE 20 | EndGlobalSection 21 | EndGlobal 22 | -------------------------------------------------------------------------------- /src/apps/win/SettingsDialog.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef SETTINGS_DIALOG_HPP 22 | #define SETTINGS_DIALOG_HPP 23 | 24 | INT_PTR CALLBACK SettingsDlgProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam ); 25 | 26 | #endif // SETTINGS_DIALOG_HPP 27 | -------------------------------------------------------------------------------- /src/apps/win/AccessRightsDialog.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef ACCESS_RIGHTS_DIALOG_HPP 22 | #define ACCESS_RIGHTS_DIALOG_HPP 23 | 24 | INT_PTR CALLBACK AccessRightsDialogProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam ); 25 | 26 | #endif // ACCESS_RIGHTS_DIALOG_HPP 27 | -------------------------------------------------------------------------------- /src/apps/win/EditAuthDomainDialog.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef EDIT_AUTH_DOMAIN_DIALOG_HPP 22 | #define EDIT_AUTH_DOMAIN_DIALOG_HPP 23 | 24 | INT_PTR CALLBACK EditAuthDomainDialogProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam ); 25 | 26 | #endif // EDIT_AUTH_DOMAIN_DIALOG_HPP 27 | -------------------------------------------------------------------------------- /externals/libjpeg-turbo/include/jconfig.h: -------------------------------------------------------------------------------- 1 | #define JPEG_LIB_VERSION 80 2 | #define LIBJPEG_TURBO_VERSION 2.0.4 3 | #define LIBJPEG_TURBO_VERSION_NUMBER 2000004 4 | 5 | #define C_ARITH_CODING_SUPPORTED 6 | #define D_ARITH_CODING_SUPPORTED 7 | /* #undef MEM_SRCDST_SUPPORTED */ 8 | #define WITH_SIMD 9 | 10 | #define BITS_IN_JSAMPLE 8 /* use 8 or 12 */ 11 | 12 | #define HAVE_STDDEF_H 13 | #define HAVE_STDLIB_H 14 | #undef NEED_SYS_TYPES_H 15 | #undef NEED_BSD_STRINGS 16 | 17 | #define HAVE_UNSIGNED_CHAR 18 | #define HAVE_UNSIGNED_SHORT 19 | #undef INCOMPLETE_TYPES_BROKEN 20 | #undef RIGHT_SHIFT_IS_UNSIGNED 21 | #undef __CHAR_UNSIGNED__ 22 | 23 | /* Define "boolean" as unsigned char, not int, per Windows custom */ 24 | #ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */ 25 | typedef unsigned char boolean; 26 | #endif 27 | #define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */ 28 | 29 | /* Define "INT32" as int, not long, per Windows custom */ 30 | #if !(defined(_BASETSD_H_) || defined(_BASETSD_H)) /* don't conflict if basetsd.h already read */ 31 | typedef short INT16; 32 | typedef signed int INT32; 33 | #endif 34 | #define XMD_H /* prevent jmorecfg.h from redefining it */ 35 | -------------------------------------------------------------------------------- /src/core/IObjectConfigurator.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef IOBJECT_CONFIGURATOR_HPP 22 | #define IOBJECT_CONFIGURATOR_HPP 23 | 24 | #include 25 | #include 26 | 27 | #include "IObjectInformation.hpp" 28 | 29 | class IObjectConfigurator : public IObjectInformation 30 | { 31 | public: 32 | virtual XError SetProperty( const std::string& propertyName, const std::string& value ) = 0; 33 | }; 34 | 35 | #endif // IOBJECT_CONFIGURATOR_HPP 36 | -------------------------------------------------------------------------------- /src/core/XInterfaces.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef XINTERFACES_HPP 22 | #define XINTERFACES_HPP 23 | 24 | // Base class used by classes which should be forbidden for copy constructor and assignment operator 25 | class Uncopyable 26 | { 27 | protected: 28 | Uncopyable( ) { } 29 | ~Uncopyable( ) { } 30 | 31 | private: 32 | Uncopyable( const Uncopyable& ) = delete; 33 | Uncopyable& operator= ( const Uncopyable& ) = delete; 34 | }; 35 | 36 | #endif // XINTERFACES_HPP 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![cam2web](images/cam2web.png) 2 | # cam2web 3 | 4 | cam2web is an application, which allows streaming a camera to web as MJPEG stream (an URL to provide individual JPEGs is also available). It allows turning a conventional USB camera (or laptop's internal camera) into an IP camera accessible over HTTP. Versions of this application are provided for: 5 | * Windows - streaming cameras supporting DirectShow API; 6 | * Linux - streaming cameras supporting V4L2 API; 7 | * Raspberry Pi - streaming from Raspberry Pi Camera Module. 8 | 9 | The streamed camera can be viewed as from different applications supporting MJPEG streams, as from a web browser. All versions of the application provide default web UI, which can be customized to get custom look and feel. If a camera supports settings like brightness, contrast, saturation, etc. - those are available to configure using the web UI (or REST API). 10 | 11 | The cam2web application supports HTTP digest authentication and allows to configure who can view the camera or change its settings (for example, it can be viewed by everyone and configured only by users, or viewed by users and configured by admins only, etc). 12 | 13 | * [Building the source code](Building.md) 14 | * [Running the application](Running.md) 15 | * [Accessing camera from other applications (WEB API)](WebAPI.md) 16 | * [Customizing Web UI](CustomWebUi.md) 17 | -------------------------------------------------------------------------------- /src/apps/win/cam2web.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio 14 3 | VisualStudioVersion = 14.0.25420.1 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cam2web", "cam2web.vcxproj", "{9AEC3B0A-79C4-4428-8B7E-FEEB1F9EDA5A}" 6 | EndProject 7 | Global 8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 9 | Debug|Win32 = Debug|Win32 10 | Debug|x64 = Debug|x64 11 | Release|Win32 = Release|Win32 12 | Release|x64 = Release|x64 13 | EndGlobalSection 14 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 15 | {9AEC3B0A-79C4-4428-8B7E-FEEB1F9EDA5A}.Debug|Win32.ActiveCfg = Debug|Win32 16 | {9AEC3B0A-79C4-4428-8B7E-FEEB1F9EDA5A}.Debug|Win32.Build.0 = Debug|Win32 17 | {9AEC3B0A-79C4-4428-8B7E-FEEB1F9EDA5A}.Debug|x64.ActiveCfg = Debug|x64 18 | {9AEC3B0A-79C4-4428-8B7E-FEEB1F9EDA5A}.Debug|x64.Build.0 = Debug|x64 19 | {9AEC3B0A-79C4-4428-8B7E-FEEB1F9EDA5A}.Release|Win32.ActiveCfg = Release|Win32 20 | {9AEC3B0A-79C4-4428-8B7E-FEEB1F9EDA5A}.Release|Win32.Build.0 = Release|Win32 21 | {9AEC3B0A-79C4-4428-8B7E-FEEB1F9EDA5A}.Release|x64.ActiveCfg = Release|x64 22 | {9AEC3B0A-79C4-4428-8B7E-FEEB1F9EDA5A}.Release|x64.Build.0 = Release|x64 23 | EndGlobalSection 24 | GlobalSection(SolutionProperties) = preSolution 25 | HideSolutionNode = FALSE 26 | EndGlobalSection 27 | EndGlobal 28 | -------------------------------------------------------------------------------- /src/apps/win/EditUserDialog.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef EDIT_USER_DIALOG_HPP 22 | #define EDIT_USER_DIALOG_HPP 23 | 24 | #include 25 | #include 26 | 27 | typedef struct 28 | { 29 | std::string Name; 30 | std::string Password; 31 | bool IsAdmin; 32 | bool PasswordChanged; 33 | 34 | std::vector ExistingUserNames; 35 | } 36 | UserInfo; 37 | 38 | INT_PTR CALLBACK EditUserDialogProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam ); 39 | 40 | #endif // EDIT_USER_DIALOG_HPP 41 | -------------------------------------------------------------------------------- /src/web/cameraproperties.js: -------------------------------------------------------------------------------- 1 | function setCameraProperty( strVar, strValue ) 2 | { 3 | var variablesMap = { }; 4 | variablesMap[strVar] = strValue; 5 | 6 | setCameraProperties( variablesMap ); 7 | } 8 | 9 | function setCameraProperties( variablesMap ) 10 | { 11 | $.ajax( { 12 | type : "POST", 13 | url : "/camera/config", 14 | data : JSON.stringify( variablesMap ), 15 | contentType : "application/json; charset=utf-8", 16 | dataType : "json", 17 | async : true, 18 | success: function( data ) 19 | { 20 | if ( data.status != "OK" ) 21 | { 22 | console.log( "Failed setting camera property: " + data.status ); 23 | if ( data.property ) 24 | { 25 | console.log( "Property: " + data.property ); 26 | } 27 | } 28 | }, 29 | failure: function( errMsg ) 30 | { 31 | console.log( errMsg ); 32 | } 33 | } ); 34 | } 35 | 36 | function handleBoolProperty( cb ) 37 | { 38 | setCameraProperty( cb.id, ( cb.checked ) ? 1 : 0 ); 39 | } 40 | 41 | function handleRangeProperty( range ) 42 | { 43 | setCameraProperty( range.id, range.value ); 44 | } 45 | 46 | function handleSelectionProperty( selection ) 47 | { 48 | setCameraProperty( selection.id, selection.value ); 49 | } 50 | -------------------------------------------------------------------------------- /CustomWebUi.md: -------------------------------------------------------------------------------- 1 | # Customizing Web UI 2 | All release builds of cam2web come with embedded Web resources, so the application can provide default Web UI without relying on any extra files. However, it is possible to override default user interface even without diving into build tools. 3 | 4 | Using configuration UI on Windows or command line options on Linux, it is possible to specify folder name to use for serving custom Web content. When the option is not set, embedded UI is provided. And when it is set, whatever is found in the specified folder will be provided instead. 5 | 6 | ### Getting default Web files 7 | The easiest way to start customizing Web UI is to get all default content first as a starting point. All the required files can be found in the two folders: [src/web](src/web) and [externals/jquery](externals/jquery). Those files must be put into a single folder, so the basic directory tree should look like this: 8 | ``` 9 | index.html 10 | cameraproperties.html 11 | styles.css 12 | cam2web.png 13 | cam2web_white.png 14 | camera.js 15 | cameraproperties.js 16 | cameraproperty.js 17 | jquery.js 18 | jquery.mobile.css 19 | jquery.mobile.js 20 | ``` 21 | Once all files are in place, the application can be configured to serve Web content from the folder containing them. To make sure it is all working, alter some styles in the **styles.css** or change some HTML in the **index.html**. If it does, you are ready to go further customizing the Web UI. 22 | -------------------------------------------------------------------------------- /Building.md: -------------------------------------------------------------------------------- 1 | # Building cam2web 2 | 3 | Before cam2web can be built in release configuration, it is required to build web2h tool provided with it, which translates some of the common web files (HTML, CSS, JS, JPEG and PNG) into header files. Those are then compiled and linked into the cam2web executable, so it could provide default web interface without relying on external files. 4 | 5 | If building in debug configuration however, the web2h is not required – all web content is served from files located in ./web folder. 6 | 7 | ## Building on Windows 8 | Microsoft Visual Studio solution files are provided for both web2h and cam2web applications (Express 2013 can be used, for example). First build **src/tools/web2h/make/msvc/web2h.sln** and then **src/apps/win/cam2web.sln**. On success, it will produce **build/msvc/[configuration]/bin** folder, which contains applications’ executables. 9 | 10 | ## Building on Linux and Raspberry Pi 11 | Makefiles for GNU make are provided for both web2h and cam2web. Running bellow commands from the project’s root folder, will produce the required executables in **build/gcc/release/bin**. 12 | ```Bash 13 | pushd . 14 | cd src/tools/web2h/make/gcc/ 15 | make 16 | popd 17 | 18 | pushd . 19 | cd src/apps/linux/ 20 | # or cd src/apps/pi/ 21 | make 22 | popd 23 | ``` 24 | Note: libjpeg development library must be installed for cam2web build to succeed (which may not be installed by default) : 25 | ``` 26 | sudo apt-get install libjpeg-dev 27 | ``` 28 | -------------------------------------------------------------------------------- /src/core/XStringTools.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef XSTRING_TOOLS_HPP 22 | #define XSTRING_TOOLS_HPP 23 | 24 | #include 25 | 26 | // Trim spaces from the start of a string 27 | std::string& StringLTrimg( std::string& s ); 28 | // Trim spaces from the end of a string 29 | std::string& StringRTrim( std::string& s ); 30 | // Trim spaces from both ends of a string 31 | std::string& StringTrim( std::string& s ); 32 | 33 | // Replace sub-string within a string 34 | std::string& StringReplace( std::string& s, const std::string& lookFor, const std::string& replaceWith ); 35 | 36 | #endif // XSTRING_TOOLS_HPP 37 | -------------------------------------------------------------------------------- /src/core/cameras/DirectShow/XDeviceName.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include "XDeviceName.hpp" 22 | using namespace std; 23 | 24 | XDeviceName::XDeviceName( ) : 25 | mMoniker( ), mName( ) 26 | { 27 | } 28 | 29 | XDeviceName::XDeviceName( string moniker, string name ) : 30 | mMoniker( moniker ), mName( name ) 31 | { 32 | } 33 | 34 | // Check if two device names are equal (moniker is checked only) 35 | bool XDeviceName::operator==( const XDeviceName& rhs ) const 36 | { 37 | return ( mMoniker == rhs.mMoniker ); 38 | } 39 | bool XDeviceName::operator==( const std::string& rhsMoniker ) const 40 | { 41 | return ( mMoniker == rhsMoniker ); 42 | } 43 | -------------------------------------------------------------------------------- /src/core/cameras/DirectShow/XDeviceCapabilities.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include "XDeviceCapabilities.hpp" 22 | 23 | XDeviceCapabilities::XDeviceCapabilities( ) : 24 | mWidth( 0 ), mHeight( 0 ), mBits( 0 ), mAvgFps( 0 ), mMaxFps( 0 ), mMinFps( 0 ) 25 | { 26 | } 27 | 28 | XDeviceCapabilities::XDeviceCapabilities( int width, int height, int bits, int avgFps, int maxFps, int minFps ) : 29 | mWidth( width ), mHeight( height ), mBits( bits ), mAvgFps( avgFps ), mMaxFps( maxFps ), mMinFps( minFps ) 30 | { 31 | } 32 | 33 | // Check if two capabilities are equal or not (width/height/bpp) 34 | bool XDeviceCapabilities::operator==( const XDeviceCapabilities& rhs ) const 35 | { 36 | return ( ( mWidth == rhs.mWidth ) && ( mHeight == rhs.mHeight ) && ( mBits == rhs.mBits ) && ( mMaxFps == rhs.mMaxFps ) ); 37 | } 38 | -------------------------------------------------------------------------------- /src/core/XObjectConfigurationSerializer.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef XOBJECT_CONFIGURATION_SERIALIZER_HPP 22 | #define XOBJECT_CONFIGURATION_SERIALIZER_HPP 23 | 24 | #include 25 | #include "IObjectConfigurator.hpp" 26 | 27 | class XObjectConfigurationSerializer 28 | { 29 | public: 30 | XObjectConfigurationSerializer( ); 31 | XObjectConfigurationSerializer( const std::string& fileName, 32 | const std::shared_ptr& objectToConfigure ); 33 | 34 | XError SaveConfiguration( ) const; 35 | XError LoadConfiguration( ) const; 36 | 37 | private: 38 | std::string FileName; 39 | std::shared_ptr ObjectToConfigure; 40 | }; 41 | 42 | #endif // XOBJECT_CONFIGURATION_SERIALIZER_HPP 43 | 44 | -------------------------------------------------------------------------------- /src/web/styles.css: -------------------------------------------------------------------------------- 1 | [data-role=page] { 2 | min-height: 100% !important; 3 | height:auto !important; 4 | } 5 | 6 | [data-role=footer] { 7 | position: absolute !important; 8 | left: 0 !important; 9 | bottom: 0 !important; 10 | width:100%; 11 | } 12 | 13 | .ui-page { 14 | background-color: #E0E8E0 !important; 15 | } 16 | 17 | .ui-page .ui-header { 18 | background-color: #00A040 !important; 19 | background: linear-gradient(#008040, #00A040) !important; 20 | } 21 | 22 | .ui-page .ui-footer { 23 | background-color: #008040 !important; 24 | background: linear-gradient(#00A040, #008040) !important; 25 | } 26 | 27 | .ui-page .ui-header .ui-btn-right { 28 | background-color: #005020 !important; 29 | } 30 | 31 | .ui-page .ui-header .ui-btn-active { 32 | background-color: #505050 !important; 33 | } 34 | 35 | .ui-page .ui-content { 36 | padding: 20px !important; 37 | margin-bottom: 40px !important; 38 | overflow-x: auto !important; 39 | white-space: nowrap; 40 | } 41 | 42 | #cameracontainer { 43 | float: left; 44 | width: 660px; 45 | } 46 | 47 | #statuscontainer { 48 | float: left; 49 | width: 300px; 50 | } 51 | 52 | #cameraproperties { 53 | margin-left: 680px; 54 | width: 300px; 55 | background-color: #D0E8D0; 56 | padding: 10px; 57 | border: 2px solid #00A040; 58 | border-radius: 10px; 59 | } 60 | 61 | #camera { 62 | border: 10px #006010 solid; 63 | } 64 | 65 | #copyright { 66 | text-align: right; 67 | padding: 10px 20px 10px 0; 68 | color: #FFFFFF; 69 | font-size: 12px; 70 | text-shadow: 1px 1px 0px #006020; 71 | } 72 | #copyright a, a:focus, a:hover { 73 | color: #FFFFFF; 74 | } 75 | -------------------------------------------------------------------------------- /src/core/XSimpleJsonParser.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef XSIMPLE_JSON_PARSER_HPP 22 | #define XSIMPLE_JSON_PARSER_HPP 23 | 24 | #include 25 | #include 26 | 27 | /* ================================================================= */ 28 | /* The function implements a *VERY* simple JSON parser. It does NOT */ 29 | /* support nested objects/arrays - those are returned as strings. */ 30 | /* In fact all values are returned as strings in a map. It is up to */ 31 | /* caller to know type of a particular value and perform further */ 32 | /* checking/parsing. */ 33 | /* ================================================================= */ 34 | 35 | bool XSimpleJsonParser( const std::string& jsonStr, std::map& values ); 36 | 37 | #endif // XSIMPLE_JSON_PARSER_HPP 38 | -------------------------------------------------------------------------------- /src/tools/web2h/make/gcc/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # web2h - converts web files into header files to be used with web2cam 3 | # 4 | # Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | # 6 | # This program is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License along 17 | # with this program; if not, write to the Free Software Foundation, Inc., 18 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | # 20 | 21 | # Additional folders to look for source files 22 | VPATH = ../../ 23 | 24 | # C++ code 25 | SRC_CPP = web2h.cpp 26 | 27 | # Output name 28 | OUT = web2h 29 | 30 | # Compiler to use 31 | COMPILER = g++ 32 | # Base compiler flags 33 | CFLAGS = -O2 -s -DNDEBUG -std=c++0x 34 | 35 | # Object files list 36 | OBJ = $(SRC_CPP:.cpp=.o) 37 | 38 | # Output folder for the build result 39 | OUT_FOLDER = ../../../../../build/gcc/release/bin 40 | 41 | # =================================== 42 | 43 | all: build 44 | 45 | %.o: %.cpp 46 | $(COMPILER) $(CFLAGS) -c $^ -o $@ 47 | 48 | $(OUT): $(OBJ) 49 | $(COMPILER) -o $@ $(OBJ) 50 | 51 | build: $(OUT) 52 | mkdir -p $(OUT_FOLDER) 53 | cp $(OUT) $(OUT_FOLDER) 54 | 55 | clean: 56 | rm $(OBJ) $(OUT) 57 | 58 | -------------------------------------------------------------------------------- /src/apps/win/Tools.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017-2019, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef TOOLS_HPP 22 | #define TOOLS_HPP 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | // Convert specfied UTF8 string to wide character string 29 | std::wstring Utf8to16( const std::string& utf8string ); 30 | // Convert specfied wide character string to UTF8 string 31 | std::string Utf16to8( const std::wstring& utf16string ); 32 | 33 | // Calculate MD5 hash string for the given buffer 34 | std::string GetMd5Hash( const uint8_t* buffer, int bufferLength ); 35 | 36 | // Get local IP address as string (if a single valid IP found). Returns empty string if fails to resolve. 37 | std::string GetLocalIpAddress( ); 38 | 39 | // Convert xargb to string 40 | std::string XargbToString( xargb color ); 41 | // Parse xargb from string 42 | bool StringToXargb( const std::string& str, xargb* color ); 43 | 44 | #endif // UI_TOOLS_HPP 45 | -------------------------------------------------------------------------------- /src/web/camera.js: -------------------------------------------------------------------------------- 1 | var Camera = (function () 2 | { 3 | var jpegUrl = '/camera/jpeg'; 4 | var mjpegUrl = '/camera/mjpeg'; 5 | var mjpegMode; 6 | var frameInterval; 7 | var imageElement; 8 | var timeStart; 9 | 10 | function refreshImage( ) 11 | { 12 | if ( mjpegMode ) 13 | { 14 | imageElement.src = mjpegUrl; 15 | } 16 | else 17 | { 18 | timeStart = new Date( ).getTime( ); 19 | imageElement.src = jpegUrl + '?t=' + timeStart; 20 | } 21 | } 22 | 23 | function onImageError( ) 24 | { 25 | // try rotating between MJPEG/JPEG modes - browsers like IE don't get MJPEG at all 26 | mjpegMode = !mjpegMode; 27 | // also give it a small pause on error 28 | setTimeout( refreshImage, 1000 ); 29 | } 30 | 31 | function onImageLoaded( ) 32 | { 33 | if ( !mjpegMode ) 34 | { 35 | var timeTaken = new Date( ).getTime( ) - timeStart; 36 | setTimeout( refreshImage, ( timeTaken > frameInterval ) ? 0 : frameInterval - timeTaken ); 37 | } 38 | } 39 | 40 | var start = function( fps ) 41 | { 42 | imageElement = document.getElementById( 'camera' ); 43 | 44 | imageElement.onload = onImageLoaded; 45 | imageElement.onerror = onImageError; 46 | 47 | if ( ( typeof fps == 'number' ) && ( fps != 0 ) ) 48 | { 49 | frameInterval = 1000 / fps; 50 | } 51 | else 52 | { 53 | frameInterval = 100; 54 | } 55 | 56 | // always try capturing in MJPEG mode 57 | mjpegMode = true; 58 | 59 | refreshImage( ); 60 | }; 61 | 62 | return { 63 | Start: start 64 | } 65 | } )( ); 66 | -------------------------------------------------------------------------------- /src/core/XError.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include "XError.hpp" 22 | 23 | static const char* ErrorMessages[] = 24 | { 25 | "Success", 26 | 27 | "Generic failure", 28 | "Input parameter is a null pointer", 29 | "Out of memory", 30 | "I/O error", 31 | "Device is not ready", 32 | "Configuration is not supported", 33 | "Property is not known", 34 | "Property is not supported", 35 | "Property value is not valid", 36 | "Property is read only", 37 | "Pixel format is not supported", 38 | "Parameters of images don't match", 39 | "Failed image encoding" 40 | }; 41 | 42 | std::string XError::ToString( ) const 43 | { 44 | std::string ret; 45 | 46 | if ( ( mCode >= 0 ) && ( mCode < sizeof( ErrorMessages ) / sizeof( ErrorMessages[0] ) ) ) 47 | { 48 | ret = ErrorMessages[mCode]; 49 | } 50 | else 51 | { 52 | char buffer[64]; 53 | 54 | sprintf( buffer, "Unknown error code: %d", mCode ); 55 | ret = buffer; 56 | } 57 | 58 | return ret; 59 | } 60 | -------------------------------------------------------------------------------- /src/core/XManualResetEvent.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef XMANUAL_RESET_EVENT_HPP 22 | #define XMANUAL_RESET_EVENT_HPP 23 | 24 | #include 25 | 26 | namespace Private 27 | { 28 | class XManualResetEventData; 29 | } 30 | 31 | // Manual reset synchronization event 32 | class XManualResetEvent 33 | { 34 | private: 35 | XManualResetEvent( const XManualResetEvent& ); 36 | XManualResetEvent& operator= ( const XManualResetEvent& ); 37 | 38 | public: 39 | XManualResetEvent( ); 40 | ~XManualResetEvent( ); 41 | 42 | // Set event to not signalled state 43 | void Reset( ); 44 | // Set event to signalled state 45 | void Signal( ); 46 | // Wait till the event gets into signalled state 47 | void Wait( ); 48 | // Wait the specified amount of time (milliseconds) till the event gets signalled 49 | bool Wait( uint32_t msec ); 50 | // Check current state of the event 51 | bool IsSignaled( ); 52 | 53 | private: 54 | Private::XManualResetEventData* mData; 55 | }; 56 | 57 | #endif // XMANUAL_RESET_EVENT_HPP 58 | -------------------------------------------------------------------------------- /src/core/IVideoSource.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef IVIDEO_SOURCE_HPP 22 | #define IVIDEO_SOURCE_HPP 23 | 24 | #include 25 | #include "IVideoSourceListener.hpp" 26 | 27 | // Interface for video sources continuously providing frames to display/process 28 | class IVideoSource 29 | { 30 | public: 31 | virtual ~IVideoSource( ) { } 32 | 33 | // Start video source so it initializes and begins providing video frames 34 | virtual bool Start( ) = 0; 35 | // Signal video source to stop, so it could finalize and clean-up 36 | virtual void SignalToStop( ) = 0; 37 | // Wait till video source (its thread) stops 38 | virtual void WaitForStop( ) = 0; 39 | // Check if video source is still running 40 | virtual bool IsRunning( ) = 0; 41 | 42 | // Get number of frames received since the start of the video source 43 | virtual uint32_t FramesReceived( ) = 0; 44 | 45 | // Set video source listener returning the old one 46 | virtual IVideoSourceListener* SetListener( IVideoSourceListener* listener ) = 0; 47 | }; 48 | 49 | #endif // IVIDEO_SOURCE_HPP 50 | -------------------------------------------------------------------------------- /src/core/cameras/DirectShow/XDevicePinInfo.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include "XDevicePinInfo.hpp" 22 | 23 | using namespace std; 24 | 25 | XDevicePinInfo::XDevicePinInfo( ) : 26 | mIndex( 0 ), mType( PinType::Unknown ), mIsInput( false ) 27 | { 28 | } 29 | 30 | XDevicePinInfo::XDevicePinInfo( int index, PinType pinType, bool isInput ) : 31 | mIndex( index ), mType( pinType ), mIsInput( isInput ) 32 | { 33 | } 34 | 35 | bool XDevicePinInfo::operator==( const XDevicePinInfo& rhs ) const 36 | { 37 | return ( ( mIndex == rhs.mIndex ) && ( mType == rhs.mType ) && ( mIsInput == rhs.mIsInput ) ); 38 | } 39 | 40 | string XDevicePinInfo::TypeToString( ) const 41 | { 42 | static const char* strTypes[] = 43 | { 44 | "Unknown", 45 | "Tuner", "Composite", "SVideo", "RGB", "YRYBY", "SerialDigital", 46 | "Parallel Digital", "SCSI", "AUX", "1394", "USB" 47 | "Decoder", "Encoder", "SCART", "Black" 48 | }; 49 | 50 | return string( ( ( mType >= PinType::Unknown ) && ( mType <= PinType::VideoBlack ) ) ? strTypes[static_cast( mType )] : strTypes[0] ); 51 | } 52 | -------------------------------------------------------------------------------- /src/core/cameras/DirectShow/XDeviceName.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef XDEVICE_NAME_HPP 22 | #define XDEVICE_NAME_HPP 23 | 24 | #include 25 | 26 | // Name of a DirectShow device including its moniker string 27 | class XDeviceName 28 | { 29 | public: 30 | XDeviceName( ); 31 | XDeviceName( std::string moniker, std::string name ); 32 | 33 | const std::string Name( ) const { return mName; } 34 | const std::string Moniker( ) const { return mMoniker; } 35 | 36 | // Check if two device names are equal (moniker is checked only) 37 | bool operator==( const XDeviceName& rhs ) const; 38 | bool operator==( const std::string& rhsMoniker ) const; 39 | 40 | // Check if two device names are NOT equal 41 | bool operator!=( const XDeviceName& rhs ) const 42 | { 43 | return ( !( (*this) == rhs ) ) ; 44 | } 45 | bool operator!=( const std::string& rhsMoniker ) const 46 | { 47 | return ( !( (*this) == rhsMoniker ) ) ; 48 | } 49 | 50 | private: 51 | std::string mMoniker; 52 | std::string mName; 53 | }; 54 | 55 | #endif // XDEVICE_NAME_HPP 56 | -------------------------------------------------------------------------------- /src/core/cameras/DirectShow/XDeviceCapabilities.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef XDEVICE_CAPABILITIES_HPP 22 | #define XDEVICE_CAPABILITIES_HPP 23 | 24 | // DirectShow device's video capabilities (most important ones) 25 | class XDeviceCapabilities 26 | { 27 | public: 28 | XDeviceCapabilities( ); 29 | XDeviceCapabilities( int width, int height, int bits, int avgFps, int maxFps, int minFps ); 30 | 31 | int Width( ) const { return mWidth; } 32 | int Height( ) const { return mHeight; } 33 | int BitCount( ) const { return mBits; } 34 | int AverageFrameRate( ) const { return mAvgFps; } 35 | int MaximumFrameRate( ) const { return mMaxFps; } 36 | int MinimumFrameRate( ) const { return mMinFps; } 37 | 38 | // Check if two capabilities are equal or not (width/height/bpp) 39 | bool operator==( const XDeviceCapabilities& rhs ) const; 40 | bool operator!=( const XDeviceCapabilities& rhs ) const 41 | { 42 | return ( !( (*this) == rhs ) ) ; 43 | } 44 | 45 | private: 46 | int mWidth; 47 | int mHeight; 48 | int mBits; 49 | int mAvgFps; 50 | int mMaxFps; 51 | int mMinFps; 52 | }; 53 | 54 | #endif // XDEVICE_CAPABILITIES_HPP 55 | -------------------------------------------------------------------------------- /src/core/XImageDrawing.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017-2019, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #pragma once 22 | #ifndef XIMAGE_DRAWING_HPP 23 | #define XIMAGE_DRAWING_HPP 24 | 25 | #include 26 | #include "XImage.hpp" 27 | #include "XError.hpp" 28 | 29 | class XImageDrawing 30 | { 31 | public: 32 | XImageDrawing( ) = delete; 33 | 34 | public: 35 | 36 | // Draw horizontal line on the specified image 37 | static XError HLine( const std::shared_ptr& image, int32_t x1, int32_t x2, int32_t y, xargb color ); 38 | 39 | // Draw vertical line on the specified image 40 | static XError VLine( const std::shared_ptr& image, int32_t y1, int32_t y2, int32_t x, xargb color ); 41 | 42 | // Draw rectangle on the specified image with the specfied color (all coordinates are inclusive) 43 | static XError Rectangle( const std::shared_ptr& image, int32_t x1, int32_t y1, int32_t x2, int32_t y2, xargb color ); 44 | 45 | // Draw ASCII text on the image at the specified location 46 | static XError PutText( const std::shared_ptr& image, const std::string& text, int32_t x, int32_t y, xargb color, xargb background, bool addBorder = true ); 47 | }; 48 | 49 | #endif // XIMAGE_DRAWING_HPP 50 | -------------------------------------------------------------------------------- /src/apps/win/UiTools.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017-2018, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef UI_TOOLS_HPP 22 | #define UI_TOOLS_HPP 23 | 24 | #include 25 | #include 26 | 27 | // Center the given window relative to the reference window 28 | void CenterWindowTo( HWND hWnd, HWND hWndRef ); 29 | // Resize window so it has client rectangle of the specified size 30 | void ResizeWindowToClientSize( HWND hWnd, LONG width, LONG height ); 31 | // Make sure the specified window is within desktop area 32 | void EnsureWindowVisible( HWND hWnd ); 33 | // Display a standard WinAPI MessageBox, but centered to its parent 34 | int CenteredMessageBox( HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType ); 35 | 36 | // Initialize up/down control and its buddy control 37 | void InitUpDownControl( HWND hwndUpDown, HWND hwndBuddy, uint16_t min, uint16_t max, uint16_t value ); 38 | // Ensure buddy control's volue is in the range of the specified up/down control 39 | void EnsureUpDownBuddyInRange( HWND hwndUpDown, HWND hwndBuddy ); 40 | 41 | // Set icon for the the given command of menu 42 | void SetMenuItemIcon( HMENU hMenu, UINT menuCommand, UINT idIcon ); 43 | 44 | // Get window's text as UTF8 string 45 | std::string GetWindowString( HWND hwnd, bool trimIt ); 46 | 47 | #endif // UI_TOOLS_HPP 48 | -------------------------------------------------------------------------------- /src/core/XObjectConfigurationRequestHandler.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef XOBJECT_CONFIGURATION_REQUEST_HANDLER_HPP 22 | #define XOBJECT_CONFIGURATION_REQUEST_HANDLER_HPP 23 | 24 | #include "IObjectConfigurator.hpp" 25 | #include "XWebServer.hpp" 26 | 27 | // Web request handler to allow configuration of object's properties 28 | class XObjectConfigurationRequestHandler : public IWebRequestHandler 29 | { 30 | public: 31 | XObjectConfigurationRequestHandler( const std::string& uri, const std::shared_ptr& objectToConfig ); 32 | 33 | void HandleHttpRequest( const IWebRequest& request, IWebResponse& response ); 34 | 35 | private: 36 | std::shared_ptr ObjectToConfig; 37 | }; 38 | 39 | // Web request handler to provide information about object's properties - read/only 40 | class XObjectInformationRequestHandler : public IWebRequestHandler 41 | { 42 | public: 43 | XObjectInformationRequestHandler( const std::string& uri, const std::shared_ptr& infoObject ); 44 | 45 | void HandleHttpRequest( const IWebRequest& request, IWebResponse& response ); 46 | 47 | private: 48 | std::shared_ptr InfoObject; 49 | }; 50 | 51 | #endif // XOBJECT_CONFIGURATION_REQUEST_HANDLER_HPP 52 | -------------------------------------------------------------------------------- /src/core/XJpegEncoder.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef XJPEG_ENCODER_HPP 22 | #define XJPEG_ENCODER_HPP 23 | 24 | #include 25 | 26 | #include "XInterfaces.hpp" 27 | #include "XImage.hpp" 28 | #include "XError.hpp" 29 | 30 | namespace Private 31 | { 32 | class XJpegEncoderData; 33 | } 34 | 35 | class XJpegEncoder : private Uncopyable 36 | { 37 | public: 38 | XJpegEncoder( uint16_t quality = 85, bool fasterCompression = false ); 39 | ~XJpegEncoder( ); 40 | 41 | // Set/get compression quality, [0, 100] 42 | uint16_t Quality( ) const; 43 | void SetQuality( uint16_t quality ); 44 | 45 | // Set/get faster compression (but less accurate) flag 46 | bool FasterCompression( ) const; 47 | void SetFasterCompression( bool faster ); 48 | 49 | /* Compress the specified image into provided buffer 50 | 51 | On input, buffer size must be set to the size of provided buffer. 52 | On output, it is set to the size of encoded JPEG image. If provided 53 | buffer is too small, it will be re-allocated (realloc). 54 | */ 55 | XError EncodeToMemory( const std::shared_ptr& image, uint8_t** buffer, uint32_t* bufferSize ); 56 | 57 | private: 58 | Private::XJpegEncoderData* mData; 59 | }; 60 | 61 | #endif // XJPEG_ENCODER_HPP 62 | -------------------------------------------------------------------------------- /src/core/cameras/V4L2/XV4LCameraConfig.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef XV4L_CAMERA_CONFIG_HPP 22 | #define XV4L_CAMERA_CONFIG_HPP 23 | 24 | #include "IObjectConfigurator.hpp" 25 | #include "XV4LCamera.hpp" 26 | 27 | // The class is to get/set camera properties 28 | class XV4LCameraConfig : public IObjectConfigurator 29 | { 30 | public: 31 | XV4LCameraConfig( const std::shared_ptr& camera ); 32 | 33 | XError SetProperty( const std::string& propertyName, const std::string& value ); 34 | XError GetProperty( const std::string& propertyName, std::string& value ) const; 35 | 36 | std::map GetAllProperties( ) const; 37 | 38 | private: 39 | std::shared_ptr mCamera; 40 | }; 41 | 42 | // The class is to get/set camera properties information - min, max, default, etc. 43 | class XV4LCameraPropsInfo : public IObjectInformation 44 | { 45 | public: 46 | XV4LCameraPropsInfo( const std::shared_ptr& camera ); 47 | 48 | XError GetProperty( const std::string& propertyName, std::string& value ) const; 49 | 50 | std::map GetAllProperties( ) const; 51 | 52 | private: 53 | std::shared_ptr mCamera; 54 | }; 55 | 56 | #endif // XV4L_CAMERA_CONFIG_HPP 57 | 58 | -------------------------------------------------------------------------------- /src/core/XVideoSourceToWeb.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef XVIDEO_SOURCE_TO_WEB_HPP 22 | #define XVIDEO_SOURCE_TO_WEB_HPP 23 | 24 | #include 25 | #include 26 | 27 | #include "XInterfaces.hpp" 28 | #include "IVideoSourceListener.hpp" 29 | #include "XWebServer.hpp" 30 | 31 | namespace Private 32 | { 33 | class XVideoSourceToWebData; 34 | } 35 | 36 | class XVideoSourceToWeb : private Uncopyable 37 | { 38 | public: 39 | XVideoSourceToWeb( uint16_t jpegQuality = 85 ); 40 | ~XVideoSourceToWeb( ); 41 | 42 | // Get video source listener, which could be fed to some video source 43 | IVideoSourceListener* VideoSourceListener( ) const; 44 | 45 | // Create web request handler to provide camera images as JPEGs 46 | std::shared_ptr CreateJpegHandler( const std::string& uri ) const; 47 | 48 | // Create web request handler to provide camera images as MJPEG stream 49 | std::shared_ptr CreateMjpegHandler( const std::string& uri, uint32_t frameRate ) const; 50 | 51 | // Get/Set JPEG quality (valid only if camera provides uncompressed images) 52 | uint16_t JpegQuality( ) const; 53 | void SetJpegQuality( uint16_t quality ); 54 | 55 | private: 56 | Private::XVideoSourceToWebData* mData; 57 | }; 58 | 59 | #endif // XVIDEO_SOURCE_TO_WEB_HPP 60 | -------------------------------------------------------------------------------- /src/core/cameras/RaspiCam/XRaspiCameraConfig.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef XRASPI_CAMERA_CONFIG_HPP 22 | #define XRASPI_CAMERA_CONFIG_HPP 23 | 24 | #include "IObjectConfigurator.hpp" 25 | #include "XRaspiCamera.hpp" 26 | 27 | // The class is to get/set camera properties 28 | class XRaspiCameraConfig : public IObjectConfigurator 29 | { 30 | public: 31 | XRaspiCameraConfig( const std::shared_ptr& camera ); 32 | 33 | XError SetProperty( const std::string& propertyName, const std::string& value ); 34 | XError GetProperty( const std::string& propertyName, std::string& value ) const; 35 | 36 | std::map GetAllProperties( ) const; 37 | 38 | private: 39 | std::shared_ptr mCamera; 40 | }; 41 | 42 | // The class is to get/set camera properties information - min, max, default, etc. 43 | class XRaspiCameraPropsInfo : public IObjectInformation 44 | { 45 | public: 46 | XRaspiCameraPropsInfo( const std::shared_ptr& camera ); 47 | 48 | XError GetProperty( const std::string& propertyName, std::string& value ) const; 49 | 50 | std::map GetAllProperties( ) const; 51 | 52 | private: 53 | std::shared_ptr mCamera; 54 | }; 55 | 56 | #endif // XRASPI_CAMERA_CONFIG_HPP 57 | 58 | -------------------------------------------------------------------------------- /src/core/cameras/DirectShow/XDevicePinInfo.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef XDEVICE_PIN_INFO_HPP 22 | #define XDEVICE_PIN_INFO_HPP 23 | 24 | #include 25 | 26 | // Types of crossbar's video pins 27 | enum class PinType 28 | { 29 | Unknown = 0, 30 | 31 | VideoTuner = 1, 32 | VideoComposite, 33 | VideoSVideo, 34 | VideoRGB, 35 | VideoYRYBY, 36 | VideoSerialDigital, 37 | VideoParallelDigital, 38 | VideoSCSI, 39 | VideoAUX, 40 | Video1394, 41 | VideoUSB, 42 | VideoDecoder, 43 | VideoEncoder, 44 | VideoSCART, 45 | VideoBlack 46 | }; 47 | 48 | // DirectShow crossbar's pin info 49 | class XDevicePinInfo 50 | { 51 | public: 52 | XDevicePinInfo( ); 53 | XDevicePinInfo( int index, PinType pinType, bool isInput = true ); 54 | 55 | int Index( ) const { return mIndex; } 56 | PinType Type( ) const { return mType; } 57 | std::string TypeToString( ) const; 58 | bool IsInput( ) const { return mIsInput; } 59 | 60 | // Check if two pin infos are equal or not 61 | bool operator==( const XDevicePinInfo& rhs ) const; 62 | bool operator!=( const XDevicePinInfo& rhs ) const 63 | { 64 | return ( !( (*this) == rhs ) ) ; 65 | } 66 | 67 | private: 68 | int mIndex; 69 | PinType mType; 70 | bool mIsInput; 71 | }; 72 | 73 | #endif // XDEVICE_PIN_INFO_HPP 74 | -------------------------------------------------------------------------------- /src/core/cameras/DirectShow/XLocalVideoDeviceConfig.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef XLOCAL_VIDEO_DEVICE_CONFIG_HPP 22 | #define XLOCAL_VIDEO_DEVICE_CONFIG_HPP 23 | 24 | #include "IObjectConfigurator.hpp" 25 | #include "XLocalVideoDevice.hpp" 26 | 27 | // The class is to get/set camera properties 28 | class XLocalVideoDeviceConfig : public IObjectConfigurator 29 | { 30 | public: 31 | XLocalVideoDeviceConfig( const std::shared_ptr& camera ); 32 | 33 | XError SetProperty( const std::string& propertyName, const std::string& value ); 34 | XError GetProperty( const std::string& propertyName, std::string& value ) const; 35 | 36 | std::map GetAllProperties( ) const; 37 | 38 | private: 39 | std::shared_ptr mCamera; 40 | }; 41 | 42 | // The class is to get/set camera properties information - min, max, default, etc. 43 | class XLocalVideoDevicePropsInfo : public IObjectInformation 44 | { 45 | public: 46 | XLocalVideoDevicePropsInfo( const std::shared_ptr& camera ); 47 | 48 | XError GetProperty( const std::string& propertyName, std::string& value ) const; 49 | 50 | std::map GetAllProperties( ) const; 51 | 52 | private: 53 | std::shared_ptr mCamera; 54 | }; 55 | 56 | 57 | #endif // XLOCAL_VIDEO_DEVICE_CONFIG_HPP 58 | -------------------------------------------------------------------------------- /src/core/IObjectInformation.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef IOBJECT_INFORMATION_HPP 22 | #define IOBJECT_INFORMATION_HPP 23 | 24 | #include 25 | #include 26 | 27 | #include "XError.hpp" 28 | 29 | typedef std::map PropertyMap; 30 | 31 | class IObjectInformation 32 | { 33 | public: 34 | virtual ~IObjectInformation( ) { } 35 | 36 | virtual XError GetProperty( const std::string& propertyName, std::string& value ) const = 0; 37 | 38 | virtual PropertyMap GetAllProperties( ) const = 0; 39 | }; 40 | 41 | class XObjectInformationMap : public IObjectInformation 42 | { 43 | public: 44 | XObjectInformationMap( const PropertyMap& infoMap ) : InfoMap( infoMap ) { } 45 | 46 | virtual XError GetProperty( const std::string& propertyName, std::string& value ) const 47 | { 48 | XError ret = XError::UnknownProperty; 49 | 50 | PropertyMap::const_iterator itProperty = InfoMap.find( propertyName ); 51 | 52 | if ( itProperty != InfoMap.end( ) ) 53 | { 54 | value = itProperty->second; 55 | ret = XError::Success; 56 | } 57 | 58 | return ret; 59 | } 60 | 61 | virtual PropertyMap GetAllProperties( ) const 62 | { 63 | return InfoMap; 64 | } 65 | 66 | private: 67 | PropertyMap InfoMap; 68 | }; 69 | 70 | #endif // IOBJECT_INFORMATION_HPP 71 | -------------------------------------------------------------------------------- /src/core/XStringTools.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include "XStringTools.hpp" 26 | 27 | using namespace std; 28 | 29 | // Trim spaces from the start of a string 30 | string& StringLTrimg( string& s ) 31 | { 32 | s.erase( s.begin( ), std::find_if( s.begin( ), s.end( ), 33 | std::not1( std::ptr_fun( std::isspace ) ) ) ); 34 | return s; 35 | } 36 | 37 | // Trim spaces from the end of a string 38 | string& StringRTrim( string& s ) 39 | { 40 | s.erase( std::find_if( s.rbegin( ), s.rend( ), 41 | std::not1( std::ptr_fun( std::isspace ) ) ).base( ), s.end( ) ); 42 | return s; 43 | } 44 | 45 | // Trim spaces from both ends of a string 46 | string& StringTrim( string& s ) 47 | { 48 | return StringLTrimg( StringRTrim( s ) ); 49 | } 50 | 51 | // Replace sub-string within a string 52 | string& StringReplace( string& s, const string& lookFor, const string& replaceWith ) 53 | { 54 | if ( !lookFor.empty( ) ) 55 | { 56 | size_t index = 0; 57 | size_t lookForLen = lookFor.length( ); 58 | size_t replaceWithLen = replaceWith.length( ); 59 | 60 | while ( index != string::npos ) 61 | { 62 | index = s.find( lookFor, index ); 63 | 64 | if ( index != string::npos ) 65 | { 66 | s.replace( index, lookForLen, replaceWith ); 67 | 68 | index += replaceWithLen; 69 | } 70 | } 71 | } 72 | 73 | return s; 74 | } 75 | -------------------------------------------------------------------------------- /src/core/XVideoFrameDecorator.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017-2019, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #pragma once 22 | #ifndef XVIDEO_FRAME_DECORATOR_HPP 23 | #define XVIDEO_FRAME_DECORATOR_HPP 24 | 25 | #include "IVideoSourceListener.hpp" 26 | 27 | // Class aimed to put any sort of decorations on the images coming from video source (title, time, watermark/logo, etc) 28 | class XVideoFrameDecorator : public IVideoSourceListener 29 | { 30 | public: 31 | XVideoFrameDecorator( ); 32 | 33 | // New video frame notification 34 | void OnNewImage( const std::shared_ptr& image ) override; 35 | // Video source error notification 36 | void OnError( const std::string& /* errorMessage */, bool /* fatal */ ) override { } 37 | 38 | // Get/Set camera title 39 | std::string CameraTitle( ) const; 40 | void SetCameraTitle( const std::string& title ); 41 | 42 | // Get/Set if timestamp should be overlayed on camera images 43 | bool TimestampOverlay( ) const; 44 | void SetTimestampOverlay( bool enabled ); 45 | 46 | // Get/Set if camera's title should be overlayed on its images 47 | bool CameraTitleOverlay( ) const; 48 | void SetCameraTitleOverlay( bool enabled ); 49 | 50 | // Get/Set overlay text color 51 | xargb OverlayTextColor( ) const; 52 | void SetOverlayTextColor( xargb color ); 53 | 54 | // Get/Set overlay background color 55 | xargb OverlayBackgroundColor( ) const; 56 | void SetOverlayBackgroundColor( xargb color ); 57 | 58 | private: 59 | std::string cameraTitle; 60 | bool addTimestampOverlay; 61 | bool addCameraTitleOverlay; 62 | xargb overlayTextColor; 63 | xargb overlayBackgroundColor; 64 | }; 65 | 66 | #endif // XVIDEO_FRAME_DECORATOR_HPP 67 | -------------------------------------------------------------------------------- /src/core/XError.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef XERROR_HPP 22 | #define XERROR_HPP 23 | 24 | #include 25 | 26 | class XError 27 | { 28 | public: 29 | 30 | enum ErrorCode 31 | { 32 | Success = 0, 33 | 34 | Failed, // Generic failure 35 | NullPointer, // Input parameter is a null pointer 36 | OutOfMemory, // Out of memory 37 | IOError, // I/O error 38 | DeivceNotReady, // Device (whatever it might be) is not ready for the requested action 39 | ConfigurationNotSupported, // Configuration is not supported by device/object/whoever 40 | UnknownProperty, // Specified property is not known 41 | UnsupportedProperty, // Specified property is not supported by device/object/whoever 42 | InvalidPropertyValue, // Specified property value is not valid 43 | ReadOnlyProperty, // Specified property is read only 44 | UnsupportedPixelFormat, // Pixel format (of an image) is not supported 45 | ImageParametersMismatch, // Parameters of images (width/height/format) don't match 46 | FailedImageEncoding // Failed image encoding 47 | }; 48 | 49 | public: 50 | XError( ErrorCode code = Success ) : mCode( code ) { } 51 | 52 | // Get the error code 53 | operator ErrorCode( ) const { return mCode; } 54 | // Check if error code is Success 55 | operator bool( ) const { return ( mCode == Success ); } 56 | // Get error code as integer 57 | int Code( ) const { return static_cast( mCode ); } 58 | 59 | std::string ToString( ) const; 60 | 61 | private: 62 | ErrorCode mCode; 63 | }; 64 | 65 | #endif // XERROR_HPP 66 | -------------------------------------------------------------------------------- /src/core/IVideoSourceListener.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef IVIDEO_SOURCE_LISTENER_HPP 22 | #define IVIDEO_SOURCE_LISTENER_HPP 23 | 24 | #include "XImage.hpp" 25 | #include 26 | #include 27 | 28 | // Interface for video source events' listener 29 | class IVideoSourceListener 30 | { 31 | public: 32 | virtual ~IVideoSourceListener( ) { } 33 | 34 | // New video frame notification 35 | virtual void OnNewImage( const std::shared_ptr& image ) = 0; 36 | 37 | // Video source error notification 38 | virtual void OnError( const std::string& errorMessage, bool fatal ) = 0; 39 | }; 40 | 41 | // A helper class to chain several listeners 42 | class XVideoSourceListenerChain : public IVideoSourceListener 43 | { 44 | public: 45 | // New video frame notification 46 | virtual void OnNewImage( const std::shared_ptr& image ) 47 | { 48 | for ( auto listener : chain ) 49 | { 50 | listener->OnNewImage( image ); 51 | } 52 | } 53 | 54 | // Video source error notification 55 | virtual void OnError( const std::string& errorMessage, bool fatal ) 56 | { 57 | for ( auto listener : chain ) 58 | { 59 | listener->OnError( errorMessage, fatal ); 60 | } 61 | } 62 | 63 | // Add new listener into the chain 64 | void Add( IVideoSourceListener* listener ) 65 | { 66 | if ( listener != nullptr ) 67 | { 68 | chain.push_back( listener ); 69 | } 70 | } 71 | 72 | // Clear all listeners from the chain 73 | void Clear( ) 74 | { 75 | chain.clear( ); 76 | } 77 | 78 | private: 79 | std::list chain; 80 | }; 81 | 82 | #endif // IVIDEO_SOURCE_LISTENER_HPP 83 | -------------------------------------------------------------------------------- /Release notes.txt: -------------------------------------------------------------------------------- 1 | cam2web 1.2.0 release notes 2 | ------------------------------------------- 3 | xx.xx.xxxx (beta) 4 | 5 | Version updates and fixes: 6 | 7 | * Fixed HTTP digest authentication, so it works with bogus clients like .NET HttpWebRequest, 8 | which calculates HA2 digest part without using query string. 9 | * Windows: Added second instance of web server, which allows to perform some administration 10 | tasks (start/stop camera streaming for now). The administration interface is only accessible 11 | by users from Admin group. The admin web server is only started when application is run 12 | with /adminport: option. 13 | 14 | 15 | 16 | cam2web 1.1.0 release notes 17 | ------------------------------------------- 18 | 30.08.2017 19 | 20 | Version updates and fixes: 21 | 22 | * The REST API is updated to provide description of camera's properties (GET request to 23 | /camera/properties). This description allows now to have common WebUI, which renders 24 | camera's properties for all supported APIs (DirectShow, V4L, MMAL). 25 | * New configuration option is added to specify name of a streamed camera, which is displayed 26 | in WebUI. 27 | * Windows: Added configuration option to override default camera's frame rate. It allows 28 | to choose from a range of supported frame rates. Note: not all frame rate values will work. 29 | This is caused by limitations of DirectShow API and simply some bad camera drivers, which 30 | don't care about what they report. 31 | * Windows: Main application's window now shows actual camera's frame rate. 32 | * Windows: Optimized BGR to RGB conversion using SSSE3 instructions if CPU supports those. 33 | * Windows: Main window's icon and system tray's icon (if minimized) show an indication of 34 | web activity - when the streamed camera is accessed. 35 | * Windows: Added an option to specify folder for custom WebUI using folder selection form. 36 | * Windows: Added configuration option to specify color of window/tray icon. This makes it 37 | easier to distinguish multiple instances of the application streaming different cameras. 38 | 39 | 40 | 41 | cam2web 1.0.0 release notes 42 | ------------------------------------------- 43 | 30.07.2017 44 | 45 | * The first public release of the application. 46 | 47 | cam2web is an application, which allows streaming a camera to web as MJPEG stream. 48 | It supports number of platforms and cameras' APIs, like Windows - cameras supporting 49 | DirectShow API (different USB cameras, laptops' cameras, etc.); Linux - cameras supporting 50 | V4L2 API; Raspberry Pi - MMAL API to access Raspbery Pi's camera module. 51 | 52 | Project page: 53 | http://www.cvsandbox.com/tools/cam2web/ 54 | 55 | GitHub page: 56 | https://github.com/cvsandbox/cam2web 57 | -------------------------------------------------------------------------------- /src/apps/win/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by cam2web.rc 4 | // 5 | 6 | #define ID_MAX 161 7 | 8 | #define IDS_APP_TITLE 103 9 | 10 | #define IDD_ABOUTBOX 103 11 | #define IDD_SETTINGS_BOX 112 12 | #define IDD_ACCESS_RIGHTS_BOX 124 13 | #define IDD_EDIT_USER_BOX 139 14 | #define IDD_EDIT_REALM_BOX 144 15 | #define IDM_ABOUT 104 16 | #define IDM_EXIT 105 17 | #define IDM_SETTINGS 111 18 | #define IDM_ACCESS_RIGHTS 123 19 | #define IDI_CAM2WEB 107 20 | #define IDI_CAM2WEB_GREEN 122 21 | #define IDI_CAM2WEB_ORANGE 130 22 | #define IDI_CAM2WEB_RED 131 23 | #define IDI_CAMERA_ACTIVE_BLUE 132 24 | #define IDI_CAMERA_ACTIVE_GREEN 133 25 | #define IDI_CAMERA_ACTIVE_ORANGE 134 26 | #define IDI_CAMERA_ACTIVE_RED 135 27 | #define IDI_SETTINGS 146 28 | #define IDI_USER 149 29 | #define IDI_ADMIN 150 30 | #define IDI_ABOUT 151 31 | #define IDI_ACCESS 152 32 | #define IDI_FAMILY 153 33 | #define IDI_PASSWORD 154 34 | #define IDI_FOLDER 155 35 | #define IDC_CAM2WEB 109 36 | #define IDC_MYICON 2 37 | #define IDC_JPEG_Q_EDIT 113 38 | #define IDC_JPEG_Q_SPIN 114 39 | #define IDC_MJPEG_RATE_EDIT 115 40 | #define IDC_MJPEG_RATE_SPIN 116 41 | #define IDC_HTTP_PORT_EDIT 117 42 | #define IDC_HTTP_PORT_SPIN 118 43 | #define IDC_CUSTOM_WEB_EDIT 119 44 | #define IDC_CUSTOM_WEB_BUTTON 148 45 | #define IDC_AUTH_METHOD_COMBO 161 46 | #define IDC_CAMERA_TITLE_EDIT 147 47 | #define IDC_OVERLAY_TIMESTAMP 157 48 | #define IDC_OVERLAY_TITLE 158 49 | #define IDC_OVERLAY_TEXT_COLOR 159 50 | #define IDC_OVERLAY_BG_COLOR 160 51 | #define IDC_SYS_TRAY_CHECK 145 52 | #define IDC_ICON_COLOR_COMBO 156 53 | #define IDC_LINK_HOME_PAGE 120 54 | #define IDC_LINK_EMAIL 121 55 | #define IDC_AUTH_DOMAIN_EDIT 125 56 | #define IDC_CHANGE_DOMAIN_BUTTON 126 57 | #define IDC_VIEWERS_COMBO 127 58 | #define IDC_CONFIGURATORS_COMBO 128 59 | #define IDC_USERS_LIST_VIEW 129 60 | #define IDC_ADD_USER_BUTTON 136 61 | #define IDC_EDIT_USER_BUTTON 137 62 | #define IDC_DELETE_USER_BUTTON 138 63 | #define IDC_USER_NAME_EDIT 140 64 | #define IDC_USER_ROLE_COMBO 141 65 | #define IDC_PASSWORD_EDIT 142 66 | #define IDC_RE_PASSWORD_EDIT 143 67 | #ifndef IDC_STATIC 68 | #define IDC_STATIC -1 69 | #endif 70 | // Next default values for new objects 71 | // 72 | #ifdef APSTUDIO_INVOKED 73 | #ifndef APSTUDIO_READONLY_SYMBOLS 74 | 75 | #define _APS_NO_MFC 130 76 | #define _APS_NEXT_RESOURCE_VALUE 129 77 | #define _APS_NEXT_COMMAND_VALUE 32771 78 | #define _APS_NEXT_CONTROL_VALUE 1000 79 | #define _APS_NEXT_SYMED_VALUE 110 80 | #endif 81 | #endif 82 | -------------------------------------------------------------------------------- /src/core/XManualResetEvent.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include "XManualResetEvent.hpp" 22 | #include 23 | 24 | using namespace std; 25 | using namespace chrono; 26 | 27 | namespace Private 28 | { 29 | class XManualResetEventData 30 | { 31 | public: 32 | uint32_t Counter; 33 | bool Triggered; 34 | mutex Mutex; 35 | condition_variable CondVariable; 36 | 37 | public: 38 | XManualResetEventData( ) : 39 | Counter( 0 ), Triggered( false ), 40 | Mutex( ), CondVariable( ) 41 | { 42 | 43 | } 44 | }; 45 | } 46 | 47 | XManualResetEvent::XManualResetEvent( ) : 48 | mData( new Private::XManualResetEventData( ) ) 49 | { 50 | } 51 | 52 | XManualResetEvent::~XManualResetEvent( ) 53 | { 54 | delete mData; 55 | } 56 | 57 | // Set event to not signalled state 58 | void XManualResetEvent::Reset( ) 59 | { 60 | unique_lock lock( mData->Mutex ); 61 | mData->Triggered = false; 62 | } 63 | 64 | // Set event to signalled state 65 | void XManualResetEvent::Signal( ) 66 | { 67 | unique_lock lock( mData->Mutex ); 68 | 69 | mData->Triggered = true; 70 | mData->Counter++; 71 | mData->CondVariable.notify_all( ); 72 | } 73 | 74 | // Wait till the event gets into signalled state 75 | void XManualResetEvent::Wait( ) 76 | { 77 | unique_lock lock( mData->Mutex ); 78 | uint32_t lastCounterValue = mData->Counter; 79 | 80 | while ( ( !mData->Triggered ) && ( mData->Counter == lastCounterValue ) ) 81 | { 82 | mData->CondVariable.wait( lock ); 83 | } 84 | } 85 | 86 | // Wait the specified amount of time (milliseconds) till the event gets signalled 87 | bool XManualResetEvent::Wait( uint32_t msec ) 88 | { 89 | steady_clock::time_point waitTill = steady_clock::now( ) + milliseconds( msec ); 90 | unique_lock lock( mData->Mutex ); 91 | uint32_t lastCounterValue = mData->Counter; 92 | 93 | if ( !mData->Triggered ) 94 | { 95 | mData->CondVariable.wait_until( lock, waitTill ); 96 | } 97 | 98 | return ( ( mData->Triggered ) || ( mData->Counter != lastCounterValue ) ); 99 | } 100 | 101 | // Check current state of the event 102 | bool XManualResetEvent::IsSignaled( ) 103 | { 104 | unique_lock lock( mData->Mutex ); 105 | return mData->Triggered; 106 | } 107 | -------------------------------------------------------------------------------- /externals/DirectShow/qedit.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////////// 2 | 3 | #ifndef __qedit_h__ 4 | #define __qedit_h__ 5 | 6 | /////////////////////////////////////////////////////////////////////////////////// 7 | 8 | #pragma once 9 | 10 | /////////////////////////////////////////////////////////////////////////////////// 11 | 12 | interface 13 | ISampleGrabberCB 14 | : 15 | public IUnknown 16 | { 17 | virtual STDMETHODIMP SampleCB( double SampleTime, IMediaSample *pSample ) = 0; 18 | virtual STDMETHODIMP BufferCB( double SampleTime, BYTE *pBuffer, long BufferLen ) = 0; 19 | }; 20 | 21 | /////////////////////////////////////////////////////////////////////////////////// 22 | 23 | static 24 | const 25 | IID IID_ISampleGrabberCB = { 0x0579154A, 0x2B53, 0x4994, { 0xB0, 0xD0, 0xE7, 0x73, 0x14, 0x8E, 0xFF, 0x85 } }; 26 | 27 | /////////////////////////////////////////////////////////////////////////////////// 28 | 29 | interface 30 | ISampleGrabber 31 | : 32 | public IUnknown 33 | { 34 | virtual HRESULT STDMETHODCALLTYPE SetOneShot( BOOL OneShot ) = 0; 35 | virtual HRESULT STDMETHODCALLTYPE SetMediaType( const AM_MEDIA_TYPE *pType ) = 0; 36 | virtual HRESULT STDMETHODCALLTYPE GetConnectedMediaType( AM_MEDIA_TYPE *pType ) = 0; 37 | virtual HRESULT STDMETHODCALLTYPE SetBufferSamples( BOOL BufferThem ) = 0; 38 | virtual HRESULT STDMETHODCALLTYPE GetCurrentBuffer( long *pBufferSize, long *pBuffer ) = 0; 39 | virtual HRESULT STDMETHODCALLTYPE GetCurrentSample( IMediaSample **ppSample ) = 0; 40 | virtual HRESULT STDMETHODCALLTYPE SetCallback( ISampleGrabberCB *pCallback, long WhichMethodToCallback ) = 0; 41 | }; 42 | 43 | /////////////////////////////////////////////////////////////////////////////////// 44 | 45 | static 46 | const 47 | IID IID_ISampleGrabber = { 0x6B652FFF, 0x11FE, 0x4fce, { 0x92, 0xAD, 0x02, 0x66, 0xB5, 0xD7, 0xC7, 0x8F } }; 48 | 49 | /////////////////////////////////////////////////////////////////////////////////// 50 | 51 | static 52 | const 53 | CLSID CLSID_SampleGrabber = { 0xC1F400A0, 0x3F08, 0x11d3, { 0x9F, 0x0B, 0x00, 0x60, 0x08, 0x03, 0x9E, 0x37 } }; 54 | 55 | /////////////////////////////////////////////////////////////////////////////////// 56 | 57 | static 58 | const 59 | CLSID CLSID_NullRenderer = { 0xC1F400A4, 0x3F08, 0x11d3, { 0x9F, 0x0B, 0x00, 0x60, 0x08, 0x03, 0x9E, 0x37 } }; 60 | 61 | /////////////////////////////////////////////////////////////////////////////////// 62 | 63 | static 64 | const 65 | CLSID CLSID_VideoEffects1Category = { 0xcc7bfb42, 0xf175, 0x11d1, { 0xa3, 0x92, 0x0, 0xe0, 0x29, 0x1f, 0x39, 0x59 } }; 66 | 67 | /////////////////////////////////////////////////////////////////////////////////// 68 | 69 | static 70 | const 71 | CLSID CLSID_VideoEffects2Category = { 0xcc7bfb43, 0xf175, 0x11d1, { 0xa3, 0x92, 0x0, 0xe0, 0x29, 0x1f, 0x39, 0x59 } }; 72 | 73 | /////////////////////////////////////////////////////////////////////////////////// 74 | 75 | static 76 | const 77 | CLSID CLSID_AudioEffects1Category = { 0xcc7bfb44, 0xf175, 0x11d1, { 0xa3, 0x92, 0x0, 0xe0, 0x29, 0x1f, 0x39, 0x59 } }; 78 | 79 | /////////////////////////////////////////////////////////////////////////////////// 80 | 81 | static 82 | const 83 | CLSID CLSID_AudioEffects2Category = { 0xcc7bfb45, 0xf175, 0x11d1, { 0xa3, 0x92, 0x0, 0xe0, 0x29, 0x1f, 0x39, 0x59 } }; 84 | 85 | /////////////////////////////////////////////////////////////////////////////////// 86 | 87 | #endif 88 | 89 | /////////////////////////////////////////////////////////////////////////////////// -------------------------------------------------------------------------------- /externals/mongoose/README.md: -------------------------------------------------------------------------------- 1 | # Mongoose - Embedded Web Server / Embedded Networking Library 2 | 3 | ![](https://img.shields.io/badge/license-GPL_2-green.svg "License") 4 | 5 | Mongoose is ideal for embedded environments. It has been designed 6 | for connecting devices and bringing them online. On the market since 2004, 7 | used by vast number of open source and 8 | commercial products - it even runs on the International Space station! 9 | Mongoose makes embedded network programming fast, robust, and easy. 10 | 11 | - [Download Mongoose Source Code here](https://www.cesanta.com) 12 | 13 | Looking for a complete IoT firmware solution? 14 | 15 | Check out [Mongoose OS](https://mongoose-iot.com) - open source embedded operating system for low-power connected microcontrollers. Secure, designed for Internet of Things, complete environment for prototyping, development and managing. 16 | 17 | # Support 18 | - [Study mongoose example code](https://github.com/cesanta/mongoose/tree/master/examples) 19 | - [Read User Guide and API reference](https://docs.cesanta.com/mongoose) 20 | - [Support Forum - ask your technical questions here] (http://forum.cesanta.com/index.php?p=/categories/mongoose) 21 | - [Commercial licensing and support available] (https://www.cesanta.com/services-support) 22 | - [Check our latest releases] (https://github.com/cesanta/mongoose/releases) 23 | 24 | # Features 25 | 26 | * Cross-platform: works on Linux/UNIX, MacOS, QNX, eCos, Windows, Android, 27 | iPhone, FreeRTOS (TI CC3200, ESP8266), etc 28 | * Supported hardware platforms: TI CC3200, TI MSP432, NRF52, STM32, PIC32, ESP8266, ESP32 and more 29 | * Builtin protocols: 30 | - plain TCP, plain UDP, SSL/TLS (over TCP, one-way or two-way) 31 | - HTTP client, HTTP server 32 | - WebSocket client, WebSocket server 33 | - MQTT client, MQTT broker 34 | - CoAP client, CoAP server 35 | - DNS client, DNS server, async DNS resolver 36 | * Single-threaded, asynchronous, non-blocking core with simple event-based API 37 | * Native support for [PicoTCP embedded TCP/IP stack](http://www.picotcp.com), 38 | [LWIP embedded TCP/IP stack](https://en.wikipedia.org/wiki/LwIP) 39 | * Tiny static and run-time footprint 40 | * Source code is both ISO C and ISO C++ compliant 41 | * Very easy to integrate: just copy 42 | [mongoose.c](https://raw.githubusercontent.com/cesanta/mongoose/master/mongoose.c) and 43 | [mongoose.h](https://raw.githubusercontent.com/cesanta/mongoose/master/mongoose.h) 44 | files to your build tree 45 | 46 | # Licensing 47 | 48 | Mongoose is released under Commercial and [GNU GPL v.2](http://www.gnu.org/licenses/old-licenses/gpl-2.0.html) open source licenses. 49 | 50 | Commercial Projects: [Contact us for commercial license.] (https://www.cesanta.com/contact) 51 | 52 | # Dashboard Example 53 | 54 | Mongoose is often used to implement device dashboards and real-time 55 | data exchange over Websocket. Here is a dashboard example that illustrates 56 | the functionality: 57 | 58 | ![](http://www.cesanta.com/hubfs/www.cesanta.com/diagrams/dash_mongoose_diagram.png) 59 | 60 | [Developing a new product? Contact us today to discuss how Mongoose can help. 61 | ](https://www.cesanta.com/contact) 62 | 63 | # Contributions 64 | 65 | To submit contributions, sign 66 | [Cesanta CLA](https://docs.cesanta.com/contributors_la.shtml) 67 | and send GitHub pull request. You retain the copyright on your contributions. 68 | 69 | # Looking for a pre-compiled Mongoose web server Windows or Mac binary? 70 | - [Download pre-compiled Mongoose web server binary.](https://www.cesanta.com/products/binary) 71 | 72 | [![Analytics](https://ga-beacon.appspot.com/UA-42732794-5/project-page)](https://github.com/cesanta/mongoose) 73 | -------------------------------------------------------------------------------- /src/web/admin.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |
21 | 22 |

cam2web Administration

23 |
24 | 25 |
26 | 27 |
28 | 29 | 30 | 31 |
32 | 33 |
34 | 35 |
36 | 40 | 41 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /src/core/XImage.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017-2019, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef XIMAGE_HPP 22 | #define XIMAGE_HPP 23 | 24 | #include 25 | 26 | #include "XInterfaces.hpp" 27 | #include "XError.hpp" 28 | 29 | enum class XPixelFormat 30 | { 31 | Unknown = 0, 32 | Grayscale8, 33 | RGB24, 34 | RGBA32, 35 | 36 | JPEG, 37 | // Enough for this project 38 | }; 39 | 40 | enum 41 | { 42 | RedIndex = 0, 43 | GreenIndex = 1, 44 | BlueIndex = 2 45 | }; 46 | 47 | // Definition of ARGB color type 48 | typedef union 49 | { 50 | uint32_t argb; 51 | struct 52 | { 53 | uint8_t b; 54 | uint8_t g; 55 | uint8_t r; 56 | uint8_t a; 57 | } 58 | components; 59 | } 60 | xargb; 61 | 62 | // A very close approximation of the famous BT709 Grayscale coefficients: (0.2125, 0.7154, 0.0721) 63 | // Pre-multiplied by 0x10000, so integer grayscaling could be done 64 | #define GRAY_COEF_RED (0x3666) 65 | #define GRAY_COEF_GREEN (0xB724) 66 | #define GRAY_COEF_BLUE (0x1276) 67 | 68 | // A macro to get gray value (intensity) out of RGB values 69 | #define RGB_TO_GRAY(r, g, b) ((uint32_t) ( GRAY_COEF_RED * (r) + GRAY_COEF_GREEN * (g) + GRAY_COEF_BLUE * (b) ) >> 16 ) 70 | 71 | 72 | // Class encapsulating image data 73 | class XImage : private Uncopyable 74 | { 75 | private: 76 | XImage( uint8_t* data, int32_t width, int32_t height, int32_t stride, XPixelFormat format, bool ownMemory ); 77 | 78 | public: 79 | ~XImage( ); 80 | 81 | // Allocate image of the specified size and format 82 | static std::shared_ptr Allocate( int32_t width, int32_t height, XPixelFormat format, bool zeroInitialize = false ); 83 | // Create image by wrapping existing memory buffer 84 | static std::shared_ptr Create( uint8_t* data, int32_t width, int32_t height, int32_t stride, XPixelFormat format ); 85 | 86 | // Clone image - make a deep copy of it 87 | std::shared_ptr Clone( ) const; 88 | // Copy content of the image - destination image must have same width/height/format 89 | XError CopyData( const std::shared_ptr& copyTo ) const; 90 | // Copy content of the image into the specified one if its size/format is same or make a clone 91 | XError CopyDataOrClone( std::shared_ptr& copyTo ) const; 92 | 93 | // Image properties 94 | int32_t Width( ) const { return mWidth; } 95 | int32_t Height( ) const { return mHeight; } 96 | int32_t Stride( ) const { return mStride; } 97 | XPixelFormat Format( ) const { return mFormat; } 98 | // Raw data of the image 99 | uint8_t* Data( ) const { return mData; } 100 | 101 | private: 102 | uint8_t* mData; 103 | int32_t mWidth; 104 | int32_t mHeight; 105 | int32_t mStride; 106 | XPixelFormat mFormat; 107 | bool mOwnMemory; 108 | }; 109 | 110 | #endif // XIMAGE_HPP 111 | -------------------------------------------------------------------------------- /src/core/XVideoFrameDecorator.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017-2019, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include "XVideoFrameDecorator.hpp" 22 | #include "XImageDrawing.hpp" 23 | #include 24 | 25 | using namespace std; 26 | 27 | XVideoFrameDecorator::XVideoFrameDecorator( ) : 28 | cameraTitle( ), 29 | addTimestampOverlay( false ), 30 | addCameraTitleOverlay( false ), 31 | overlayTextColor( { 0xFF000000 } ), 32 | overlayBackgroundColor( { 0xFFFFFFFF } ) 33 | { 34 | 35 | } 36 | 37 | // Decorate the video frame coming from video source 38 | void XVideoFrameDecorator::OnNewImage( const shared_ptr& image ) 39 | { 40 | string overlay; 41 | 42 | if ( addTimestampOverlay ) 43 | { 44 | std::time_t time = std::time( 0 ); 45 | std::tm* now = std::localtime( &time ); 46 | char buffer[32]; 47 | 48 | sprintf( buffer, "%02d/%02d/%02d %02d:%02d:%02d", now->tm_year - 100, now->tm_mon + 1, now->tm_mday, 49 | now->tm_hour, now->tm_min, now->tm_sec ); 50 | 51 | overlay = buffer; 52 | } 53 | 54 | if ( ( addCameraTitleOverlay ) && ( !cameraTitle.empty( ) ) ) 55 | { 56 | if ( !overlay.empty( ) ) 57 | { 58 | overlay += " :: "; 59 | } 60 | 61 | overlay += cameraTitle; 62 | } 63 | 64 | if ( !overlay.empty( ) ) 65 | { 66 | XImageDrawing::PutText( image, overlay, 0, 0, overlayTextColor, overlayBackgroundColor ); 67 | } 68 | } 69 | 70 | // Get/Set camera title 71 | string XVideoFrameDecorator::CameraTitle( ) const 72 | { 73 | return cameraTitle; 74 | } 75 | void XVideoFrameDecorator::SetCameraTitle( const string& title ) 76 | { 77 | cameraTitle = title; 78 | } 79 | 80 | // Get/Set if timestamp should be overlayed on camera images 81 | bool XVideoFrameDecorator::TimestampOverlay( ) const 82 | { 83 | return addTimestampOverlay; 84 | } 85 | void XVideoFrameDecorator::SetTimestampOverlay( bool enabled ) 86 | { 87 | addTimestampOverlay = enabled; 88 | } 89 | 90 | // Get/Set if camera's title should be overlayed on its images 91 | bool XVideoFrameDecorator::CameraTitleOverlay( ) const 92 | { 93 | return addCameraTitleOverlay; 94 | } 95 | void XVideoFrameDecorator::SetCameraTitleOverlay( bool enabled ) 96 | { 97 | addCameraTitleOverlay = enabled; 98 | } 99 | 100 | // Get/Set overlay text color 101 | xargb XVideoFrameDecorator::OverlayTextColor( ) const 102 | { 103 | return overlayTextColor; 104 | } 105 | void XVideoFrameDecorator::SetOverlayTextColor( xargb color ) 106 | { 107 | overlayTextColor = color; 108 | } 109 | 110 | // Get/Set overlay background color 111 | xargb XVideoFrameDecorator::OverlayBackgroundColor( ) const 112 | { 113 | return overlayBackgroundColor; 114 | } 115 | void XVideoFrameDecorator::SetOverlayBackgroundColor( xargb color ) 116 | { 117 | overlayBackgroundColor = color; 118 | } 119 | -------------------------------------------------------------------------------- /src/apps/win/EditAuthDomainDialog.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | // Exclude rarely-used stuff from Windows headers 22 | #define WIN32_LEAN_AND_MEAN 23 | 24 | #include 25 | #include 26 | 27 | #include "resource.h" 28 | #include "EditAuthDomainDialog.hpp" 29 | #include "Tools.hpp" 30 | #include "UiTools.hpp" 31 | 32 | using namespace std; 33 | 34 | #define STR_ERROR TEXT( "Error" ) 35 | 36 | // Message handler for Edit HTTP auth domain dialog box 37 | INT_PTR CALLBACK EditAuthDomainDialogProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam ) 38 | { 39 | static HICON hIcon = NULL; 40 | static char* strAuthDomain = nullptr; 41 | int wmId; 42 | int wmEvent; 43 | 44 | switch ( message ) 45 | { 46 | case WM_INITDIALOG: 47 | { 48 | HWND hwndAuthDomainEdit = GetDlgItem( hDlg, IDC_AUTH_DOMAIN_EDIT ); 49 | 50 | CenterWindowTo( hDlg, GetParent( hDlg ) ); 51 | 52 | hIcon = (HICON) LoadImage( GetModuleHandle( NULL ), MAKEINTRESOURCE( IDI_PASSWORD ), IMAGE_ICON, 53 | GetSystemMetrics( SM_CXSMICON ), GetSystemMetrics( SM_CYSMICON ), 0 ); 54 | 55 | if ( hIcon ) 56 | { 57 | SendMessage( hDlg, WM_SETICON, ICON_SMALL, (LPARAM) hIcon ); 58 | } 59 | 60 | SendMessage( hwndAuthDomainEdit, EM_SETLIMITTEXT, 32, 0 ); 61 | 62 | strAuthDomain = (char*) lParam; 63 | 64 | if ( strAuthDomain != nullptr ) 65 | { 66 | SetWindowText( hwndAuthDomainEdit, Utf8to16( strAuthDomain ).c_str( ) ); 67 | } 68 | 69 | EnableWindow( GetDlgItem( hDlg, IDOK ), ( GetWindowTextLength( hwndAuthDomainEdit ) > 0 ) ? TRUE : FALSE ); 70 | } 71 | return (INT_PTR) TRUE; 72 | 73 | case WM_DESTROY: 74 | 75 | if ( hIcon ) 76 | { 77 | DestroyIcon( hIcon ); 78 | } 79 | 80 | return (INT_PTR) TRUE; 81 | 82 | case WM_COMMAND: 83 | wmId = LOWORD( wParam ); 84 | wmEvent = HIWORD( wParam ); 85 | 86 | if ( ( wmId == IDOK ) || ( wmId == IDCANCEL ) ) 87 | { 88 | if ( ( wmId == IDOK ) && ( strAuthDomain ) ) 89 | { 90 | string authDomain = GetWindowString( GetDlgItem( hDlg, IDC_AUTH_DOMAIN_EDIT ), true ); 91 | 92 | strcpy( strAuthDomain, authDomain.c_str( ) ); 93 | } 94 | 95 | EndDialog( hDlg, wmId ); 96 | return (INT_PTR) TRUE; 97 | } 98 | else if ( ( wmEvent == EN_CHANGE ) && ( wmId == IDC_AUTH_DOMAIN_EDIT ) ) 99 | { 100 | string authDomain = GetWindowString( GetDlgItem( hDlg, IDC_AUTH_DOMAIN_EDIT ), true ); 101 | 102 | EnableWindow( GetDlgItem( hDlg, IDOK ), ( authDomain.empty( ) ) ? FALSE : TRUE ); 103 | 104 | return (INT_PTR) TRUE; 105 | } 106 | 107 | break; 108 | } 109 | 110 | return (INT_PTR) FALSE; 111 | } 112 | -------------------------------------------------------------------------------- /Running.md: -------------------------------------------------------------------------------- 1 | # Running cam2web 2 | cam2web application comes as a single executable, which does not require any installation to run correctly. Once built or extracted from downloaded package, it is ready to run and stream a camera over HTTP. Release builds have all web resources embedded into the executable, so no extra files are needed to access camera from web browsers. 3 | 4 | ## Windows version 5 | Windows version of cam2web provides graphical user interface, which allows to start/stop camera streaming and set different configuration settings. The application’s main window lists all detected cameras and their supported resolutions. Once selection is done, streaming can be started. All other settings are optional and are used to change default behaviour. 6 | 7 | **Note**: The resolution box shows default average frame rate for all resolutions supported by a camera. However, some cameras support a range of frames rates - minimum/maximum rate. For such cameras it is possible to override default frame rate and set the one needed. But, don't expect all frame rate values to work from the provided range. Due to limitations of DirectShow API and badly written drivers of some cameras, many frame rate values may no work. 8 | 9 | ![winMain](https://github.com/cvsandbox/cam2web/blob/master/images/win_main.png) 10 | 11 | When a camera is streamed, it can be accessed from a web browser – http://ip:port/ (or by clicking the link in the main window for a quick start). If camera provides any configuration settings, like brightness, contrast, saturation, etc., those can be changed from the web UI. 12 | 13 | The "Settings" window allows changing different application’s option like HTTP port to listen on, maximum frame rate of MJPEG stream, quality level of JPEG images, etc.: 14 | 15 | ![winSettings](https://github.com/cvsandbox/cam2web/blob/master/images/win_settings.png) 16 | 17 | The "Access rights" window allows to configure who can view the camera and change its settings. By default, anyone can do everything. However, if there is no desire to keep the camera public, it is possible to limit access only to registered users. Furthermore, changing camera’s settings can be restricted more and allowed to administrators only. 18 | 19 | ![winAccessRights](https://github.com/cvsandbox/cam2web/blob/master/images/win_access_rights.png) 20 | 21 | **Note**: changing any application’s settings requires restarting camera streaming. 22 | 23 | The Windows version of cam2web also provides few command line options: 24 | * /start – Automatically start camera streaming on application start. 25 | * /minimize – Minimize application’s window on its start. 26 | * /fcfg:file_name – Name of configuration file to store application’s settings. By default, the application stores all settings (including last run camera/resolution) in app.cfg stored in cam2web folder within user’s home directory. However, the name of configuration file can be set different, so several instances of the application could run, having different settings and streaming different cameras. 27 | 28 | ## Linux and Raspberry Pi versions 29 | Both Linux and Raspberry Pi versions are implemented as command line applications, which do not provide any graphical user interface. Running them will start streaming of the available camera automatically using default settings. However, if **-?** option is specified, the list of supported command line options is provided, which includes their description. 30 | 31 | Same as with Windows version, once the camera is streamed, it is accessible on http://ip:port/ URL. 32 | 33 | Unlike Windows version, the Linux/Pi version does not provide means for editing users’ list who can access camera. Instead, the [Apache htdigest](https://httpd.apache.org/docs/2.4/programs/htdigest.html) tool is used to manage users’ file, which name can then be specified as one of the cam2web’s command line options. This creates a limitation though – only one user with administrator role can be created, which is **admin**. All other names get user role. 34 | 35 | -------------------------------------------------------------------------------- /src/core/cameras/V4L2/XV4LCamera.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef XV4L_CAMERA_HPP 22 | #define XV4L_CAMERA_HPP 23 | 24 | #include 25 | 26 | #include "IVideoSource.hpp" 27 | #include "XInterfaces.hpp" 28 | 29 | namespace Private 30 | { 31 | class XV4LCameraData; 32 | } 33 | 34 | enum class XVideoProperty 35 | { 36 | Brightness = 0, 37 | Contrast, 38 | Saturation, 39 | Hue, 40 | Sharpness, 41 | Gain, 42 | BacklightCompensation, 43 | RedBalance, 44 | BlueBalance, 45 | AutoWhiteBalance, 46 | HorizontalFlip, 47 | VerticalFlip 48 | }; 49 | 50 | // Class which provides access to cameras using V4L2 API (Video for Linux, v2) 51 | class XV4LCamera : public IVideoSource, private Uncopyable 52 | { 53 | protected: 54 | XV4LCamera( ); 55 | 56 | public: 57 | ~XV4LCamera( ); 58 | 59 | static const std::shared_ptr Create( ); 60 | 61 | // Start video source so it initializes and begins providing video frames 62 | bool Start( ); 63 | // Signal source video to stop, so it could finalize and clean-up 64 | void SignalToStop( ); 65 | // Wait till video source (its thread) stops 66 | void WaitForStop( ); 67 | // Check if video source is still running 68 | bool IsRunning( ); 69 | 70 | // Get number of frames received since the start of the video source 71 | uint32_t FramesReceived( ); 72 | 73 | // Set video source listener returning the old one 74 | IVideoSourceListener* SetListener( IVideoSourceListener* listener ); 75 | 76 | public: // Set of poperties, which can be set only when device is NOT running. 77 | // If it is running, then setting these properties is silently ignored. 78 | 79 | // Set/get video device 80 | uint32_t VideoDevice( ) const; 81 | void SetVideoDevice( uint32_t videoDevice ); 82 | 83 | // Get/Set video size 84 | uint32_t Width( ) const; 85 | uint32_t Height( ) const; 86 | void SetVideoSize( uint32_t width, uint32_t height ); 87 | 88 | // Get/Set frame rate 89 | uint32_t FrameRate( ) const; 90 | void SetFrameRate( uint32_t frameRate ); 91 | 92 | // Enable/Disable JPEG encoding 93 | bool IsJpegEncodingEnabled( ) const; 94 | void EnableJpegEncoding( bool enable ); 95 | 96 | public: 97 | 98 | // Set the specified video property. The device does not have to be running. If it is not, 99 | // the setting will be cached and applied as soon as the device gets running. 100 | XError SetVideoProperty( XVideoProperty property, int32_t value ); 101 | // Get current value if the specified video property. The device must be running. 102 | XError GetVideoProperty( XVideoProperty property, int32_t* value ) const; 103 | // Get range of values supported by the specified video property 104 | XError GetVideoPropertyRange( XVideoProperty property, int32_t* min, int32_t* max, int32_t* step, int32_t* def ) const; 105 | 106 | private: 107 | Private::XV4LCameraData* mData; 108 | }; 109 | 110 | #endif // XV4L_CAMERA_HPP 111 | 112 | -------------------------------------------------------------------------------- /WebAPI.md: -------------------------------------------------------------------------------- 1 | # Accessing camera from other applications (WEB API) 2 | 3 | The streamed camera can be accessed not only from web browser, but also from any other application supporting MJPEG streams (like VLC media player, for example, or different applications for IP cameras monitoring). The URL format to access MJPEG stream is: 4 | ``` 5 | http://ip:port/camera/mjpeg 6 | ``` 7 | 8 | In the case an individual image is required, the next URL provides the latest camera snapshot: 9 | ``` 10 | http://ip:port/camera/jpeg 11 | ``` 12 | 13 | ### Camera information 14 | To get some camera information, like device name, width, height, etc., an HTTP GET request should be sent the next URL: 15 | ``` 16 | http://ip:port/camera/info 17 | ``` 18 | It provides reply in JSON format, which may look like the one below: 19 | ```JSON 20 | { 21 | "status":"OK", 22 | "config": 23 | { 24 | "device":"RaspberryPi Camera", 25 | "title":"My home camera", 26 | "width":"640", 27 | "height":"480" 28 | } 29 | } 30 | ```` 31 | 32 | ### Changing camera’s settings 33 | ``` 34 | http://ip:port/camera/config 35 | ``` 36 | To get current camera’ settings, an HTTP GET request is sent to the above URL, which provides all values as JSON reply: 37 | ```JSON 38 | { 39 | "status":"OK", 40 | "config": 41 | { 42 | "awb":"Auto", 43 | "brightness":"50", 44 | "contrast":"15", 45 | "effect":"None", 46 | "expmeteringmode":"Average", 47 | "expmode":"Auto", 48 | "hflip":"1", 49 | "saturation":"25", 50 | "sharpness":"100", 51 | "vflip":"1", 52 | "videostabilisation":"0" 53 | } 54 | } 55 | ``` 56 | In the case if only some values are required, their names (separated with coma) can be passed as **vars** variable. For example: 57 | ``` 58 | http://ip:port/camera/config?vars=brightness,contrast 59 | ``` 60 | 61 | For setting camera’s properties, the same URL is used, but HTTP POST request must be used. The posted data must contain collection of variables to set encoded in JSON format. 62 | ```JSON 63 | { 64 | "brightness":"50", 65 | "contrast":"15" 66 | } 67 | ``` 68 | On success, the reply JSON will have **status** variable set to "OK". Or it will contain failure reason otherwise. 69 | 70 | ### Getting description of camera properties 71 | Starting from version 1.1.0, the cam2web application provides description of all properties camera provides. This allows, for example, to have single WebUI code, which queries the list of available properties first and then does unified rendering. The properties description can be optained using the below URL: 72 | ``` 73 | http://ip:port/camera/properties 74 | ``` 75 | 76 | The JSON response provides name of all available properties, their default value, type, display name and order. For integer type properties, it also includes allowed minimum and maximum values. And for selection type properties, it provides all possible choices for the property. 77 | ```JSON 78 | { 79 | "status":"OK", 80 | "config": 81 | { 82 | "hflip": 83 | { 84 | "def":0, 85 | "type":"bool", 86 | "order":8, 87 | "name":"Horizontal Flip" 88 | }, 89 | "brightness": 90 | { 91 | "min":0, 92 | "max":100, 93 | "def":50, 94 | "type":"int", 95 | "order":0, 96 | "name":"Brightness" 97 | }, 98 | "awb": 99 | { 100 | "def":"Auto", 101 | "type":"select", 102 | "order":4, 103 | "name":"White Balance", 104 | "choices": 105 | [ 106 | ["Off","Off"], 107 | ["Auto","Auto"], 108 | ["Sunlight","Sunlight"], 109 | ... 110 | ] 111 | }, 112 | ... 113 | } 114 | } 115 | ``` 116 | 117 | ### Getting version information 118 | To get information about version of the cam2web application streaming the camera, the next URL is used 119 | ``` 120 | http://ip:port/version 121 | ``` 122 | Which provides information in the format below: 123 | ```JSON 124 | { 125 | "status":"OK", 126 | "config": 127 | { 128 | "platform":"RaspberryPi", 129 | "product":"cam2web", 130 | "version":"1.0.0" 131 | } 132 | } 133 | ``` 134 | 135 | ### Access rights 136 | Accessing JPEG, MJPEG and camera information URLs is available to those who can view the camera. Access to camera configuration URL is available to those who can configure it. The version URL is accessible to anyone. See [Running cam2web](Running.md) for more information about access rights. 137 | -------------------------------------------------------------------------------- /src/apps/linux/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # cam2web - streaming camera to web 3 | # 4 | # Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | # 6 | # This program is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License along 17 | # with this program; if not, write to the Free Software Foundation, Inc., 18 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | # 20 | 21 | # Additional folders to look for source files 22 | VPATH = ../../../externals/mongoose/ \ 23 | ../../core \ 24 | ../../core/cameras/V4L2 25 | 26 | # C code 27 | SRC_C = mongoose.c 28 | # C++ code 29 | SRC_CPP = cam2web.cpp XImage.cpp XJpegEncoder.cpp XManualResetEvent.cpp \ 30 | XV4LCamera.cpp XV4LCameraConfig.cpp XVideoSourceToWeb.cpp XWebServer.cpp \ 31 | XSimpleJsonParser.cpp XObjectConfigurationSerializer.cpp \ 32 | XObjectConfigurationRequestHandler.cpp XStringTools.cpp \ 33 | XError.cpp 34 | 35 | # Output name 36 | OUT = cam2web 37 | 38 | # Compiler to use 39 | COMPILER = g++ 40 | # Base compiler flags 41 | CFLAGS = -std=c++0x 42 | 43 | # Object files list 44 | OBJ = $(SRC_CPP:.cpp=.o) $(SRC_C:.c=.o) 45 | 46 | # Additional include folders 47 | INCLUDE = -I../../../externals/mongoose/ \ 48 | -I../../core \ 49 | -I../../core/cameras/V4L2 50 | 51 | # Libraries to use 52 | LIBS = -ljpeg 53 | 54 | # Enable threads in Mongoose 55 | mongoose.o: CFLAGS += -DMG_ENABLE_THREADS 56 | XWebServer.o: CFLAGS += -DMG_ENABLE_THREADS 57 | 58 | ifneq "$(findstring debug, $(MAKECMDGOALS))" "" 59 | # "Debug" build - no optimization and add debugging symbols 60 | OUT_FOLDER = ../../../build/gcc/debug/ 61 | CFLAGS += -O0 -g 62 | else 63 | # "Release" build - optimization and no debug symbols 64 | OUT_FOLDER = ../../../build/gcc/release/ 65 | CFLAGS += -O2 -s -DNDEBUG 66 | INCLUDE += -I$(OUT_FOLDER)include 67 | endif 68 | 69 | # Update compiler/linker flags include folders and libraries 70 | CFLAGS += $(INCLUDE) 71 | LDFLAGS = $(LIBS) -pthread 72 | 73 | # Different output folders 74 | OUT_BIN = $(OUT_FOLDER)bin/ 75 | OUT_INC = $(OUT_FOLDER)include/ 76 | OUT_WEB = $(OUT_BIN)web/ 77 | 78 | # web2h tool used to generate header files for web files 79 | WEB2H = $(OUT_BIN)web2h 80 | 81 | # =================================== 82 | 83 | all: release 84 | 85 | release: generateweb build 86 | 87 | debug: build copyweb 88 | 89 | %.o: %.c 90 | $(COMPILER) $(CFLAGS) -c $^ -o $@ 91 | %.o: %.cpp 92 | $(COMPILER) $(CFLAGS) -c $^ -o $@ 93 | 94 | $(OUT): $(OBJ) 95 | $(COMPILER) -o $@ $(OBJ) $(LDFLAGS) 96 | 97 | build: $(OUT) 98 | mkdir -p $(OUT_BIN) 99 | cp $(OUT) $(OUT_BIN) 100 | 101 | clean: 102 | rm $(OBJ) $(OUT) 103 | rm -rf web 104 | 105 | copyweb: 106 | mkdir -p $(OUT_WEB) 107 | cp ../../web/* $(OUT_WEB) 108 | cp ../../../externals/jquery/*.js $(OUT_WEB) 109 | cp ../../../externals/jquery/*.css $(OUT_WEB) 110 | cp -r $(OUT_WEB) . 111 | 112 | generateweb: 113 | mkdir -p $(OUT_INC) 114 | cp ../../web/* $(OUT_INC) 115 | cp ../../../externals/jquery/*.js $(OUT_INC) 116 | cp ../../../externals/jquery/*.css $(OUT_INC) 117 | $(WEB2H) -i $(OUT_INC)index.html -o $(OUT_INC)index.html.h 118 | $(WEB2H) -i $(OUT_INC)styles.css -o $(OUT_INC)styles.css.h 119 | $(WEB2H) -i $(OUT_INC)cam2web.png -o $(OUT_INC)cam2web.png.h 120 | $(WEB2H) -i $(OUT_INC)cam2web_white.png -o $(OUT_INC)cam2web_white.png.h 121 | $(WEB2H) -i $(OUT_INC)cameraproperties.html -o $(OUT_INC)cameraproperties.html.h 122 | $(WEB2H) -i $(OUT_INC)camera.js -o $(OUT_INC)camera.js.h 123 | $(WEB2H) -i $(OUT_INC)cameraproperties.js -o $(OUT_INC)cameraproperties.js.h 124 | $(WEB2H) -i $(OUT_INC)jquery.js -o $(OUT_INC)jquery.js.h 125 | $(WEB2H) -i $(OUT_INC)jquery.mobile.js -o $(OUT_INC)jquery.mobile.js.h 126 | $(WEB2H) -i $(OUT_INC)jquery.mobile.css -o $(OUT_INC)jquery.mobile.css.h 127 | rm $(OUT_INC)*.html 128 | rm $(OUT_INC)*.css 129 | rm $(OUT_INC)*.js 130 | -------------------------------------------------------------------------------- /src/tools/web2h/make/msvc/web2h.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | 15 | 16 | 17 | {FA0B8656-7FBF-439A-995B-60000AFD32F0} 18 | Win32Proj 19 | web2h 20 | 21 | 22 | 23 | Application 24 | true 25 | v140 26 | Unicode 27 | 28 | 29 | Application 30 | false 31 | v140 32 | true 33 | Unicode 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | true 47 | 48 | 49 | false 50 | 51 | 52 | 53 | 54 | 55 | Level4 56 | Disabled 57 | WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 58 | 59 | 60 | Console 61 | true 62 | 63 | 64 | xcopy /Y "$(TargetPath)" "$(ProjectDir)..\..\..\..\..\build\msvc\debug\bin\" 65 | 66 | 67 | 68 | 69 | Level4 70 | 71 | 72 | MaxSpeed 73 | true 74 | true 75 | WIN32;NDEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 76 | 77 | 78 | Console 79 | true 80 | true 81 | true 82 | 83 | 84 | xcopy /Y "$(TargetPath)" "$(ProjectDir)..\..\..\..\..\build\msvc\release\bin\" 85 | 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /src/apps/pi/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # cam2web - streaming camera to web 3 | # 4 | # Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | # 6 | # This program is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License along 17 | # with this program; if not, write to the Free Software Foundation, Inc., 18 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | # 20 | 21 | # Additional folders to look for source files 22 | VPATH = ../../../externals/mongoose/ \ 23 | ../../core \ 24 | ../../core/cameras/RaspiCam 25 | 26 | # C code 27 | SRC_C = mongoose.c 28 | # C++ code 29 | SRC_CPP = cam2web.cpp XImage.cpp XJpegEncoder.cpp XManualResetEvent.cpp \ 30 | XRaspiCamera.cpp XRaspiCameraConfig.cpp XVideoSourceToWeb.cpp XWebServer.cpp \ 31 | XSimpleJsonParser.cpp XObjectConfigurationSerializer.cpp \ 32 | XObjectConfigurationRequestHandler.cpp XStringTools.cpp \ 33 | XError.cpp 34 | 35 | # Output name 36 | OUT = cam2web 37 | 38 | # Compiler to use 39 | COMPILER = g++ 40 | # Base compiler flags 41 | CFLAGS = -std=c++0x 42 | 43 | # Object files list 44 | OBJ = $(SRC_CPP:.cpp=.o) $(SRC_C:.c=.o) 45 | 46 | # Additional include folders 47 | INCLUDE = -I../../../externals/mongoose/ \ 48 | -I../../core \ 49 | -I../../core/cameras/RaspiCam \ 50 | -I/opt/vc/include \ 51 | -I/opt/vc/include/interface/vcos \ 52 | -I/opt/vc/include/interface/vcos/pthreads \ 53 | -I/opt/vc/include/interface/vmcs_host/linux 54 | 55 | # Libraries to use 56 | LIBS = -lmmal_core -lmmal_util -lmmal_vc_client -lvcos -lbcm_host -ljpeg 57 | 58 | # Folders to look for additional libraries 59 | LIBDIR = -L/opt/vc/lib 60 | 61 | # Enable threads in Mongoose 62 | mongoose.o: CFLAGS += -DMG_ENABLE_THREADS 63 | XWebServer.o: CFLAGS += -DMG_ENABLE_THREADS 64 | 65 | ifneq "$(findstring debug, $(MAKECMDGOALS))" "" 66 | # "Debug" build - no optimization and add debugging symbols 67 | OUT_FOLDER = ../../../build/gcc/debug/ 68 | CFLAGS += -O0 -g 69 | else 70 | # "Release" build - optimization and no debug symbols 71 | OUT_FOLDER = ../../../build/gcc/release/ 72 | CFLAGS += -O2 -s -DNDEBUG 73 | INCLUDE += -I$(OUT_FOLDER)include 74 | endif 75 | 76 | # Update compiler/linker flags include folders and libraries 77 | CFLAGS += $(INCLUDE) 78 | LDFLAGS = $(LIBDIR) $(LIBS) -pthread 79 | 80 | # Different output folders 81 | OUT_BIN = $(OUT_FOLDER)bin/ 82 | OUT_INC = $(OUT_FOLDER)include/ 83 | OUT_WEB = $(OUT_BIN)web/ 84 | 85 | # web2h tool used to generate header files for web files 86 | WEB2H = $(OUT_BIN)web2h 87 | 88 | # =================================== 89 | 90 | all: release 91 | 92 | release: generateweb build 93 | 94 | debug: build copyweb 95 | 96 | %.o: %.c 97 | $(COMPILER) $(CFLAGS) -c $^ -o $@ 98 | %.o: %.cpp 99 | $(COMPILER) $(CFLAGS) -c $^ -o $@ 100 | 101 | $(OUT): $(OBJ) 102 | $(COMPILER) -o $@ $(OBJ) $(LDFLAGS) 103 | 104 | build: $(OUT) 105 | mkdir -p $(OUT_BIN) 106 | cp $(OUT) $(OUT_BIN) 107 | 108 | clean: 109 | rm $(OBJ) $(OUT) 110 | rm -rf web 111 | 112 | copyweb: 113 | mkdir -p $(OUT_WEB) 114 | cp ../../web/* $(OUT_WEB) 115 | cp ../../../externals/jquery/*.js $(OUT_WEB) 116 | cp ../../../externals/jquery/*.css $(OUT_WEB) 117 | cp -r $(OUT_WEB) . 118 | 119 | generateweb: 120 | mkdir -p $(OUT_INC) 121 | cp ../../web/* $(OUT_INC) 122 | cp ../../../externals/jquery/*.js $(OUT_INC) 123 | cp ../../../externals/jquery/*.css $(OUT_INC) 124 | $(WEB2H) -i $(OUT_INC)index.html -o $(OUT_INC)index.html.h 125 | $(WEB2H) -i $(OUT_INC)styles.css -o $(OUT_INC)styles.css.h 126 | $(WEB2H) -i $(OUT_INC)cam2web.png -o $(OUT_INC)cam2web.png.h 127 | $(WEB2H) -i $(OUT_INC)cam2web_white.png -o $(OUT_INC)cam2web_white.png.h 128 | $(WEB2H) -i $(OUT_INC)cameraproperties.html -o $(OUT_INC)cameraproperties.html.h 129 | $(WEB2H) -i $(OUT_INC)camera.js -o $(OUT_INC)camera.js.h 130 | $(WEB2H) -i $(OUT_INC)cameraproperties.js -o $(OUT_INC)cameraproperties.js.h 131 | $(WEB2H) -i $(OUT_INC)jquery.js -o $(OUT_INC)jquery.js.h 132 | $(WEB2H) -i $(OUT_INC)jquery.mobile.js -o $(OUT_INC)jquery.mobile.js.h 133 | $(WEB2H) -i $(OUT_INC)jquery.mobile.css -o $(OUT_INC)jquery.mobile.css.h 134 | rm $(OUT_INC)*.html 135 | rm $(OUT_INC)*.css 136 | rm $(OUT_INC)*.js 137 | -------------------------------------------------------------------------------- /src/web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 16 | 17 | 18 | 19 | 20 |
21 | 22 |
23 | 24 |

Remote Camera

25 | Settings 26 |
27 | 28 |
29 | 30 |
31 | 32 |
33 | 34 | 36 | 37 |
38 | 39 |
40 | 41 |
42 | 43 |
44 | 45 | 159 | 160 | 161 | -------------------------------------------------------------------------------- /src/apps/win/AppConfig.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017-2019, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef APP_CONFIG_HPP 22 | #define APP_CONFIG_HPP 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | class AppConfig : public IObjectConfigurator 29 | { 30 | public: 31 | AppConfig( ); 32 | 33 | // Get/Set JPEG quality 34 | uint16_t JpegQuality( ) const; 35 | void SetJpegQuality( uint16_t quality ); 36 | 37 | // Get/Set MJPEG frame rate 38 | uint16_t MjpegFrameRate( ) const; 39 | void SetMjpegFrameRate( uint16_t frameRate ); 40 | 41 | // Get/Set HTTP port to listen 42 | uint16_t HttpPort( ) const; 43 | void SetHttpPort( uint16_t port ); 44 | 45 | // Get/Set viewers group ID 46 | uint16_t ViewersGroup( ); 47 | void SetViewersGroup( uint16_t groupId ); 48 | 49 | // Get/Set configurators group ID 50 | uint16_t ConfiguratorsGroup( ); 51 | void SetConfiguratorsGroup( uint16_t groupId ); 52 | 53 | // Get/Set HTTP digest auth domain 54 | std::string AuthDomain( ) const; 55 | void SetAuthDomain( const std::string& authDomain ); 56 | 57 | // Get/Set HTTP authentication method 58 | std::string AuthenticationMethod( ) const; 59 | void SetAuthenticationMethod( const std::string& method ); 60 | 61 | // Get/Set path to the folder with custom web content 62 | std::string CustomWebContent( ) const; 63 | void SetCustomWebContent( const std::string& path ); 64 | 65 | // Get/Set camera moniker string 66 | std::string CameraMoniker( ) const; 67 | void SetCameraMoniker( const std::string& moniker ); 68 | 69 | // Get/Set camera title 70 | std::string CameraTitle( ) const; 71 | void SetCameraTitle( const std::string& title ); 72 | 73 | // Get/Set if timestamp should be overlayed on camera images 74 | bool TimestampOverlay( ) const; 75 | void SetTimestampOverlay( bool enabled ); 76 | 77 | // Get/Set if camera's title should be overlayed on its images 78 | bool CameraTitleOverlay( ) const; 79 | void SetCameraTitleOverlay( bool enabled ); 80 | 81 | // Get/Set overlay text color 82 | xargb OverlayTextColor( ) const; 83 | void SetOverlayTextColor( xargb color ); 84 | 85 | // Get/Set overlay background color 86 | xargb OverlayBackgroundColor( ) const; 87 | void SetOverlayBackgroundColor( xargb color ); 88 | 89 | // Get/Set last used video resolution 90 | void GetLastVideoResolution( uint16_t* width, uint16_t* height, uint16_t* bpp, uint16_t* fps ) const; 91 | void SetLastVideoResolution( uint16_t width, uint16_t height, uint16_t bpp, uint16_t fps ); 92 | 93 | // Get/Set last requested frame rate 94 | uint16_t LastRequestedFrameRate( ) const; 95 | void SetLastRequestedFrameRate( uint16_t fps ); 96 | 97 | // Get/Set the flag inidicating that application should minimize to system tray 98 | bool MinimizeToSystemTray( ) const; 99 | void SetMinimizeToSystemTray( bool enabled ); 100 | 101 | // Get/Set index of the window/tray icon to use 102 | uint16_t WindowIconIndex( ) const; 103 | void SetWindowIconIndex( uint16_t index ); 104 | 105 | // Get/Set file name to store users' list in 106 | std::string UsersFileName( ) const; 107 | void SetUsersFileName( const std::string& fileName ); 108 | 109 | // Get/Set main window's position 110 | int32_t MainWindowX( ) const; 111 | int32_t MainWindowY( ) const; 112 | void SetMainWindowXY( int32_t x, int32_t y ); 113 | 114 | // Get user camaera device preference 115 | std::string DevicePreference( ) const; 116 | 117 | public: // IObjectConfigurator interface 118 | 119 | virtual XError SetProperty( const std::string& propertyName, const std::string& value ); 120 | virtual XError GetProperty( const std::string& propertyName, std::string& value ) const; 121 | 122 | virtual std::map GetAllProperties( ) const; 123 | 124 | private: 125 | uint16_t jpegQuality; 126 | uint16_t mjpegFrameRate; 127 | uint16_t httpPort; 128 | uint16_t viewersGroup; 129 | uint16_t configuratorsGroup; 130 | std::string authDomain; 131 | std::string authMethod; 132 | std::string customWebContent; 133 | std::string cameraMoniker; 134 | std::string cameraTitle; 135 | std::string devicePreference; 136 | bool addTimestampOverlay; 137 | bool addCameraTitleOverlay; 138 | xargb overlayTextColor; 139 | xargb overlayBackgroundColor; 140 | uint16_t cameraWidth; 141 | uint16_t cameraHeight; 142 | uint16_t cameraBpp; 143 | uint16_t cameraFps; 144 | uint16_t requestedFps; 145 | uint16_t windowIcon; 146 | bool minimizeToSystemTray; 147 | int32_t mainWindowX; 148 | int32_t mainWindowY; 149 | 150 | std::string usersFileName; 151 | }; 152 | 153 | #endif // APP_CONFIG_HPP 154 | -------------------------------------------------------------------------------- /src/core/cameras/RaspiCam/XRaspiCamera.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017-2019, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef XRASPI_CAMERA_HPP 22 | #define XRASPI_CAMERA_HPP 23 | 24 | #include 25 | 26 | #include "IVideoSource.hpp" 27 | #include "XInterfaces.hpp" 28 | 29 | namespace Private 30 | { 31 | class XRaspiCameraData; 32 | } 33 | 34 | enum class AwbMode 35 | { 36 | Off = 0, 37 | Auto, 38 | Sunlight, 39 | Cloudy, 40 | Shade, 41 | Tungsten, 42 | Fluorescent, 43 | Incandescent, 44 | Flash, 45 | Horizon 46 | }; 47 | 48 | enum class ExposureMode 49 | { 50 | Off = 0, 51 | Auto, 52 | Night, 53 | NightPreview, 54 | Backlight, 55 | Spotlight, 56 | Sports, 57 | Snow, 58 | Beach, 59 | VeryLong, 60 | FixedFps, 61 | AntiShake, 62 | Fireworks 63 | }; 64 | 65 | enum class ExposureMeteringMode 66 | { 67 | Average = 0, 68 | Spot, 69 | Backlit, 70 | Matrix 71 | }; 72 | 73 | enum class ImageEffect 74 | { 75 | None = 0, 76 | Negative, 77 | Solarize, 78 | Posterize, 79 | WhiteBoard, 80 | BlackBoard, 81 | Sketch, 82 | Denoise, 83 | Emboss, 84 | OilPaint, 85 | Hatch, 86 | Gpen, 87 | Pastel, 88 | WaterColor, 89 | Film, 90 | Blur, 91 | Saturation, 92 | ColorSwap, 93 | WashedOut, 94 | Posterise, 95 | ColorPoint, 96 | ColorBalance, 97 | Cartoon 98 | }; 99 | 100 | class XRaspiCamera : public IVideoSource, private Uncopyable 101 | { 102 | protected: 103 | XRaspiCamera( ); 104 | 105 | public: 106 | ~XRaspiCamera( ); 107 | 108 | static const std::shared_ptr Create( ); 109 | 110 | // Start video source so it initializes and begins providing video frames 111 | bool Start( ); 112 | // Signal source video to stop, so it could finalize and clean-up 113 | void SignalToStop( ); 114 | // Wait till video source (its thread) stops 115 | void WaitForStop( ); 116 | // Check if video source is still running 117 | bool IsRunning( ); 118 | 119 | // Get number of frames received since the start of the video source 120 | uint32_t FramesReceived( ); 121 | 122 | // Set video source listener returning the old one 123 | IVideoSourceListener* SetListener( IVideoSourceListener* listener ); 124 | 125 | public: // Camera configuration to be done before starting it 126 | 127 | // Get/Set video size 128 | uint32_t Width( ) const; 129 | uint32_t Height( ) const; 130 | void SetVideoSize( uint32_t width, uint32_t height ); 131 | 132 | // Get/Set frame rate 133 | uint32_t FrameRate( ) const; 134 | void SetFrameRate( uint32_t frameRate ); 135 | 136 | // Enable/Disable JPEG encoding 137 | bool IsJpegEncodingEnabled( ) const; 138 | void EnableJpegEncoding( bool enable ); 139 | 140 | // Get/Set JPEG quality 141 | uint32_t JpegQuality( ) const; 142 | void SetJpegQuality( uint32_t jpegQuality ); 143 | 144 | public: // Different settings of the video source (can be changed at run time) 145 | 146 | // Get/Set camera's image rotation, (0, 90, 180, 270) 147 | uint32_t GetImageRotation( ) const; 148 | bool SetImageRotation( uint32_t rotation ); 149 | 150 | // Get/Set camera's horizontal/vertical flip 151 | bool GetHorizontalFlip( ) const; 152 | bool GetVerticalFlip( ) const; 153 | bool SetCameraFlip( bool horizontal, bool vertical ); 154 | 155 | // Get/Set video stabilisation flag 156 | bool GetVideoStabilisation( ) const; 157 | bool SetVideoStabilisation( bool enabled ); 158 | 159 | // Get/Set camera's sharpness value, [-100, 100] 160 | int32_t GetSharpness( ) const; 161 | bool SetSharpness( int32_t sharpness ); 162 | 163 | // Get/Set camera's contrast value, [-100, 100] 164 | int32_t GetContrast( ) const; 165 | bool SetContrast( int32_t contrast ); 166 | 167 | // Get/Set camera's brightness value, [0, 100] 168 | int32_t GetBrightness( ) const; 169 | bool SetBrightness( int32_t brightness ); 170 | 171 | // Get/Set camera's saturation value, [-100, 100] 172 | int32_t GetSaturation( ) const; 173 | bool SetSaturation( int32_t saturation ); 174 | 175 | // Get/Set camera's Automatic White Balance mode 176 | AwbMode GetWhiteBalanceMode( ) const; 177 | bool SetWhiteBalanceMode( AwbMode mode ); 178 | 179 | // Get/Set camera's exposure mode 180 | ExposureMode GetExposureMode( ) const; 181 | bool SetExposureMode( ExposureMode mode ); 182 | 183 | // Get/Set camera's exposure metering mode 184 | ExposureMeteringMode GetExposureMeteringMode( ) const; 185 | bool SetExposureMeteringMode( ExposureMeteringMode mode ); 186 | 187 | // Get/Set camera's image effect 188 | ImageEffect GetImageEffect( ) const; 189 | bool SetImageEffect( ImageEffect effect ); 190 | 191 | // Get/Set text annotation 192 | std::string TextAnnotation( ) const; 193 | bool SetTextTextAnnotation( const std::string& text, bool blackBackground = true ); 194 | bool ClearTextTextAnnotation( ); 195 | 196 | private: 197 | Private::XRaspiCameraData* mData; 198 | }; 199 | 200 | #endif // XRASPI_CAMERA_HPP 201 | 202 | -------------------------------------------------------------------------------- /src/core/XObjectConfigurationSerializer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include "XObjectConfigurationSerializer.hpp" 22 | 23 | #ifdef WIN32 24 | #include 25 | #endif 26 | 27 | using namespace std; 28 | 29 | XObjectConfigurationSerializer::XObjectConfigurationSerializer( ) : 30 | FileName( ), 31 | ObjectToConfigure( ) 32 | { 33 | 34 | } 35 | 36 | XObjectConfigurationSerializer::XObjectConfigurationSerializer( const std::string& fileName, 37 | const std::shared_ptr& objectToConfigure ) : 38 | FileName( fileName ), 39 | ObjectToConfigure( objectToConfigure ) 40 | { 41 | } 42 | 43 | // Save properties of the specified object into a file 44 | XError XObjectConfigurationSerializer::SaveConfiguration( ) const 45 | { 46 | XError ret = XError::Success; 47 | 48 | if ( ( FileName.empty( ) ) || ( !ObjectToConfigure ) ) 49 | { 50 | ret = XError::Failed; 51 | } 52 | else 53 | { 54 | FILE* file = nullptr; 55 | 56 | #ifdef WIN32 57 | { 58 | int charsRequired = MultiByteToWideChar( CP_UTF8, 0, FileName.c_str( ), -1, NULL, 0 ); 59 | 60 | if ( charsRequired > 0 ) 61 | { 62 | WCHAR* filenameUtf16 = (WCHAR*) malloc( sizeof( WCHAR ) * charsRequired ); 63 | 64 | if ( MultiByteToWideChar( CP_UTF8, 0, FileName.c_str( ), -1, filenameUtf16, charsRequired ) > 0 ) 65 | { 66 | file = _wfopen( filenameUtf16, L"w" ); 67 | } 68 | 69 | free( filenameUtf16 ); 70 | } 71 | } 72 | #else 73 | file = fopen( FileName.c_str( ), "w" ); 74 | #endif 75 | 76 | if ( file == nullptr ) 77 | { 78 | ret = XError::IOError; 79 | } 80 | else 81 | { 82 | map properties = ObjectToConfigure->GetAllProperties( ); 83 | bool first = true; 84 | 85 | // write a simple file, where property name and value go separate lines 86 | for ( auto property : properties ) 87 | { 88 | if ( !first ) 89 | { 90 | fprintf( file, "\n" ); 91 | } 92 | 93 | fprintf( file, "%s\n%s\n", property.first.c_str( ), property.second.c_str( ) ); 94 | 95 | first = false; 96 | } 97 | 98 | fclose( file ); 99 | } 100 | } 101 | 102 | return ret; 103 | } 104 | 105 | // Load properties of the specified object from a file 106 | XError XObjectConfigurationSerializer::LoadConfiguration( ) const 107 | { 108 | XError ret = XError::Success; 109 | 110 | if ( ( FileName.empty( ) ) || ( !ObjectToConfigure ) ) 111 | { 112 | ret = XError::Failed; 113 | } 114 | else 115 | { 116 | FILE* file = nullptr; 117 | 118 | #ifdef WIN32 119 | { 120 | int charsRequired = MultiByteToWideChar( CP_UTF8, 0, FileName.c_str( ), -1, NULL, 0 ); 121 | 122 | if ( charsRequired > 0 ) 123 | { 124 | WCHAR* filenameUtf16 = (WCHAR*) malloc( sizeof( WCHAR ) * charsRequired ); 125 | 126 | if ( MultiByteToWideChar( CP_UTF8, 0, FileName.c_str( ), -1, filenameUtf16, charsRequired ) > 0 ) 127 | { 128 | file = _wfopen( filenameUtf16, L"r" ); 129 | } 130 | 131 | free( filenameUtf16 ); 132 | } 133 | } 134 | #else 135 | file = fopen( FileName.c_str( ), "r" ); 136 | #endif 137 | 138 | if ( file == nullptr ) 139 | { 140 | ret = XError::IOError; 141 | } 142 | else 143 | { 144 | char buffer[256]; 145 | string name; 146 | string line; 147 | bool gotName = false; 148 | 149 | while ( fgets( buffer, sizeof( buffer ) - 1, file ) ) 150 | { 151 | line = string( buffer ); 152 | 153 | while ( ( !line.empty( ) ) && 154 | ( ( line.back( ) == ' ' ) || ( line.back( ) == '\t' ) || 155 | ( line.back( ) == '\n' ) || ( line.back( ) == '\r' ) ) ) 156 | { 157 | line.pop_back( ); 158 | } 159 | 160 | // allow blank lines between configuration options, but not between option and its value 161 | if ( ( !line.empty( ) ) || ( gotName ) ) 162 | { 163 | if ( !gotName ) 164 | { 165 | name = line; 166 | gotName = true; 167 | } 168 | else 169 | { 170 | ObjectToConfigure->SetProperty( name, line ); 171 | gotName = false; 172 | } 173 | } 174 | } 175 | } 176 | } 177 | 178 | return ret; 179 | } 180 | -------------------------------------------------------------------------------- /src/core/XImage.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include 22 | #include 23 | 24 | #include "XImage.hpp" 25 | 26 | using namespace std; 27 | 28 | // Returns number of bits required for pixel in certain format 29 | uint32_t XImageBitsPerPixel( XPixelFormat format ) 30 | { 31 | static int sizes[] = { 0, 8, 24, 32, 8 }; 32 | int formatIndex = static_cast( format ); 33 | 34 | return ( formatIndex >= ( sizeof( sizes ) / sizeof( sizes[0] ) ) ) ? 0 : sizes[formatIndex]; 35 | } 36 | 37 | // Returns number of bytes per stride when number of bits per line is known (stride is always 32 bit aligned) 38 | static uint32_t XImageBytesPerStride( uint32_t bitsPerLine ) 39 | { 40 | return ( ( bitsPerLine + 31 ) & ~31 ) >> 3; 41 | } 42 | 43 | // Returns number of bytes per line when number of bits per line is known (line is always 8 bit aligned) 44 | static uint32_t XImageBytesPerLine( uint32_t bitsPerLine ) 45 | { 46 | return ( bitsPerLine + 7 ) >> 3; 47 | } 48 | 49 | // Create empty image 50 | XImage::XImage( uint8_t* data, int32_t width, int32_t height, int32_t stride, XPixelFormat format, bool ownMemory ) : 51 | mData( data ), mWidth( width ), mHeight( height ), mStride( stride ), mFormat( format ), mOwnMemory( ownMemory ) 52 | { 53 | } 54 | 55 | // Destroy image 56 | XImage::~XImage( ) 57 | { 58 | if ( ( mOwnMemory ) && ( mData != nullptr ) ) 59 | { 60 | free( mData ); 61 | } 62 | } 63 | 64 | // Allocate image of the specified size and format 65 | shared_ptr XImage::Allocate( int32_t width, int32_t height, XPixelFormat format, bool zeroInitialize ) 66 | { 67 | int32_t stride = (int32_t) XImageBytesPerStride( width * XImageBitsPerPixel( format ) ); 68 | XImage* image = nullptr; 69 | uint8_t* data = nullptr; 70 | 71 | if ( zeroInitialize ) 72 | { 73 | data = (uint8_t*) calloc( 1, height * stride ); 74 | } 75 | else 76 | { 77 | data = (uint8_t*) malloc( height * stride ); 78 | } 79 | 80 | if ( data != nullptr ) 81 | { 82 | image = new (nothrow) XImage( data, width, height, stride, format, true ); 83 | } 84 | 85 | return shared_ptr( image ); 86 | } 87 | 88 | // Create image by wrapping existing memory buffer 89 | shared_ptr XImage::Create( uint8_t* data, int32_t width, int32_t height, int32_t stride, XPixelFormat format ) 90 | { 91 | return shared_ptr( new (nothrow) XImage( data, width, height, stride, format, false ) ); 92 | } 93 | 94 | // Clone image - make a deep copy of it 95 | shared_ptr XImage::Clone( ) const 96 | { 97 | shared_ptr clone; 98 | 99 | if ( mData != nullptr ) 100 | { 101 | clone = Allocate( mWidth, mHeight, mFormat ); 102 | 103 | if ( clone ) 104 | { 105 | if ( CopyData( clone ) != XError::Success ) 106 | { 107 | clone.reset( ); 108 | } 109 | } 110 | } 111 | 112 | return clone; 113 | } 114 | 115 | // Copy content of the image - destination image must have same width/height/format 116 | XError XImage::CopyData( const shared_ptr& copyTo ) const 117 | { 118 | XError ret = XError::Success; 119 | 120 | if ( ( mData == nullptr ) || ( !copyTo ) || ( copyTo->mData == nullptr ) ) 121 | { 122 | ret = XError::NullPointer; 123 | } 124 | // for JPEGs we just make sure there is enough space to copy the image data, 125 | // but for all uncompressed formats we check for exact match of width/height 126 | else if ( ( mHeight != copyTo->mHeight ) || ( mFormat != copyTo->mFormat ) ) 127 | { 128 | ret = XError::ImageParametersMismatch; 129 | } 130 | else if ( ( ( mFormat != XPixelFormat::JPEG ) && ( mWidth != copyTo->mWidth ) ) || 131 | ( ( mFormat == XPixelFormat::JPEG ) && ( mStride > copyTo->mStride ) ) ) 132 | { 133 | ret = XError::ImageParametersMismatch; 134 | } 135 | else 136 | { 137 | uint32_t lineSize = XImageBytesPerLine( mWidth * XImageBitsPerPixel( mFormat ) ); 138 | uint8_t* srcPtr = mData; 139 | uint8_t* dstPtr = copyTo->mData; 140 | int32_t dstStride = copyTo->mStride; 141 | 142 | for ( int y = 0; y < mHeight; y++ ) 143 | { 144 | memcpy( dstPtr, srcPtr, lineSize ); 145 | srcPtr += mStride; 146 | dstPtr += dstStride; 147 | } 148 | 149 | if ( mFormat == XPixelFormat::JPEG ) 150 | { 151 | // set correct size of destionation JPEG image 152 | copyTo->mWidth = mWidth; 153 | } 154 | } 155 | 156 | return ret; 157 | } 158 | 159 | // Copy content of the image into the specified one if its size/format is same or make a clone 160 | XError XImage::CopyDataOrClone( std::shared_ptr& copyTo ) const 161 | { 162 | XError ret = XError::Success; 163 | 164 | if ( ( !copyTo ) || 165 | ( copyTo->Height( ) != mHeight ) || 166 | ( copyTo->Format( ) != mFormat ) || 167 | ( ( mFormat != XPixelFormat::JPEG ) && ( copyTo->Width( ) != mWidth ) ) || 168 | ( ( mFormat == XPixelFormat::JPEG ) && ( copyTo->Stride( ) < mStride ) ) 169 | ) 170 | { 171 | copyTo = Clone( ); 172 | if ( !copyTo ) 173 | { 174 | ret = XError::OutOfMemory; 175 | } 176 | } 177 | else 178 | { 179 | ret = CopyData( copyTo ); 180 | } 181 | 182 | return ret; 183 | } 184 | -------------------------------------------------------------------------------- /src/core/XJpegEncoder.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include "XJpegEncoder.hpp" 22 | 23 | #include 24 | #include 25 | 26 | using namespace std; 27 | 28 | namespace Private 29 | { 30 | class JpegException : public exception 31 | { 32 | public: 33 | virtual const char* what( ) const throw( ) 34 | { 35 | return "JPEG coding failure"; 36 | } 37 | }; 38 | 39 | static void my_error_exit( j_common_ptr /* cinfo */ ) 40 | { 41 | throw JpegException( ); 42 | } 43 | 44 | static void my_output_message( j_common_ptr /* cinfo */ ) 45 | { 46 | // do nothing - kill the message 47 | } 48 | 49 | class XJpegEncoderData 50 | { 51 | public: 52 | uint16_t Quality; 53 | bool FasterCompression; 54 | private: 55 | struct jpeg_compress_struct cinfo; 56 | struct jpeg_error_mgr jerr; 57 | 58 | public: 59 | XJpegEncoderData( uint16_t quality, bool fasterCompression) : 60 | Quality( quality ), FasterCompression( fasterCompression ) 61 | { 62 | if ( Quality > 100 ) 63 | { 64 | Quality = 100; 65 | } 66 | 67 | // allocate and initialize JPEG compression object 68 | cinfo.err = jpeg_std_error( &jerr ); 69 | jerr.error_exit = my_error_exit; 70 | jerr.output_message = my_output_message; 71 | 72 | jpeg_create_compress( &cinfo ); 73 | } 74 | 75 | ~XJpegEncoderData( ) 76 | { 77 | jpeg_destroy_compress( &cinfo ); 78 | } 79 | 80 | XError EncodeToMemory( const shared_ptr& image, uint8_t** buffer, uint32_t* bufferSize ); 81 | }; 82 | } 83 | 84 | XJpegEncoder::XJpegEncoder( uint16_t quality, bool fasterCompression ) : 85 | mData( new Private::XJpegEncoderData( quality, fasterCompression ) ) 86 | { 87 | 88 | } 89 | 90 | XJpegEncoder::~XJpegEncoder( ) 91 | { 92 | delete mData; 93 | } 94 | 95 | // Set/get compression quality, [0, 100] 96 | uint16_t XJpegEncoder::Quality( ) const 97 | { 98 | return mData->Quality; 99 | } 100 | void XJpegEncoder::SetQuality( uint16_t quality ) 101 | { 102 | mData->Quality = quality; 103 | if ( mData->Quality > 100 ) mData->Quality = 100; 104 | if ( mData->Quality < 1 ) mData->Quality = 1; 105 | } 106 | 107 | // Set/get faster compression (but less accurate) flag 108 | bool XJpegEncoder::FasterCompression( ) const 109 | { 110 | return mData->FasterCompression; 111 | } 112 | void XJpegEncoder::SetFasterCompression( bool faster ) 113 | { 114 | mData->FasterCompression = faster; 115 | } 116 | 117 | // Compress the specified image into provided buffer 118 | XError XJpegEncoder::EncodeToMemory( const shared_ptr& image, uint8_t** buffer, uint32_t* bufferSize ) 119 | { 120 | return mData->EncodeToMemory( image, buffer, bufferSize ); 121 | } 122 | 123 | namespace Private 124 | { 125 | 126 | XError XJpegEncoderData::EncodeToMemory( const shared_ptr& image, uint8_t** buffer, uint32_t* bufferSize ) 127 | { 128 | JSAMPROW row_pointer[1]; 129 | XError ret = XError::Success; 130 | 131 | if ( ( !image ) || ( image->Data( ) == nullptr ) || ( buffer == nullptr ) || ( *buffer == nullptr ) || ( bufferSize == nullptr ) ) 132 | { 133 | ret = XError::NullPointer; 134 | } 135 | else if ( ( image->Format( ) != XPixelFormat::RGB24 ) && ( image->Format( ) != XPixelFormat::Grayscale8 ) ) 136 | { 137 | ret = XError::UnsupportedPixelFormat; 138 | } 139 | else 140 | { 141 | try 142 | { 143 | // 1 - specify data destination 144 | unsigned long mem_buffer_size = *bufferSize; 145 | jpeg_mem_dest( &cinfo, buffer, &mem_buffer_size ); 146 | 147 | // 2 - set parameters for compression 148 | cinfo.image_width = image->Width( ); 149 | cinfo.image_height = image->Height( ); 150 | 151 | if ( image->Format( ) == XPixelFormat::RGB24 ) 152 | { 153 | cinfo.input_components = 3; 154 | cinfo.in_color_space = JCS_RGB; 155 | } 156 | else 157 | { 158 | cinfo.input_components = 1; 159 | cinfo.in_color_space = JCS_GRAYSCALE; 160 | } 161 | 162 | // set default compression parameters 163 | jpeg_set_defaults( &cinfo ); 164 | // set quality 165 | jpeg_set_quality( &cinfo, (int) Quality, TRUE /* limit to baseline-JPEG values */ ); 166 | 167 | // use faster, but less accurate compressions 168 | cinfo.dct_method = ( FasterCompression ) ? JDCT_FASTEST : JDCT_DEFAULT; 169 | 170 | // 3 - start compressor 171 | jpeg_start_compress( &cinfo, TRUE ); 172 | 173 | // 4 - do compression 174 | while ( cinfo.next_scanline < cinfo.image_height ) 175 | { 176 | row_pointer[0] = image->Data( ) + image->Stride( ) * cinfo.next_scanline; 177 | 178 | jpeg_write_scanlines( &cinfo, row_pointer, 1 ); 179 | } 180 | 181 | // 5 - finish compression 182 | jpeg_finish_compress( &cinfo ); 183 | 184 | *bufferSize = (uint32_t) mem_buffer_size; 185 | } 186 | catch ( const JpegException& ) 187 | { 188 | ret = XError::FailedImageEncoding; 189 | } 190 | } 191 | 192 | return ret; 193 | } 194 | 195 | } // namespace Private 196 | -------------------------------------------------------------------------------- /src/core/cameras/DirectShow/XLocalVideoDevice.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef XLOCAL_VIDEO_DEVICE_HPP 22 | #define XLOCAL_VIDEO_DEVICE_HPP 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #include "XDeviceName.hpp" 29 | #include "XDeviceCapabilities.hpp" 30 | #include "XDevicePinInfo.hpp" 31 | 32 | namespace Private 33 | { 34 | class XLocalVideoDeviceData; 35 | }; 36 | 37 | enum class XVideoProperty 38 | { 39 | Brightness = 0, 40 | Contrast, 41 | Hue, 42 | Saturation, 43 | Sharpness, 44 | Gamma, 45 | ColorEnable, 46 | WhiteBalance, 47 | BacklightCompensation, 48 | Gain 49 | }; 50 | 51 | enum class XCameraProperty 52 | { 53 | Pan = 0, 54 | Tilt, 55 | Roll, 56 | Zoom, 57 | Exposure, 58 | Iris, 59 | Focus 60 | }; 61 | 62 | // Class which provides access to local video devices available through DirectShow interface 63 | class XLocalVideoDevice : public IVideoSource, private Uncopyable 64 | { 65 | private: 66 | XLocalVideoDevice( const std::string& deviceMoniker ); 67 | 68 | public: 69 | ~XLocalVideoDevice( ); 70 | 71 | static const std::shared_ptr Create( const std::string& deviceMoniker = std::string( ) ); 72 | 73 | // Start video source so it initializes and begins providing video frames 74 | virtual bool Start( ); 75 | // Signal video source to stop, so it could finalize and clean-up 76 | virtual void SignalToStop( ); 77 | // Wait till video source stops 78 | virtual void WaitForStop( ); 79 | // Check if video source (its background thread) is running or not 80 | virtual bool IsRunning( ); 81 | // Get number of frames received since the the start of the video source 82 | virtual uint32_t FramesReceived( ); 83 | 84 | // Set video source listener returning the old one 85 | virtual IVideoSourceListener* SetListener( IVideoSourceListener* listener ); 86 | 87 | // Set device moniker for the video source (video source must not be running) 88 | bool SetDeviceMoniker( const std::string& moniker ); 89 | // Set resolution and frame rate of the device (video source must not be running) 90 | bool SetResolution( const XDeviceCapabilities& resolution, uint32_t requestedFps = 0 ); 91 | // Set video input of the device 92 | void SetVideoInput( const XDevicePinInfo& input ); 93 | 94 | // Get/Set JPEG encoding preference. Not guaranteed as device/driver may not support it. 95 | bool IsJpegEncodingPreferred( ) const; 96 | void PreferJpegEncoding( bool prefer ); 97 | // Check if running device was configured to provide JPEG images. Always returns 98 | // false for not running devices. NOTE: provided image pixel format already will indicate 99 | // this, but having extra property may be handy. 100 | bool IsJpegEncodingEnabled( ) const; 101 | 102 | // Get capabilities of the device (resolutions and frame rates) 103 | const std::vector GetCapabilities( ); 104 | // Get available video pins of the device if any 105 | const std::vector GetInputVideoPins( ); 106 | // Check if device supports crossbar, which would allow setting video input pin 107 | bool IsCrossbarSupported( ); 108 | 109 | // Get list of available video devices in the system 110 | static std::vector GetAvailableDevices( ); 111 | 112 | // The IsRunning() reports if video source's background thread is running or not. However, 113 | // it does not mean the video device itself is running. When the thread is started, it 114 | // needs to perform certain configuration of the device and start it, which may or may not 115 | // succeed (device can be un-plugged, used by another application, etc). So the 116 | // IsDeviceRunning() reports status of the device itself. 117 | 118 | // Check if device is running 119 | bool IsDeviceRunning( ) const; 120 | // Wait till video configuration becomes available (milliseconds) 121 | bool WaitForDeviceRunning( uint32_t msec ); 122 | 123 | // Check if video configuration is supported (device must be running) 124 | bool IsVideoConfigSupported( ) const; 125 | 126 | // Set the specified video property. The device does not have to be running. If it is not, 127 | // the setting will be cached and applied as soon as the device gets running. 128 | XError SetVideoProperty( XVideoProperty property, int32_t value, bool automatic = false ); 129 | // Get current value if the specified video property. The device must be running. 130 | XError GetVideoProperty( XVideoProperty property, int32_t* value, bool* automatic = nullptr ) const; 131 | // Get range of values supported by the specified video property 132 | XError GetVideoPropertyRange( XVideoProperty property, int32_t* min, int32_t* max, int32_t* step, int32_t* default, bool* isAutomaticSupported ) const; 133 | 134 | // Check if camera configuration is supported (device must be running) 135 | bool IsCameraConfigSupported( ) const; 136 | 137 | // Set the specified camera property. The device does not have to be running. If it is not, 138 | // the setting will be cached and applied as soon as the device gets running. 139 | XError SetCameraProperty( XCameraProperty property, int32_t value, bool automatic = false ); 140 | // Get current value if the specified camera property. The device must be running. 141 | XError GetCameraProperty( XCameraProperty property, int32_t* value, bool* automatic = nullptr ) const; 142 | // Get range of values supported by the specified camera property 143 | XError GetCameraPropertyRange( XCameraProperty property, int32_t* min, int32_t* max, int32_t* step, int32_t* default, bool* isAutomaticSupported ) const; 144 | 145 | private: 146 | Private::XLocalVideoDeviceData* mData; 147 | }; 148 | 149 | #endif // XLOCAL_VIDEO_DEVICE_HPP 150 | -------------------------------------------------------------------------------- /src/web/cameraproperties.html: -------------------------------------------------------------------------------- 1 | 9 | 10 | 194 | -------------------------------------------------------------------------------- /src/apps/win/Tools.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017-2019, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | // Exclude rarely-used stuff from Windows headers 22 | #define WIN32_LEAN_AND_MEAN 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include "Tools.hpp" 30 | 31 | using namespace std; 32 | 33 | static const char* STR_ARGB_FORMAT32 = "%08X"; 34 | static const char* STR_ARGB_FORMAT24 = "%06X"; 35 | 36 | // Convert specfied UTF8 string to wide character string 37 | wstring Utf8to16( const string& utf8string ) 38 | { 39 | wstring ret; 40 | 41 | int required = MultiByteToWideChar( CP_UTF8, 0, utf8string.c_str( ), -1, nullptr, 0 ); 42 | 43 | if ( required > 0 ) 44 | { 45 | wchar_t* utf16string = new wchar_t[required]; 46 | 47 | if ( MultiByteToWideChar( CP_UTF8, 0, utf8string.c_str( ), -1, utf16string, required ) > 0 ) 48 | { 49 | ret = wstring( utf16string ); 50 | } 51 | 52 | delete[] utf16string; 53 | } 54 | 55 | return ret; 56 | } 57 | 58 | // Convert specfied wide character string to UTF8 string 59 | string Utf16to8( const wstring& utf16string ) 60 | { 61 | string ret; 62 | 63 | int required = WideCharToMultiByte( CP_UTF8, 0, utf16string.c_str( ), -1, nullptr, 0, nullptr, nullptr ); 64 | 65 | if ( required > 0 ) 66 | { 67 | char* utf8string = new char[required]; 68 | 69 | if ( WideCharToMultiByte( CP_UTF8, 0, utf16string.c_str( ), -1, utf8string, required, nullptr, nullptr ) > 0 ) 70 | { 71 | ret = string( utf8string ); 72 | } 73 | 74 | delete[] utf8string; 75 | } 76 | 77 | return ret; 78 | } 79 | 80 | // Calculate MD5 hash string for the given buffer 81 | string GetMd5Hash( const uint8_t* buffer, int bufferLength ) 82 | { 83 | HCRYPTPROV hCryptProv = NULL; 84 | HCRYPTHASH hHash = NULL; 85 | string md5str; 86 | 87 | if ( CryptAcquireContext( &hCryptProv, NULL, NULL, PROV_RSA_FULL, 0 ) ) 88 | { 89 | if ( CryptCreateHash( hCryptProv, CALG_MD5, 0, 0, &hHash ) ) 90 | { 91 | if ( CryptHashData( hHash, buffer, bufferLength, 0 ) ) 92 | { 93 | DWORD dataLength; 94 | DWORD hashSize; 95 | 96 | dataLength = sizeof( hashSize ); 97 | if ( CryptGetHashParam( hHash, HP_HASHSIZE, (BYTE*) &hashSize, &dataLength, 0 ) ) 98 | { 99 | BYTE* hashValue = new BYTE[hashSize]; 100 | 101 | dataLength = hashSize; 102 | if ( CryptGetHashParam( hHash, HP_HASHVAL, hashValue, &dataLength, 0 ) ) 103 | { 104 | char hex[3]; 105 | 106 | for ( DWORD i = 0; i < hashSize; i++ ) 107 | { 108 | _itoa( hashValue[i], hex, 16 ); 109 | md5str += hex; 110 | } 111 | } 112 | 113 | delete [] hashValue; 114 | } 115 | } 116 | } 117 | } 118 | 119 | if ( hHash != NULL ) 120 | { 121 | CryptDestroyHash( hHash ); 122 | } 123 | if ( hCryptProv != NULL ) 124 | { 125 | CryptReleaseContext( hCryptProv, 0 ); 126 | } 127 | 128 | return md5str; 129 | } 130 | 131 | // Get local IP address as string (if a single valid IP found). Returns empty string if fails to resolve. 132 | string GetLocalIpAddress( ) 133 | { 134 | PIP_ADAPTER_INFO pAdapterInfo = (IP_ADAPTER_INFO *) malloc( sizeof( IP_ADAPTER_INFO ) ); 135 | PIP_ADAPTER_INFO pAdapter = nullptr; 136 | ULONG ulOutBufLen = sizeof( IP_ADAPTER_INFO ); 137 | string localIp; 138 | 139 | if ( pAdapterInfo != nullptr ) 140 | { 141 | if ( GetAdaptersInfo( pAdapterInfo, &ulOutBufLen ) == ERROR_BUFFER_OVERFLOW ) 142 | { 143 | free( pAdapterInfo ); 144 | pAdapterInfo = (IP_ADAPTER_INFO *) malloc( ulOutBufLen ); 145 | } 146 | } 147 | 148 | if ( pAdapterInfo != nullptr ) 149 | { 150 | if ( GetAdaptersInfo( pAdapterInfo, &ulOutBufLen ) == NO_ERROR ) 151 | { 152 | pAdapter = pAdapterInfo; 153 | 154 | while ( pAdapter ) 155 | { 156 | if ( ( strcmp( pAdapter->IpAddressList.IpAddress.String, "0.0.0.0" ) != 0 ) && 157 | ( strcmp( pAdapter->GatewayList.IpAddress.String, "0.0.0.0" ) != 0 ) && 158 | ( pAdapter->IpAddressList.Next == nullptr ) && 159 | ( pAdapter->GatewayList.Next == nullptr ) ) 160 | { 161 | if ( localIp.empty( ) ) 162 | { 163 | localIp = string( pAdapter->IpAddressList.IpAddress.String ); 164 | } 165 | else 166 | { 167 | // if there is more than one valid IP, assume we've failed 168 | localIp.clear( ); 169 | break; 170 | } 171 | } 172 | 173 | pAdapter = pAdapter->Next; 174 | } 175 | } 176 | 177 | free( pAdapterInfo ); 178 | } 179 | 180 | return localIp; 181 | } 182 | 183 | // Convert xargb to string 184 | std::string XargbToString( xargb color ) 185 | { 186 | char buffer[16]; 187 | 188 | if ( color.components.a != 0xFF ) 189 | { 190 | sprintf( buffer, STR_ARGB_FORMAT32, color.argb ); 191 | } 192 | else 193 | { 194 | color.components.a = 0; 195 | sprintf( buffer, STR_ARGB_FORMAT24, color.argb ); 196 | } 197 | 198 | return string( buffer ); 199 | } 200 | 201 | // Parse xargb from string 202 | bool StringToXargb( const string& str, xargb* color ) 203 | { 204 | size_t len = str.length( ); 205 | xargb newColor = { 0xFF000000 }; 206 | bool parsed = false; 207 | 208 | if ( len == 8 ) 209 | { 210 | parsed = ( sscanf( str.c_str( ), STR_ARGB_FORMAT32, &newColor.argb ) == 1 ); 211 | } 212 | else if ( len == 6 ) 213 | { 214 | // in the case if only 6 hex numbers present, suppose it is RGB value with alpha set to FF 215 | if ( sscanf( str.c_str( ), STR_ARGB_FORMAT24, &newColor.argb ) == 1 ) 216 | { 217 | newColor.components.a = 0xFF; 218 | parsed = true; 219 | } 220 | } 221 | 222 | if ( ( color != nullptr ) && ( parsed ) ) 223 | { 224 | *color = newColor; 225 | } 226 | 227 | return parsed; 228 | } 229 | -------------------------------------------------------------------------------- /src/apps/win/EditUserDialog.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | // Exclude rarely-used stuff from Windows headers 22 | #define WIN32_LEAN_AND_MEAN 23 | 24 | #include 25 | #include 26 | 27 | #include "resource.h" 28 | #include "EditUserDialog.hpp" 29 | #include "Tools.hpp" 30 | #include "UiTools.hpp" 31 | 32 | using namespace std; 33 | 34 | #define STR_ERROR TEXT( "Error" ) 35 | 36 | // Message handler for Add/Edit User dialog box 37 | INT_PTR CALLBACK EditUserDialogProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam ) 38 | { 39 | static HICON hIcon = NULL; 40 | static UserInfo* pUserInfo = nullptr; 41 | int wmId; 42 | int wmEvent; 43 | 44 | switch ( message ) 45 | { 46 | case WM_INITDIALOG: 47 | { 48 | HWND hwndUserNameEdit = GetDlgItem( hDlg, IDC_USER_NAME_EDIT ); 49 | HWND hwndUserRoleCombo = GetDlgItem( hDlg, IDC_USER_ROLE_COMBO ); 50 | HWND hwndPasswordEdit = GetDlgItem( hDlg, IDC_PASSWORD_EDIT ); 51 | HWND hwndRePasswordEdit = GetDlgItem( hDlg, IDC_RE_PASSWORD_EDIT ); 52 | 53 | CenterWindowTo( hDlg, GetParent( hDlg ) ); 54 | 55 | hIcon = (HICON) LoadImage( GetModuleHandle( NULL ), MAKEINTRESOURCE( IDI_FAMILY ), IMAGE_ICON, 56 | GetSystemMetrics( SM_CXSMICON ), GetSystemMetrics( SM_CYSMICON ), 0 ); 57 | 58 | if ( hIcon ) 59 | { 60 | SendMessage( hDlg, WM_SETICON, ICON_SMALL, (LPARAM) hIcon ); 61 | } 62 | 63 | // limit length of user name/password to something sensible 64 | SendMessage( hwndUserNameEdit, EM_SETLIMITTEXT, 32, 0 ); 65 | SendMessage( hwndPasswordEdit, EM_SETLIMITTEXT, 32, 0 ); 66 | SendMessage( hwndRePasswordEdit, EM_SETLIMITTEXT, 32, 0 ); 67 | 68 | SendMessage( hwndUserRoleCombo, CB_ADDSTRING, 0, (LPARAM) L"User" ); 69 | SendMessage( hwndUserRoleCombo, CB_ADDSTRING, 0, (LPARAM) L"Admin" ); 70 | SendMessage( hwndUserRoleCombo, CB_SETCURSEL, 0, 0 ); 71 | 72 | pUserInfo = (UserInfo*) lParam; 73 | 74 | if ( pUserInfo != nullptr ) 75 | { 76 | if ( !pUserInfo->Name.empty( ) ) 77 | { 78 | wstring password = Utf8to16( pUserInfo->Password ); 79 | 80 | SetWindowText( hwndUserNameEdit, Utf8to16( pUserInfo->Name ).c_str( ) ); 81 | SetWindowText( hwndPasswordEdit, password.c_str( ) ); 82 | SetWindowText( hwndRePasswordEdit, password.c_str( ) ); 83 | SendMessage( hwndUserRoleCombo, CB_SETCURSEL, ( pUserInfo->IsAdmin ) ? 1 : 0, 0 ); 84 | 85 | // allow editting everything except user name 86 | SendMessage( hwndUserNameEdit, EM_SETREADONLY, 1, 0 ); 87 | 88 | SetWindowText( hDlg, L"Edit user" ); 89 | } 90 | else 91 | { 92 | // disable OK button, since user name/password are all empty 93 | EnableWindow( GetDlgItem( hDlg, IDOK ), FALSE ); 94 | } 95 | 96 | pUserInfo->PasswordChanged = false; 97 | } 98 | } 99 | return (INT_PTR) TRUE; 100 | 101 | case WM_DESTROY: 102 | 103 | if ( hIcon ) 104 | { 105 | DestroyIcon( hIcon ); 106 | } 107 | 108 | pUserInfo = nullptr; 109 | 110 | return (INT_PTR) TRUE; 111 | 112 | case WM_COMMAND: 113 | wmId = LOWORD( wParam ); 114 | wmEvent = HIWORD( wParam ); 115 | 116 | if ( ( wmId == IDOK ) || ( wmId == IDCANCEL ) ) 117 | { 118 | bool allFine = true; 119 | 120 | if ( ( wmId == IDOK ) && ( pUserInfo ) ) 121 | { 122 | string userName = GetWindowString( GetDlgItem( hDlg, IDC_USER_NAME_EDIT ), true ); 123 | string password1 = GetWindowString( GetDlgItem( hDlg, IDC_PASSWORD_EDIT ), false ); 124 | string password2 = GetWindowString( GetDlgItem( hDlg, IDC_RE_PASSWORD_EDIT ), false ); 125 | 126 | allFine = false; 127 | 128 | if ( std::find( pUserInfo->ExistingUserNames.begin( ), pUserInfo->ExistingUserNames.end( ), userName ) != pUserInfo->ExistingUserNames.end( ) ) 129 | { 130 | CenteredMessageBox( hDlg, L"A user with the specified name already exists.", STR_ERROR, MB_OK | MB_ICONERROR ); 131 | } 132 | else if ( password1 != password2 ) 133 | { 134 | CenteredMessageBox( hDlg, L"The two passwords don't match.", STR_ERROR, MB_OK | MB_ICONERROR ); 135 | } 136 | else if ( userName.find( ':' ) != string::npos ) 137 | { 138 | CenteredMessageBox( hDlg, L"User names are not allowed to contain colon character (':').", STR_ERROR, MB_OK | MB_ICONERROR ); 139 | } 140 | else 141 | { 142 | allFine = true; 143 | 144 | pUserInfo->Name = userName; 145 | pUserInfo->Password = password1; 146 | pUserInfo->IsAdmin = ( SendMessage( GetDlgItem( hDlg, IDC_USER_ROLE_COMBO ), CB_GETCURSEL, 0, 0 ) == 1 ); 147 | } 148 | } 149 | 150 | if ( allFine ) 151 | { 152 | EndDialog( hDlg, wmId ); 153 | } 154 | return (INT_PTR) TRUE; 155 | } 156 | else if ( wmEvent == EN_CHANGE ) 157 | { 158 | if ( ( wmId == IDC_USER_NAME_EDIT ) || ( wmId == IDC_PASSWORD_EDIT ) || ( wmId == IDC_RE_PASSWORD_EDIT ) ) 159 | { 160 | string userName = GetWindowString( GetDlgItem( hDlg, IDC_USER_NAME_EDIT ), true ); 161 | string password1 = GetWindowString( GetDlgItem( hDlg, IDC_PASSWORD_EDIT ), false ); 162 | string password2 = GetWindowString( GetDlgItem( hDlg, IDC_RE_PASSWORD_EDIT ), false ); 163 | bool isEmpty = ( userName.empty( ) || password1.empty( ) || password2.empty( ) ); 164 | 165 | EnableWindow( GetDlgItem( hDlg, IDOK ), ( isEmpty ) ? FALSE : TRUE ); 166 | 167 | if ( ( pUserInfo != nullptr ) && ( ( wmId == IDC_PASSWORD_EDIT ) || ( wmId == IDC_RE_PASSWORD_EDIT ) ) ) 168 | { 169 | pUserInfo->PasswordChanged = true; 170 | } 171 | 172 | return (INT_PTR) TRUE; 173 | } 174 | } 175 | 176 | break; 177 | } 178 | 179 | return (INT_PTR) FALSE; 180 | } 181 | -------------------------------------------------------------------------------- /src/core/cameras/V4L2/XV4LCameraConfig.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include "XV4LCameraConfig.hpp" 26 | 27 | using namespace std; 28 | 29 | #define TYPE_INT (0) 30 | #define TYPE_BOOL (1) 31 | 32 | typedef struct 33 | { 34 | XVideoProperty VideoProperty; 35 | uint16_t Type; 36 | uint16_t Order; 37 | const char* Name; 38 | } 39 | PropertyInformation; 40 | 41 | const static map SupportedProperties = 42 | { 43 | { "brightness", { XVideoProperty::Brightness, TYPE_INT, 0, "Brightness" } }, 44 | { "contrast", { XVideoProperty::Contrast, TYPE_INT, 1, "Contrast" } }, 45 | { "saturation", { XVideoProperty::Saturation, TYPE_INT, 2, "Saturation" } }, 46 | { "hue", { XVideoProperty::Hue, TYPE_INT, 3, "Hue" } }, 47 | { "sharpness", { XVideoProperty::Sharpness, TYPE_INT, 4, "Sharpness" } }, 48 | { "gain", { XVideoProperty::Gain, TYPE_INT, 5, "Gain" } }, 49 | { "blc", { XVideoProperty::BacklightCompensation, TYPE_INT, 6, "Back Light Compensation" } }, 50 | { "redBalance", { XVideoProperty::RedBalance, TYPE_INT, 7, "Red Balance" } }, 51 | { "blueBalance", { XVideoProperty::BlueBalance, TYPE_INT, 8, "Blue Balance" } }, 52 | { "awb", { XVideoProperty::AutoWhiteBalance, TYPE_BOOL, 9, "Automatic White Balance" } }, 53 | { "hflip", { XVideoProperty::HorizontalFlip, TYPE_BOOL, 10, "Horizontal Flip" } }, 54 | { "vflip", { XVideoProperty::VerticalFlip, TYPE_BOOL, 11, "Vertical Flip" } } 55 | }; 56 | 57 | // ------------------------------------------------------------------------------------------ 58 | 59 | XV4LCameraConfig::XV4LCameraConfig( const shared_ptr& camera ) : 60 | mCamera( camera ) 61 | { 62 | 63 | } 64 | 65 | // Set the specified property of a DirectShow video device 66 | XError XV4LCameraConfig::SetProperty( const string& propertyName, const string& value ) 67 | { 68 | XError ret = XError::Success; 69 | int32_t propValue = 0; 70 | 71 | // assume all configuration values are numeric 72 | int scannedCount = sscanf( value.c_str( ), "%d", &propValue ); 73 | 74 | if ( scannedCount != 1 ) 75 | { 76 | ret = XError::InvalidPropertyValue; 77 | } 78 | else 79 | { 80 | map::const_iterator itSupportedProperty = SupportedProperties.find( propertyName ); 81 | 82 | if ( itSupportedProperty == SupportedProperties.end( ) ) 83 | { 84 | ret = XError::UnknownProperty; 85 | } 86 | else 87 | { 88 | ret = mCamera->SetVideoProperty( itSupportedProperty->second.VideoProperty, propValue ); 89 | } 90 | } 91 | 92 | return ret; 93 | } 94 | 95 | // Get the specified property of a DirectShow video device 96 | XError XV4LCameraConfig::GetProperty( const string& propertyName, string& value ) const 97 | { 98 | XError ret = XError::Success; 99 | int32_t propValue = 0; 100 | char buffer[32]; 101 | 102 | // find the property in the list of supported 103 | map::const_iterator itSupportedProperty = SupportedProperties.find( propertyName ); 104 | 105 | if ( itSupportedProperty == SupportedProperties.end( ) ) 106 | { 107 | ret = XError::UnknownProperty; 108 | } 109 | else 110 | { 111 | // get the property value itself 112 | ret = mCamera->GetVideoProperty( itSupportedProperty->second.VideoProperty, &propValue ); 113 | } 114 | 115 | if ( ret ) 116 | { 117 | sprintf( buffer, "%d", propValue ); 118 | value = buffer; 119 | } 120 | 121 | return ret; 122 | } 123 | 124 | // Get all supported properties of a DirectShow video device 125 | map XV4LCameraConfig::GetAllProperties( ) const 126 | { 127 | map properties; 128 | string value; 129 | 130 | for ( auto property : SupportedProperties ) 131 | { 132 | if ( GetProperty( property.first, value ) ) 133 | { 134 | properties.insert( pair( property.first, value ) ); 135 | } 136 | } 137 | 138 | return properties; 139 | } 140 | 141 | // ------------------------------------------------------------------------------------------ 142 | 143 | XV4LCameraPropsInfo::XV4LCameraPropsInfo( const shared_ptr& camera ) : 144 | mCamera( camera ) 145 | { 146 | } 147 | 148 | XError XV4LCameraPropsInfo::GetProperty( const std::string& propertyName, std::string& value ) const 149 | { 150 | XError ret = XError::Success; 151 | char buffer[128]; 152 | 153 | // find the property in the list of supported 154 | map::const_iterator itSupportedProperty = SupportedProperties.find( propertyName ); 155 | 156 | if ( itSupportedProperty == SupportedProperties.end( ) ) 157 | { 158 | ret = XError::UnknownProperty; 159 | } 160 | else 161 | { 162 | int32_t min, max, step, def; 163 | 164 | // get property features - min/max/default/etc 165 | ret = mCamera->GetVideoPropertyRange( itSupportedProperty->second.VideoProperty, &min, &max, &step, &def ); 166 | 167 | if ( ret ) 168 | { 169 | if ( itSupportedProperty->second.Type == TYPE_INT ) 170 | { 171 | sprintf( buffer, "{\"min\":%d,\"max\":%d,\"def\":%d,\"type\":\"int\",\"order\":%d,\"name\":\"%s\"}", 172 | min, max, def, itSupportedProperty->second.Order, itSupportedProperty->second.Name ); 173 | } 174 | else 175 | { 176 | sprintf( buffer, "{\"def\":%d,\"type\":\"bool\",\"order\":%d,\"name\":\"%s\"}", 177 | def, itSupportedProperty->second.Order, itSupportedProperty->second.Name ); 178 | } 179 | 180 | value = buffer; 181 | } 182 | } 183 | 184 | return ret; 185 | } 186 | 187 | // Get information for all supported properties of a DirectShow video device 188 | map XV4LCameraPropsInfo::GetAllProperties( ) const 189 | { 190 | map properties; 191 | string value; 192 | 193 | for ( auto property : SupportedProperties ) 194 | { 195 | if ( GetProperty( property.first, value ) ) 196 | { 197 | properties.insert( pair( property.first, value ) ); 198 | } 199 | } 200 | 201 | return properties; 202 | } 203 | 204 | -------------------------------------------------------------------------------- /src/core/XWebServer.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | cam2web - streaming camera to web 3 | 4 | Copyright (C) 2017-2019, cvsandbox, cvsandbox@gmail.com 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef XWEB_SERVER_HPP 22 | #define XWEB_SERVER_HPP 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include "XInterfaces.hpp" 31 | 32 | namespace Private 33 | { 34 | class XWebServerData; 35 | } 36 | 37 | enum class UserGroup 38 | { 39 | Anyone = 0, 40 | User = 1, 41 | Power = 2, 42 | Admin = 3 43 | }; 44 | 45 | enum class Authentication 46 | { 47 | Basic = 0, 48 | Digest = 1 49 | }; 50 | 51 | /* ================================================================= */ 52 | /* Web request data */ 53 | /* ================================================================= */ 54 | class IWebRequest 55 | { 56 | public: 57 | virtual ~IWebRequest( ) { } 58 | 59 | virtual std::string Uri( ) const = 0; 60 | virtual std::string Method( ) const = 0; 61 | virtual std::string Proto( ) const = 0; 62 | virtual std::string Query( ) const = 0; 63 | virtual std::string Body( ) const = 0; 64 | 65 | virtual std::string GetVariable( const std::string& name ) const = 0; 66 | 67 | virtual std::map Headers( ) const = 0; 68 | }; 69 | 70 | /* ================================================================= */ 71 | /* Web response methods */ 72 | /* ================================================================= */ 73 | class IWebResponse 74 | { 75 | public: 76 | virtual ~IWebResponse( ) { } 77 | 78 | // Length of data, which is still enqueued for sending 79 | virtual size_t ToSendDataLength( ) const = 0; 80 | 81 | virtual void Send( const uint8_t* buffer, size_t length ) = 0; 82 | virtual void Printf( const char* fmt, ... ) = 0; 83 | 84 | virtual void SendChunk( const uint8_t* buffer, size_t length ) = 0; 85 | virtual void PrintfChunk( const char* fmt, ... ) = 0; 86 | 87 | virtual void SendError( int errorCode, const char* reason = nullptr ) = 0; 88 | 89 | virtual void CloseConnection( ) = 0; 90 | 91 | // Generate timer event for the connection associated with the response 92 | // after the specified number of milliseconds 93 | virtual void SetTimer( uint32_t msec ) = 0; 94 | }; 95 | 96 | /* ================================================================= */ 97 | /* Handler of a web request */ 98 | /* ================================================================= */ 99 | class IWebRequestHandler 100 | { 101 | protected: 102 | IWebRequestHandler( const std::string& uri, bool canHandleSubContent ); 103 | 104 | public: 105 | virtual ~IWebRequestHandler( ) { } 106 | 107 | const std::string& Uri( ) const { return mUri; } 108 | bool CanHandleSubContent( ) const { return mCanHandleSubContent; } 109 | 110 | // Handle the specified request 111 | virtual void HandleHttpRequest( const IWebRequest& request, IWebResponse& response ) = 0; 112 | 113 | // Handle timer event 114 | virtual void HandleTimer( IWebResponse& ) { }; 115 | 116 | private: 117 | std::string mUri; 118 | bool mCanHandleSubContent; 119 | }; 120 | 121 | /* ================================================================= */ 122 | /* Definition of embedded content */ 123 | /* ================================================================= */ 124 | typedef struct 125 | { 126 | uint32_t Length; 127 | const char* Type; 128 | const uint8_t* Body; 129 | } 130 | XEmbeddedContent; 131 | 132 | /* ================================================================= */ 133 | /* Web request handler serving embedded content */ 134 | /* ================================================================= */ 135 | class XEmbeddedContentHandler : public IWebRequestHandler 136 | { 137 | public: 138 | XEmbeddedContentHandler( const std::string& uri, const XEmbeddedContent* content ); 139 | 140 | // Handle request providing given embedded content 141 | void HandleHttpRequest( const IWebRequest& request, IWebResponse& response ); 142 | 143 | private: 144 | const XEmbeddedContent* mContent; 145 | }; 146 | 147 | /* ================================================================= */ 148 | /* Web server class */ 149 | /* ================================================================= */ 150 | class XWebServer : private Uncopyable 151 | { 152 | public: 153 | XWebServer( const std::string& documentRoot = "", uint16_t port = 8000 ); 154 | ~XWebServer( ); 155 | 156 | /* ================================================================= */ 157 | /* All of the below configuration must be done before starting */ 158 | /* an instance of a Web server. Setting those while it is running */ 159 | /* has no effect until it is restarted. */ 160 | /* ================================================================= */ 161 | 162 | // Get/Set document root 163 | std::string DocumentRoot( ) const; 164 | XWebServer& SetDocumentRoot( const std::string& documentRoot ); 165 | 166 | // Get/Set authentication domain 167 | std::string AuthDomain( ) const; 168 | XWebServer& SetAuthDomain( const std::string& authDomain ); 169 | 170 | // Get/Set authentication method (default Digest) 171 | Authentication AuthenticationMethod( ) const; 172 | XWebServer& SetAuthenticationMethod( Authentication authMethod ); 173 | 174 | // Get/Set port 175 | uint16_t Port( ) const; 176 | XWebServer& SetPort( uint16_t port ); 177 | 178 | // Add/Remove web handler 179 | XWebServer& AddHandler( const std::shared_ptr& handler, UserGroup allowedUserGroup = UserGroup::Anyone ); 180 | void RemoveHandler( const std::shared_ptr& handler ); 181 | 182 | // Remove all handlers 183 | void ClearHandlers( ); 184 | 185 | // ============================================================== 186 | 187 | // Start/Stop the Web server 188 | bool Start( ); 189 | void Stop( ); 190 | 191 | // Get time of the last access/request to the web server 192 | std::chrono::steady_clock::time_point LastAccessTime( bool* pWasAccessed = nullptr ); 193 | // Get time of the last access/request to the specified handler 194 | std::chrono::steady_clock::time_point LastAccessTime( const std::string& handlerUri, bool* pWasAccessed = nullptr ); 195 | 196 | // Add/Remove user to access protected request handlers 197 | XWebServer& AddUser( const std::string& name, const std::string& digestHa1, UserGroup group ); 198 | void RemoveUser( const std::string& name ); 199 | 200 | // Load users from file having "htdigest" format (returns number of loaded users) 201 | uint32_t LoadUsersFromFile( const std::string& fileName ); 202 | 203 | // Clear the list of users who can access the web server 204 | void ClearUsers( ); 205 | 206 | public: 207 | // Calculate HA1 as defined by Digest authentication algorithm, MD5(user:domain:pass). 208 | static std::string CalculateDigestAuthHa1( const std::string& user, const std::string& domain, const std::string& pass ); 209 | 210 | private: 211 | Private::XWebServerData* mData; 212 | }; 213 | 214 | #endif // XWEB_SERVER_HPP 215 | --------------------------------------------------------------------------------