Änderungen Gruppe 30_10_2022 V2

This commit is contained in:
2022-10-30 20:01:47 +01:00
parent 269f807b31
commit 2517e52e59
239 changed files with 54983 additions and 9 deletions
+53
View File
@@ -0,0 +1,53 @@
INCLUDE_DIRECTORIES(.)
SET(private_hdrs_base "private/private_types.h private/private_impl.h exceptions.h private/threadcondition.h ")
SET(private_still_hdrs_base "private_still/private_still_types.h private/private_still_impl.h")
SET(public_hdrs_base raspicamtypes.h raspicam.h)
SET(srcs_base raspicam.cpp raspicam_still.cpp private/private_impl.cpp private/threadcondition.cpp private_still/private_still_impl.cpp)
if(NOT( ${CMAKE_SYSTEM_PROCESSOR} MATCHES arm*) )#in a pc, adds fake dependencies to mmal functions to enable compilation
SET(srcs_base ${srcs_base} private/fake_mmal_dependencies.cpp)
endif()
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} )
ADD_LIBRARY(${PROJECT_NAME} ${hdrs_base} ${srcs_base} )
SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES # create *nix style library versions + symbolic links
DEFINE_SYMBOL DSO_EXPORTS
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_SOVERSION}
CLEAN_DIRECT_OUTPUT 1 # allow creating static and shared libs without conflicts
OUTPUT_NAME "${PROJECT_NAME}${PROJECT_DLLVERSION}" # avoid conflicts between library and binary target names
)
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${REQUIRED_LIBRARIES} )
INSTALL(TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION bin COMPONENT main
LIBRARY DESTINATION lib PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE COMPONENT main
ARCHIVE DESTINATION lib COMPONENT main)
#Add opencv component if required
#Opencv Lib
IF (${OpenCV_FOUND})
message(STATUS "Adding cv library")
SET(hdrs_cv raspicam_cv.h raspicam_still_cv.h)
SET(srcs_cv raspicam_cv.cpp raspicam_still_cv.cpp)
ADD_LIBRARY(${PROJECT_NAME}_cv ${hdrs_cv} ${srcs_cv} ${srcs_base})
SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES # create *nix style library versions + symbolic links
DEFINE_SYMBOL DSO_EXPORTS
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_SOVERSION}
CLEAN_DIRECT_OUTPUT 1 # allow creating static and shared libs without conflicts
OUTPUT_NAME "${PROJECT_NAME}${PROJECT_DLLVERSION}" # avoid conflicts between library and binary target names
)
TARGET_LINK_LIBRARIES(${PROJECT_NAME}_cv ${REQUIRED_LIBRARIES} ${OpenCV_LIBS} )
INSTALL(TARGETS ${PROJECT_NAME}_cv
RUNTIME DESTINATION bin COMPONENT main
LIBRARY DESTINATION lib PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE COMPONENT main
ARCHIVE DESTINATION lib COMPONENT main)
ENDIF()
#Installation of all header files
INSTALL(FILES ${public_hdrs_base} ${hdrs_cv}
DESTINATION include/${PROJECT_NAME}
COMPONENT main)
+114
View File
@@ -0,0 +1,114 @@
/**********************************************************
Software developed by AVA ( Ava Group of the University of Cordoba, ava at uco dot es)
Main author Rafael Munoz Salinas (rmsalinas at uco dot es)
This software is released under BSD license as expressed below
-------------------------------------------------------------------
Copyright (c) 2013, AVA ( Ava Group University of Cordoba, ava at uco dot es)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software
must display the following acknowledgement:
This product includes software developed by the Ava group of the University of Cordoba.
4. Neither the name of the University nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY AVA ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL AVA BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
****************************************************************/
#ifndef _RaspiCam__Exceptions_h
#define _RaspiCam__Exceptions_h
#include <string>
#include <fstream>
#include <cstdarg>
namespace raspicam {
/**
* Types of valid exceptions
*/
class Exceptions {
public:
static const int Generic=81799;
};
/*!
The standard exception class.
*/
class Exception : public std::exception
{
public:
/*!
Default constructor
*/
Exception() {
code = 0;
line = 0;
}
/*!
Full constructor. Normally the constuctor is not called explicitly.
Instead, the macros CV_Error(), CV_Error_() and CV_Assert() are used.
*/
Exception(int _code, const std::string& _err, const std::string& _func, const std::string& _file, int _line)
: code(_code), err(_err), func(_func), file(_file), line(_line)
{
formatMessage();
}
virtual ~Exception() throw() {}
/*!
\return the error description and the context as a text string.
*/
virtual const char *what() const throw() {
return msg.c_str();
}
void formatMessage()
{
if ( func.size() > 0 )
msg = format("%s:%d: error: (%d) %s in function %s\n", file.c_str(), line, code, err.c_str(), func.c_str());
else
msg = format("%s:%d: error: (%d) %s\n", file.c_str(), line, code, err.c_str());
}
std::string msg; ///< the formatted error message
int code; ///< error code @see CVStatus
std::string err; ///< error description
std::string func; ///< function name. Available only when the compiler supports __func__ macro
std::string file; ///< source file name where the error has occured
int line; ///< line number in the source file where the error has occured
private:
std::string format( const char* fmt, ... )
{
char buf[1 << 16];
va_list args;
va_start( args, fmt );
vsprintf( buf, fmt, args );
return std::string(buf);
}
};
}
#endif
@@ -0,0 +1,400 @@
#include "mmal/util/mmal_default_components.h"
#include "mmal/util/mmal_util.h"
#include "mmal/util/mmal_util_params.h"
#include "mmal/mmal.h"
#include "mmal/util/mmal_connection.h"
#define UNUSED(x) ((void)x)
MMAL_BUFFER_HEADER_T *mmal_queue_get(MMAL_QUEUE_T *queue){UNUSED(queue); return NULL;}
MMAL_STATUS_T mmal_buffer_header_mem_lock(MMAL_BUFFER_HEADER_T *header){UNUSED(header); return MMAL_SUCCESS;}
void mmal_buffer_header_mem_unlock(MMAL_BUFFER_HEADER_T *header){UNUSED(header);}
void mmal_port_pool_destroy(MMAL_PORT_T *port, MMAL_POOL_T *pool){UNUSED(port);UNUSED(pool);}
/** Create an instance of a component.
* The newly created component will expose ports to the client. All the exposed ports are
* disabled by default.
* Note that components are reference counted and creating a component automatically
* acquires a reference to it (released when \ref mmal_component_destroy is called).
*
* @param name name of the component to create, e.g. "video_decode"
* @param component returned component
* @return MMAL_SUCCESS on success
*/
MMAL_STATUS_T mmal_component_create(const char *name,
MMAL_COMPONENT_T **component){UNUSED(name);UNUSED(component);return MMAL_SUCCESS;}
/** Acquire a reference on a component.
* Acquiring a reference on a component will prevent a component from being destroyed until
* the acquired reference is released (by a call to \ref mmal_component_destroy).
* References are internally counted so all acquired references need a matching call to
* release them.
*
* @param component component to acquire
*/
void mmal_component_acquire(MMAL_COMPONENT_T *component){UNUSED(component);}
/** Release a reference on a component
* Release an acquired reference on a component. Triggers the destruction of the component when
* the last reference is being released.
* \note This is in fact an alias of \ref mmal_component_destroy which is added to make client
* code clearer.
*
* @param component component to release
* @return MMAL_SUCCESS on success
*/
MMAL_STATUS_T mmal_component_release(MMAL_COMPONENT_T *component){UNUSED(component);return MMAL_SUCCESS;}
/** Destroy a previously created component
* Release an acquired reference on a component. Only actually destroys the component when
* the last reference is being released.
*
* @param component component to destroy
* @return MMAL_SUCCESS on success
*/
MMAL_STATUS_T mmal_component_destroy(MMAL_COMPONENT_T *component){UNUSED(component);return MMAL_SUCCESS;}
/** Enable processing on a component
* @param component component to enable
* @return MMAL_SUCCESS on success
*/
MMAL_STATUS_T mmal_component_enable(MMAL_COMPONENT_T *component){UNUSED(component);return MMAL_SUCCESS;}
/** Disable processing on a component
* @param component component to disable
* @return MMAL_SUCCESS on success
*/
MMAL_STATUS_T mmal_component_disable(MMAL_COMPONENT_T *component){UNUSED(component);return MMAL_SUCCESS;}
/** Commit format changes on a port.
*
* @param port The port for which format changes are to be committed.
* @return MMAL_SUCCESS on success
*/
MMAL_STATUS_T mmal_port_format_commit(MMAL_PORT_T *port){UNUSED(port);return MMAL_SUCCESS;}
/** Enable processing on a port
*
* If this port is connected to another, the given callback must be NULL, while for a
* disconnected port, the callback must be non-NULL.
*
* If this is a connected output port and is successfully enabled:
* <ul>
* <li>The port shall be populated with a pool of buffers, allocated as required, according
* to the buffer_num and buffer_size values.
* <li>The input port to which it is connected shall be set to the same buffer
* configuration and then be enabled. Should that fail, the original port shall be
* disabled.
* </ul>
*
* @param port port to enable
* @param cb callback use by the port to send a \ref MMAL_BUFFER_HEADER_T back
* @return MMAL_SUCCESS on success
*/
MMAL_STATUS_T mmal_port_enable(MMAL_PORT_T *port, MMAL_PORT_BH_CB_T cb){UNUSED(port);UNUSED(cb);return MMAL_SUCCESS;}
/** Disable processing on a port
*
* Disabling a port will stop all processing on this port and return all (non-processed)
* buffer headers to the client.
*
* If this is a connected output port, the input port to which it is connected shall
* also be disabled. Any buffer pool shall be released.
*
* @param port port to disable
* @return MMAL_SUCCESS on success
*/
MMAL_STATUS_T mmal_port_disable(MMAL_PORT_T *port){UNUSED(port);return MMAL_SUCCESS;}
/** Ask a port to release all the buffer headers it currently has.
*
* Flushing a port will ask the port to send all the buffer headers it currently has
* to the client. Flushing is an asynchronous request and the flush call will
* return before all the buffer headers are returned to the client.
* It is up to the client to keep a count on the buffer headers to know when the
* flush operation has completed.
* It is also important to note that flushing will also reset the state of the port
* and any processing which was buffered by the port will be lost.
*
* \attention Flushing a connected port behaviour TBD.
*
* @param port The port to flush.
* @return MMAL_SUCCESS on success
*/
MMAL_STATUS_T mmal_port_flush(MMAL_PORT_T *port){UNUSED(port);return MMAL_SUCCESS;}
/** Set a parameter on a port.
*
* @param port The port to which the request is sent.
* @param param The pointer to the header of the parameter to set.
* @return MMAL_SUCCESS on success
*/
MMAL_STATUS_T mmal_port_parameter_set(MMAL_PORT_T *port,
const MMAL_PARAMETER_HEADER_T *param){UNUSED(port);UNUSED(param);return MMAL_SUCCESS;}
/** Get a parameter from a port.
* The size field must be set on input to the maximum size of the parameter
* (including the header) and will be set on output to the actual size of the
* parameter retrieved.
*
* \note If MMAL_ENOSPC is returned, the parameter is larger than the size
* given. The given parameter will have been filled up to its size and then
* the size field set to the full parameter's size. This can be used to
* resize the parameter buffer so that a second call should succeed.
*
* @param port The port to which the request is sent.
* @param param The pointer to the header of the parameter to get.
* @return MMAL_SUCCESS on success
*/
MMAL_STATUS_T mmal_port_parameter_get(MMAL_PORT_T *port,
MMAL_PARAMETER_HEADER_T *param){UNUSED(port);UNUSED(param);return MMAL_SUCCESS;}
/** Send a buffer header to a port.
*
* @param port The port to which the buffer header is to be sent.
* @param buffer The buffer header to send.
* @return MMAL_SUCCESS on success
*/
MMAL_STATUS_T mmal_port_send_buffer(MMAL_PORT_T *port,
MMAL_BUFFER_HEADER_T *buffer){UNUSED(port);UNUSED(buffer);return MMAL_SUCCESS;}
/** Connect an output port to an input port.
*
* When connected and enabled, buffers will automatically progress from the
* output port to the input port when they become available, and released back
* to the output port when no longer required by the input port.
*
* Ports can be given either way around, but one must be an output port and
* the other must be an input port. Neither can be connected or enabled
* already. The format of the output port will be applied to the input port
* on connection.
*
* @param port One of the ports to connect.
* @param other_port The other port to connect.
* @return MMAL_SUCCESS on success.
*/
MMAL_STATUS_T mmal_port_connect(MMAL_PORT_T *port, MMAL_PORT_T *other_port){UNUSED(port);UNUSED(other_port);return MMAL_SUCCESS;}
/** Disconnect a connected port.
*
* If the port is not connected, an error will be returned. Otherwise, if the
* ports are enabled, they will be disabled and any buffer pool created will be
* freed.
*
* @param port The ports to disconnect.
* @return MMAL_SUCCESS on success.
*/
MMAL_STATUS_T mmal_port_disconnect(MMAL_PORT_T *port){UNUSED(port);return MMAL_SUCCESS;}
/** Allocate a payload buffer.
* This allows a client to allocate memory for a payload buffer based on the preferences
* of a port. This for instance will allow the port to allocate memory which can be shared
* between the host processor and videocore.
*
* See \ref mmal_pool_create_with_allocator().
*
* @param port Port responsible for allocating the memory.
* @param payload_size Size of the payload buffer which will be allocated.
*
* @return Pointer to the allocated memory.
*/
uint8_t *mmal_port_payload_alloc(MMAL_PORT_T *port, uint32_t payload_size){UNUSED(port);UNUSED(payload_size);return NULL;}
/** Free a payload buffer.
* This allows a client to free memory allocated by a previous call to \ref mmal_port_payload_alloc.
*
* See \ref mmal_pool_create_with_allocator().
*
* @param port Port responsible for allocating the memory.
* @param payload Pointer to the memory to free.
*/
void mmal_port_payload_free(MMAL_PORT_T *port, uint8_t *payload){UNUSED(port);UNUSED(payload);}
/** Get an empty event buffer header from a port
*
* @param port The port from which to get the event buffer header.
* @param buffer The address of a buffer header pointer, which will be set on return.
* @param event The specific event FourCC required. See the \ref MmalEvents "pre-defined events".
* @return MMAL_SUCCESS on success
*/
MMAL_STATUS_T mmal_port_event_get(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T **buffer, uint32_t event){UNUSED(port);UNUSED(buffer);UNUSED(event);return MMAL_SUCCESS;}
/** Shallow copy a format structure.
* It is worth noting that the extradata buffer will not be copied in the new format.
*
* @param format_dest destination \ref MMAL_ES_FORMAT_T for the copy
* @param format_src source \ref MMAL_ES_FORMAT_T for the copy
*/
void mmal_format_copy(MMAL_ES_FORMAT_T *format_dest, MMAL_ES_FORMAT_T *format_src){UNUSED(format_dest);UNUSED(format_src);}
/** Create a connection between two ports.
* The connection shall include a pool of buffer headers suitable for the current format of
* the output port. The format of the input port shall have been set to the same as that of
* the input port.
* Note that connections are reference counted and creating a connection automatically
* acquires a reference to it (released when \ref mmal_connection_destroy is called).
*
* @param connection The address of a connection pointer that will be set to point to the created
* connection.
* @param out The output port to use for the connection.
* @param in The input port to use for the connection.
* @param flags The flags specifying which type of connection should be created.
* A bitwise combination of \ref connectionflags "Connection flags" values.
* @return MMAL_SUCCESS on success.
*/
MMAL_STATUS_T mmal_connection_create(MMAL_CONNECTION_T **connection,
MMAL_PORT_T *out, MMAL_PORT_T *in, uint32_t flags){UNUSED(connection);UNUSED(out);UNUSED(in);UNUSED(flags);return MMAL_SUCCESS;}
/** Acquire a reference on a connection.
* Acquiring a reference on a connection will prevent a connection from being destroyed until
* the acquired reference is released (by a call to \ref mmal_connection_destroy).
* References are internally counted so all acquired references need a matching call to
* release them.
*
* @param connection connection to acquire
*/
void mmal_connection_acquire(MMAL_CONNECTION_T *connection){UNUSED(connection);}
/** Release a reference on a connection
* Release an acquired reference on a connection. Triggers the destruction of the connection when
* the last reference is being released.
* \note This is in fact an alias of \ref mmal_connection_destroy which is added to make client
* code clearer.
*
* @param connection connection to release
* @return MMAL_SUCCESS on success
*/
MMAL_STATUS_T mmal_connection_release(MMAL_CONNECTION_T *connection){UNUSED(connection);return MMAL_SUCCESS;}
/** Destroy a connection.
* Release an acquired reference on a connection. Only actually destroys the connection when
* the last reference is being released.
* The actual destruction of the connection will start by disabling it, if necessary.
* Any pool, queue, and so on owned by the connection shall then be destroyed.
*
* @param connection The connection to be destroyed.
* @return MMAL_SUCCESS on success.
*/
MMAL_STATUS_T mmal_connection_destroy(MMAL_CONNECTION_T *connection){UNUSED(connection);return MMAL_SUCCESS;}
/** Enable a connection.
* The format of the two ports must have been committed before calling this function,
* although note that on creation, the connection automatically copies and commits the
* output port's format to the input port.
*
* The MMAL_CONNECTION_T::callback field must have been set if the \ref MMAL_CONNECTION_FLAG_TUNNELLING
* flag was not specified on creation. The client may also set the MMAL_CONNECTION_T::user_data
* in order to get a pointer passed, via the connection, to the callback.
*
* @param connection The connection to be enabled.
* @return MMAL_SUCCESS on success.
*/
MMAL_STATUS_T mmal_connection_enable(MMAL_CONNECTION_T *connection){UNUSED(connection);return MMAL_SUCCESS;}
/** Disable a connection.
*
* @param connection The connection to be disabled.
* @return MMAL_SUCCESS on success.
*/
MMAL_STATUS_T mmal_connection_disable(MMAL_CONNECTION_T *connection){UNUSED(connection);return MMAL_SUCCESS;}
/** Apply a format changed event to the connection.
* This function can be used when the client is processing buffer headers and receives
* a format changed event (\ref MMAL_EVENT_FORMAT_CHANGED). The connection is
* reconfigured, changing the format of the ports, the number of buffer headers and
* the size of the payload buffers as necessary.
*
* @param connection The connection to which the event shall be applied.
* @param buffer The buffer containing a format changed event.
* @return MMAL_SUCCESS on success.
*/
MMAL_STATUS_T mmal_connection_event_format_changed(MMAL_CONNECTION_T *connection,
MMAL_BUFFER_HEADER_T *buffer){UNUSED(connection);UNUSED(buffer);return MMAL_SUCCESS;}
/** Helper function to set the value of a rational parameter.
* @param port port on which to set the parameter
* @param id parameter id
* @param value value to set the parameter to
*
* @return MMAL_SUCCESS or error
*/
MMAL_STATUS_T mmal_port_parameter_set_rational(MMAL_PORT_T *port, uint32_t id, MMAL_RATIONAL_T value){UNUSED(port);UNUSED(id);UNUSED(value);return MMAL_SUCCESS;}
/** Helper function to set the value of a 32 bits signed integer parameter.
* @param port port on which to set the parameter
* @param id parameter id
* @param value value to set the parameter to
*
* @return MMAL_SUCCESS or error
*/
MMAL_STATUS_T mmal_port_parameter_set_int32(MMAL_PORT_T *port, uint32_t id, int32_t value){UNUSED(port);UNUSED(id);UNUSED(value);return MMAL_SUCCESS;}
/** Helper function to set the value of a 32 bits unsigned integer parameter.
* @param port port on which to set the parameter
* @param id parameter id
* @param value value to set the parameter to
*
* @return MMAL_SUCCESS or error
*/
MMAL_STATUS_T mmal_port_parameter_set_uint32(MMAL_PORT_T *port, uint32_t id, uint32_t value){UNUSED(port);UNUSED(id);UNUSED(value);return MMAL_SUCCESS;}
/** Helper function to set the value of a boolean parameter.
* @param port port on which to set the parameter
* @param id parameter id
* @param value value to set the parameter to
*
* @return MMAL_SUCCESS or error
*/
MMAL_STATUS_T mmal_port_parameter_set_boolean(MMAL_PORT_T *port, uint32_t id, MMAL_BOOL_T value){UNUSED(port);UNUSED(id);UNUSED(value);return MMAL_SUCCESS;}
/** Create a pool of MMAL_BUFFER_HEADER_T associated with a specific port.
* This allows a client to allocate memory for the payload buffers based on the preferences
* of a port. This for instance will allow the port to allocate memory which can be shared
* between the host processor and videocore.
* After allocation, all allocated buffer headers will have been added to the queue.
*
* It is valid to create a pool with no buffer headers, or with zero size payload buffers.
* The mmal_pool_resize() function can be used to increase or decrease the number of buffer
* headers, or the size of the payload buffers, after creation of the pool.
*
* @param port Port responsible for creating the pool.
* @param headers Number of buffers which will be allocated with the pool.
* @param payload_size Size of the payload buffer which will be allocated in
* each of the buffer headers.
* @return Pointer to the newly created pool or NULL on failure.
*/
MMAL_POOL_T *mmal_port_pool_create(MMAL_PORT_T *port,
unsigned int headers, uint32_t payload_size){UNUSED(port);UNUSED(headers);UNUSED(payload_size);return NULL;}
/** Release a buffer header.
* Releasing a buffer header will decrease its reference counter and when no more references
* are left, the buffer header will be recycled by calling its 'release' callback function.
*
* If a pre-release callback is set (\ref MMAL_BH_PRE_RELEASE_CB_T), this will be invoked
* before calling the buffer's release callback and potentially postpone buffer recycling.
* Once pre-release is complete the buffer header is recycled with
* \ref mmal_buffer_header_release_continue.
*
* @param header buffer header to release
*/
void mmal_buffer_header_release(MMAL_BUFFER_HEADER_T *header){UNUSED(header);}
/** Get the number of MMAL_BUFFER_HEADER_T currently in a queue.
*
* @param queue Pointer to a queue
*
* @return length (in elements) of the queue.
*/
unsigned int mmal_queue_length(MMAL_QUEUE_T *queue){UNUSED(queue);return 0;}
int mmal_util_rgb_order_fixed(MMAL_PORT_T *port) {return 0;}
@@ -0,0 +1,942 @@
/**********************************************************
Software developed by AVA ( Ava Group of the University of Cordoba, ava at uco dot es)
Main author Rafael Munoz Salinas (rmsalinas at uco dot es)
This software is released under BSD license as expressed below
-------------------------------------------------------------------
Copyright (c) 2013, AVA ( Ava Group University of Cordoba, ava at uco dot es)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software
must display the following acknowledgement:
This product includes software developed by the Ava group of the University of Cordoba.
4. Neither the name of the University nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY AVA ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL AVA BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
****************************************************************/
#include "private_impl.h"
#include <iostream>
#include <cstdio>
#include "mmal/util/mmal_util.h"
#include "mmal/util/mmal_util_params.h"
#include "mmal/util/mmal_default_components.h"
using namespace std;
namespace raspicam {
namespace _private{
#define MMAL_CAMERA_VIDEO_PORT 1
#define MMAL_CAMERA_CAPTURE_PORT 2
#define VIDEO_FRAME_RATE_DEN 1
#define VIDEO_OUTPUT_BUFFERS_NUM 3
Private_Impl::Private_Impl() {
camera_video_port = NULL;
// camera_still_port = NULL;
_isOpened=false;
_isCapturing=false;
//set default state params
setDefaultStateParams();
}
Private_Impl::~Private_Impl() {
release();
}
void Private_Impl::setDefaultStateParams() {
// Default everything to zero
memset ( &State, 0, sizeof ( RASPIVID_STATE ) );
State.framerate = 10;
State.width = 1280; // use a multiple of 320 (640, 1280)
State.height = 960; // use a multiple of 240 (480, 960)
State.sharpness = 0;
State.contrast = 0;
State.brightness = 50;
State.saturation = 0;
State.ISO = 400;
State.videoStabilisation = false;
State.exposureCompensation = 0;
State.captureFtm=RASPICAM_FORMAT_RGB;
State.rpc_exposureMode = RASPICAM_EXPOSURE_AUTO;
State.rpc_exposureMeterMode = RASPICAM_METERING_AVERAGE;
State.rpc_awbMode = RASPICAM_AWB_AUTO;
State.rpc_imageEffect = RASPICAM_IMAGE_EFFECT_NONE;
State.colourEffects.enable = 0;
State.colourEffects.u = 128;
State.colourEffects.v = 128;
State.rotation = 0;
State.hflip = State.vflip = 0;
State.roi.x = State.roi.y = 0.0;
State.roi.w = State.roi.h = 1.0;
State.shutterSpeed=0;//auto
State.awbg_red=1.0;
State.awbg_blue=1.0;
State.sensor_mode = 0; //do not set mode by default
}
bool Private_Impl::open ( bool StartCapture ) {
if ( _isOpened ) return false; //already opened
// create camera
if ( ! create_camera_component ( &State ) ) {
cerr<<__func__<<" Failed to create camera component"<<__FILE__<<" "<<__LINE__<<endl;
return false;
}
commitParameters();
camera_video_port = State.camera_component->output[MMAL_CAMERA_VIDEO_PORT];
callback_data.pstate = &State;
callback_data.inst = this;
// assign data to use for callback
camera_video_port->userdata = ( struct MMAL_PORT_USERDATA_T * ) &callback_data;
State.camera_component->control->userdata = ( struct MMAL_PORT_USERDATA_T * ) &callback_data;
_isOpened=true;
if ( StartCapture ) return startCapture();
else return true;
}
/**
*/
bool Private_Impl::startCapture() {
if ( !_isOpened ) {
cerr<<__FILE__<<":"<<__LINE__<<":"<<__func__<<" not opened."<<endl;
return false; //already opened
}
// start capture
if ( mmal_port_parameter_set_boolean ( camera_video_port, MMAL_PARAMETER_CAPTURE, 1 ) != MMAL_SUCCESS ) {
release();
return false;
}
// Send all the buffers to the video port
int num = mmal_queue_length ( State.video_pool->queue );
int q;
for ( q=0; q<num; q++ ) {
MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get ( State.video_pool->queue );
if ( !buffer )
cerr<<"Unable to get a required buffer"<<q<<" from pool queue"<<endl;
if ( mmal_port_send_buffer ( camera_video_port, buffer ) != MMAL_SUCCESS )
cerr<<"Unable to send a buffer to encoder output port "<< q<<endl;
}
_isCapturing=true;
return true;
}
void Private_Impl::setUserCallback(void (*userCallback)(void*) , void* data){
callback_data._userCallbackData = data;
callback_data._userCallback = userCallback;
}
void Private_Impl::release() {
if ( !_isOpened ) return;
// Disable camera_video_port
if ( camera_video_port && camera_video_port->is_enabled ) {
mmal_port_disable ( camera_video_port );
camera_video_port = NULL;
}
////
// Disable all our ports that are not handled by connections
if ( State.camera_component )
mmal_component_disable ( State.camera_component );
destroy_camera_component ( &State );
_isOpened=false;
_isCapturing=false;
}
/**
*
*/
bool Private_Impl::grab() {
if ( !isCapturing() ) return false;
callback_data.waitForFrame();
return true;
}
/**
*
*/
void Private_Impl::retrieve ( unsigned char *data,RASPICAM_FORMAT type ) {
if ( callback_data._buffData.size==0 ) return;
if ( type!=RASPICAM_FORMAT_IGNORE ) {
cerr<<__FILE__<<":"<<__LINE__<<" :Private_Impl::retrieve type is not RASPICAM_FORMAT_IGNORE as it should be"<<endl;
}
memcpy ( data,callback_data._buffData.data,getImageTypeSize ( State.captureFtm ) );
}
unsigned char *Private_Impl::getImageBufferData() const{
return callback_data._buffData.data;
}
size_t Private_Impl::getImageBufferSize() const{
return getImageTypeSize ( getFormat() );
}
/**
*
*
*/
size_t Private_Impl::getImageTypeSize ( RASPICAM_FORMAT type ) const{
switch ( type ) {
case RASPICAM_FORMAT_YUV420:
return getWidth() *getHeight() + 2* ( ( getWidth() /2 *getHeight() /2 ) );
break;
case RASPICAM_FORMAT_GRAY:
return getWidth() *getHeight();
break;
case RASPICAM_FORMAT_BGR:
case RASPICAM_FORMAT_RGB:
return 3*getWidth() *getHeight();
break;
default:
return 0;
};
}
/**
* Destroy the camera component
*
* @param state Pointer to state control struct
*
*/
void Private_Impl::destroy_camera_component ( RASPIVID_STATE *state ) {
if ( state->video_pool )
mmal_port_pool_destroy ( state->camera_component->output[MMAL_CAMERA_VIDEO_PORT], state->video_pool );
if ( state->camera_component ) {
mmal_component_destroy ( state->camera_component );
state->camera_component = NULL;
}
}
MMAL_COMPONENT_T *Private_Impl::create_camera_component ( RASPIVID_STATE *state ) {
MMAL_COMPONENT_T *camera = 0;
MMAL_ES_FORMAT_T *format;
MMAL_PORT_T *video_port = NULL;
MMAL_STATUS_T status;
/* Create the component */
status = mmal_component_create ( MMAL_COMPONENT_DEFAULT_CAMERA, &camera );
if ( status != MMAL_SUCCESS ) {
cerr<< ( "Failed to create camera component" );
return 0;
}
if ( !camera->output_num ) {
cerr<< ( "Camera doesn't have output ports" );
mmal_component_destroy ( camera );
return 0;
}
video_port = camera->output[MMAL_CAMERA_VIDEO_PORT];
//set sensor mode
if ( state->sensor_mode != 0 && mmal_port_parameter_set_uint32 ( camera->control,
MMAL_PARAMETER_CAMERA_CUSTOM_SENSOR_CONFIG,
state->sensor_mode) != MMAL_SUCCESS)
{
cerr << __func__ << ": Failed to set sensmode.";
}
_rgb_bgr_fixed = !(mmal_util_rgb_order_fixed(video_port));
// set up the camera configuration
MMAL_PARAMETER_CAMERA_CONFIG_T cam_config;
cam_config.hdr.id=MMAL_PARAMETER_CAMERA_CONFIG;
cam_config.hdr.size=sizeof ( cam_config );
cam_config.max_stills_w = state->width;
cam_config.max_stills_h = state->height;
cam_config.stills_yuv422 = 0;
cam_config.one_shot_stills = 0;
cam_config.max_preview_video_w = state->width;
cam_config.max_preview_video_h = state->height;
cam_config.num_preview_video_frames = 3;
cam_config.stills_capture_circular_buffer_height = 0;
cam_config.fast_preview_resume = 0;
cam_config.use_stc_timestamp = MMAL_PARAM_TIMESTAMP_MODE_RESET_STC;
mmal_port_parameter_set ( camera->control, &cam_config.hdr );
MMAL_PARAMETER_CHANGE_EVENT_REQUEST_T change_event_request =
{{MMAL_PARAMETER_CHANGE_EVENT_REQUEST, sizeof(MMAL_PARAMETER_CHANGE_EVENT_REQUEST_T)},
MMAL_PARAMETER_CAMERA_SETTINGS, 1};
status = mmal_port_parameter_set(camera->control, &change_event_request.hdr);
if ( status != MMAL_SUCCESS )
{
cerr<<("No camera settings events");
mmal_component_destroy ( camera );
return 0;
}
// Enable the camera, and tell it its control callback function
status = mmal_port_enable(camera->control, camera_control_callback);
if (status != MMAL_SUCCESS)
{
cerr << "Unable to enable control port : error " << (int) status;
mmal_component_destroy ( camera );
return 0;
}
// Set the encode format on the video port
format = video_port->format;
format->encoding_variant = convertFormat ( State.captureFtm );
format->encoding = convertFormat ( State.captureFtm );
format->es->video.width = VCOS_ALIGN_UP(state->width, 32);
format->es->video.height = VCOS_ALIGN_UP(state->height, 16);
format->es->video.crop.x = 0;
format->es->video.crop.y = 0;
format->es->video.crop.width = state->width;
format->es->video.crop.height = state->height;
format->es->video.frame_rate.num = state->framerate;
format->es->video.frame_rate.den = VIDEO_FRAME_RATE_DEN;
status = mmal_port_format_commit ( video_port );
if ( status ) {
cerr<< ( "camera video format couldn't be set" );
mmal_component_destroy ( camera );
return 0;
}
// PR : plug the callback to the video port
status = mmal_port_enable ( video_port,video_buffer_callback );
if ( status ) {
cerr<< ( "camera video callback2 error" );
mmal_component_destroy ( camera );
return 0;
}
// Ensure there are enough buffers to avoid dropping frames
if ( video_port->buffer_num < VIDEO_OUTPUT_BUFFERS_NUM )
video_port->buffer_num = VIDEO_OUTPUT_BUFFERS_NUM;
//PR : create pool of message on video port
MMAL_POOL_T *pool;
video_port->buffer_size = video_port->buffer_size_recommended;
video_port->buffer_num = video_port->buffer_num_recommended;
pool = mmal_port_pool_create ( video_port, video_port->buffer_num, video_port->buffer_size );
if ( !pool ) {
cerr<< ( "Failed to create buffer header pool for video output port" );
}
state->video_pool = pool;
/* Enable component */
status = mmal_component_enable ( camera );
if ( status ) {
cerr<< ( "camera component couldn't be enabled" );
mmal_component_destroy ( camera );
return 0;
}
state->camera_component = camera;//this needs to be before set_all_parameters
return camera;
}
void Private_Impl::commitBrightness() {
mmal_port_parameter_set_rational ( State.camera_component->control, MMAL_PARAMETER_BRIGHTNESS, ( MMAL_RATIONAL_T ) {
State.brightness, 100
} );
}
void Private_Impl::commitRotation() {
int rotation = int ( State.rotation / 90 ) * 90;
mmal_port_parameter_set_int32 ( State.camera_component->output[0], MMAL_PARAMETER_ROTATION,rotation );
mmal_port_parameter_set_int32 ( State.camera_component->output[1], MMAL_PARAMETER_ROTATION,rotation );
mmal_port_parameter_set_int32 ( State.camera_component->output[2], MMAL_PARAMETER_ROTATION, rotation );
}
void Private_Impl::commitISO() {
if ( mmal_port_parameter_set_uint32 ( State.camera_component->control, MMAL_PARAMETER_ISO, State.ISO ) != MMAL_SUCCESS )
cout << __func__ << ": Failed to set ISO parameter.\n";
}
void Private_Impl::commitSharpness() {
if ( mmal_port_parameter_set_rational ( State.camera_component->control, MMAL_PARAMETER_SHARPNESS, ( MMAL_RATIONAL_T ) {
State.sharpness, 100
} ) != MMAL_SUCCESS )
cout << __func__ << ": Failed to set sharpness parameter.\n";
}
void Private_Impl::commitShutterSpeed() {
if ( mmal_port_parameter_set_uint32 ( State.camera_component->control, MMAL_PARAMETER_SHUTTER_SPEED, State.shutterSpeed ) != MMAL_SUCCESS )
cout << __func__ << ": Failed to set shutter parameter.\n";
}
void Private_Impl::commitContrast() {
if ( mmal_port_parameter_set_rational ( State.camera_component->control, MMAL_PARAMETER_CONTRAST, ( MMAL_RATIONAL_T ) {
State.contrast, 100
} ) != MMAL_SUCCESS )
cout << __func__ << ": Failed to set contrast parameter.\n";
}
void Private_Impl::commitSaturation() {
if ( mmal_port_parameter_set_rational ( State.camera_component->control, MMAL_PARAMETER_SATURATION, ( MMAL_RATIONAL_T ) {
State.saturation, 100
} ) != MMAL_SUCCESS )
cout << __func__ << ": Failed to set saturation parameter.\n";
}
void Private_Impl::commitExposure() {
MMAL_PARAMETER_EXPOSUREMODE_T exp_mode = {{MMAL_PARAMETER_EXPOSURE_MODE,sizeof ( exp_mode ) }, convertExposure ( State.rpc_exposureMode ) };
if ( mmal_port_parameter_set ( State.camera_component->control, &exp_mode.hdr ) != MMAL_SUCCESS )
cout << __func__ << ": Failed to set exposure parameter.\n";
}
/**
* Adjust the exposure compensation for images (EV)
* @param camera Pointer to camera component
* @param exp_comp Value to adjust, -10 to +10
* @return 0 if successful, non-zero if any parameters out of range
*/
void Private_Impl::commitExposureCompensation() {
if ( mmal_port_parameter_set_int32 ( State.camera_component->control, MMAL_PARAMETER_EXPOSURE_COMP , State.exposureCompensation ) !=MMAL_SUCCESS )
cout << __func__ << ": Failed to set Exposure Compensation parameter.\n";
}
void Private_Impl::commitAWB() {
MMAL_PARAMETER_AWBMODE_T param = {{MMAL_PARAMETER_AWB_MODE,sizeof ( param ) }, convertAWB ( State.rpc_awbMode ) };
if ( mmal_port_parameter_set ( State.camera_component->control, &param.hdr ) != MMAL_SUCCESS )
cout << __func__ << ": Failed to set AWB parameter.\n";
}
void Private_Impl::commitImageEffect() {
MMAL_PARAMETER_IMAGEFX_T imgFX = {{MMAL_PARAMETER_IMAGE_EFFECT,sizeof ( imgFX ) }, convertImageEffect ( State.rpc_imageEffect ) };
if ( mmal_port_parameter_set ( State.camera_component->control, &imgFX.hdr ) != MMAL_SUCCESS )
cout << __func__ << ": Failed to set image effect parameter.\n";
}
void Private_Impl::commitMetering() {
MMAL_PARAMETER_EXPOSUREMETERINGMODE_T meter_mode = {{MMAL_PARAMETER_EXP_METERING_MODE, sizeof ( meter_mode ) }, convertMetering ( State.rpc_exposureMeterMode ) };
if ( mmal_port_parameter_set ( State.camera_component->control, &meter_mode.hdr ) != MMAL_SUCCESS )
cout << __func__ << ": Failed to set metering parameter.\n";
}
void Private_Impl::commitFlips() {
MMAL_PARAMETER_MIRROR_T mirror = {{MMAL_PARAMETER_MIRROR, sizeof ( MMAL_PARAMETER_MIRROR_T ) }, MMAL_PARAM_MIRROR_NONE};
if ( State.hflip && State.vflip )
mirror.value = MMAL_PARAM_MIRROR_BOTH;
else if ( State.hflip )
mirror.value = MMAL_PARAM_MIRROR_HORIZONTAL;
else if ( State.vflip )
mirror.value = MMAL_PARAM_MIRROR_VERTICAL;
if ( mmal_port_parameter_set ( State.camera_component->output[0], &mirror.hdr ) != MMAL_SUCCESS ||
mmal_port_parameter_set ( State.camera_component->output[1], &mirror.hdr ) != MMAL_SUCCESS ||
mmal_port_parameter_set ( State.camera_component->output[2], &mirror.hdr ) )
cout << __func__ << ": Failed to set horizontal/vertical flip parameter.\n";
}
/**
* Set the specified camera to all the specified settings
* @param camera Pointer to camera component
* @param params Pointer to parameter block containing parameters
* @return 0 if successful, none-zero if unsuccessful.
*/
void Private_Impl::commitParameters ( ) {
assert ( State.camera_component!=0 );
commitSaturation();
commitSharpness();
commitContrast();
commitBrightness();
commitISO();
if ( State.shutterSpeed!=0 ) {
commitShutterSpeed();
State.rpc_exposureMode=RASPICAM_EXPOSURE_FIXEDFPS;
commitExposure();
} else commitExposure();
commitExposureCompensation();
commitMetering();
commitImageEffect();
commitRotation();
commitFlips();
commitVideoStabilization();
commitAWB();
commitAWB_RB();
}
void Private_Impl::commitVideoStabilization() {
// Set Video Stabilization
if ( mmal_port_parameter_set_boolean ( State.camera_component->control, MMAL_PARAMETER_VIDEO_STABILISATION, State.videoStabilisation ) != MMAL_SUCCESS )
cout << __func__ << ": Failed to set video stabilization parameter.\n";
}
void Private_Impl::camera_control_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
{
PORT_USERDATA *pData = ( PORT_USERDATA * ) port->userdata;
std::unique_lock<std::mutex> lck ( pData->_mutex );
if (buffer->cmd == MMAL_EVENT_PARAMETER_CHANGED)
{
MMAL_EVENT_PARAMETER_CHANGED_T *param = (MMAL_EVENT_PARAMETER_CHANGED_T *)buffer->data;
if (param->hdr.id == MMAL_PARAMETER_CAMERA_SETTINGS) {
MMAL_PARAMETER_CAMERA_SETTINGS_T *settings = (MMAL_PARAMETER_CAMERA_SETTINGS_T*)param;
pData->pstate->shutterSpeed = settings->exposure;
pData->pstate->awbg_red = float(settings->awb_red_gain.num)/settings->awb_red_gain.den;
pData->pstate->awbg_blue = float(settings->awb_blue_gain.num)/settings->awb_blue_gain.den;
}
}
else if (buffer->cmd == MMAL_EVENT_ERROR)
{
printf("No data received from sensor. Check all connections, including the Sunny one on the camera board");
}
else
printf("Received unexpected camera control callback event, 0x%08x", buffer->cmd);
mmal_buffer_header_release(buffer);
}
void Private_Impl::video_buffer_callback ( MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer ) {
MMAL_BUFFER_HEADER_T *new_buffer;
PORT_USERDATA *pData = ( PORT_USERDATA * ) port->userdata;
bool hasGrabbed=false;
// pData->_mutex.lock();
std::unique_lock<std::mutex> lck ( pData->_mutex );
if ( pData ) {
if( buffer->length &&
( pData->_userCallback || pData->wantToGrab )){
mmal_buffer_header_mem_lock ( buffer );
Private_Impl *self = pData->inst;
int width = pData->pstate->width;
int height = pData->pstate->height;
RASPICAM_FORMAT fmt = pData->pstate->captureFtm;
bool encoded = false; // So far only unencoded formats can be configured
// For unencoded formats, the buffer is padding to blocks
// TODO: According to picamera ('Under certain circumstances (non-resized, non-YUV, video-port captures), the resolution is rounded to 16x16 blocks instead of 32x16. Adjust your resolution rounding accordingly')
int bufferWidth = VCOS_ALIGN_UP(width, 32);
int bufferHeight = VCOS_ALIGN_UP(height, 16);
if ( bufferWidth == width || encoded ) {
pData->_buffData.resize ( buffer->length );
memcpy ( pData->_buffData.data,buffer->data,buffer->length );
}
else {
pData->_buffData.resize ( self->getImageTypeSize( fmt ) );
int bpp = 1;
if(fmt == RASPICAM_FORMAT_RGB || fmt == RASPICAM_FORMAT_BGR) {
bpp = 3;
}
for(int i = 0; i < height; i++) {
memcpy ( pData->_buffData.data + i*width*bpp, buffer->data + i*bufferWidth*bpp, width*bpp);
}
if ( fmt == RASPICAM_FORMAT_YUV420 ) {
// Starting points in both buffers
uint8_t *outUV = pData->_buffData.data + width*height;
uint8_t *bufferUV = buffer->data + bufferHeight*bufferWidth;
width /= 2;
height /= 2;
bufferWidth /= 2;
bufferHeight /= 2;
for(int plane = 0; plane < 2; plane++) {
for(int i = 0; i < height; i++) {
memcpy ( outUV + i*width, bufferUV + i*bufferWidth, width );
}
outUV += width*height;
bufferUV += bufferWidth*bufferHeight;
}
}
}
pData->wantToGrab =false;
hasGrabbed=true;
mmal_buffer_header_mem_unlock ( buffer );
}
}
//pData->_mutex.unlock();
// if ( hasGrabbed ) pData->Thcond.BroadCast(); //wake up waiting client
// release buffer back to the pool
mmal_buffer_header_release ( buffer );
// and send one back to the port (if still open)
if ( port->is_enabled ) {
MMAL_STATUS_T status;
new_buffer = mmal_queue_get ( pData->pstate->video_pool->queue );
if ( new_buffer )
status = mmal_port_send_buffer ( port, new_buffer );
if ( !new_buffer || status != MMAL_SUCCESS )
printf ( "Unable to return a buffer to the encoder port" );
}
if ( pData->pstate->shutterSpeed!=0 && pData->pstate->rpc_exposureMode == RASPICAM_EXPOSURE_FIXEDFPS)
mmal_port_parameter_set_uint32 ( pData->pstate->camera_component->control, MMAL_PARAMETER_SHUTTER_SPEED, pData->pstate->shutterSpeed ) ;
if ( hasGrabbed ) {
if ( pData->_userCallback ) {
// TODO - add locking mechanism for the callback
pData->_userCallback(pData->_userCallbackData);
}
pData->Thcond.BroadCast(); //wake up waiting client
}
}
void Private_Impl::setWidth ( unsigned int width ) {
State.width = width;
}
void Private_Impl::setHeight ( unsigned int height ) {
State.height = height;
}
void Private_Impl::setFormat ( RASPICAM_FORMAT fmt ) {
if ( isOpened() ) {
cerr<<__FILE__<<":"<<__LINE__<<":"<<__func__<<": can not change format with camera already opened"<<endl;
return;
}
State.captureFtm = fmt;
}
void Private_Impl::setSensorMode ( int mode ) {
if ( isOpened() ) {
cerr<<__FILE__<<":"<<__LINE__<<":"<<__func__<<": can not change sensor mode with camera already opened"<<endl;
return;
}
State.sensor_mode = mode;
}
void Private_Impl::setCaptureSize ( unsigned int width, unsigned int height ) {
setWidth ( width );
setHeight ( height );
}
void Private_Impl::setVideoStabilization ( bool v ) {
State.videoStabilisation=v;
if ( isOpened() ) commitVideoStabilization();
}
void Private_Impl::setBrightness ( unsigned int brightness ) {
if ( brightness > 100 ) brightness = 100 ;
State.brightness = brightness;
if ( isOpened() ) commitBrightness();
}
void Private_Impl::setShutterSpeed ( unsigned int shutter ) {
if ( shutter > 330000 )
shutter = 330000;
State.shutterSpeed= shutter;
if ( isOpened() ) commitShutterSpeed();
}
void Private_Impl::setRotation ( int rotation ) {
while ( rotation < 0 )
rotation += 360;
if ( rotation >= 360 )
rotation = rotation % 360;
State.rotation = rotation;
if ( isOpened() ) commitRotation();
}
void Private_Impl::setISO ( int iso ) {
State.ISO = iso;
if ( isOpened() ) commitISO();
}
void Private_Impl::setSharpness ( int sharpness ) {
if ( sharpness < -100 ) sharpness = -100;
if ( sharpness > 100 ) sharpness = 100;
State.sharpness = sharpness;
if ( isOpened() ) commitSharpness();
}
void Private_Impl::setContrast ( int contrast ) {
if ( contrast < -100 ) contrast = -100;
if ( contrast > 100 ) contrast = 100;
State.contrast = contrast;
if ( isOpened() ) commitContrast();
}
void Private_Impl::setSaturation ( int saturation ) {
if ( saturation < -100 ) saturation = -100;
if ( saturation > 100 ) saturation = 100;
State.saturation = saturation;
if ( isOpened() ) commitSaturation();
}
void Private_Impl::setAWB_RB ( float red_g, float blue_g ) {
State.awbg_blue = blue_g;
State.awbg_red = red_g;
if ( isOpened() ) commitAWB_RB();
}
void Private_Impl::setExposure ( RASPICAM_EXPOSURE exposure ) {
State.rpc_exposureMode = exposure;
if ( isOpened() ) commitExposure();
}
void Private_Impl::setAWB ( RASPICAM_AWB awb ) {
State.rpc_awbMode = awb;
if ( isOpened() ) commitAWB();
}
void Private_Impl::setImageEffect ( RASPICAM_IMAGE_EFFECT imageEffect ) {
State.rpc_imageEffect = imageEffect;
if ( isOpened() ) commitImageEffect();
}
void Private_Impl::setMetering ( RASPICAM_METERING metering ) {
State.rpc_exposureMeterMode = metering;
if ( isOpened() ) commitMetering();
}
void Private_Impl::setExposureCompensation ( int val ) {
if ( val < -10 ) val= -10;
if ( val > 10 ) val = 10;
State.exposureCompensation=val;
if ( isOpened() ) commitExposureCompensation();
}
void Private_Impl::setHorizontalFlip ( bool hFlip ) {
State.hflip = hFlip;
if ( isOpened() ) commitFlips();
}
void Private_Impl::setVerticalFlip ( bool vFlip ) {
State.vflip = vFlip;
if ( isOpened() ) commitFlips();
}
void Private_Impl::setFrameRate ( int frames_per_second ) {
State.framerate = frames_per_second;
}
MMAL_PARAM_EXPOSUREMETERINGMODE_T Private_Impl::convertMetering ( RASPICAM_METERING metering ) {
switch ( metering ) {
case RASPICAM_METERING_AVERAGE:
return MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE;
case RASPICAM_METERING_SPOT:
return MMAL_PARAM_EXPOSUREMETERINGMODE_SPOT;
case RASPICAM_METERING_BACKLIT:
return MMAL_PARAM_EXPOSUREMETERINGMODE_BACKLIT;
case RASPICAM_METERING_MATRIX:
return MMAL_PARAM_EXPOSUREMETERINGMODE_MATRIX;
default:
return MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE;
}
}
MMAL_PARAM_EXPOSUREMODE_T Private_Impl::convertExposure ( RASPICAM_EXPOSURE exposure ) {
switch ( exposure ) {
case RASPICAM_EXPOSURE_OFF:
return MMAL_PARAM_EXPOSUREMODE_OFF;
case RASPICAM_EXPOSURE_AUTO:
return MMAL_PARAM_EXPOSUREMODE_AUTO;
case RASPICAM_EXPOSURE_NIGHT:
return MMAL_PARAM_EXPOSUREMODE_NIGHT;
case RASPICAM_EXPOSURE_NIGHTPREVIEW:
return MMAL_PARAM_EXPOSUREMODE_NIGHTPREVIEW;
case RASPICAM_EXPOSURE_BACKLIGHT:
return MMAL_PARAM_EXPOSUREMODE_BACKLIGHT;
case RASPICAM_EXPOSURE_SPOTLIGHT:
return MMAL_PARAM_EXPOSUREMODE_SPOTLIGHT;
case RASPICAM_EXPOSURE_SPORTS:
return MMAL_PARAM_EXPOSUREMODE_SPORTS;
case RASPICAM_EXPOSURE_SNOW:
return MMAL_PARAM_EXPOSUREMODE_SNOW;
case RASPICAM_EXPOSURE_BEACH:
return MMAL_PARAM_EXPOSUREMODE_BEACH;
case RASPICAM_EXPOSURE_VERYLONG:
return MMAL_PARAM_EXPOSUREMODE_VERYLONG;
case RASPICAM_EXPOSURE_FIXEDFPS:
return MMAL_PARAM_EXPOSUREMODE_FIXEDFPS;
case RASPICAM_EXPOSURE_ANTISHAKE:
return MMAL_PARAM_EXPOSUREMODE_ANTISHAKE;
case RASPICAM_EXPOSURE_FIREWORKS:
return MMAL_PARAM_EXPOSUREMODE_FIREWORKS;
default:
return MMAL_PARAM_EXPOSUREMODE_AUTO;
}
}
MMAL_PARAM_AWBMODE_T Private_Impl::convertAWB ( RASPICAM_AWB awb ) {
switch ( awb ) {
case RASPICAM_AWB_OFF:
return MMAL_PARAM_AWBMODE_OFF;
case RASPICAM_AWB_AUTO:
return MMAL_PARAM_AWBMODE_AUTO;
case RASPICAM_AWB_SUNLIGHT:
return MMAL_PARAM_AWBMODE_SUNLIGHT;
case RASPICAM_AWB_CLOUDY:
return MMAL_PARAM_AWBMODE_CLOUDY;
case RASPICAM_AWB_SHADE:
return MMAL_PARAM_AWBMODE_SHADE;
case RASPICAM_AWB_TUNGSTEN:
return MMAL_PARAM_AWBMODE_TUNGSTEN;
case RASPICAM_AWB_FLUORESCENT:
return MMAL_PARAM_AWBMODE_FLUORESCENT;
case RASPICAM_AWB_INCANDESCENT:
return MMAL_PARAM_AWBMODE_INCANDESCENT;
case RASPICAM_AWB_FLASH:
return MMAL_PARAM_AWBMODE_FLASH;
case RASPICAM_AWB_HORIZON:
return MMAL_PARAM_AWBMODE_HORIZON;
default:
return MMAL_PARAM_AWBMODE_AUTO;
}
}
MMAL_PARAM_IMAGEFX_T Private_Impl::convertImageEffect ( RASPICAM_IMAGE_EFFECT imageEffect ) {
switch ( imageEffect ) {
case RASPICAM_IMAGE_EFFECT_NONE:
return MMAL_PARAM_IMAGEFX_NONE;
case RASPICAM_IMAGE_EFFECT_NEGATIVE:
return MMAL_PARAM_IMAGEFX_NEGATIVE;
case RASPICAM_IMAGE_EFFECT_SOLARIZE:
return MMAL_PARAM_IMAGEFX_SOLARIZE;
case RASPICAM_IMAGE_EFFECT_SKETCH:
return MMAL_PARAM_IMAGEFX_SKETCH;
case RASPICAM_IMAGE_EFFECT_DENOISE:
return MMAL_PARAM_IMAGEFX_DENOISE;
case RASPICAM_IMAGE_EFFECT_EMBOSS:
return MMAL_PARAM_IMAGEFX_EMBOSS;
case RASPICAM_IMAGE_EFFECT_OILPAINT:
return MMAL_PARAM_IMAGEFX_OILPAINT;
case RASPICAM_IMAGE_EFFECT_HATCH:
return MMAL_PARAM_IMAGEFX_HATCH;
case RASPICAM_IMAGE_EFFECT_GPEN:
return MMAL_PARAM_IMAGEFX_GPEN;
case RASPICAM_IMAGE_EFFECT_PASTEL:
return MMAL_PARAM_IMAGEFX_PASTEL;
case RASPICAM_IMAGE_EFFECT_WATERCOLOR:
return MMAL_PARAM_IMAGEFX_WATERCOLOUR;
case RASPICAM_IMAGE_EFFECT_FILM:
return MMAL_PARAM_IMAGEFX_FILM;
case RASPICAM_IMAGE_EFFECT_BLUR:
return MMAL_PARAM_IMAGEFX_BLUR;
case RASPICAM_IMAGE_EFFECT_SATURATION:
return MMAL_PARAM_IMAGEFX_SATURATION;
case RASPICAM_IMAGE_EFFECT_COLORSWAP:
return MMAL_PARAM_IMAGEFX_COLOURSWAP;
case RASPICAM_IMAGE_EFFECT_WASHEDOUT:
return MMAL_PARAM_IMAGEFX_WASHEDOUT;
case RASPICAM_IMAGE_EFFECT_POSTERISE:
return MMAL_PARAM_IMAGEFX_POSTERISE;
case RASPICAM_IMAGE_EFFECT_COLORPOINT:
return MMAL_PARAM_IMAGEFX_COLOURPOINT;
case RASPICAM_IMAGE_EFFECT_COLORBALANCE:
return MMAL_PARAM_IMAGEFX_COLOURBALANCE;
case RASPICAM_IMAGE_EFFECT_CARTOON:
return MMAL_PARAM_IMAGEFX_CARTOON;
default:
return MMAL_PARAM_IMAGEFX_NONE;
}
}
int Private_Impl::convertFormat ( RASPICAM_FORMAT fmt ) {
switch ( fmt ) {
case RASPICAM_FORMAT_RGB:
return _rgb_bgr_fixed ? MMAL_ENCODING_RGB24 : MMAL_ENCODING_BGR24;
case RASPICAM_FORMAT_BGR:
return _rgb_bgr_fixed ? MMAL_ENCODING_BGR24 : MMAL_ENCODING_RGB24;
case RASPICAM_FORMAT_GRAY:
return MMAL_ENCODING_I420;
case RASPICAM_FORMAT_YUV420:
return MMAL_ENCODING_I420;
default:
return MMAL_ENCODING_I420;
}
}
//Returns an id of the camera. We assume the camera id is the one of the raspberry
//the id is obtained using raspberry serial number obtained in /proc/cpuinfo
string Private_Impl::getId() const{
char serial[1024];
serial[0]='\0';
ifstream file ( "/proc/cpuinfo" );
if ( !file ) {
cerr<<__FILE__<<" "<<__LINE__<<":"<<__func__<<"Could not read /proc/cpuinfo"<<endl;
return serial;
}
//read lines until find serial
bool found=false;
while ( !file.eof() && !found ) {
char line[1024];
file.getline ( line,1024 );
string str ( line );
char aux[100];
if ( str.find ( "Serial" ) !=string::npos ) {
if ( sscanf ( line,"%s : %s",aux,serial ) !=2 ) {
cerr<<__FILE__<<" "<<__LINE__<<":"<<__func__<<"Error parsing /proc/cpuinfo"<<endl;
} else found=true;
}
};
return serial;
}
void Private_Impl::convertBGR2RGB ( unsigned char * in_bgr,unsigned char * out_rgb,int size ) {
unsigned char *end=in_bgr+size;
unsigned char *in_ptr=in_bgr;
while ( in_ptr<end ) {
swap ( in_ptr[2],in_ptr[0] );
in_ptr+=3;
}
mempcpy ( out_rgb,in_bgr,size );
}
void Private_Impl::commitAWB_RB() {
MMAL_PARAMETER_AWB_GAINS_T param = {{MMAL_PARAMETER_CUSTOM_AWB_GAINS,sizeof(param)}, {0,0}, {0,0}};
param.r_gain.num = (unsigned int)(State.awbg_red * 65536);
param.b_gain.num = (unsigned int)(State.awbg_blue * 65536);
param.r_gain.den = param.b_gain.den = 65536;
if ( mmal_port_parameter_set(State.camera_component->control, &param.hdr) != MMAL_SUCCESS )
cout << __func__ << ": Failed to set AWBG gains parameter.\n";
}
}
}
@@ -0,0 +1,311 @@
/**********************************************************
Software developed by AVA ( Ava Group of the University of Cordoba, ava at uco dot es)
Main author Rafael Munoz Salinas (rmsalinas at uco dot es)
This software is released under BSD license as expressed below
-------------------------------------------------------------------
Copyright (c) 2013, AVA ( Ava Group University of Cordoba, ava at uco dot es)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software
must display the following acknowledgement:
This product includes software developed by the Ava group of the University of Cordoba.
4. Neither the name of the University nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY AVA ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL AVA BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
****************************************************************/
#ifndef _Private_RaspiCam_IMPL_H
#define _Private_RaspiCam_IMPL_H
#include "mmal/mmal.h"
//#include "mmal_connection.h"
#include <mutex>
#include <string>
#include "raspicamtypes.h"
#include "private_types.h"
#include "threadcondition.h"
namespace raspicam {
namespace _private
{
/**Base class that do all the hard work
*/
class Private_Impl
{
/** Struct used to pass information in encoder port userdata to callback
*/
struct PORT_USERDATA
{
PORT_USERDATA() {
wantToGrab=false;
pstate=0;
}
void waitForFrame() {
//_mutex.lock();
std::unique_lock<std::mutex> lck ( _mutex );
wantToGrab=true;
// _mutex.unlock();
// Thcond.Wait();
Thcond.Wait(lck); //this will unlock the mutex and wait atomically
};
RASPIVID_STATE *pstate; /// pointer to our state in case required in callback
Private_Impl *inst;
std::mutex _mutex;
ThreadCondition Thcond;
bool wantToGrab;
membuf<unsigned char> _buffData;
/* User define callback interface */
void (*_userCallback)(void*) = 0;
void* _userCallbackData;
};
public:
/**Constructor
*/
Private_Impl();
/**Destructor
*/
~Private_Impl();
/**Opens the camera and start capturing
*/
bool open ( bool StartCapture=true );
/**indicates if camera is open
*/
bool isOpened() const
{
return _isOpened;
}
/**Starts camera capture
*/
bool startCapture();
/**Indicates if is capturing
*/
bool isCapturing() const{return _isCapturing;}
/*
* the function 'userCallback' will be called every time new data arrived from camera,
* with 'data' as argument.
*/
void setUserCallback(void (*userCallback)(void*) , void* data = 0);
/**Grabs the next frame and keeps it in internal buffer. Blocks until next frame arrives
*/
bool grab();
/**Retrieves the buffer previously grabbed.
* NOTE: Change in version 0.0.5. Format is stablished in setFormat function
* So type param is ignored. Do not use this parameter.
* You can use getFormat to know the current format
*/
void retrieve ( unsigned char *data,RASPICAM_FORMAT type=RASPICAM_FORMAT_IGNORE );
/**Alternative to retrieve. Returns a pointer to the original image data buffer.
* Be careful, if you call grab(), this will be rewritten with the new data
*/
unsigned char *getImageBufferData() const;
/**
* Returns the size of the buffer returned in getImagePtr. If is like calling getImageTypeSize(getFormat()). Just for dummies :P
*/
size_t getImageBufferSize() const;
/** Stops camera and free resources
*/
void release();
//sets capture format. Can not be changed once camera is opened
void setFormat ( RASPICAM_FORMAT fmt );
//sets sensor mode. Can not be changed once camera is opened
void setSensorMode ( int mode );
//sets width. Can not be changed once camera is opened
void setWidth ( unsigned int width ) ;
//sets height. Can not be changed once camera is opened
void setHeight ( unsigned int height );
//sets capture size. Can not be changed once camera is opened
void setCaptureSize ( unsigned int width, unsigned int height );
void setBrightness ( unsigned int brightness );
void setRotation ( int rotation );
void setISO ( int iso );
void setSharpness ( int sharpness );
void setContrast ( int contrast );
void setSaturation ( int saturation );
void setExposure ( RASPICAM_EXPOSURE exposure );
void setVideoStabilization ( bool v );
void setExposureCompensation ( int val ); //-10,10
void setAWB ( RASPICAM_AWB awb );
void setAWB_RB ( float red,float blue );//ranges [0,1]
void setImageEffect ( RASPICAM_IMAGE_EFFECT imageEffect );
void setMetering ( RASPICAM_METERING metering );
void setHorizontalFlip ( bool hFlip );
void setVerticalFlip ( bool vFlip );
/**
*Set the shutter speed to the specified value (in microseconds).
*There is currently an upper limit of approximately 330000us (330ms, 0.33s) past which operation is undefined.
*/
void setShutterSpeed ( unsigned int shutter ); //currently not supported
//sets frame rate. Can not be changed once camera is opened
void setFrameRate ( int fps );
RASPICAM_FORMAT getFormat() const {return State.captureFtm;}
//Accessors
unsigned int getSensorMode() const
{
return State.sensor_mode;
}
unsigned int getWidth() const
{
return State.width;
}
unsigned int getHeight() const
{
return State.height;
}
unsigned int getBrightness() const
{
return State.brightness;
}
unsigned int getRotation() const
{
return State.rotation;
}
int getISO() const
{
return State.ISO;
}
int getSharpness() const
{
return State.sharpness;
}
int getContrast() const
{
return State.contrast;
}
int getSaturation() const
{
return State.saturation;
}
unsigned int getShutterSpeed() const
{
return State.shutterSpeed;
}
RASPICAM_EXPOSURE getExposure() const
{
return State.rpc_exposureMode;
}
RASPICAM_AWB getAWB() const
{
return State.rpc_awbMode;
}
float getAWBG_red(){return State.awbg_red;}
float getAWBG_blue(){return State.awbg_blue;}
int getFrameRate() const
{
return State.framerate;
}
RASPICAM_IMAGE_EFFECT getImageEffect() const
{
return State.rpc_imageEffect;
}
RASPICAM_METERING getMetering() const
{
return State.rpc_exposureMeterMode;
}
bool isHorizontallyFlipped() const
{
return State.hflip;
}
bool isVerticallyFlipped() const
{
return State.vflip;
}
//Returns an id of the camera. We assume the camera id is the one of the raspberry
//the id is obtained using raspberry serial number obtained in /proc/cpuinfo
std::string getId() const;
/**Returns the size of the required buffer for the different image types in retrieve
*/
size_t getImageTypeSize ( RASPICAM_FORMAT type ) const;
private:
static void video_buffer_callback ( MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer );
static void camera_control_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer);
void setDefaultStateParams();
MMAL_COMPONENT_T *create_camera_component ( RASPIVID_STATE *state );
void destroy_camera_component ( RASPIVID_STATE *state );
//Commit
void commitParameters( );
void commitBrightness();
void commitRotation() ;
void commitISO() ;
void commitSharpness();
void commitContrast();
void commitSaturation();
void commitExposure();
void commitAWB();
void commitImageEffect();
void commitMetering();
void commitFlips();
void commitExposureCompensation();
void commitVideoStabilization();
void commitShutterSpeed();
void commitAWB_RB();
MMAL_PARAM_EXPOSUREMODE_T convertExposure ( RASPICAM_EXPOSURE exposure ) ;
MMAL_PARAM_AWBMODE_T convertAWB ( RASPICAM_AWB awb ) ;
MMAL_PARAM_IMAGEFX_T convertImageEffect ( RASPICAM_IMAGE_EFFECT imageEffect ) ;
MMAL_PARAM_EXPOSUREMETERINGMODE_T convertMetering ( RASPICAM_METERING metering ) ;
int convertFormat ( RASPICAM_FORMAT fmt ) ;
//Color conversion
void convertBGR2RGB(unsigned char * in_bgr,unsigned char * out_rgb,int size);
float VIDEO_FRAME_RATE_NUM;
RASPIVID_STATE State;
MMAL_STATUS_T status;
MMAL_PORT_T *camera_video_port;//,*camera_still_port
PORT_USERDATA callback_data;
bool _isOpened;
bool _isCapturing;
bool _rgb_bgr_fixed;
};
}
}
#endif
@@ -0,0 +1,117 @@
/**********************************************************
Software developed by AVA ( Ava Group of the University of Cordoba, ava at uco dot es)
Main author Rafael Munoz Salinas (rmsalinas at uco dot es)
This software is released under BSD license as expressed below
-------------------------------------------------------------------
Copyright (c) 2013, AVA ( Ava Group University of Cordoba, ava at uco dot es)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software
must display the following acknowledgement:
This product includes software developed by the Ava group of the University of Cordoba.
4. Neither the name of the University nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY AVA ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL AVA BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
****************************************************************/
#ifndef _RaspiCam_private_types_H
#define _RaspiCam_private_types_H
namespace raspicam {
namespace _private{
/// struct contain camera settings
struct MMAL_PARAM_COLOURFX_T
{
int enable,u,v; /// Turn colourFX on or off, U and V to use
} ;
struct PARAM_FLOAT_RECT_T
{
double x,y,w,h;
} ;
/** Structure containing all state information for the current run
*/
struct RASPIVID_STATE
{
int sensor_mode; /// Requested width of image
int width; /// Requested width of image
int height; /// requested height of image
int framerate; /// Requested frame rate (fps)
/// the camera output or the encoder output (with compression artifacts)
MMAL_COMPONENT_T *camera_component; /// Pointer to the camera component
MMAL_POOL_T *video_pool; /// Pointer to the pool of buffers used by encoder output port
//camera params
int sharpness; /// -100 to 100
int contrast; /// -100 to 100
int brightness; /// 0 to 100
int saturation; /// -100 to 100
int ISO; /// TODO : what range?
bool videoStabilisation; /// 0 or 1 (false or true)
int exposureCompensation; /// -10 to +10 ?
int shutterSpeed;
RASPICAM_FORMAT captureFtm;
RASPICAM_EXPOSURE rpc_exposureMode;
RASPICAM_METERING rpc_exposureMeterMode;
RASPICAM_AWB rpc_awbMode;
RASPICAM_IMAGE_EFFECT rpc_imageEffect;
MMAL_PARAMETER_IMAGEFX_PARAMETERS_T imageEffectsParameters;
MMAL_PARAM_COLOURFX_T colourEffects;
int rotation; /// 0-359
int hflip; /// 0 or 1
int vflip; /// 0 or 1
PARAM_FLOAT_RECT_T roi; /// region of interest to use on the sensor. Normalised [0,1] values in the rect
float awbg_red;//white balance red and blue
float awbg_blue;
} ;
//clean buffer
template<typename T>
class membuf{
public:
membuf() {
data=0;
size=0;
}
~membuf() {
if ( data!=0 ) delete []data;
}
void resize ( size_t s ) {
if ( s!=size ) {
delete data;
size=s;
data=new T[size];
}
}
T *data;
size_t size;
};
}
}
#endif
@@ -0,0 +1,72 @@
/**********************************************************
Software developed by AVA ( Ava Group of the University of Cordoba, ava at uco dot es)
Main author Rafael Munoz Salinas (rmsalinas at uco dot es)
This software is released under BSD license as expressed below
-------------------------------------------------------------------
Copyright (c) 2013, AVA ( Ava Group University of Cordoba, ava at uco dot es)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software
must display the following acknowledgement:
This product includes software developed by the Ava group of the University of Cordoba.
4. Neither the name of the University nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY AVA ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL AVA BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
****************************************************************/
#include "threadcondition.h"
namespace raspicam {
namespace _private
{
////////////////////////////////
//
////////////////////////////////
ThreadCondition::ThreadCondition() throw ( raspicam::Exception ) {
ready=false;
}
////////////////////////////////
//
//
////////////////////////////////
void ThreadCondition::Wait(std::unique_lock<std::mutex>& lck) throw ( raspicam::Exception ) {
ready=false;
while ( !ready ) cv.wait ( lck );
}
////////////////////////////////
//
//
////////////////////////////////
void ThreadCondition::BroadCast() throw ( raspicam::Exception ) {
ready = true;
cv.notify_all();
}
} /* ----- end of namespace gu ----- */
}
@@ -0,0 +1,74 @@
/**********************************************************
Software developed by AVA ( Ava Group of the University of Cordoba, ava at uco dot es)
Main author Rafael Munoz Salinas (rmsalinas at uco dot es)
This software is released under BSD license as expressed below
-------------------------------------------------------------------
Copyright (c) 2013, AVA ( Ava Group University of Cordoba, ava at uco dot es)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software
must display the following acknowledgement:
This product includes software developed by the Ava group of the University of Cordoba.
4. Neither the name of the University nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY AVA ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL AVA BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
****************************************************************/
#ifndef _RASPICAM_THREADTHREADCONDITION_H
#define _RASPICAM_THREADTHREADCONDITION_H
#include <string>
#include <thread> // std::thread
#include <mutex> // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable
#include "exceptions.h"
namespace raspicam {
namespace _private
{
/** @brief This class implements a condition to stop a thread until the
* condition is reached.
* @ingroup threads */
class ThreadCondition
{
public:
ThreadCondition() throw ( raspicam::Exception );
/**The thread that call this function waits untils the condition is activated */
void Wait(std::unique_lock<std::mutex>& lck) throw ( raspicam::Exception );
/**Wake up all threads waiting for this condition */
void BroadCast() throw ( raspicam::Exception );
private:
std::mutex mtx;
std::condition_variable cv;
bool ready ;
};
}
} /* ----- end of namespace gu ----- */
#endif
@@ -0,0 +1,853 @@
/**********************************************************
Software developed by AVA ( Ava Group of the University of Cordoba, ava at uco dot es)
Main author Rafael Munoz Salinas (rmsalinas at uco dot es)
This software is released under BSD license as expressed below
-------------------------------------------------------------------
Copyright (c) 2013, AVA ( Ava Group University of Cordoba, ava at uco dot es)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software
must display the following acknowledgement:
This product includes software developed by the Ava group of the University of Cordoba.
4. Neither the name of the University nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY AVA ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL AVA BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
****************************************************************/
#include <fstream>
#include "private_still_impl.h"
#include "mmal/mmal_buffer.h"
#include "mmal/util/mmal_default_components.h"
#include "mmal/util/mmal_util.h"
#include "mmal/util/mmal_util_params.h"
#include <iostream>
#include <semaphore.h>
using namespace std;
namespace raspicam {
namespace _private
{
typedef struct {
Private_Impl_Still * cameraBoard;
MMAL_POOL_T * encoderPool;
imageTakenCallback imageCallback;
sem_t *mutex;
unsigned char * data;
unsigned int bufferPosition;
unsigned int startingOffset;
unsigned int offset;
unsigned int length;
} RASPICAM_USERDATA;
static void control_callback ( MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer ) {
(void)port;
if ( buffer->cmd == MMAL_EVENT_PARAMETER_CHANGED ) {
} else {
// Unexpected control callback event!
}
mmal_buffer_header_release ( buffer );
}
static void buffer_callback ( MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer ) {
RASPICAM_USERDATA *userdata = ( RASPICAM_USERDATA* ) port->userdata;
if ( userdata == NULL || userdata->cameraBoard == NULL ) {
} else {
unsigned int flags = buffer->flags;
mmal_buffer_header_mem_lock ( buffer );
for ( unsigned int i = 0; i < buffer->length; i++, userdata->bufferPosition++ ) {
if ( userdata->offset >= userdata->length ) {
cout << userdata->cameraBoard->API_NAME << ": Buffer provided was too small! Failed to copy data into buffer.\n";
userdata->cameraBoard = NULL;
break;
} else {
if ( userdata->cameraBoard->getEncoding() == RASPICAM_ENCODING_RGB ) {
// Determines if the byte is an RGB value
if ( userdata->bufferPosition >= 54 ) {
userdata->data[userdata->offset] = buffer->data[i];
userdata->offset++;
}
} else {
userdata->data[userdata->offset] = buffer->data[i];
userdata->offset++;
}
}
}
mmal_buffer_header_mem_unlock ( buffer );
unsigned int END_FLAG = 0;
END_FLAG |= MMAL_BUFFER_HEADER_FLAG_FRAME_END;
END_FLAG |= MMAL_BUFFER_HEADER_FLAG_TRANSMISSION_FAILED;
END_FLAG &= flags;
if ( END_FLAG != 0 ) {
if ( userdata->mutex == NULL ) {
userdata->imageCallback ( userdata->data, userdata->startingOffset, userdata->length - userdata->startingOffset );
} else {
sem_post ( userdata->mutex );
}
}
}
mmal_buffer_header_release ( buffer );
if ( port->is_enabled ) {
MMAL_BUFFER_HEADER_T *new_buffer = mmal_queue_get ( userdata->encoderPool->queue );
if ( new_buffer ) mmal_port_send_buffer ( port, new_buffer );
}
}
void Private_Impl_Still::setDefaults() {
width = 640;
height = 480;
encoding = RASPICAM_ENCODING_BMP;
encoder = NULL;
encoder_connection = NULL;
sharpness = 0;
contrast = 0;
brightness = 50;
quality = 85;
saturation = 0;
iso = 400;
//videoStabilisation = 0;
//exposureCompensation = 0;
exposure = RASPICAM_EXPOSURE_AUTO;
metering = RASPICAM_METERING_AVERAGE;
awb = RASPICAM_AWB_AUTO;
imageEffect = RASPICAM_IMAGE_EFFECT_NONE;
//colourEffects.enable = 0;
//colourEffects.u = 128;
//colourEffects.v = 128;
rotation = 0;
changedSettings = true;
horizontalFlip = false;
verticalFlip = false;
//roi.x = params->roi.y = 0.0;
//roi.w = params->roi.h = 1.0;
}
void Private_Impl_Still::commitParameters() {
if ( !changedSettings ) return;
commitSharpness();
commitContrast();
commitBrightness();
commitQuality();
commitSaturation();
commitISO();
commitExposure();
commitMetering();
commitAWB();
commitImageEffect();
commitRotation();
commitFlips();
// Set Video Stabilization
if ( mmal_port_parameter_set_boolean ( camera->control, MMAL_PARAMETER_VIDEO_STABILISATION, 0 ) != MMAL_SUCCESS )
cout << API_NAME << ": Failed to set video stabilization parameter.\n";
// Set Exposure Compensation
if ( mmal_port_parameter_set_int32 ( camera->control, MMAL_PARAMETER_EXPOSURE_COMP , 0 ) != MMAL_SUCCESS )
cout << API_NAME << ": Failed to set exposure compensation parameter.\n";
// Set Color Efects
MMAL_PARAMETER_COLOURFX_T colfx = {{MMAL_PARAMETER_COLOUR_EFFECT,sizeof ( colfx ) }, 0, 0, 0};
colfx.enable = 0;
colfx.u = 128;
colfx.v = 128;
if ( mmal_port_parameter_set ( camera->control, &colfx.hdr ) != MMAL_SUCCESS )
cout << API_NAME << ": Failed to set color effects parameter.\n";
// Set ROI
MMAL_PARAMETER_INPUT_CROP_T crop = {{MMAL_PARAMETER_INPUT_CROP, sizeof ( MMAL_PARAMETER_INPUT_CROP_T ) },{0,0,0,0}};
crop.rect.x = ( 65536 * 0 );
crop.rect.y = ( 65536 * 0 );
crop.rect.width = ( 65536 * 1 );
crop.rect.height = ( 65536 * 1 );
if ( mmal_port_parameter_set ( camera->control, &crop.hdr ) != MMAL_SUCCESS )
cout << API_NAME << ": Failed to set ROI parameter.\n";
// Set encoder encoding
if ( encoder_output_port != NULL ) {
encoder_output_port->format->encoding = convertEncoding ( encoding );
mmal_port_format_commit ( encoder_output_port );
}
changedSettings = false;
}
MMAL_STATUS_T Private_Impl_Still::connectPorts ( MMAL_PORT_T *output_port, MMAL_PORT_T *input_port, MMAL_CONNECTION_T **connection ) {
MMAL_STATUS_T status = mmal_connection_create ( connection, output_port, input_port, MMAL_CONNECTION_FLAG_TUNNELLING | MMAL_CONNECTION_FLAG_ALLOCATION_ON_INPUT );
if ( status == MMAL_SUCCESS ) {
status = mmal_connection_enable ( *connection );
if ( status != MMAL_SUCCESS )
mmal_connection_destroy ( *connection );
}
return status;
}
int Private_Impl_Still::createCamera() {
if ( mmal_component_create ( MMAL_COMPONENT_DEFAULT_CAMERA, &camera ) ) {
cout << API_NAME << ": Failed to create camera component.\n";
destroyCamera();
return -1;
}
if ( !camera->output_num ) {
cout << API_NAME << ": Camera does not have output ports!\n";
destroyCamera();
return -1;
}
camera_still_port = camera->output[MMAL_CAMERA_CAPTURE_PORT];
// Enable the camera, and tell it its control callback function
if ( mmal_port_enable ( camera->control, control_callback ) ) {
cout << API_NAME << ": Could not enable control port.\n";
destroyCamera();
return -1;
}
MMAL_PARAMETER_CAMERA_CONFIG_T camConfig = {
{MMAL_PARAMETER_CAMERA_CONFIG, sizeof ( camConfig ) },
width, // max_stills_w
height, // max_stills_h
0, // stills_yuv422
1, // one_shot_stills
width, // max_preview_video_w
height, // max_preview_video_h
3, // num_preview_video_frames
0, // stills_capture_circular_buffer_height
0, // fast_preview_resume
MMAL_PARAM_TIMESTAMP_MODE_RESET_STC // use_stc_timestamp
};
if ( mmal_port_parameter_set ( camera->control, &camConfig.hdr ) != MMAL_SUCCESS )
cout << API_NAME << ": Could not set port parameters.\n";
commitParameters();
MMAL_ES_FORMAT_T * format = camera_still_port->format;
format->encoding = MMAL_ENCODING_OPAQUE;
format->es->video.width = width;
format->es->video.height = height;
format->es->video.crop.x = 0;
format->es->video.crop.y = 0;
format->es->video.crop.width = width;
format->es->video.crop.height = height;
format->es->video.frame_rate.num = STILLS_FRAME_RATE_NUM;
format->es->video.frame_rate.den = STILLS_FRAME_RATE_DEN;
if ( camera_still_port->buffer_size < camera_still_port->buffer_size_min )
camera_still_port->buffer_size = camera_still_port->buffer_size_min;
camera_still_port->buffer_num = camera_still_port->buffer_num_recommended;
if ( mmal_port_format_commit ( camera_still_port ) ) {
cout << API_NAME << ": Camera still format could not be set.\n";
destroyCamera();
return -1;
}
if ( mmal_component_enable ( camera ) ) {
cout << API_NAME << ": Camera component could not be enabled.\n";
destroyCamera();
return -1;
}
if ( ! ( encoder_pool = mmal_port_pool_create ( camera_still_port, camera_still_port->buffer_num, camera_still_port->buffer_size ) ) ) {
cout << API_NAME << ": Failed to create buffer header pool for camera.\n";
destroyCamera();
return -1;
}
return 0;
}
int Private_Impl_Still::createEncoder() {
if ( mmal_component_create ( MMAL_COMPONENT_DEFAULT_IMAGE_ENCODER, &encoder ) ) {
cout << API_NAME << ": Could not create encoder component.\n";
destroyEncoder();
return -1;
}
if ( !encoder->input_num || !encoder->output_num ) {
cout << API_NAME << ": Encoder does not have input/output ports.\n";
destroyEncoder();
return -1;
}
encoder_input_port = encoder->input[0];
encoder_output_port = encoder->output[0];
mmal_format_copy ( encoder_output_port->format, encoder_input_port->format );
encoder_output_port->format->encoding = convertEncoding ( encoding ); // Set output encoding
encoder_output_port->buffer_size = encoder_output_port->buffer_size_recommended;
if ( encoder_output_port->buffer_size < encoder_output_port->buffer_size_min )
encoder_output_port->buffer_size = encoder_output_port->buffer_size_min;
encoder_output_port->buffer_num = encoder_output_port->buffer_num_recommended;
if ( encoder_output_port->buffer_num < encoder_output_port->buffer_num_min )
encoder_output_port->buffer_num = encoder_output_port->buffer_num_min;
if ( mmal_port_format_commit ( encoder_output_port ) ) {
cout << API_NAME << ": Could not set format on encoder output port.\n";
destroyEncoder();
return -1;
}
if ( mmal_component_enable ( encoder ) ) {
cout << API_NAME << ": Could not enable encoder component.\n";
destroyEncoder();
return -1;
}
if ( ! ( encoder_pool = mmal_port_pool_create ( encoder_output_port, encoder_output_port->buffer_num, encoder_output_port->buffer_size ) ) ) {
cout << API_NAME << ": Failed to create buffer header pool for encoder output port.\n";
destroyEncoder();
return -1;
}
return 0;
}
void Private_Impl_Still::destroyCamera() {
if ( camera ) {
mmal_component_destroy ( camera );
camera = NULL;
}
}
void Private_Impl_Still::destroyEncoder() {
if ( encoder_pool ) {
mmal_port_pool_destroy ( encoder->output[0], encoder_pool );
}
if ( encoder ) {
mmal_component_destroy ( encoder );
encoder = NULL;
}
}
int Private_Impl_Still::initialize() {
if ( _isInitialized ) return 0;
if ( createCamera() ) {
cout << API_NAME << ": Failed to create camera component.\n";
destroyCamera();
return -1;
} else if ( createEncoder() ) {
cout << API_NAME << ": Failed to create encoder component.\n";
destroyCamera();
return -1;
} else {
camera_still_port = camera->output[MMAL_CAMERA_CAPTURE_PORT];
encoder_input_port = encoder->input[0];
encoder_output_port = encoder->output[0];
if ( connectPorts ( camera_still_port, encoder_input_port, &encoder_connection ) != MMAL_SUCCESS ) {
cout << "ERROR: Could not connect encoder ports!\n";
return -1;
}
}
_isInitialized=true;
return 0;
}
bool Private_Impl_Still::takePicture ( unsigned char * preallocated_data, unsigned int length ) {
initialize();
int ret = 0;
sem_t mutex;
sem_init ( &mutex, 0, 0 );
RASPICAM_USERDATA * userdata = new RASPICAM_USERDATA();
userdata->cameraBoard = this;
userdata->encoderPool = encoder_pool;
userdata->mutex = &mutex;
userdata->data = preallocated_data;
userdata->bufferPosition = 0;
userdata->offset = 0;
userdata->startingOffset = 0;
userdata->length = length;
userdata->imageCallback = NULL;
encoder_output_port->userdata = ( struct MMAL_PORT_USERDATA_T * ) userdata;
if ( ( ret = startCapture() ) != 0 ) {
delete userdata;
return false;
}
sem_wait ( &mutex );
sem_destroy ( &mutex );
stopCapture();
delete userdata;
return true;
}
size_t Private_Impl_Still::getImageBufferSize() const{
return width*height*3+54 ;//oversize the buffer so to fit BMP images
}
int Private_Impl_Still::startCapture ( imageTakenCallback userCallback, unsigned char * preallocated_data, unsigned int offset, unsigned int length ) {
RASPICAM_USERDATA * userdata = new RASPICAM_USERDATA();
userdata->cameraBoard = this;
userdata->encoderPool = encoder_pool;
userdata->mutex = NULL;
userdata->data = preallocated_data;
userdata->bufferPosition = 0;
userdata->offset = offset;
userdata->startingOffset = offset;
userdata->length = length;
userdata->imageCallback = userCallback;
encoder_output_port->userdata = ( struct MMAL_PORT_USERDATA_T * ) userdata;
startCapture();
return 0;
}
int Private_Impl_Still::startCapture() {
// If the parameters were changed and this function wasn't called, it will be called here
// However if the parameters weren't changed, the function won't do anything - it will return right away
commitParameters();
if ( encoder_output_port->is_enabled ) {
cout << API_NAME << ": Could not enable encoder output port. Try waiting longer before attempting to take another picture.\n";
return -1;
}
if ( mmal_port_enable ( encoder_output_port, buffer_callback ) != MMAL_SUCCESS ) {
cout << API_NAME << ": Could not enable encoder output port.\n";
return -1;
}
int num = mmal_queue_length ( encoder_pool->queue );
for ( int b = 0; b < num; b++ ) {
MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get ( encoder_pool->queue );
if ( !buffer )
cout << API_NAME << ": Could not get buffer (#" << b << ") from pool queue.\n";
if ( mmal_port_send_buffer ( encoder_output_port, buffer ) != MMAL_SUCCESS )
cout << API_NAME << ": Could not send a buffer (#" << b << ") to encoder output port.\n";
}
if ( mmal_port_parameter_set_boolean ( camera_still_port, MMAL_PARAMETER_CAPTURE, 1 ) != MMAL_SUCCESS ) {
cout << API_NAME << ": Failed to start capture.\n";
return -1;
}
return 0;
}
void Private_Impl_Still::stopCapture() {
if ( !encoder_output_port->is_enabled ) return;
if ( mmal_port_disable ( encoder_output_port ) )
delete ( RASPICAM_USERDATA* ) encoder_output_port->userdata;
}
void Private_Impl_Still::setWidth ( unsigned int width ) {
this->width = width;
changedSettings = true;
}
void Private_Impl_Still::setHeight ( unsigned int height ) {
this->height = height;
changedSettings = true;
}
void Private_Impl_Still::setCaptureSize ( unsigned int width, unsigned int height ) {
setWidth ( width );
setHeight ( height );
}
void Private_Impl_Still::setBrightness ( unsigned int brightness ) {
if ( brightness > 100 )
brightness = brightness % 100;
this->brightness = brightness;
changedSettings = true;
}
void Private_Impl_Still::setQuality ( unsigned int quality ) {
if ( quality > 100 )
quality = 100;
this->quality = quality;
changedSettings = true;
}
void Private_Impl_Still::setRotation ( int rotation ) {
while ( rotation < 0 )
rotation += 360;
if ( rotation >= 360 )
rotation = rotation % 360;
this->rotation = rotation;
changedSettings = true;
}
void Private_Impl_Still::setISO ( int iso ) {
this->iso = iso;
changedSettings = true;
}
void Private_Impl_Still::setSharpness ( int sharpness ) {
if ( sharpness < -100 ) sharpness = -100;
if ( sharpness > 100 ) sharpness = 100;
this->sharpness = sharpness;
changedSettings = true;
}
void Private_Impl_Still::setContrast ( int contrast ) {
if ( contrast < -100 ) contrast = -100;
if ( contrast > 100 ) contrast = 100;
this->contrast = contrast;
changedSettings = true;
}
void Private_Impl_Still::setSaturation ( int saturation ) {
if ( saturation < -100 ) saturation = -100;
if ( saturation > 100 ) saturation = 100;
this->saturation = saturation;
changedSettings = true;
}
void Private_Impl_Still::setEncoding ( RASPICAM_ENCODING encoding ) {
this->encoding = encoding;
changedSettings = true;
}
void Private_Impl_Still::setExposure ( RASPICAM_EXPOSURE exposure ) {
this->exposure = exposure;
changedSettings = true;
}
void Private_Impl_Still::setAWB ( RASPICAM_AWB awb ) {
this->awb = awb;
changedSettings = true;
}
void Private_Impl_Still::setImageEffect ( RASPICAM_IMAGE_EFFECT imageEffect ) {
this->imageEffect = imageEffect;
changedSettings = true;
}
void Private_Impl_Still::setMetering ( RASPICAM_METERING metering ) {
this->metering = metering;
changedSettings = true;
}
void Private_Impl_Still::setHorizontalFlip ( bool hFlip ) {
horizontalFlip = hFlip;
changedSettings = true;
}
void Private_Impl_Still::setVerticalFlip ( bool vFlip ) {
verticalFlip = vFlip;
changedSettings = true;
}
unsigned int Private_Impl_Still::getWidth() {
return width;
}
unsigned int Private_Impl_Still::getHeight() {
return height;
}
unsigned int Private_Impl_Still::getBrightness() {
return brightness;
}
unsigned int Private_Impl_Still::getRotation() {
return rotation;
}
unsigned int Private_Impl_Still::getQuality() {
return quality;
}
int Private_Impl_Still::getISO() {
return iso;
}
int Private_Impl_Still::getSharpness() {
return sharpness;
}
int Private_Impl_Still::getContrast() {
return contrast;
}
int Private_Impl_Still::getSaturation() {
return saturation;
}
RASPICAM_ENCODING Private_Impl_Still::getEncoding() {
return encoding;
}
RASPICAM_EXPOSURE Private_Impl_Still::getExposure() {
return exposure;
}
RASPICAM_AWB Private_Impl_Still::getAWB() {
return awb;
}
RASPICAM_IMAGE_EFFECT Private_Impl_Still::getImageEffect() {
return imageEffect;
}
RASPICAM_METERING Private_Impl_Still::getMetering() {
return metering;
}
bool Private_Impl_Still::isHorizontallyFlipped() {
return horizontalFlip;
}
bool Private_Impl_Still::isVerticallyFlipped() {
return verticalFlip;
}
void Private_Impl_Still::commitBrightness() {
mmal_port_parameter_set_rational ( camera->control, MMAL_PARAMETER_BRIGHTNESS, ( MMAL_RATIONAL_T ) {
(int32_t)brightness, 100
} );
}
void Private_Impl_Still::commitQuality() {
if ( encoder_output_port != NULL )
mmal_port_parameter_set_uint32 ( encoder_output_port, MMAL_PARAMETER_JPEG_Q_FACTOR, quality );
}
void Private_Impl_Still::commitRotation() {
int rotation = int ( this->rotation / 90 ) * 90;
mmal_port_parameter_set_int32 ( camera->output[0], MMAL_PARAMETER_ROTATION, rotation );
mmal_port_parameter_set_int32 ( camera->output[1], MMAL_PARAMETER_ROTATION, rotation );
mmal_port_parameter_set_int32 ( camera->output[2], MMAL_PARAMETER_ROTATION, rotation );
}
void Private_Impl_Still::commitISO() {
if ( mmal_port_parameter_set_uint32 ( camera->control, MMAL_PARAMETER_ISO, iso ) != MMAL_SUCCESS )
cout << API_NAME << ": Failed to set ISO parameter.\n";
}
void Private_Impl_Still::commitSharpness() {
if ( mmal_port_parameter_set_rational ( camera->control, MMAL_PARAMETER_SHARPNESS, ( MMAL_RATIONAL_T ) {
sharpness, 100
} ) != MMAL_SUCCESS )
cout << API_NAME << ": Failed to set sharpness parameter.\n";
}
void Private_Impl_Still::commitContrast() {
if ( mmal_port_parameter_set_rational ( camera->control, MMAL_PARAMETER_CONTRAST, ( MMAL_RATIONAL_T ) {
contrast, 100
} ) != MMAL_SUCCESS )
cout << API_NAME << ": Failed to set contrast parameter.\n";
}
void Private_Impl_Still::commitSaturation() {
if ( mmal_port_parameter_set_rational ( camera->control, MMAL_PARAMETER_SATURATION, ( MMAL_RATIONAL_T ) {
saturation, 100
} ) != MMAL_SUCCESS )
cout << API_NAME << ": Failed to set saturation parameter.\n";
}
void Private_Impl_Still::commitExposure() {
MMAL_PARAMETER_EXPOSUREMODE_T exp_mode = {{MMAL_PARAMETER_EXPOSURE_MODE,sizeof ( exp_mode ) }, convertExposure ( exposure ) };
if ( mmal_port_parameter_set ( camera->control, &exp_mode.hdr ) != MMAL_SUCCESS )
cout << API_NAME << ": Failed to set exposure parameter.\n";
}
void Private_Impl_Still::commitAWB() {
MMAL_PARAMETER_AWBMODE_T param = {{MMAL_PARAMETER_AWB_MODE,sizeof ( param ) }, convertAWB ( awb ) };
if ( mmal_port_parameter_set ( camera->control, &param.hdr ) != MMAL_SUCCESS )
cout << API_NAME << ": Failed to set AWB parameter.\n";
}
void Private_Impl_Still::commitImageEffect() {
MMAL_PARAMETER_IMAGEFX_T imgFX = {{MMAL_PARAMETER_IMAGE_EFFECT,sizeof ( imgFX ) }, convertImageEffect ( imageEffect ) };
if ( mmal_port_parameter_set ( camera->control, &imgFX.hdr ) != MMAL_SUCCESS )
cout << API_NAME << ": Failed to set image effect parameter.\n";
}
void Private_Impl_Still::commitMetering() {
MMAL_PARAMETER_EXPOSUREMETERINGMODE_T meter_mode = {{MMAL_PARAMETER_EXP_METERING_MODE, sizeof ( meter_mode ) }, convertMetering ( metering ) };
if ( mmal_port_parameter_set ( camera->control, &meter_mode.hdr ) != MMAL_SUCCESS )
cout << API_NAME << ": Failed to set metering parameter.\n";
}
void Private_Impl_Still::commitFlips() {
MMAL_PARAMETER_MIRROR_T mirror = {{MMAL_PARAMETER_MIRROR, sizeof ( MMAL_PARAMETER_MIRROR_T ) }, MMAL_PARAM_MIRROR_NONE};
if ( horizontalFlip && verticalFlip )
mirror.value = MMAL_PARAM_MIRROR_BOTH;
else if ( horizontalFlip )
mirror.value = MMAL_PARAM_MIRROR_HORIZONTAL;
else if ( verticalFlip )
mirror.value = MMAL_PARAM_MIRROR_VERTICAL;
if ( mmal_port_parameter_set ( camera->output[0], &mirror.hdr ) != MMAL_SUCCESS ||
mmal_port_parameter_set ( camera->output[1], &mirror.hdr ) != MMAL_SUCCESS ||
mmal_port_parameter_set ( camera->output[2], &mirror.hdr ) )
cout << API_NAME << ": Failed to set horizontal/vertical flip parameter.\n";
}
MMAL_FOURCC_T Private_Impl_Still::convertEncoding ( RASPICAM_ENCODING encoding ) {
switch ( encoding ) {
case RASPICAM_ENCODING_JPEG:
return MMAL_ENCODING_JPEG;
case RASPICAM_ENCODING_BMP:
return MMAL_ENCODING_BMP;
case RASPICAM_ENCODING_GIF:
return MMAL_ENCODING_GIF;
case RASPICAM_ENCODING_PNG:
return MMAL_ENCODING_PNG;
case RASPICAM_ENCODING_RGB:
return MMAL_ENCODING_BMP;
default:
return -1;
}
}
MMAL_PARAM_EXPOSUREMETERINGMODE_T Private_Impl_Still::convertMetering ( RASPICAM_METERING metering ) {
switch ( metering ) {
case RASPICAM_METERING_AVERAGE:
return MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE;
case RASPICAM_METERING_SPOT:
return MMAL_PARAM_EXPOSUREMETERINGMODE_SPOT;
case RASPICAM_METERING_BACKLIT:
return MMAL_PARAM_EXPOSUREMETERINGMODE_BACKLIT;
case RASPICAM_METERING_MATRIX:
return MMAL_PARAM_EXPOSUREMETERINGMODE_MATRIX;
default:
return MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE;
}
}
MMAL_PARAM_EXPOSUREMODE_T Private_Impl_Still::convertExposure ( RASPICAM_EXPOSURE exposure ) {
switch ( exposure ) {
case RASPICAM_EXPOSURE_OFF:
return MMAL_PARAM_EXPOSUREMODE_OFF;
case RASPICAM_EXPOSURE_AUTO:
return MMAL_PARAM_EXPOSUREMODE_AUTO;
case RASPICAM_EXPOSURE_NIGHT:
return MMAL_PARAM_EXPOSUREMODE_NIGHT;
case RASPICAM_EXPOSURE_NIGHTPREVIEW:
return MMAL_PARAM_EXPOSUREMODE_NIGHTPREVIEW;
case RASPICAM_EXPOSURE_BACKLIGHT:
return MMAL_PARAM_EXPOSUREMODE_BACKLIGHT;
case RASPICAM_EXPOSURE_SPOTLIGHT:
return MMAL_PARAM_EXPOSUREMODE_SPOTLIGHT;
case RASPICAM_EXPOSURE_SPORTS:
return MMAL_PARAM_EXPOSUREMODE_SPORTS;
case RASPICAM_EXPOSURE_SNOW:
return MMAL_PARAM_EXPOSUREMODE_SNOW;
case RASPICAM_EXPOSURE_BEACH:
return MMAL_PARAM_EXPOSUREMODE_BEACH;
case RASPICAM_EXPOSURE_VERYLONG:
return MMAL_PARAM_EXPOSUREMODE_VERYLONG;
case RASPICAM_EXPOSURE_FIXEDFPS:
return MMAL_PARAM_EXPOSUREMODE_FIXEDFPS;
case RASPICAM_EXPOSURE_ANTISHAKE:
return MMAL_PARAM_EXPOSUREMODE_ANTISHAKE;
case RASPICAM_EXPOSURE_FIREWORKS:
return MMAL_PARAM_EXPOSUREMODE_FIREWORKS;
default:
return MMAL_PARAM_EXPOSUREMODE_AUTO;
}
}
MMAL_PARAM_AWBMODE_T Private_Impl_Still::convertAWB ( RASPICAM_AWB awb ) {
switch ( awb ) {
case RASPICAM_AWB_OFF:
return MMAL_PARAM_AWBMODE_OFF;
case RASPICAM_AWB_AUTO:
return MMAL_PARAM_AWBMODE_AUTO;
case RASPICAM_AWB_SUNLIGHT:
return MMAL_PARAM_AWBMODE_SUNLIGHT;
case RASPICAM_AWB_CLOUDY:
return MMAL_PARAM_AWBMODE_CLOUDY;
case RASPICAM_AWB_SHADE:
return MMAL_PARAM_AWBMODE_SHADE;
case RASPICAM_AWB_TUNGSTEN:
return MMAL_PARAM_AWBMODE_TUNGSTEN;
case RASPICAM_AWB_FLUORESCENT:
return MMAL_PARAM_AWBMODE_FLUORESCENT;
case RASPICAM_AWB_INCANDESCENT:
return MMAL_PARAM_AWBMODE_INCANDESCENT;
case RASPICAM_AWB_FLASH:
return MMAL_PARAM_AWBMODE_FLASH;
case RASPICAM_AWB_HORIZON:
return MMAL_PARAM_AWBMODE_HORIZON;
default:
return MMAL_PARAM_AWBMODE_AUTO;
}
}
MMAL_PARAM_IMAGEFX_T Private_Impl_Still::convertImageEffect ( RASPICAM_IMAGE_EFFECT imageEffect ) {
switch ( imageEffect ) {
default:
case RASPICAM_IMAGE_EFFECT_NONE:
return MMAL_PARAM_IMAGEFX_NONE;
case RASPICAM_IMAGE_EFFECT_NEGATIVE:
return MMAL_PARAM_IMAGEFX_NEGATIVE;
case RASPICAM_IMAGE_EFFECT_SOLARIZE:
return MMAL_PARAM_IMAGEFX_SOLARIZE;
case RASPICAM_IMAGE_EFFECT_SKETCH:
return MMAL_PARAM_IMAGEFX_SKETCH;
case RASPICAM_IMAGE_EFFECT_DENOISE:
return MMAL_PARAM_IMAGEFX_DENOISE;
case RASPICAM_IMAGE_EFFECT_EMBOSS:
return MMAL_PARAM_IMAGEFX_EMBOSS;
case RASPICAM_IMAGE_EFFECT_OILPAINT:
return MMAL_PARAM_IMAGEFX_OILPAINT;
case RASPICAM_IMAGE_EFFECT_HATCH:
return MMAL_PARAM_IMAGEFX_HATCH;
case RASPICAM_IMAGE_EFFECT_GPEN:
return MMAL_PARAM_IMAGEFX_GPEN;
case RASPICAM_IMAGE_EFFECT_PASTEL:
return MMAL_PARAM_IMAGEFX_PASTEL;
case RASPICAM_IMAGE_EFFECT_WATERCOLOR:
return MMAL_PARAM_IMAGEFX_WATERCOLOUR;
case RASPICAM_IMAGE_EFFECT_FILM:
return MMAL_PARAM_IMAGEFX_FILM;
case RASPICAM_IMAGE_EFFECT_BLUR:
return MMAL_PARAM_IMAGEFX_BLUR;
case RASPICAM_IMAGE_EFFECT_SATURATION:
return MMAL_PARAM_IMAGEFX_SATURATION;
case RASPICAM_IMAGE_EFFECT_COLORSWAP:
return MMAL_PARAM_IMAGEFX_COLOURSWAP;
case RASPICAM_IMAGE_EFFECT_WASHEDOUT:
return MMAL_PARAM_IMAGEFX_WASHEDOUT;
case RASPICAM_IMAGE_EFFECT_POSTERISE:
return MMAL_PARAM_IMAGEFX_POSTERISE;
case RASPICAM_IMAGE_EFFECT_COLORPOINT:
return MMAL_PARAM_IMAGEFX_COLOURPOINT;
case RASPICAM_IMAGE_EFFECT_COLORBALANCE:
return MMAL_PARAM_IMAGEFX_COLOURBALANCE;
case RASPICAM_IMAGE_EFFECT_CARTOON:
return MMAL_PARAM_IMAGEFX_CARTOON;
}
}
//Returns an id of the camera. We assume the camera id is the one of the raspberry
//the id is obtained using raspberry serial number obtained in /proc/cpuinfo
string Private_Impl_Still::getId() const{
char serial[1024];
serial[0]='\0';
ifstream file ( "/proc/cpuinfo" );
if ( !file ) {
cerr<<__FILE__<<" "<<__LINE__<<":"<<__func__<<"Could not read /proc/cpuinfo"<<endl;
return serial;
}
//read lines until find serial
bool found=false;
while ( !file.eof() && !found ) {
char line[1024];
file.getline ( line,1024 );
string str ( line );
char aux[100];
if ( str.find ( "Serial" ) !=string::npos ) {
if ( sscanf ( line,"%s : %s",aux,serial ) !=2 ) {
cerr<<__FILE__<<" "<<__LINE__<<":"<<__func__<<"Error parsing /proc/cpuinfo"<<endl;
} else found=true;
}
};
return serial;
}
}
}
@@ -0,0 +1,173 @@
/**********************************************************
Software developed by AVA ( Ava Group of the University of Cordoba, ava at uco dot es)
Main author Rafael Munoz Salinas (rmsalinas at uco dot es)
This software is released under BSD license as expressed below
-------------------------------------------------------------------
Copyright (c) 2013, AVA ( Ava Group University of Cordoba, ava at uco dot es)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software
must display the following acknowledgement:
This product includes software developed by the Ava group of the University of Cordoba.
4. Neither the name of the University nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY AVA ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL AVA BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
****************************************************************/
#ifndef _Private_RaspiCam_STILL_IMPL_H
#define _Private_RaspiCam_STILL_IMPL_H
#include "raspicamtypes.h"
#include "mmal/mmal.h"
#include "mmal/util/mmal_connection.h"
#include <string>
#define MMAL_CAMERA_CAPTURE_PORT 2
#define STILLS_FRAME_RATE_NUM 3
#define STILLS_FRAME_RATE_DEN 1
namespace raspicam {
namespace _private
{
typedef void ( *imageTakenCallback ) ( unsigned char * data, unsigned int image_offset, unsigned int length );
class Private_Impl_Still {
private:
MMAL_COMPONENT_T * camera; /// Pointer to the camera component
MMAL_COMPONENT_T * encoder; /// Pointer to the encoder component
MMAL_CONNECTION_T * encoder_connection; // Connection from the camera to the encoder
MMAL_POOL_T * encoder_pool; /// Pointer to the pool of buffers used by encoder output port
MMAL_PORT_T * camera_still_port;
MMAL_PORT_T * encoder_input_port;
MMAL_PORT_T * encoder_output_port;
unsigned int width;
unsigned int height;
unsigned int rotation; // 0 to 359
unsigned int brightness; // 0 to 100
unsigned int quality; // 0 to 100
int iso;
int sharpness; // -100 to 100
int contrast; // -100 to 100
int saturation; // -100 to 100
RASPICAM_ENCODING encoding;
RASPICAM_EXPOSURE exposure;
RASPICAM_AWB awb;
RASPICAM_IMAGE_EFFECT imageEffect;
RASPICAM_METERING metering;
bool changedSettings;
bool horizontalFlip;
bool verticalFlip;
MMAL_FOURCC_T convertEncoding ( RASPICAM_ENCODING encoding );
MMAL_PARAM_EXPOSUREMETERINGMODE_T convertMetering ( RASPICAM_METERING metering );
MMAL_PARAM_EXPOSUREMODE_T convertExposure ( RASPICAM_EXPOSURE exposure );
MMAL_PARAM_AWBMODE_T convertAWB ( RASPICAM_AWB awb );
MMAL_PARAM_IMAGEFX_T convertImageEffect ( RASPICAM_IMAGE_EFFECT imageEffect );
void commitBrightness();
void commitQuality();
void commitRotation();
void commitISO();
void commitSharpness();
void commitContrast();
void commitSaturation();
void commitExposure();
void commitAWB();
void commitImageEffect();
void commitMetering();
void commitFlips();
int startCapture();
int createCamera();
int createEncoder();
void destroyCamera();
void destroyEncoder();
void setDefaults();
MMAL_STATUS_T connectPorts ( MMAL_PORT_T *output_port, MMAL_PORT_T *input_port, MMAL_CONNECTION_T **connection );
bool _isInitialized;
public:
const char * API_NAME;
Private_Impl_Still() {
API_NAME = "Private_Impl_Still";
setDefaults();
camera = NULL;
encoder = NULL;
encoder_connection = NULL;
encoder_pool = NULL;
camera_still_port = NULL;
encoder_input_port = NULL;
encoder_output_port = NULL;
_isInitialized=false;
}
int initialize();
int startCapture ( imageTakenCallback userCallback, unsigned char * preallocated_data, unsigned int offset, unsigned int length );
void stopCapture();
bool takePicture ( unsigned char * preallocated_data, unsigned int length );
size_t getImageBufferSize() const;
void bufferCallback ( MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer );
void commitParameters();
void setWidth ( unsigned int width );
void setHeight ( unsigned int height );
void setCaptureSize ( unsigned int width, unsigned int height );
void setBrightness ( unsigned int brightness );
void setQuality ( unsigned int quality );
void setRotation ( int rotation );
void setISO ( int iso );
void setSharpness ( int sharpness );
void setContrast ( int contrast );
void setSaturation ( int saturation );
void setEncoding ( RASPICAM_ENCODING encoding );
void setExposure ( RASPICAM_EXPOSURE exposure );
void setAWB ( RASPICAM_AWB awb );
void setImageEffect ( RASPICAM_IMAGE_EFFECT imageEffect );
void setMetering ( RASPICAM_METERING metering );
void setHorizontalFlip ( bool hFlip );
void setVerticalFlip ( bool vFlip );
unsigned int getWidth();
unsigned int getHeight();
unsigned int getBrightness();
unsigned int getRotation();
unsigned int getQuality();
int getISO();
int getSharpness();
int getContrast();
int getSaturation();
RASPICAM_ENCODING getEncoding();
RASPICAM_EXPOSURE getExposure();
RASPICAM_AWB getAWB();
RASPICAM_IMAGE_EFFECT getImageEffect();
RASPICAM_METERING getMetering();
bool isHorizontallyFlipped();
bool isVerticallyFlipped();
//Returns an id of the camera. We assume the camera id is the one of the raspberry
//the id is obtained using raspberry serial number obtained in /proc/cpuinfo
std::string getId() const;
};
}
}
#endif // RASPICAM_H
+177
View File
@@ -0,0 +1,177 @@
/**********************************************************
Software developed by AVA ( Ava Group of the University of Cordoba, ava at uco dot es)
Main author Rafael Munoz Salinas (rmsalinas at uco dot es)
This software is released under BSD license as expressed below
-------------------------------------------------------------------
Copyright (c) 2013, AVA ( Ava Group University of Cordoba, ava at uco dot es)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software
must display the following acknowledgement:
This product includes software developed by the Ava group of the University of Cordoba.
4. Neither the name of the University nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY AVA ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL AVA BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
****************************************************************/
#include "raspicam.h"
#include "private/private_impl.h"
namespace raspicam {
RaspiCam::RaspiCam() {
_impl=new _private::Private_Impl;
}
RaspiCam::~RaspiCam() {
delete _impl;
}
bool RaspiCam::open ( bool StartCapture ) {
return _impl->open ( StartCapture );
}
bool RaspiCam::startCapture() {
return _impl->startCapture();
}
void RaspiCam::setUserCallback(void (*userCallback)(void*) , void* data) {
_impl->setUserCallback(userCallback, data);
}
bool RaspiCam::isOpened() const {return _impl->isOpened();}
bool RaspiCam::grab() {
return _impl->grab();
}
void RaspiCam::retrieve ( unsigned char *data,RASPICAM_FORMAT type ) {
_impl->retrieve ( data,type );
}
unsigned char *RaspiCam::getImageBufferData() const{return _impl->getImageBufferData();}
size_t RaspiCam::getImageBufferSize() const{return _impl->getImageBufferSize();}
size_t RaspiCam::getImageTypeSize ( RASPICAM_FORMAT type ) const{return _impl->getImageTypeSize ( type );}
void RaspiCam::release() {
_impl->release();
}
void RaspiCam::setFormat(RASPICAM_FORMAT fmt){
_impl->setFormat( fmt);
}
void RaspiCam::setWidth ( unsigned int width ) {
_impl->setWidth ( width );
}
void RaspiCam::setHeight ( unsigned int height ) {
_impl->setHeight ( height );
}
void RaspiCam::setCaptureSize ( unsigned int width, unsigned int height ) {
_impl->setCaptureSize ( width,height );
}
void RaspiCam::setBrightness ( unsigned int brightness ) {
_impl->setBrightness ( brightness );
}
void RaspiCam::setRotation ( int rotation ) {
_impl->setRotation ( rotation );
}
void RaspiCam::setISO ( int iso ) {
_impl->setISO ( iso );
}
void RaspiCam::setSharpness ( int sharpness ) {
_impl->setSharpness ( sharpness );
}
void RaspiCam::setContrast ( int contrast ) {
_impl->setContrast ( contrast );
}
void RaspiCam::setSaturation ( int saturation ) {
_impl->setSaturation ( saturation );
}
void RaspiCam::setExposure ( RASPICAM_EXPOSURE exposure ) {
_impl->setExposure ( exposure );
}
void RaspiCam::setShutterSpeed ( unsigned int ss ) {
_impl->setShutterSpeed ( ss );
}
void RaspiCam::setVideoStabilization ( bool v ) {
_impl->setVideoStabilization ( v );
}
void RaspiCam::setExposureCompensation ( int val ) {
_impl->setExposureCompensation ( val );
}
void RaspiCam::setAWB ( RASPICAM_AWB awb ) {
_impl->setAWB ( awb );
}
void RaspiCam::setAWB_RB ( float r,float b ){
_impl->setAWB_RB(r,b);
}
void RaspiCam::setImageEffect ( RASPICAM_IMAGE_EFFECT imageEffect ) {
_impl->setImageEffect ( imageEffect );
}
void RaspiCam::setMetering ( RASPICAM_METERING metering ) {
_impl->setMetering ( metering );
}
void RaspiCam::setHorizontalFlip ( bool hFlip ) {
_impl->setHorizontalFlip ( hFlip );
}
void RaspiCam::setVerticalFlip ( bool vFlip ) {
_impl->setVerticalFlip ( vFlip );
}
void RaspiCam::setFrameRate ( int frames_per_second ) {
_impl->setFrameRate ( frames_per_second );
}
void RaspiCam::setSensorMode ( int mode ) {
_impl->setSensorMode ( mode );
}
RASPICAM_FORMAT RaspiCam::getFormat()const{return _impl->getFormat( ); }
unsigned int RaspiCam::getWidth() const{return _impl->getWidth() ;}
unsigned int RaspiCam::getHeight() const{return _impl->getHeight() ;}
unsigned int RaspiCam::getBrightness() const{return _impl->getBrightness() ;}
unsigned int RaspiCam::getRotation() const{return _impl->getRotation() ;}
int RaspiCam::getISO() const{return _impl->getISO() ;}
unsigned int RaspiCam::getShutterSpeed() const{return _impl->getShutterSpeed();}
int RaspiCam::getSharpness() const{return _impl->getSharpness() ;}
int RaspiCam::getContrast() const{return _impl->getContrast() ;}
int RaspiCam::getSaturation() const{return _impl->getSaturation() ;}
RASPICAM_EXPOSURE RaspiCam::getExposure() const {return _impl->getExposure() ;}
RASPICAM_AWB RaspiCam::getAWB() const{return _impl->getAWB() ;}
float RaspiCam::getAWBG_red()const{return _impl->getAWBG_red();}
float RaspiCam::getAWBG_blue()const{return _impl->getAWBG_blue();}
RASPICAM_IMAGE_EFFECT RaspiCam::getImageEffect() const{return _impl->getImageEffect() ;}
RASPICAM_METERING RaspiCam::getMetering() const{return _impl->getMetering() ;}
int RaspiCam::getFrameRate() const{return _impl->getFrameRate() ;}
bool RaspiCam::isHorizontallyFlipped() const {return _impl->isHorizontallyFlipped() ;}
bool RaspiCam::isVerticallyFlipped() const {return _impl->isVerticallyFlipped() ;}
//Returns an id of the camera. We assume the camera id is the one of the raspberry
//the id is obtained using raspberry serial number obtained in /proc/cpuinfo
std::string RaspiCam::getId() const{return _impl->getId();}
}
+187
View File
@@ -0,0 +1,187 @@
/**********************************************************
Software developed by AVA ( Ava Group of the University of Cordoba, ava at uco dot es)
Main author Rafael Munoz Salinas (rmsalinas at uco dot es)
This software is released under BSD license as expressed below
-------------------------------------------------------------------
Copyright (c) 2013, AVA ( Ava Group University of Cordoba, ava at uco dot es)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software
must display the following acknowledgement:
This product includes software developed by the Ava group of the University of Cordoba.
4. Neither the name of the University nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY AVA ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL AVA BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
****************************************************************/
#ifndef _RaspiCam_H_
#define _RaspiCam_H_
#include <cstdio>
#include <string>
#include "raspicamtypes.h"
namespace raspicam {
namespace _private{
class Private_Impl;
}
/**Base class that do all the hard work
*/
class RaspiCam
{
public:
/**Constructor
*/
RaspiCam();
/**Destructor
*/
~RaspiCam();
/**Opens the camera
* @param StartCapture determines if camera must start capture or not.
*/
bool open ( bool StartCapture=true );
/**Makes camera start capturing
*/
bool startCapture();
/*
* the function 'userCallback' will be called every time new data arrived from camera,
* with 'data' as argument.
*/
void setUserCallback(void (*userCallback)(void*) , void* data=0);
/**indicates if camera is open
*/
bool isOpened() const ;
/**Grabs the next frame and keeps it in internal buffer. Blocks until next frame arrives
*/
bool grab();
/**Retrieves the buffer previously grabbed.
* You can decide how image is given by setting type. The input buffer provided must have the appropriate
* size accordingly. You can use getImageTypeSize() to determine the size
* NOTE: Change in version 0.0.5. Format is stablished in setFormat function
* So type param is ignored. Do not use this parameter.
* You can use getFormat() to know the current format
*/
void retrieve ( unsigned char *data,RASPICAM_FORMAT type=RASPICAM_FORMAT_IGNORE );
/**Alternative to retrieve. Returns a pointer to the original image data buffer (which is in getFormat() format).
*
* Be careful, if you call grab(), this will be rewritten with the new data
*/
unsigned char *getImageBufferData() const;
/**
* Returns the size of the images captured.
*/
size_t getImageBufferSize() const;
/** Stops camera and free resources
*/
void release();
/**Sets capture format
*/
void setFormat ( RASPICAM_FORMAT fmt );
/**Sets camera width. Use a multiple of 320 (640, 1280)
*/
void setWidth ( unsigned int width ) ;
/**Sets camera Height. Use a multiple of 240 (480, 960)
*/
void setHeight ( unsigned int height );
void setCaptureSize ( unsigned int width, unsigned int height );
/** Set image brightness [0,100]
*/
void setBrightness ( unsigned int brightness );
/**
* Set image sharpness (-100 to 100)
*/
void setSharpness ( int sharpness );
/**
* Set image contrast (-100 to 100)
*/
void setContrast ( int contrast );
/**
* Set capture ISO (100 to 800)
*/
void setISO ( int iso );
/**
* Set image saturation (-100 to 100)
*/
void setSaturation ( int saturation );
/**Sets on/off video stabilisation
*/
void setVideoStabilization ( bool v );
/**
* Set EV compensation (-10,10)
*/
void setExposureCompensation ( int val ); //-10,10
void setRotation ( int rotation );
void setExposure ( RASPICAM_EXPOSURE exposure );
void setShutterSpeed ( unsigned int ss );
void setAWB ( RASPICAM_AWB awb );
// et specific values for whitebalance. Requires to set seAWB in OFF mode first
void setAWB_RB ( float r,float b );//range is 0-1.
void setImageEffect ( RASPICAM_IMAGE_EFFECT imageEffect );
void setMetering ( RASPICAM_METERING metering );
void setHorizontalFlip ( bool hFlip );
void setVerticalFlip ( bool vFlip );
void setFrameRate ( int frames_per_second );
void setSensorMode ( int mode );
//Accessors
RASPICAM_FORMAT getFormat() const;
unsigned int getWidth() const;
unsigned int getHeight() const;
unsigned int getBrightness() const;
unsigned int getRotation() const;
int getISO() const;
int getSharpness() const;
int getContrast() const;
int getSaturation() const;
unsigned int getShutterSpeed() const;
RASPICAM_EXPOSURE getExposure() const ;
RASPICAM_AWB getAWB() const;
float getAWBG_red()const;
float getAWBG_blue()const;
RASPICAM_IMAGE_EFFECT getImageEffect() const ;
RASPICAM_METERING getMetering() const;
int getFrameRate() const;
bool isHorizontallyFlipped() const ;
bool isVerticallyFlipped() const ;
/** Returns an id of the camera. We assume the camera id is the one of the raspberry
*the id is obtained using raspberry serial number obtained in /proc/cpuinfo
*/
std::string getId() const;
/**Returns the size of the required buffer for the different image types in retrieve
*/
size_t getImageTypeSize ( RASPICAM_FORMAT type ) const;
private:
_private::Private_Impl *_impl;
};
}
#endif
+234
View File
@@ -0,0 +1,234 @@
/**********************************************************
Software developed by AVA ( Ava Group of the University of Cordoba, ava at uco dot es)
Main author Rafael Munoz Salinas (rmsalinas at uco dot es)
This software is released under BSD license as expressed below
-------------------------------------------------------------------
Copyright (c) 2013, AVA ( Ava Group University of Cordoba, ava at uco dot es)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software
must display the following acknowledgement:
This product includes software developed by the Ava group of the University of Cordoba.
4. Neither the name of the University nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY AVA ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL AVA BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
****************************************************************/
#include "raspicam_cv.h"
#include "private/private_impl.h"
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include "scaler.h"
namespace raspicam {
RaspiCam_Cv::RaspiCam_Cv() {
_impl=new _private::Private_Impl();
set(cv::CAP_PROP_FORMAT,CV_8UC3);
}
RaspiCam_Cv::~RaspiCam_Cv() {
delete _impl;
}
/** Open capturing device for video capturing
*/
bool RaspiCam_Cv::open ( void ) {
return _impl->open();
}
/**
* Returns true if video capturing has been initialized already.
*/
bool RaspiCam_Cv::isOpened() const {return _impl->isOpened();}
/**
*Closes video file or capturing device.
*/
void RaspiCam_Cv::release() {
_impl->release();
}
/**
* Grabs the next frame from video file or capturing device.
*/
bool RaspiCam_Cv::grab() {
return _impl->grab();
}
void RaspiCam_Cv::setUserCallback(void (*userCallback)(void*) , void* data) {
_impl->setUserCallback(userCallback, data);
}
/**
*Decodes and returns the grabbed video frame.
*/
void RaspiCam_Cv::retrieve ( cv::Mat& image ) {
//here we go!
image.create ( _impl->getHeight(),_impl->getWidth(),imgFormat );
_impl->retrieve ( image.ptr<uchar> ( 0 ));
}
/**Returns the specified VideoCapture property
*/
double RaspiCam_Cv::get ( int propId ) {
switch ( propId ) {
case cv::CAP_PROP_MODE:
return _impl->getSensorMode();
case cv::CAP_PROP_FRAME_WIDTH :
return _impl->getWidth();
case cv::CAP_PROP_FRAME_HEIGHT :
return _impl->getHeight();
case cv::CAP_PROP_FPS:
return _impl->getFrameRate();
case cv::CAP_PROP_FORMAT :
return imgFormat;
case cv::CAP_PROP_BRIGHTNESS :
return _impl->getBrightness();
case cv::CAP_PROP_CONTRAST :
return Scaler::scale ( -100,100,0,100, _impl->getContrast() );
case cv::CAP_PROP_SATURATION :
return Scaler::scale ( -100,100,0,100, _impl->getSaturation() );;
// case cv::CAP_PROP_HUE : return _cam_impl->getSharpness();
case cv::CAP_PROP_GAIN :
return Scaler::scale ( 0,800,0,100, _impl->getISO() );
case cv::CAP_PROP_EXPOSURE :
if ( _impl->getShutterSpeed() ==0 )
return -1;//auto
else return Scaler::scale (0,330000, 0,100, _impl->getShutterSpeed() ) ;
break;
default :
return -1;
};
}
/**Sets a property in the VideoCapture.
*/
bool RaspiCam_Cv::set ( int propId, double value ) {
switch ( propId ) {
case cv::CAP_PROP_MODE:
_impl->setSensorMode(value);
break;
case cv::CAP_PROP_FRAME_WIDTH :
_impl->setWidth ( value );
break;
case cv::CAP_PROP_FRAME_HEIGHT :
_impl->setHeight ( value );
break;
case cv::CAP_PROP_FORMAT :{
bool res=true;
if ( value==CV_8UC1 ){
_impl->setFormat(RASPICAM_FORMAT_GRAY);
imgFormat=value;
}
else if (value==CV_8UC3){
_impl->setFormat(RASPICAM_FORMAT_RGB);
imgFormat=value;
}
else res=false;//error int format
return res;
}break;
case cv::CAP_PROP_BRIGHTNESS :
_impl->setBrightness ( value );
break;
case cv::CAP_PROP_CONTRAST :
_impl->setContrast ( Scaler::scale ( 0,100,-100,100, value ) );
break;
case cv::CAP_PROP_SATURATION :
_impl->setSaturation ( Scaler::scale ( 0,100,-100,100, value ) );
break;
// case cv::CAP_PROP_HUE : return _cam_impl->getSharpness();
case cv::CAP_PROP_GAIN :
_impl->setISO ( Scaler::scale ( 0,100,0,800, value ) );
break;
case cv::CAP_PROP_EXPOSURE :
if ( value>0 && value<=100 ) {
_impl->setShutterSpeed ( Scaler::scale ( 0,100,0,330000, value ) );
} else {
_impl->setExposure ( RASPICAM_EXPOSURE_AUTO );
_impl->setShutterSpeed ( 0 );
}
break;
case cv::CAP_PROP_CONVERT_RGB :
imgFormat=CV_8UC3;
break;
case cv::CAP_PROP_FPS:
_impl->setFrameRate ( value );
default :
return false;
};
return true;
}
void RaspiCam_Cv::setRotation ( int nRotation ) {
// input is [0;3], map to [0; 360]
int clamped = std::max(0, std::min(nRotation, 3));
int degrees = clamped * 90;
_impl->setRotation ( degrees );
}
void RaspiCam_Cv::setImageEffect ( int nEffect ) {
// Clamp to enum
int clamped = std::max((int)RASPICAM_IMAGE_EFFECT::RASPICAM_IMAGE_EFFECT_NONE, std::min(nEffect, (int)RASPICAM_IMAGE_EFFECT::RASPICAM_IMAGE_EFFECT_CARTOON));
_impl->setImageEffect ( (RASPICAM_IMAGE_EFFECT)clamped );
}
void RaspiCam_Cv::setVideoStabilization ( bool enable ) {
_impl->setVideoStabilization ( enable );
}
void RaspiCam_Cv::setHorizontalFlip ( bool enable ) {
_impl->setHorizontalFlip ( enable );
}
void RaspiCam_Cv::setVerticalFlip ( bool enable ) {
_impl->setVerticalFlip ( enable );
}
void RaspiCam_Cv::setExposureCompensation ( int value ) {
// clamp to [-10; 10]
int clamped = std::max(-10, std::min(value, 10));
_impl->setExposureCompensation ( clamped );
}
void RaspiCam_Cv::setAWB ( int nEnumValue ) {
// Clamp to enum
int clamped = std::max((int)RASPICAM_AWB::RASPICAM_AWB_OFF, std::min(nEnumValue, (int)RASPICAM_AWB::RASPICAM_AWB_HORIZON));
_impl->setAWB ( (RASPICAM_AWB)clamped );
}
void RaspiCam_Cv::setMetering ( int nEnumValue ) {
// Clamp to enum
int clamped = std::max((int)RASPICAM_METERING::RASPICAM_METERING_AVERAGE, std::min(nEnumValue, (int)RASPICAM_METERING::RASPICAM_METERING_MATRIX));
_impl->setMetering ( (RASPICAM_METERING)clamped );
}
std::string RaspiCam_Cv::getId() const{
return _impl->getId();
}
}
+158
View File
@@ -0,0 +1,158 @@
/**********************************************************
Software developed by AVA ( Ava Group of the University of Cordoba, ava at uco dot es)
Main author Rafael Munoz Salinas (rmsalinas at uco dot es)
This software is released under BSD license as expressed below
-------------------------------------------------------------------
Copyright (c) 2013, AVA ( Ava Group University of Cordoba, ava at uco dot es)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software
must display the following acknowledgement:
This product includes software developed by the Ava group of the University of Cordoba.
4. Neither the name of the University nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY AVA ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL AVA BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
****************************************************************/
#ifndef RaspiCam_CV_H
#define RaspiCam_CV_H
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
namespace raspicam {
namespace _private{
class Private_Impl;
}
/**Class for using Raspberry camera as in opencv
*/
class RaspiCam_Cv {
_private::Private_Impl *_impl;
public:
/**Constructor
*/
RaspiCam_Cv();
/**Destructor
*/
~RaspiCam_Cv();
/** Open capturing device for video capturing
*/
bool open ( void );
/**
* Returns true if video capturing has been initialized already.
*/
bool isOpened() const;
/**
*Closes video file or capturing device.
*/
void release();
/*
* the function 'userCallback' will be called every time new data arrived from camera,
* with 'data' as argument.
*/
void setUserCallback(void (*userCallback)(void*) , void* data=0);
/**
* Grabs the next frame from video file or capturing device.
*/
bool grab();
/**
*Decodes and returns the grabbed video frame.
*/
void retrieve ( cv::Mat& image );
/**Returns the specified VideoCapture property
*/
double get ( int propId );
/**Sets a property in the VideoCapture.
*
*
* Implemented properties:
* cv::CAP_PROP_FRAME_WIDTH,cv::CAP_PROP_FRAME_HEIGHT,
* cv::CAP_PROP_FORMAT: CV_8UC1 or CV_8UC3
* cv::CAP_PROP_BRIGHTNESS: [0,100]
* cv::CAP_PROP_CONTRAST: [0,100]
* cv::CAP_PROP_SATURATION: [0,100]
* cv::CAP_PROP_GAIN: (iso): [0,100]
* cv::CAP_PROP_EXPOSURE: -1 auto. [1,100] shutter speed from 0 to 33ms
* cv::CAP_PROP_WHITE_BALANCE_RED_V : [1,100] -1 auto whitebalance
* cv::CAP_PROP_WHITE_BALANCE_BLUE_U : [1,100] -1 auto whitebalance
* cv::CAP_PROP_MODE : [1,7] 0 auto mode
*
*/
bool set ( int propId, double value );
/** Sets the rotation
0: none
1: 90 degrees clockwise
2: 180 degrees
3: 270 degrees clockwise
*/
void setRotation ( int nRotation );
/** Sets the image effect. See RASPICAM_IMAGE_EFFECT enum. 19 values as of current implementation.
*/
void setImageEffect ( int nEffect );
/** Enable or disable video stabilization
*/
void setVideoStabilization ( bool enable );
/** Enable or disable horizontal flip
*/
void setHorizontalFlip ( bool enable );
/** Enable or disable vertical flip
*/
void setVerticalFlip ( bool enable );
/** Set exposure compensation. -10,10
*/
void setExposureCompensation( int value );
/** Sets auto white balance. See RASPICAM_AWB enum. 9 values as of current implementation.
*/
void setAWB ( int nEnumValue );
/** Sets metering type. See RASPICAM_METERING enum. 4 values as of current implementation.
*/
void setMetering ( int nEnumValue );
/** Returns the camera identifier. We assume the camera id is the one of the raspberry obtained using raspberry serial number obtained in /proc/cpuinfo
*/
std::string getId()const;
private:
cv::Mat image;
int imgFormat;//required image format //
};
}
#endif
+167
View File
@@ -0,0 +1,167 @@
/**********************************************************
Software developed by AVA ( Ava Group of the University of Cordoba, ava at uco dot es)
Main author Rafael Munoz Salinas (rmsalinas at uco dot es)
This software is released under BSD license as expressed below
-------------------------------------------------------------------
Copyright (c) 2013, AVA ( Ava Group University of Cordoba, ava at uco dot es)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software
must display the following acknowledgement:
This product includes software developed by the Ava group of the University of Cordoba.
4. Neither the name of the University nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY AVA ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL AVA BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
****************************************************************/
#include "raspicam_still.h"
#include "private_still/private_still_impl.h"
namespace raspicam {
RaspiCam_Still::RaspiCam_Still() {
_impl= new _private::Private_Impl_Still() ;
}
RaspiCam_Still::~RaspiCam_Still() {
release();
delete _impl;
}
bool RaspiCam_Still::open ( ) {
return _impl->initialize() ==0;
}
bool RaspiCam_Still::grab_retrieve ( unsigned char * preallocated_data, unsigned int length ) {
return _impl->takePicture ( preallocated_data, length );
}
void RaspiCam_Still::release() {}
size_t RaspiCam_Still::getImageBufferSize() const{
return _impl-> getImageBufferSize();
}
void RaspiCam_Still::commitParameters() {
_impl-> commitParameters();
}
void RaspiCam_Still::setWidth ( unsigned int width ) {
_impl-> setWidth ( width );
}
void RaspiCam_Still::setHeight ( unsigned int height ) {
_impl->setHeight ( height );
}
void RaspiCam_Still::setCaptureSize ( unsigned int width, unsigned int height ) {
_impl->setCaptureSize ( width,height );
}
void RaspiCam_Still::setBrightness ( unsigned int brightness ) {
_impl->setBrightness ( brightness );
}
void RaspiCam_Still::setQuality ( unsigned int quality ) {
_impl->setQuality ( quality );
}
void RaspiCam_Still::setRotation ( int rotation ) {
_impl-> setRotation ( rotation );
}
void RaspiCam_Still::setISO ( int iso ) {
_impl-> setISO ( iso );
}
void RaspiCam_Still::setSharpness ( int sharpness ) {
_impl->setSharpness ( sharpness );
}
void RaspiCam_Still::setContrast ( int contrast ) {
_impl->setContrast ( contrast );
}
void RaspiCam_Still::setSaturation ( int saturation ) {
_impl->setSaturation ( saturation );
}
void RaspiCam_Still::setEncoding ( RASPICAM_ENCODING encoding ) {
_impl->setEncoding ( encoding );
}
void RaspiCam_Still::setExposure ( RASPICAM_EXPOSURE exposure ) {
_impl->setExposure ( exposure );
}
void RaspiCam_Still::setAWB ( RASPICAM_AWB awb ) {
_impl->setAWB ( awb );
}
void RaspiCam_Still::setImageEffect ( RASPICAM_IMAGE_EFFECT imageEffect ) {
_impl-> setImageEffect ( imageEffect );
}
void RaspiCam_Still::setMetering ( RASPICAM_METERING metering ) {
_impl->setMetering ( metering );
}
void RaspiCam_Still::setHorizontalFlip ( bool hFlip ) {
_impl->setHorizontalFlip ( hFlip );
}
void RaspiCam_Still::setVerticalFlip ( bool vFlip ) {
_impl->setVerticalFlip ( vFlip );
}
unsigned int RaspiCam_Still::getWidth() {
return _impl->getWidth();
}
unsigned int RaspiCam_Still::getHeight() {
return _impl->getHeight();
}
unsigned int RaspiCam_Still::getBrightness() {
return _impl->getBrightness();
}
unsigned int RaspiCam_Still::getRotation() {
return _impl->getRotation();
}
unsigned int RaspiCam_Still::getQuality() {
return _impl->getQuality();
}
int RaspiCam_Still::getISO() {
return _impl->getISO();
}
int RaspiCam_Still::getSharpness() {
return _impl->getSharpness();
}
int RaspiCam_Still::getContrast() {
return _impl->getContrast();
}
int RaspiCam_Still::getSaturation() {
return _impl->getSaturation();
}
RASPICAM_ENCODING RaspiCam_Still::getEncoding() {
return _impl->getEncoding();
}
RASPICAM_EXPOSURE RaspiCam_Still::getExposure() {
return _impl->getExposure ();
}
RASPICAM_AWB RaspiCam_Still::getAWB() {
return _impl->getAWB();
}
RASPICAM_IMAGE_EFFECT RaspiCam_Still::getImageEffect() {
return _impl->getImageEffect();
}
RASPICAM_METERING RaspiCam_Still::getMetering() {
return _impl->getMetering();
}
bool RaspiCam_Still::isHorizontallyFlipped() {
return _impl->isHorizontallyFlipped();
}
bool RaspiCam_Still::isVerticallyFlipped() {
return _impl->isVerticallyFlipped();
}
}
+111
View File
@@ -0,0 +1,111 @@
/**********************************************************
Software developed by AVA ( Ava Group of the University of Cordoba, ava at uco dot es)
Main author Rafael Munoz Salinas (rmsalinas at uco dot es)
This software is released under BSD license as expressed below
-------------------------------------------------------------------
Copyright (c) 2013, AVA ( Ava Group University of Cordoba, ava at uco dot es)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software
must display the following acknowledgement:
This product includes software developed by the Ava group of the University of Cordoba.
4. Neither the name of the University nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY AVA ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL AVA BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
****************************************************************/
#ifndef _RaspiCam_STILL_H
#define _RaspiCam_STILL_H
#include "raspicamtypes.h"
#include <cstdio>
namespace raspicam {
namespace _private{
class Private_Impl_Still;
}
/**Raspicam API for still camera
*/
class RaspiCam_Still{
//the implementation of the camera
_private::Private_Impl_Still *_impl;
public:
//Constructor
RaspiCam_Still();
//Destructor
~RaspiCam_Still();
// Opens camera connection
bool open ( );
//Grabs and set the data into the data buffer which has the indicated length. It is your responsability
// to alloc the buffer. You can use getImageBufferSize for that matter.
bool grab_retrieve ( unsigned char * data, unsigned int length );
//Releases the camera
void release();//not working
// Returns the size of the images captured with the current parameters
size_t getImageBufferSize() const;
void commitParameters();
void setWidth ( unsigned int width );
void setHeight ( unsigned int height );
void setCaptureSize ( unsigned int width, unsigned int height );
void setBrightness ( unsigned int brightness );
void setQuality ( unsigned int quality );
void setRotation ( int rotation );
void setISO ( int iso );
void setSharpness ( int sharpness );
void setContrast ( int contrast );
void setSaturation ( int saturation );
void setEncoding ( RASPICAM_ENCODING encoding );
void setExposure ( RASPICAM_EXPOSURE exposure );
void setAWB ( RASPICAM_AWB awb );
void setImageEffect ( RASPICAM_IMAGE_EFFECT imageEffect );
void setMetering ( RASPICAM_METERING metering );
void setHorizontalFlip ( bool hFlip );
void setVerticalFlip ( bool vFlip );
unsigned int getWidth();
unsigned int getHeight();
unsigned int getBrightness();
unsigned int getRotation();
unsigned int getQuality();
int getISO();
int getSharpness();
int getContrast();
int getSaturation();
RASPICAM_ENCODING getEncoding();
RASPICAM_EXPOSURE getExposure();
RASPICAM_AWB getAWB();
RASPICAM_IMAGE_EFFECT getImageEffect();
RASPICAM_METERING getMetering();
bool isHorizontallyFlipped();
bool isVerticallyFlipped();
};
}
#endif
@@ -0,0 +1,185 @@
/**********************************************************
Software developed by AVA ( Ava Group of the University of Cordoba, ava at uco dot es)
Main author Rafael Munoz Salinas (rmsalinas at uco dot es)
This software is released under BSD license as expressed below
-------------------------------------------------------------------
Copyright (c) 2013, AVA ( Ava Group University of Cordoba, ava at uco dot es)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software
must display the following acknowledgement:
This product includes software developed by the Ava group of the University of Cordoba.
4. Neither the name of the University nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY AVA ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL AVA BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
****************************************************************/
#include "private_still/private_still_impl.h"
#include "raspicam_still_cv.h"
#include "scaler.h"
using namespace cv;
namespace raspicam {
RaspiCam_Still_Cv::RaspiCam_Still_Cv() {
_impl= new _private::Private_Impl_Still() ;
_isOpened=false;
image_buffer=0;
_impl->setEncoding ( raspicam::RASPICAM_ENCODING_RGB );
_isGrabbed=false;
_impl->setVerticalFlip(true);
}
RaspiCam_Still_Cv::~RaspiCam_Still_Cv() {
release();
delete _impl;
}
bool RaspiCam_Still_Cv::open ( ) {
_isOpened= _impl->initialize() ==0;
return _isOpened;
}
bool RaspiCam_Still_Cv::isOpened ( ) const{
return _isOpened;
}
bool RaspiCam_Still_Cv::grab () {
if ( image_buffer==0 ) image_buffer=new uchar [ _impl-> getImageBufferSize()];
_isGrabbed= _impl->takePicture ( image_buffer, _impl-> getImageBufferSize() );
return _isGrabbed;
}
void RaspiCam_Still_Cv::retrieve ( cv::Mat &image ) {
if ( image_buffer!=0 && _isGrabbed ) {
image.create ( _impl->getHeight(),_impl->getWidth(),CV_8UC3 );
memcpy ( image.ptr<uchar> ( 0 ),image_buffer,image.cols*image.rows*3 );
}
}
void RaspiCam_Still_Cv::release() {}
/**Returns the specified VideoCapture property
*/
double RaspiCam_Still_Cv::get ( int propId ) {
switch ( propId ) {
case cv::CAP_PROP_FRAME_WIDTH :
return _impl->getWidth();
case cv::CAP_PROP_FRAME_HEIGHT :
return _impl->getHeight();
case cv::CAP_PROP_FPS:
return 30;
case cv::CAP_PROP_FORMAT :
return CV_8UC3;
case cv::CAP_PROP_MODE :
return 0;
case cv::CAP_PROP_BRIGHTNESS :
return _impl->getBrightness();
case cv::CAP_PROP_CONTRAST :
return Scaler::scale ( -100,100,0,100, _impl->getContrast() );
case cv::CAP_PROP_SATURATION :
return Scaler::scale ( -100,100,0,100, _impl->getSaturation() );;
// case cv::CAP_PROP_HUE : return _cam_impl->getSharpness();
case cv::CAP_PROP_GAIN :
return Scaler::scale ( 0,800,0,100, _impl->getISO() );
case cv::CAP_PROP_EXPOSURE :
// if ( _impl->getShutterSpeed() ==0 )
return -1;//not yet
// else return Scaler::scale (0,330000, 0,100, _impl->getShutterSpeed() ) ;
break;
case cv::CAP_PROP_CONVERT_RGB :
return ( true );
// case cv::CAP_PROP_WHITE_BALANCE :return _cam_impl->getAWB();
default :
return -1;
};
}
/**Sets a property in the VideoCapture.
*/
bool RaspiCam_Still_Cv::set ( int propId, double value ) {
switch ( propId ) {
case cv::CAP_PROP_FRAME_WIDTH :
if ( value!=_impl->getWidth() ) {
delete image_buffer;
image_buffer=0;
_impl->setWidth ( value );
}
break;
case cv::CAP_PROP_FRAME_HEIGHT :
if ( value!=_impl->getHeight() ) {
delete image_buffer;
image_buffer=0;
_impl->setHeight ( value );
}
break;
case cv::CAP_PROP_FORMAT : {
return false; //ONLY 8UC3 allowed at this moment
}
break;
case cv::CAP_PROP_MODE ://nothing to do yet
return false;
break;
case cv::CAP_PROP_BRIGHTNESS :
_impl->setBrightness ( value );
break;
case cv::CAP_PROP_CONTRAST :
_impl->setContrast ( Scaler::scale ( 0,100,-100,100, value ) );
break;
case cv::CAP_PROP_SATURATION :
_impl->setSaturation ( Scaler::scale ( 0,100,-100,100, value ) );
break;
// case cv::CAP_PROP_HUE : return _cam_impl->getSharpness();
case cv::CAP_PROP_GAIN :
_impl->setISO ( Scaler::scale ( 0,100,0,800, value ) );
break;
case cv::CAP_PROP_EXPOSURE :
// if ( value>0 && value<=100 ) {
// _impl->setShutterSpeed ( Scaler::scale ( 0,100,0,330000, value ) );
// } else {
// _impl->setExposure ( RASPICAM_EXPOSURE_AUTO );
// _impl->setShutterSpeed ( 0 );
// }
break;
case cv::CAP_PROP_CONVERT_RGB :
// CV_8UC3;
break;
// case cv::CAP_PROP_WHITE_BALANCE :return _cam_impl->getAWB();
default :
return false;
};
return true;
}
std::string RaspiCam_Still_Cv::getId() const{
return _impl->getId();
}
}
+118
View File
@@ -0,0 +1,118 @@
/**********************************************************
Software developed by AVA ( Ava Group of the University of Cordoba, ava at uco dot es)
Main author Rafael Munoz Salinas (rmsalinas at uco dot es)
This software is released under BSD license as expressed below
-------------------------------------------------------------------
Copyright (c) 2013, AVA ( Ava Group University of Cordoba, ava at uco dot es)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software
must display the following acknowledgement:
This product includes software developed by the Ava group of the University of Cordoba.
4. Neither the name of the University nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY AVA ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL AVA BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
****************************************************************/
#ifndef _RaspiCam_STILL_H
#define _RaspiCam_STILL_H
#include <opencv2/highgui/highgui.hpp>
#include "raspicamtypes.h"
#include <cstdio>
#include <opencv2/core/core.hpp>
namespace raspicam {
namespace _private{
class Private_Impl_Still;
}
/**Raspicam API for still camera
*/
class RaspiCam_Still_Cv{
//the implementation of the camera
_private::Private_Impl_Still *_impl;
public:
/**Constructor
*/
RaspiCam_Still_Cv();
/**Destructor
*/
~RaspiCam_Still_Cv();
/** Open capturing device for video capturing
*/
bool open ( void );
/**
* Returns true if video capturing has been initialized already.
*/
bool isOpened() const;
/**
*Closes video file or capturing device.
*/
void release();
/**
* Grabs the next frame from video file or capturing device.
*/
bool grab();
/**
*Decodes and returns the grabbed video frame.
*/
void retrieve ( cv::Mat& image );
/**Returns the specified VideoCapture property
*/
double get ( int propId );
/**Sets a property in the VideoCapture.
*
*
* Implemented properties:
* cv::CAP_PROP_FRAME_WIDTH,cv::CAP_PROP_FRAME_HEIGHT,
* cv::CAP_PROP_FORMAT: CV_8UC1 or CV_8UC3
* cv::CAP_PROP_BRIGHTNESS: [0,100]
* cv::CAP_PROP_CONTRAST: [0,100]
* cv::CAP_PROP_SATURATION: [0,100]
* cv::CAP_PROP_GAIN: (iso): [0,100]
* cv::CAP_PROP_EXPOSURE: -1 auto. [1,100] shutter speed from 0 to 33ms
*
*/
bool set ( int propId, double value );
/** Returns the camera identifier. We assume the camera id is the one of the raspberry obtained using raspberry serial number obtained in /proc/cpuinfo
*/
std::string getId() const;
private:
uchar *image_buffer;
bool _isOpened;
bool _isGrabbed;
};
}
#endif
+132
View File
@@ -0,0 +1,132 @@
/**********************************************************
Software developed by AVA ( Ava Group of the University of Cordoba, ava at uco dot es)
Main author Rafael Munoz Salinas (rmsalinas at uco dot es)
This software is released under BSD license as expressed below
-------------------------------------------------------------------
Copyright (c) 2013, AVA ( Ava Group University of Cordoba, ava at uco dot es)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software
must display the following acknowledgement:
This product includes software developed by the Ava group of the University of Cordoba.
4. Neither the name of the University nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY AVA ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL AVA BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
****************************************************************/
#ifndef _RASPICAM_TYPES_H
#define _RASPICAM_TYPES_H
namespace raspicam {
/**Image formats
*/
enum RASPICAM_FORMAT{
RASPICAM_FORMAT_YUV420,
RASPICAM_FORMAT_GRAY,
RASPICAM_FORMAT_BGR,
RASPICAM_FORMAT_RGB,
RASPICAM_FORMAT_IGNORE //do not use
};
/**Exposure types
*/
enum RASPICAM_EXPOSURE {
RASPICAM_EXPOSURE_OFF,
RASPICAM_EXPOSURE_AUTO,
RASPICAM_EXPOSURE_NIGHT,
RASPICAM_EXPOSURE_NIGHTPREVIEW,
RASPICAM_EXPOSURE_BACKLIGHT,
RASPICAM_EXPOSURE_SPOTLIGHT,
RASPICAM_EXPOSURE_SPORTS,
RASPICAM_EXPOSURE_SNOW,
RASPICAM_EXPOSURE_BEACH,
RASPICAM_EXPOSURE_VERYLONG,
RASPICAM_EXPOSURE_FIXEDFPS,
RASPICAM_EXPOSURE_ANTISHAKE,
RASPICAM_EXPOSURE_FIREWORKS
} ;
/**Auto white balance types
*/
enum RASPICAM_AWB {
RASPICAM_AWB_OFF,
RASPICAM_AWB_AUTO,
RASPICAM_AWB_SUNLIGHT,
RASPICAM_AWB_CLOUDY,
RASPICAM_AWB_SHADE,
RASPICAM_AWB_TUNGSTEN,
RASPICAM_AWB_FLUORESCENT,
RASPICAM_AWB_INCANDESCENT,
RASPICAM_AWB_FLASH,
RASPICAM_AWB_HORIZON
} ;
/**Image effects
*/
enum RASPICAM_IMAGE_EFFECT {
RASPICAM_IMAGE_EFFECT_NONE,
RASPICAM_IMAGE_EFFECT_NEGATIVE,
RASPICAM_IMAGE_EFFECT_SOLARIZE,
RASPICAM_IMAGE_EFFECT_SKETCH,
RASPICAM_IMAGE_EFFECT_DENOISE,
RASPICAM_IMAGE_EFFECT_EMBOSS,
RASPICAM_IMAGE_EFFECT_OILPAINT,
RASPICAM_IMAGE_EFFECT_HATCH,
RASPICAM_IMAGE_EFFECT_GPEN,
RASPICAM_IMAGE_EFFECT_PASTEL,
RASPICAM_IMAGE_EFFECT_WATERCOLOR,
RASPICAM_IMAGE_EFFECT_FILM,
RASPICAM_IMAGE_EFFECT_BLUR,
RASPICAM_IMAGE_EFFECT_SATURATION,
RASPICAM_IMAGE_EFFECT_COLORSWAP,
RASPICAM_IMAGE_EFFECT_WASHEDOUT,
RASPICAM_IMAGE_EFFECT_POSTERISE,
RASPICAM_IMAGE_EFFECT_COLORPOINT,
RASPICAM_IMAGE_EFFECT_COLORBALANCE,
RASPICAM_IMAGE_EFFECT_CARTOON
} ;
/**Metering types
*/
enum RASPICAM_METERING {
RASPICAM_METERING_AVERAGE,
RASPICAM_METERING_SPOT,
RASPICAM_METERING_BACKLIT,
RASPICAM_METERING_MATRIX
} ;
/*Econdig modes (for still mode)
*/
typedef enum RASPICAM_ENCODING {
RASPICAM_ENCODING_JPEG,
RASPICAM_ENCODING_BMP,
RASPICAM_ENCODING_GIF,
RASPICAM_ENCODING_PNG,
RASPICAM_ENCODING_RGB
} RASPICAM_ENCODING;
}
#endif
+47
View File
@@ -0,0 +1,47 @@
#ifndef _RASPICAM_SCALER_H_
#define _RASPICAM_SCALER_H_
namespace raspicam {
/**CLass to calculate linear scale
*/
class Scaler
{
float a,b;
float _inMin, _inMax, _outMin,_outMax;
public:
float aa;
float bb;
Scaler() {}
Scaler ( float inMin, float inMax, float outMin,float outMax ) {
setParams ( inMin,inMax,outMin,outMax );
}
void setParams ( float inMin, float inMax, float outMin,float outMax ) {
_inMin=inMin;
_inMax=inMax;
_outMin=outMin;
_outMax=outMax;
double aux = ( _inMax - _inMin );
if ( aux != 0.0 ) {
a = ( _outMax - _outMin ) /aux;
b = _outMax - ( a * _inMax );
} else
a = b = 0.0;
aa = ( _outMax - _outMin ) / ( _inMax - _inMin );
bb= ( _outMax - ( aa * _inMax ) );
}
inline float operator() ( float val ) const
{
if ( val<=_inMin ) return _outMin;
else if ( val>=_inMax ) return _outMax;
return val * aa + bb;
}
static float scale ( float inMin, float inMax, float outMin,float outMax,float val ) {
Scaler s ( inMin,inMax,outMin,outMax );
return s ( val );
}
};
}
#endif