/*
-----------------------------------------------------------------------------
This source file is part of OpenSpace3D
For the latest info, see http://www.openspace3d.com
Copyright (c) 2012 I-maginer
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt
-----------------------------------------------------------------------------
*/
/*
Version : 1.0
First version : 01/05/2011
Author : Aymeric Suteau
*/
/*-------------------- Global variables --------------------*/
var sCaptureFilePath = "tmp/capture/";;
var sCaptureFolder = "";;
var iPictureIndex = 0;;
var sExtension = "";;
/*-------------------- Global structure --------------------*/
struct CaptureStr = [
PCAPTURE_inst : PInstance,
PCAPTURE_preview : Video,
PCAPTURE_capBmp : ObjBitmap,
PCAPTURE_file : W,
PCAPTURE_sFileName : S,
PCAPTURE_width : I,
PCAPTURE_heigth : I,
PCAPTURE_cameraIndex : I,
PCAPTURE_fps : I,
PCAPTURE_showVideo : I,
PCAPTURE_format : I,
PCAPTURE_quality : I,
PCAPTURE_timer : Timer
] mkCaptureStr;;
/*! \brief Callback on instance destruction
*
* Prototype: fun [PInstance] I
*
* \param PInstance : destroyed plugIT instance
*
* \return I : 0
**/
fun deleteOb(inst, captureStr)=
// Destroy timer
if (captureStr.PCAPTURE_timer == nil) then nil else
(
_deltimer captureStr.PCAPTURE_timer;
set captureStr.PCAPTURE_timer = nil;
);
// Destroy bitmap
_DSbitmap captureStr.PCAPTURE_capBmp;
// Destroy the capture window
if (captureStr.PCAPTURE_preview == nil) then nil else _DScapWindow captureStr.PCAPTURE_preview;
// Reset picture index
set iPictureIndex = 0;
0;;
/*! \brief Get current frame
*
* Get the current frame and save it to ObjBitmap
*
* Prototype: fun [PInstance DMI S S I [F F F I]] I
*
* \param captureStr : object structure
* \param PInstance : plugIT instance
*
* \return I : 0
**/
fun cbSetupVideoCap(video, captureStr, sbmp)=
// Bitmap
let _InvertCapBitmap sbmp captureStr.PCAPTURE_width -> sbmp in
set captureStr.PCAPTURE_capBmp = _SETbitmap captureStr.PCAPTURE_capBmp sbmp;
// Update picture index to 1 (means that the first frame has been successfully grabbed)
if (iPictureIndex == 0) then set iPictureIndex = iPictureIndex + 1 else nil;
0;;
/*! \brief Add a line to the log file
*
* Prototype: fun [PInstance] I
*
* \param PInstance : Log file Instance
*
* \return I : 0
**/
fun cbTimerSaveFrame(trm, captureStr)=
// Update file name
if (captureStr.PCAPTURE_format == 0) then set sExtension = ".jpg" else set sExtension = ".bmp";
set captureStr.PCAPTURE_sFileName = strcatn sCaptureFilePath::sCaptureFolder::"/"::(strreplace (strcatnSep (hd strextr (ctime time)) "_") ":" "-")::"_"::(itoa iPictureIndex)::"_"::(getPluginInstanceName captureStr.PCAPTURE_inst)::sExtension::nil;
_deletepack _checkpack captureStr.PCAPTURE_sFileName;
set captureStr.PCAPTURE_file = _getmodifypack captureStr.PCAPTURE_sFileName;
// Save bitmap to file
if (iPictureIndex == 0) then nil else
(
if (captureStr.PCAPTURE_format == 0) then
(
_SAVEjpeg captureStr.PCAPTURE_capBmp captureStr.PCAPTURE_file captureStr.PCAPTURE_quality;
_fooS ">>> JPEG format";
)
else
(
_SAVEbitmap captureStr.PCAPTURE_capBmp captureStr.PCAPTURE_file;
_fooS ">>> BMP format";
);
set iPictureIndex = iPictureIndex + 1;
);
0;;
/*! \brief Start capture
*
* Start capture from camera
*
* Prototype: fun [PInstance DMI S S I [F F F I]] I
*
* \param captureStr : object structure
* \param PInstance : plugIT instance
*
* \return I : 0
**/
fun cbStartCapture(inst, from, action, param, reply, captureStr)=
// Start capture
if captureStr.PCAPTURE_preview == nil then _fooS ">>> Camera not started" else
(
_SETcapVideoStart captureStr.PCAPTURE_preview @cbSetupVideoCap captureStr;
_fooS ">>> Camera started";
);
// Start log: timer period = 1000 * (1 / fps) (ms)
if (captureStr.PCAPTURE_timer != nil) then nil else
set captureStr.PCAPTURE_timer = _rfltimer _starttimer _channel (ftoi (1000.0 *. (1.0 /. (itof captureStr.PCAPTURE_fps)))) @cbTimerSaveFrame captureStr;
0;;
/*! \brief Stop capture
*
* Stop capture from camera
*
* Prototype: fun [PInstance DMI S S I [F F F I]] I
*
* \param captureStr : object structure
* \param PInstance : plugIT instance
*
* \return I : 0
**/
fun cbStopCapture(inst, from, action, param, reply, captureStr)=
// Stop timer
if (captureStr.PCAPTURE_timer == nil) then nil else
(
_deltimer captureStr.PCAPTURE_timer;
set captureStr.PCAPTURE_timer = nil;
);
// Stop capture from camera
if (captureStr.PCAPTURE_preview == nil) then nil else _SETcapVideoStop captureStr.PCAPTURE_preview;
// Reset global variable
set iPictureIndex = 0;
0;;
/*! \brief Pause capture
*
* Pause capture from camera
*
* Prototype: fun [PInstance DMI S S I [F F F I]] I
*
* \param captureStr : object structure
* \param PInstance : plugIT instance
*
* \return I : 0
**/
fun cbPauseCapture(inst, from, action, param, reply, captureStr)=
// Pause timer
if (captureStr.PCAPTURE_timer == nil) then nil else
(
_deltimer captureStr.PCAPTURE_timer;
set captureStr.PCAPTURE_timer = nil;
);
// Pause capture from camera
if (captureStr.PCAPTURE_preview == nil) then nil else _SETcapVideoStop captureStr.PCAPTURE_preview;
0;;
/*! \brief Resume capture
*
* Resume capture from camera
*
* Prototype: fun [PInstance DMI S S I [F F F I]] I
*
* \param captureStr : object structure
* \param PInstance : plugIT instance
*
* \return I : 0
**/
fun cbResumeCapture(inst, from, action, param, reply, captureStr)=
// Resume capture
if captureStr.PCAPTURE_preview == nil then _fooS ">>> Camera not restarted" else
(
_SETcapVideoStart captureStr.PCAPTURE_preview @cbSetupVideoCap captureStr;
_fooS ">>> Camera restarted";
);
// Start log: timer period = 1000 * (1 / fps) (ms)
if (captureStr.PCAPTURE_timer != nil) then nil else
set captureStr.PCAPTURE_timer = _rfltimer _starttimer _channel (ftoi (1000.0 *. (1.0 /. (itof captureStr.PCAPTURE_fps)))) @cbTimerSaveFrame captureStr;
0;;
/*! \brief Callback on new plugIT instance
*
* Create a new log file
*
* Prototype: fun [PInstance] I
*
* \param PInstance : plugIT instance
*
* \return I : 0
**/
fun newOb(inst)=
// Get parameters from editor
let atoi (getPluginInstanceParam inst "width") -> width in
let atoi (getPluginInstanceParam inst "heigth") -> heigth in
let atoi (getPluginInstanceParam inst "cameraIndex") -> cameraIndex in
let atoi (getPluginInstanceParam inst "fps") -> fps in
let atoi (getPluginInstanceParam inst "showVideo") -> showVideo in
let atoi (getPluginInstanceParam inst "format") -> format in
let atoi (getPluginInstanceParam inst "quality") -> quality in
// Create capture structure
let mkCaptureStr [inst nil nil nil "" width heigth cameraIndex fps showVideo format quality nil] -> captureStr in
(
// Create a new capture window using parameters
// NOTE: Create, destroy and create again window otherwise video source may not be opened correctly
set captureStr.PCAPTURE_preview = _CRcapWindow _channel nil cameraIndex 120 120 width heigth showVideo 25000;
_DScapWindow captureStr.PCAPTURE_preview;
set captureStr.PCAPTURE_preview = _CRcapWindow _channel nil cameraIndex 120 120 width heigth showVideo 25000;
// Create a bitmap to fill the capture window
set captureStr.PCAPTURE_capBmp = _FILLbitmap _CRbitmap _channel width heigth 0;
// Create folder according to system time to save snapshots
set sCaptureFolder = (strreplace (strcatnSep (hd strextr (ctime time)) "_") ":" "-");
// Associate callbacks to actions
PluginRegisterAction inst "Start capture" mkfun6 @cbStartCapture captureStr;
PluginRegisterAction inst "Stop capture" mkfun6 @cbStopCapture captureStr;
PluginRegisterAction inst "Pause capture" mkfun6 @cbPauseCapture captureStr;
PluginRegisterAction inst "Resume capture" mkfun6 @cbResumeCapture captureStr;
// Define the callback to call when the plugin instance is deleted
setPluginInstanceCbDel inst mkfun2 @deleteOb captureStr;
);
0;;
/*! \brief Global plugIT function to initialize the plugIT callbacks
*
* Prototype: fun [S] I
*
* \param S : plugIT file path
*
* \return I : 0
**/
fun IniPlug(file)=
PlugRegister @newOb nil;
setPluginEditor @dynamicedit;
0;;