Änderungen Gruppe 30_10_2022 V2
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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, ¶m.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, ¶m.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, ¶m.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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
Reference in New Issue
Block a user