Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RAW MMAL Buffer callback #51

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,11 @@ set(EXTRA_EXE_LINKER_FLAGS "")
set(EXTRA_EXE_LINKER_FLAGS_RELEASE "")
set(EXTRA_EXE_LINKER_FLAGS_DEBUG "")

IF(CMAKE_COMPILER_IS_GNUCXX OR MINGW)
IF ((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR
(CMAKE_CXX_COMPILER_ID MATCHES "Clang") OR
MINGW
)

set(ENABLE_PROFILING OFF CACHE BOOL "Enable profiling in the GCC compiler (Add flags: -g -pg)")
set(USE_OMIT_FRAME_POINTER ON CACHE BOOL "Enable -fomit-frame-pointer for GCC")
if(${CMAKE_SYSTEM_PROCESSOR} MATCHES arm*) # We can use only -O2 because the -O3 causes gcc crash
Expand Down
17 changes: 15 additions & 2 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,22 @@ 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(public_hdrs_base
raspicamtypes.h
raspicam.h
raspicamrawbuffer.h
)

SET(srcs_base
raspicam.cpp
raspicam_still.cpp
raspicamrawbuffer.cpp
private/private_impl.cpp
private/raspicamrawbuffer_impl.cpp
private/threadcondition.cpp
private_still/private_still_impl.cpp
)

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()
Expand Down
227 changes: 156 additions & 71 deletions src/private/private_impl.cpp

Large diffs are not rendered by default.

28 changes: 26 additions & 2 deletions src/private/private_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "raspicamtypes.h"
#include "private_types.h"
#include "threadcondition.h"

namespace raspicam {
class RaspiCamRawBuffer;
namespace _private
{

Expand Down Expand Up @@ -81,6 +83,10 @@ namespace raspicam {

/* User define callback interface */
void (*_userCallback)(void*) = 0;

void (*_userRawBufferCallback)(const RaspiCamRawBuffer&, void*) = 0;
uint32_t _numRawBuffersUsedByClient;

void* _userCallbackData;

};
Expand All @@ -102,6 +108,7 @@ namespace raspicam {
{
return _isOpened;
}

/**Starts camera capture
*/
bool startCapture();
Expand All @@ -115,6 +122,23 @@ namespace raspicam {
*/
void setUserCallback(void (*userCallback)(void*) , void* data = 0);

/**
* Specify callback which is called every time when new camera raw buffer is
* obtained.
* @param userCallback callback function
* @param data user data you want to pass into callback.
* @param enableZeroCopyMode
* Enable ZERO_COPY mode on the preview port which instructs MMAL to only
* pass the 4-byte opaque buffer handle instead of the contents of the opaque
* buffer.
* The opaque handle is resolved on VideoCore by the GL driver when the EGL
* image is created.
*/
void setRawBufferCallback(
void (*userCallback)(const RaspiCamRawBuffer&, void*) ,
void* data=0,
bool enableZeroCopyMode = false);

/**Grabs the next frame and keeps it in internal buffer. Blocks until next frame arrives
*/
bool grab();
Expand Down Expand Up @@ -261,6 +285,8 @@ namespace raspicam {
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);
static void process_video_buffer(PORT_USERDATA *pData, MMAL_BUFFER_HEADER_T *buffer);

void setDefaultStateParams();
MMAL_COMPONENT_T *create_camera_component ( RASPIVID_STATE *state );
void destroy_camera_component ( RASPIVID_STATE *state );
Expand Down Expand Up @@ -302,8 +328,6 @@ namespace raspicam {
bool _isCapturing;

bool _rgb_bgr_fixed;


};
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/private/private_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ namespace raspicam {
int height; /// requested height of image
int framerate; /// Requested frame rate (fps)
/// the camera output or the encoder output (with compression artifacts)

/// In this case MMAL will pass opaque buffer header only.
/// May be used with rawBufferCallback only.
bool zeroCopyMode;

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
Expand Down
98 changes: 98 additions & 0 deletions src/private/raspicamrawbuffer_impl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/**********************************************************
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 <iostream>

#include "mmal/util/mmal_util.h"
#include "mmal/util/mmal_util_params.h"
#include "mmal/util/mmal_default_components.h"

#include "raspicamrawbuffer_impl.h"

namespace raspicam {
namespace _private {

void RaspiCamRawBufferImpl::moveFrom(RaspiCamRawBufferImpl &src) {
_buffer.reset<MMAL_BUFFER_HEADER_T>(0);
_buffer.swap(src._buffer);
}

void RaspiCamRawBufferImpl::setMmalBufferHeader(MMAL_BUFFER_HEADER_T *buffer) {
_buffer = std::shared_ptr<MMAL_BUFFER_HEADER_T>(buffer, Deleter());

#ifdef RASPICAM_RAW_BUFFER_ENABLE_TRACE
std::cout << std::hex
<< "RaspiCam: buffer " << buffer << "->" << (void*)buffer->data
<< " has been wrapped by RaspiCamRawBuffer."
<< std::endl
<< std::flush;
#endif
}

void* RaspiCamRawBufferImpl::getBuffer() {
return _buffer ? _buffer.get()->data : 0;
}

const void* RaspiCamRawBufferImpl::getBuffer() const {
return _buffer ? _buffer.get()->data : 0;
}

void RaspiCamRawBufferImpl::lock() {
if (_buffer)
mmal_buffer_header_mem_lock(_buffer.get());
}

void RaspiCamRawBufferImpl::unlock() {
if (_buffer)
mmal_buffer_header_mem_unlock(_buffer.get());
}

void RaspiCamRawBufferImpl::Deleter::operator()(MMAL_BUFFER_HEADER_T *_buffer) const {
#ifdef RASPICAM_RAW_BUFFER_ENABLE_TRACE
std::cout << std::hex
<< "RaspiCam: buffer " << _buffer << "->" << (void*)_buffer->data
<< " has been released." << std::endl
<< std::flush;
#endif
mmal_buffer_header_release(_buffer);
}

long RaspiCamRawBufferImpl::getUseCount() const {
return _buffer.use_count();
}
}
}
110 changes: 110 additions & 0 deletions src/private/raspicamrawbuffer_impl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/**********************************************************
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 RaspiCamRawBuffer_Impl_H
#define RaspiCamRawBuffer_Impl_H

#include <memory>

#if 0
// Enables detailed trace about buffer lifetime.
#define RASPICAM_RAW_BUFFER_ENABLE_TRACE
#endif

struct MMAL_BUFFER_HEADER_T;

namespace raspicam {
namespace _private {

/**
* Raspberry Camera RAW buffer implementation.
* In fact this is a wrapper for MMAL buffer.
*/
class RaspiCamRawBufferImpl {
public:

/**
* Move contents
* Moves reference from source to current reference holder.
* After move source refers to nullptr.
* @param src buffer reference to be moved.
*/
void moveFrom(RaspiCamRawBufferImpl& src);

/**
* Setup MMAL buffer header.
* @param buffer MMAL buffer to be wrapped.
* @param acquire true if you want acquire/release to be called for this buffer.
*/
void setMmalBufferHeader(MMAL_BUFFER_HEADER_T *buffer);

/**
* Get buffer contents
* @return buffer contents.
*/
void* getBuffer();

/**
* Get buffer contents
* @return buffer contents.
*/
const void* getBuffer() const;

/**
* Lock buffer's memory.
*/
void lock();

/**
* Unlocks buffer's memory.
*/
void unlock();

long getUseCount() const;

private:

struct Deleter {
void operator()(MMAL_BUFFER_HEADER_T* _buffer) const;
};

std::shared_ptr<MMAL_BUFFER_HEADER_T> _buffer;
};
}
}

#endif
7 changes: 7 additions & 0 deletions src/raspicam.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ namespace raspicam {
_impl->setUserCallback(userCallback, data);
}

void RaspiCam::setRawBufferCallback(
void (* userCallback)(const raspicam::RaspiCamRawBuffer &, void *),
void *data,
bool enableZeroCopyMode) {
_impl->setRawBufferCallback(userCallback, data, enableZeroCopyMode);
}

bool RaspiCam::isOpened() const {return _impl->isOpened();}

bool RaspiCam::grab() {
Expand Down
18 changes: 18 additions & 0 deletions src/raspicam.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ namespace raspicam {
}
/**Base class that do all the hard work
*/
class RaspiCamRawBuffer;
class RaspiCam
{
public:
Expand All @@ -70,6 +71,23 @@ namespace raspicam {
*/
void setUserCallback(void (*userCallback)(void*) , void* data=0);

/**
* Specify callback which is called every time when new camera raw buffer is
* obtained.
* @param userCallback callback function
* @param data user data you want to pass into callback.
* @param enableZeroCopyMode
* Enable ZERO_COPY mode on the preview port which instructs MMAL to only
* pass the 4-byte opaque buffer handle instead of the contents of the opaque
* buffer.
* The opaque handle is resolved on VideoCore by the GL driver when the EGL
* image is created.
*/
void setRawBufferCallback(
void (*userCallback)(const RaspiCamRawBuffer&, void*) ,
void* data=0,
bool enableZeroCopyMode = false);

/**indicates if camera is open
*/
bool isOpened() const ;
Expand Down
Loading